import assert from "node:assert/strict"; import test from "node:test"; import type { PermissionsService } from "@gotgenes/pi-permission-system"; import { formatSshPermissionInput, installSshPermissionIntegration, type SshPermissionConnection, } from "../permission-integration.ts"; function makeService() { const formatters = new Map) => string | undefined>(); const extractors = new Map) => string | undefined>(); const service = { registerToolInputFormatter(name: string, formatter: (input: Record) => string | undefined) { formatters.set(name, formatter); return () => formatters.delete(name); }, registerToolAccessExtractor(name: string, extractor: (input: Record) => string | undefined) { extractors.set(name, extractor); return () => extractors.delete(name); }, } as unknown as PermissionsService; return { service, formatters, extractors }; } function makePi() { const hooks = new Map void>>(); const eventHooks = new Map void>>(); const add = (map: Map void>>, name: string, handler: () => void) => { map.set(name, [...(map.get(name) ?? []), handler]); }; return { api: { on: (name: string, handler: () => void) => add(hooks, name, handler), events: { on: (name: string, handler: () => void) => add(eventHooks, name, handler) }, }, emit: (name: string) => hooks.get(name)?.forEach((handler) => handler()), emitEvent: (name: string) => eventHooks.get(name)?.forEach((handler) => handler()), }; } const connection: SshPermissionConnection = { remote: "packaging-server", port: 2222, remoteCwd: "/srv/build", }; test("formats the SSH target and bounded operation details", () => { assert.equal( formatSshPermissionInput("ssh_read", { path: "src/main.ts", offset: 5, limit: 20 }, connection), "SSH target 'packaging-server:2222' in remote cwd '/srv/build'; read remote path 'src/main.ts', offset 5, limit 20", ); assert.equal( formatSshPermissionInput("ssh_write", { path: "dist/a.txt", content: "one\ntwo" }, connection), "SSH target 'packaging-server:2222' in remote cwd '/srv/build'; write remote path 'dist/a.txt' (2 lines, 7 characters)", ); assert.equal( formatSshPermissionInput("ssh_grep", { pattern: "TODO", path: "src", include: "*.ts", limit: 25 }, connection), "SSH target 'packaging-server:2222' in remote cwd '/srv/build'; search remote file contents under 'src', for 'TODO', limit 25, file glob '*.ts'", ); }); test("registers previews and disables local path extraction for remote file tools", () => { const { service, formatters, extractors } = makeService(); const pi = makePi(); const dispose = installSshPermissionIntegration( pi.api as never, () => connection, { getPermissionsService: () => service, permissionsReadyChannel: "permissions:ready" }, ); assert.deepEqual([...formatters.keys()], ["ssh_read", "ssh_write", "ssh_edit", "ssh_find", "ssh_grep", "ssh_bash"]); assert.deepEqual([...extractors.keys()], ["ssh_read", "ssh_write", "ssh_edit", "ssh_find", "ssh_grep"]); assert.equal(extractors.get("ssh_read")?.({ path: "/remote/secret" }), undefined); assert.equal(extractors.get("ssh_grep")?.({ path: "/remote/src" }), undefined); assert.match(formatters.get("ssh_bash")?.({ command: "git push" }) ?? "", /packaging-server:2222/); dispose(); assert.equal(formatters.size, 0); assert.equal(extractors.size, 0); }); test("registers when the permission service becomes ready and cleans up on shutdown", () => { const { service, formatters, extractors } = makeService(); const pi = makePi(); let published: PermissionsService | undefined; installSshPermissionIntegration(pi.api as never, () => connection, { getPermissionsService: () => published, permissionsReadyChannel: "permissions:ready", }); assert.equal(formatters.size, 0); published = service; pi.emitEvent("permissions:ready"); assert.equal(formatters.size, 6); assert.equal(extractors.size, 5); pi.emit("session_shutdown"); assert.equal(formatters.size, 0); assert.equal(extractors.size, 0); });