@parlor/agent-host 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/acp.d.ts +21 -0
  2. package/dist/acp.d.ts.map +1 -1
  3. package/dist/acp.js +138 -12
  4. package/dist/acp.js.map +1 -1
  5. package/dist/adapter-launch.js.map +1 -1
  6. package/dist/agent-options.d.ts +17 -0
  7. package/dist/agent-options.d.ts.map +1 -0
  8. package/dist/agent-options.js +73 -0
  9. package/dist/agent-options.js.map +1 -0
  10. package/dist/agent-tools.d.ts +30 -0
  11. package/dist/agent-tools.d.ts.map +1 -0
  12. package/dist/agent-tools.js +71 -0
  13. package/dist/agent-tools.js.map +1 -0
  14. package/dist/agents.js.map +1 -1
  15. package/dist/assertion.js.map +1 -1
  16. package/dist/control.d.ts +15 -0
  17. package/dist/control.d.ts.map +1 -1
  18. package/dist/control.js.map +1 -1
  19. package/dist/daemon.d.ts +10 -2
  20. package/dist/daemon.d.ts.map +1 -1
  21. package/dist/daemon.js +149 -14
  22. package/dist/daemon.js.map +1 -1
  23. package/dist/dev-host.js.map +1 -1
  24. package/dist/device-list.js.map +1 -1
  25. package/dist/embedded.js.map +1 -1
  26. package/dist/fold.d.ts.map +1 -1
  27. package/dist/fold.js +2 -0
  28. package/dist/fold.js.map +1 -1
  29. package/dist/grants.d.ts +9 -0
  30. package/dist/grants.d.ts.map +1 -1
  31. package/dist/grants.js.map +1 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/json-file.js.map +1 -1
  34. package/dist/learned.d.ts +23 -0
  35. package/dist/learned.d.ts.map +1 -0
  36. package/dist/learned.js +36 -0
  37. package/dist/learned.js.map +1 -0
  38. package/dist/lines.js.map +1 -1
  39. package/dist/link-device.js.map +1 -1
  40. package/dist/link.js.map +1 -1
  41. package/dist/lock.js.map +1 -1
  42. package/dist/log.js.map +1 -1
  43. package/dist/main.js +105 -9
  44. package/dist/main.js.map +1 -1
  45. package/dist/mcp-proxy.d.ts +26 -3
  46. package/dist/mcp-proxy.d.ts.map +1 -1
  47. package/dist/mcp-proxy.js +180 -9
  48. package/dist/mcp-proxy.js.map +1 -1
  49. package/dist/naming.js.map +1 -1
  50. package/dist/pairing.d.ts +2 -0
  51. package/dist/pairing.d.ts.map +1 -1
  52. package/dist/pairing.js +25 -3
  53. package/dist/pairing.js.map +1 -1
  54. package/dist/paths.d.ts +2 -0
  55. package/dist/paths.d.ts.map +1 -1
  56. package/dist/paths.js +1 -0
  57. package/dist/paths.js.map +1 -1
  58. package/dist/policy.d.ts +12 -2
  59. package/dist/policy.d.ts.map +1 -1
  60. package/dist/policy.js +13 -3
  61. package/dist/policy.js.map +1 -1
  62. package/dist/pool.js.map +1 -1
  63. package/dist/prompter.d.ts +5 -0
  64. package/dist/prompter.d.ts.map +1 -1
  65. package/dist/prompter.js +15 -0
  66. package/dist/prompter.js.map +1 -1
  67. package/dist/release-main.js.map +1 -1
  68. package/dist/release.js.map +1 -1
  69. package/dist/revoke.js.map +1 -1
  70. package/dist/self.js.map +1 -1
  71. package/dist/service.js.map +1 -1
  72. package/dist/shell-path.js.map +1 -1
  73. package/dist/skeleton-kit.js.map +1 -1
  74. package/dist/spec-kit.d.ts +2 -1
  75. package/dist/spec-kit.d.ts.map +1 -1
  76. package/dist/spec-kit.js +6 -1
  77. package/dist/spec-kit.js.map +1 -1
  78. package/dist/testing/fake-agent.d.ts +12 -0
  79. package/dist/testing/fake-agent.d.ts.map +1 -1
  80. package/dist/testing/fake-agent.js +11 -1
  81. package/dist/testing/fake-agent.js.map +1 -1
  82. package/dist/trust.js.map +1 -1
  83. package/dist/turn.d.ts +7 -1
  84. package/dist/turn.d.ts.map +1 -1
  85. package/dist/turn.js +16 -3
  86. package/dist/turn.js.map +1 -1
  87. package/dist/version.js.map +1 -1
  88. package/package.json +9 -9
package/dist/pairing.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createHash, randomBytes, randomInt } from "node:crypto";
2
2
  import { createServer } from "node:http";
3
3
  import { HOST_PAIRING_FRAGMENT, } from "@parlor/auth";
4
+ import { agentToolsName } from "./agent-tools.js";
4
5
  import { hostAssertion } from "./assertion.js";
5
6
  import { workspaceOf } from "./naming.js";
6
7
  import { printable } from "./prompter.js";
@@ -52,7 +53,10 @@ async function loopback(state) {
52
53
  }
53
54
  waiting = response;
54
55
  const code = url.searchParams.get("code");
55
- deliver(code ? { code } : { declined: true });
56
+ const agentTools = url.searchParams.get("agentTools");
57
+ deliver(code
58
+ ? { code, ...(agentTools === null ? {} : { agentTools: agentTools === "on" }) }
59
+ : { declined: true });
56
60
  });
57
61
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
58
62
  const { port } = server.address();
@@ -102,6 +106,11 @@ function timeout(ms) {
102
106
  });
103
107
  return { expired, clear: () => clearTimeout(timer) };
104
108
  }
109
+ /** The pairing secret goes nowhere but the app's own origin; an older app has no landing page. */
110
+ function landingOf(origin, landing) {
111
+ const url = landing === undefined ? undefined : URL.parse(landing, origin);
112
+ return url?.origin === origin ? url : new URL("/", origin);
113
+ }
105
114
  /**
106
115
  * Only the host starts a pairing: it makes the PKCE verifier, `state`, the matching code
107
116
  * and the key pair, so nothing from the web side can complete one.
@@ -109,6 +118,7 @@ function timeout(ms) {
109
118
  export async function pair(input) {
110
119
  const origin = new URL(input.appOrigin).origin;
111
120
  const appName = await appNameOf(origin);
121
+ const toolsName = input.offerAgentTools ? agentToolsName(appName, origin) : undefined;
112
122
  const key = await input.keys.create(origin);
113
123
  const codeVerifier = base64url(randomBytes(32));
114
124
  const pairing = {
@@ -136,6 +146,7 @@ export async function pair(input) {
136
146
  const query = new URLSearchParams({
137
147
  redirectUri: listener.redirectUri,
138
148
  ...pairing,
149
+ ...(toolsName ? { agentTools: "offered" } : {}),
139
150
  });
140
151
  await input.channel.open(`${origin}/_parlor/auth/hosts/authorize?${query}`);
141
152
  const callback = await Promise.race([listener.callback, deadline.expired]);
@@ -155,10 +166,21 @@ export async function pair(input) {
155
166
  }
156
167
  await key.keep(granted.grant.id);
157
168
  const pairingSecret = base64url(randomBytes(32));
158
- listener.redirect(`${origin}/#${new URLSearchParams({ [HOST_PAIRING_FRAGMENT]: pairingSecret })}`);
169
+ const landing = landingOf(origin, granted.landing);
170
+ const agentTools = toolsName && "agentTools" in callback ? callback.agentTools : undefined;
171
+ if (agentTools && toolsName)
172
+ landing.searchParams.set("agentTools", toolsName);
173
+ landing.hash = new URLSearchParams({
174
+ [HOST_PAIRING_FRAGMENT]: pairingSecret,
175
+ }).toString();
176
+ listener.redirect(landing.href);
159
177
  return {
160
178
  paired: true,
161
- grant: { ...grantOf(granted), pairingSecret },
179
+ grant: {
180
+ ...grantOf(granted),
181
+ pairingSecret,
182
+ ...(agentTools === undefined ? {} : { agentTools: { on: agentTools } }),
183
+ },
162
184
  approvedBy: granted.approvedBy,
163
185
  };
164
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pairing.js","sourceRoot":"","sources":["../src/pairing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pairing.js","sourceRoot":"","sources":["../src/pairing.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes, randomInt } from \"node:crypto\";\nimport { createServer, type Server, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport {\n type AccountSummary,\n HOST_PAIRING_FRAGMENT,\n type HostGrantResponse,\n} from \"@parlor/auth\";\nimport type { HostPairing, PairingDevice } from \"@parlor/capabilities\";\n\nimport { agentToolsName } from \"./agent-tools.js\";\nimport { hostAssertion } from \"./assertion.js\";\nimport type { AppGrant, HostKeyPair, HostKeys } from \"./grants.js\";\nimport { workspaceOf } from \"./naming.js\";\nimport { printable } from \"./prompter.js\";\nimport { revokeGrant } from \"./revoke.js\";\n\nexport const PAIRING_TIMEOUT_MS = 10 * 60_000;\n\nexport interface PairingReview {\n readonly appName: string;\n readonly appOrigin: string;\n readonly account: AccountSummary;\n readonly matchingCode: string;\n}\n\n/**\n * `browser`: a one-shot 127.0.0.1 listener (RFC 8252) accepting exactly this attempt's\n * `state`; the consent page is the one decision. `ipc`: the desktop shell's signed-in\n * webview gets the code from the backend and hands it over Tauri IPC, with no consent page,\n * so the shell's native dialog confirms the account the host got back.\n */\nexport type PairingChannel =\n | { readonly kind: \"browser\"; open(url: string): Promise<void> }\n | {\n readonly kind: \"ipc\";\n authorize(pairing: HostPairing): Promise<string>;\n confirm(review: PairingReview): Promise<boolean>;\n };\n\nexport interface PairInput {\n readonly appOrigin: string;\n readonly hostName: string;\n readonly platform: string;\n readonly channel: PairingChannel;\n readonly keys: HostKeys;\n readonly workspaceRoot: string;\n /** Offers, on the consent page, to let the coding agents here use the app outside its sidebar. */\n readonly offerAgentTools?: boolean | undefined;\n}\n\nexport type PairOutcome =\n | {\n readonly paired: true;\n readonly grant: AppGrant;\n readonly approvedBy: HostGrantResponse[\"approvedBy\"];\n }\n | {\n readonly paired: false;\n readonly reason: \"declined_locally\" | \"declined_in_app\" | \"timeout\";\n };\n\nexport class UnrevokedGrant extends Error {\n override readonly name = \"UnrevokedGrant\";\n constructor(\n readonly grant: AppGrant,\n cause: Error,\n ) {\n super(cause.message, { cause });\n }\n}\n\nconst MATCHING_ALPHABET = \"ABCDEFGHJKLMNPQRSTUVWXYZ23456789\";\n\nconst base64url = (bytes: Buffer) => bytes.toString(\"base64url\");\n\nfunction matchingCode(): string {\n const part = () =>\n Array.from(\n { length: 3 },\n () => MATCHING_ALPHABET[randomInt(MATCHING_ALPHABET.length)],\n ).join(\"\");\n return `${part()}-${part()}`;\n}\n\nasync function appNameOf(origin: string): Promise<string> {\n const response = await fetch(`${origin}/_parlor/manifest`);\n if (!response.ok) {\n throw new Error(`${origin} answered HTTP ${response.status}; is it a Parlor app?`);\n }\n const manifest = (await response.json()) as {\n readonly app?: { readonly name?: unknown };\n };\n return typeof manifest.app?.name === \"string\"\n ? manifest.app.name\n : new URL(origin).host;\n}\n\ntype Callback =\n | { readonly code: string; readonly agentTools?: boolean | undefined }\n | { readonly declined: true };\n\nconst escapeHtml = (text: string) =>\n printable(text).replace(/[&<>\"']/g, (char) => `&#${char.charCodeAt(0)};`);\n\nconst RESULT_STYLE = `:root{color-scheme:light dark;--bg:#f6f6f4;--card:#fff;--text:#1d1d1b;--muted:#5f5f5a;--line:#e2e2dc}@media (prefers-color-scheme:dark){:root{--bg:#151514;--card:#1f1f1d;--text:#ededea;--muted:#a3a39d;--line:#34342f}}*{box-sizing:border-box}body{margin:0;min-height:100vh;display:grid;place-items:center;padding:16px;background:var(--bg);color:var(--text);font:15px/1.5 system-ui,-apple-system,\"Segoe UI\",sans-serif}main{width:100%;max-width:420px;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:28px}h1{font-size:20px;line-height:1.3;margin:0 0 8px}p{margin:0;color:var(--muted)}`;\n\nfunction resultPage(heading: string, detail: string): string {\n return `<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>${escapeHtml(heading)}</title><style>${RESULT_STYLE}</style></head><body><main><h1>${escapeHtml(heading)}</h1><p>${escapeHtml(detail)}</p></main></body></html>`;\n}\n\n/** Holds the browser's request until the exchange settles, so the tab says what happened. */\nasync function loopback(state: string): Promise<{\n readonly redirectUri: string;\n readonly callback: Promise<Callback>;\n readonly answer: (heading: string, detail: string) => void;\n readonly redirect: (url: string) => void;\n readonly close: () => void;\n}> {\n let deliver: (callback: Callback) => void = () => undefined;\n const callback = new Promise<Callback>((resolve) => (deliver = resolve));\n let waiting: ServerResponse | undefined;\n const server: Server = createServer((request, response) => {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (\n waiting ||\n url.pathname !== \"/callback\" ||\n url.searchParams.get(\"state\") !== state\n ) {\n response\n .writeHead(404, { \"content-type\": \"text/plain\" })\n .end(\"Not this connection.\");\n return;\n }\n waiting = response;\n const code = url.searchParams.get(\"code\");\n const agentTools = url.searchParams.get(\"agentTools\");\n deliver(\n code\n ? { code, ...(agentTools === null ? {} : { agentTools: agentTools === \"on\" }) }\n : { declined: true },\n );\n });\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n const { port } = server.address() as AddressInfo;\n const answer = (heading: string, detail: string) => {\n if (!waiting || waiting.headersSent) return;\n waiting\n .writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" })\n .end(resultPage(heading, detail));\n };\n return {\n redirectUri: `http://127.0.0.1:${port}/callback`,\n callback,\n answer,\n redirect: (url) => {\n if (!waiting || waiting.headersSent) return;\n waiting.writeHead(303, { location: url, \"cache-control\": \"no-store\" }).end();\n },\n close: () => {\n answer(\"Parlor Host stopped\", \"Go back to your terminal.\");\n server.close();\n },\n };\n}\n\nasync function exchange(\n origin: string,\n key: HostKeyPair,\n code: string,\n codeVerifier: string,\n): Promise<HostGrantResponse> {\n const response = await fetch(`${origin}/_parlor/auth/hosts/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n code,\n codeVerifier,\n publicKey: key.publicKey,\n proof: await key.sign(new TextEncoder().encode(code)),\n }),\n });\n const body = (await response.json().catch(() => undefined)) as\n | (HostGrantResponse & { readonly error?: { readonly message?: string } })\n | undefined;\n if (!response.ok || !body?.grant) {\n throw new Error(body?.error?.message ?? `The app answered HTTP ${response.status}.`);\n }\n return body;\n}\n\nfunction timeout(ms: number): {\n readonly expired: Promise<\"timeout\">;\n readonly clear: () => void;\n} {\n let timer: NodeJS.Timeout | undefined;\n const expired = new Promise<\"timeout\">((resolve) => {\n timer = setTimeout(() => resolve(\"timeout\"), ms);\n });\n return { expired, clear: () => clearTimeout(timer) };\n}\n\n/** The pairing secret goes nowhere but the app's own origin; an older app has no landing page. */\nfunction landingOf(origin: string, landing: string | undefined): URL {\n const url = landing === undefined ? undefined : URL.parse(landing, origin);\n return url?.origin === origin ? url : new URL(\"/\", origin);\n}\n\n/**\n * Only the host starts a pairing: it makes the PKCE verifier, `state`, the matching code\n * and the key pair, so nothing from the web side can complete one.\n */\nexport async function pair(input: PairInput): Promise<PairOutcome> {\n const origin = new URL(input.appOrigin).origin;\n const appName = await appNameOf(origin);\n const toolsName = input.offerAgentTools ? agentToolsName(appName, origin) : undefined;\n const key = await input.keys.create(origin);\n const codeVerifier = base64url(randomBytes(32));\n const pairing: HostPairing = {\n hostName: input.hostName,\n platform: input.platform,\n codeChallenge: base64url(createHash(\"sha256\").update(codeVerifier).digest()),\n state: base64url(randomBytes(16)),\n matchingCode: matchingCode(),\n keyThumbprint: key.thumbprint,\n };\n const grantOf = (granted: HostGrantResponse): AppGrant => ({\n appOrigin: origin,\n appName,\n grantId: granted.grant.id,\n hostId: granted.grant.hostId,\n account: granted.account,\n workspace: workspaceOf(input.workspaceRoot, origin),\n createdAt: Date.now(),\n });\n const deadline = timeout(PAIRING_TIMEOUT_MS);\n try {\n if (input.channel.kind === \"browser\") {\n const listener = await loopback(pairing.state);\n try {\n const query = new URLSearchParams({\n redirectUri: listener.redirectUri,\n ...pairing,\n ...(toolsName ? { agentTools: \"offered\" } : {}),\n });\n await input.channel.open(`${origin}/_parlor/auth/hosts/authorize?${query}`);\n const callback = await Promise.race([listener.callback, deadline.expired]);\n if (callback === \"timeout\") return { paired: false, reason: \"timeout\" };\n if (!(\"code\" in callback)) {\n listener.answer(\"Not connected\", \"You cancelled the connection.\");\n return { paired: false, reason: \"declined_in_app\" };\n }\n let granted: HostGrantResponse;\n try {\n granted = await exchange(origin, key, callback.code, codeVerifier);\n } catch (error) {\n listener.answer(\"Not connected\", (error as Error).message);\n throw error;\n }\n await key.keep(granted.grant.id);\n const pairingSecret = base64url(randomBytes(32));\n const landing = landingOf(origin, granted.landing);\n const agentTools =\n toolsName && \"agentTools\" in callback ? callback.agentTools : undefined;\n if (agentTools && toolsName) landing.searchParams.set(\"agentTools\", toolsName);\n landing.hash = new URLSearchParams({\n [HOST_PAIRING_FRAGMENT]: pairingSecret,\n }).toString();\n listener.redirect(landing.href);\n return {\n paired: true,\n grant: {\n ...grantOf(granted),\n pairingSecret,\n ...(agentTools === undefined ? {} : { agentTools: { on: agentTools } }),\n },\n approvedBy: granted.approvedBy,\n };\n } finally {\n listener.close();\n }\n }\n\n const callback = await Promise.race([\n input.channel.authorize(pairing).then((code) => ({ code })),\n deadline.expired,\n ]);\n if (callback === \"timeout\") return { paired: false, reason: \"timeout\" };\n const granted = await exchange(origin, key, callback.code, codeVerifier);\n const grant = grantOf(granted);\n const confirmed = await Promise.race([\n input.channel.confirm({\n appName,\n appOrigin: origin,\n account: granted.account,\n matchingCode: pairing.matchingCode,\n }),\n deadline.expired,\n ]);\n if (confirmed !== true) {\n await revokeGrant({\n appOrigin: origin,\n appName,\n assert: (request) =>\n hostAssertion(\n (payload) => key.sign(payload),\n { kid: key.thumbprint, grantId: grant.grantId },\n request,\n ),\n }).catch(async (error: Error) => {\n await key.keep(grant.grantId);\n throw new UnrevokedGrant({ ...grant, declined: true }, error);\n });\n return {\n paired: false,\n reason: confirmed === \"timeout\" ? \"timeout\" : \"declined_locally\",\n };\n }\n await key.keep(grant.grantId);\n return { paired: true, grant, approvedBy: granted.approvedBy };\n } finally {\n deadline.clear();\n }\n}\n\ninterface Deferred<T> {\n readonly promise: Promise<T>;\n readonly resolve: (value: T) => void;\n readonly reject: (error: unknown) => void;\n}\n\nfunction deferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<T>((done, fail) => {\n resolve = done;\n reject = fail;\n });\n promise.catch(() => undefined);\n return { promise, resolve, reject };\n}\n\nexport interface LocalPairingReview {\n readonly account: string;\n readonly appName: string;\n readonly matchingCode: string;\n}\n\n/**\n * A pairing driven over the control socket by the desktop shell: `pairing` once the host\n * made its key and code, `finish` with the code the signed-in page got from the backend,\n * `confirm` with the user's answer in the native dialog.\n */\nexport interface LocalPairing {\n readonly pairing: Promise<HostPairing>;\n finish(code: string): Promise<LocalPairingReview>;\n confirm(connect: boolean): Promise<PairOutcome>;\n}\n\nexport function startLocalPairing(input: Omit<PairInput, \"channel\">): LocalPairing {\n const ready = deferred<HostPairing>();\n const code = deferred<string>();\n const review = deferred<LocalPairingReview>();\n const decision = deferred<boolean>();\n const outcome = pair({\n ...input,\n channel: {\n kind: \"ipc\",\n authorize: (pairing) => {\n ready.resolve(pairing);\n return code.promise;\n },\n confirm: (shown) => {\n review.resolve({\n account: printable(shown.account.email ?? shown.account.name),\n appName: printable(shown.appName),\n matchingCode: shown.matchingCode,\n });\n return decision.promise;\n },\n },\n });\n outcome.then(\n (result) => {\n if (result.paired) return;\n const stopped = new Error(`The pairing ended: ${result.reason}.`);\n ready.reject(stopped);\n review.reject(stopped);\n },\n (error: unknown) => {\n ready.reject(error);\n review.reject(error);\n },\n );\n outcome.catch(() => undefined);\n return {\n pairing: ready.promise,\n finish: (value) => {\n code.resolve(value);\n return review.promise;\n },\n confirm: (connect) => {\n decision.resolve(connect);\n return outcome;\n },\n };\n}\n\nconst isText = (value: unknown): value is string =>\n typeof value === \"string\" && value !== \"\";\n\ntype Point = JsonWebKey & { readonly x: string; readonly y: string };\n\nconst isPoint = (value: unknown): value is Point => {\n if (typeof value !== \"object\" || value === null) return false;\n const key = value as Record<string, unknown>;\n return key.kty === \"EC\" && key.crv === \"P-256\" && isText(key.x) && isText(key.y);\n};\n\nfunction presenceKeyOf(value: unknown): PairingDevice[\"presenceKey\"] {\n if (typeof value !== \"object\" || value === null) return undefined;\n const key = value as Record<string, unknown>;\n if (!isPoint(key.publicKey)) return undefined;\n const publicKey = { kty: \"EC\", crv: \"P-256\", x: key.publicKey.x, y: key.publicKey.y };\n if (key.format === \"webauthn\" && isText(key.credentialId) && isText(key.rpId)) {\n return {\n format: \"webauthn\",\n credentialId: key.credentialId,\n rpId: key.rpId,\n publicKey,\n };\n }\n if (key.format === \"es256-raw\" && isText(key.keyId)) {\n return { format: \"es256-raw\", keyId: key.keyId, publicKey };\n }\n return undefined;\n}\n\nexport function pairingDeviceOf(value: unknown): PairingDevice | undefined {\n if (typeof value !== \"object\" || value === null) return undefined;\n const device = value as Record<string, unknown>;\n if (!isText(device.deviceId) || !isText(device.name) || !isText(device.platform)) {\n return undefined;\n }\n if (!isPoint(device.signingKey)) return undefined;\n return {\n deviceId: device.deviceId,\n name: device.name,\n platform: device.platform,\n signingKey: {\n kty: \"EC\",\n crv: \"P-256\",\n x: device.signingKey.x,\n y: device.signingKey.y,\n },\n presenceKey: presenceKeyOf(device.presenceKey),\n };\n}\n"]}
package/dist/paths.d.ts CHANGED
@@ -5,6 +5,8 @@ export interface HostPaths {
5
5
  readonly policy: string;
6
6
  readonly sessions: string;
7
7
  readonly agents: string;
8
+ /** What each agent last said about itself: its options and the account's allowance. */
9
+ readonly learned: string;
8
10
  readonly control: string;
9
11
  readonly proxy: string;
10
12
  readonly versions: string;
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kGAAkG;IAClG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAA2C,GAAG,SAAS,CAmBtF"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kGAAkG;IAClG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAA2C,GAAG,SAAS,CAoBtF"}
package/dist/paths.js CHANGED
@@ -10,6 +10,7 @@ export function hostPaths(root = join(homedir(), ".parlor", "host")) {
10
10
  policy: join(root, "policy.json"),
11
11
  sessions: join(root, "sessions.json"),
12
12
  agents: join(root, "agents.json"),
13
+ learned: join(root, "learned.json"),
13
14
  control: join(run, "control.sock"),
14
15
  proxy: join(run, "proxy.sock"),
15
16
  versions: join(root, "versions"),
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAoB1C,MAAM,UAAU,SAAS,CAAC,IAAI,GAAW,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC;IACzE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC;QAC/B,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC;QACrC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC;QAClC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC;QAC9B,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;QAChC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC;QAC9B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,uBAAuB,CAAC;QAC3E,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;KACjC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsB1C,MAAM,UAAU,SAAS,CAAC,IAAI,GAAW,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC;IACzE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC;QAC/B,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC;QACrC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;QACnC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC;QAClC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC;QAC9B,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;QAChC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC;QAC9B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,uBAAuB,CAAC;QAC3E,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;KACjC,CAAC;AACJ,CAAC","sourcesContent":["import { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport interface HostPaths {\n readonly root: string;\n readonly grants: string;\n readonly trust: string;\n readonly policy: string;\n readonly sessions: string;\n readonly agents: string;\n /** What each agent last said about itself: its options and the account's allowance. */\n readonly learned: string;\n readonly control: string;\n readonly proxy: string;\n readonly versions: string;\n /** What the login item points at; a link into `versions/<version>/`, never into an app bundle. */\n readonly current: string;\n readonly lock: string;\n readonly logs: string;\n readonly launchAgent: string;\n readonly workspaces: string;\n}\n\nexport function hostPaths(root: string = join(homedir(), \".parlor\", \"host\")): HostPaths {\n const run = join(root, \"run\");\n const home = dirname(dirname(root));\n return {\n root,\n grants: join(root, \"grants.json\"),\n trust: join(root, \"trust.json\"),\n policy: join(root, \"policy.json\"),\n sessions: join(root, \"sessions.json\"),\n agents: join(root, \"agents.json\"),\n learned: join(root, \"learned.json\"),\n control: join(run, \"control.sock\"),\n proxy: join(run, \"proxy.sock\"),\n versions: join(root, \"versions\"),\n current: join(root, \"current\"),\n lock: join(root, \"service.lock\"),\n logs: join(root, \"logs\"),\n launchAgent: join(home, \"Library\", \"LaunchAgents\", \"dev.parlor.host.plist\"),\n workspaces: join(home, \"Parlor\"),\n };\n}\n"]}
package/dist/policy.d.ts CHANGED
@@ -19,6 +19,11 @@ export interface RemotePolicy {
19
19
  readonly promptPresence?: {
20
20
  readonly maxAgeHours: number;
21
21
  } | "off" | undefined;
22
+ /**
23
+ * `auto`: the agent's own safety review decides, asking only for what it flags, where the
24
+ * agent has one. `ask`: it asks before every action. Absent: `auto`.
25
+ */
26
+ readonly agentMode?: "auto" | "ask" | undefined;
22
27
  }
23
28
  export declare const DEFAULT_POLICY: RemotePolicy;
24
29
  export declare const DEV_POLICY: RemotePolicy;
@@ -29,8 +34,13 @@ export declare function presenceDueAt(policy: RemotePolicy, device: TrustedDevic
29
34
  * app's `confirm: true`, and asking twice only teaches users to click through.
30
35
  */
31
36
  export declare function isAppTool(ask: AgentAsk, appServer: string): boolean;
32
- /** The ask item's `approval`; `undefined` lets any trusted device answer without presence. */
33
- export declare function approvalFor(policy: RemotePolicy, ask: AgentAsk): "presence" | "computer" | undefined;
37
+ /**
38
+ * The ask item's `approval`; `undefined` lets any trusted device answer without presence.
39
+ * Where presence is wanted, the browser that approved `connect` here answers its own turn's
40
+ * asks in the chat, since the loopback redirect put it on this computer; any other device
41
+ * without presence leaves them to this computer.
42
+ */
43
+ export declare function approvalFor(policy: RemotePolicy, ask: AgentAsk, device?: Pick<TrustedDevice, "presenceKey" | "via">): "presence" | "computer" | "device" | undefined;
34
44
  /** `base` with the settings `parlor-host config` wrote to `file`; read afresh on every call. */
35
45
  export declare function loadPolicy(file: string, base: RemotePolicy): Promise<RemotePolicy>;
36
46
  export declare function changePolicy(file: string, base: RemotePolicy, change: Partial<RemotePolicy>): Promise<RemotePolicy>;
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,8FAA8F;IAC9F,QAAQ,CAAC,cAAc,EAAE,OAAO,GAAG,KAAK,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,KAAK,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,GAAG,SAAS,CAAC;CAChF;AAED,eAAO,MAAM,cAAc,EAAE,YAI5B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAIxB,CAAC;AAEF,4FAA4F;AAC5F,wBAAgB,aAAa,CAC3B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,aAAa,GACpB,MAAM,GAAG,SAAS,CAIpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,8FAA8F;AAC9F,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,QAAQ,GACZ,UAAU,GAAG,UAAU,GAAG,SAAS,CAGrC;AAOD,gGAAgG;AAChG,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,YAAY,CAAC,CAYvB;AAaD,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAC5B,OAAO,CAAC,YAAY,CAAC,CAGvB"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,8FAA8F;IAC9F,QAAQ,CAAC,cAAc,EAAE,OAAO,GAAG,KAAK,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,KAAK,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/E;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;CACjD;AAED,eAAO,MAAM,cAAc,EAAE,YAK5B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,YAKxB,CAAC;AAEF,4FAA4F;AAC5F,wBAAgB,aAAa,CAC3B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,aAAa,GACpB,MAAM,GAAG,SAAS,CAIpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,QAAQ,EACb,MAAM,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,KAAK,CAAC,GAClD,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAKhD;AAOD,gGAAgG;AAChG,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,YAAY,CAAC,CAiBvB;AAaD,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAC5B,OAAO,CAAC,YAAY,CAAC,CAGvB"}
package/dist/policy.js CHANGED
@@ -3,11 +3,13 @@ export const DEFAULT_POLICY = {
3
3
  deviceApproval: "local",
4
4
  answers: "presence",
5
5
  promptPresence: { maxAgeHours: 18 },
6
+ agentMode: "auto",
6
7
  };
7
8
  export const DEV_POLICY = {
8
9
  deviceApproval: "off",
9
10
  answers: "off",
10
11
  promptPresence: "off",
12
+ agentMode: "auto",
11
13
  };
12
14
  /** When `device`'s prompts need Face ID or Touch ID again; undefined when they never do. */
13
15
  export function presenceDueAt(policy, device) {
@@ -23,11 +25,18 @@ export function presenceDueAt(policy, device) {
23
25
  export function isAppTool(ask, appServer) {
24
26
  return ask.kind === "permission" && ask.mcp?.server === appServer;
25
27
  }
26
- /** The ask item's `approval`; `undefined` lets any trusted device answer without presence. */
27
- export function approvalFor(policy, ask) {
28
+ /**
29
+ * The ask item's `approval`; `undefined` lets any trusted device answer without presence.
30
+ * Where presence is wanted, the browser that approved `connect` here answers its own turn's
31
+ * asks in the chat, since the loopback redirect put it on this computer; any other device
32
+ * without presence leaves them to this computer.
33
+ */
34
+ export function approvalFor(policy, ask, device) {
28
35
  if (ask.kind === "question" || policy.answers === "off")
29
36
  return undefined;
30
- return policy.answers;
37
+ if (policy.answers === "computer" || !device || device.presenceKey)
38
+ return policy.answers;
39
+ return device.via === "pairing" ? "device" : "computer";
31
40
  }
32
41
  const choose = (allowed, value, base) => allowed.find((candidate) => candidate === value) ?? base;
33
42
  /** `base` with the settings `parlor-host config` wrote to `file`; read afresh on every call. */
@@ -43,6 +52,7 @@ export async function loadPolicy(file, base) {
43
52
  deviceApproval: choose(["local", "off"], overlay.deviceApproval, base.deviceApproval),
44
53
  answers: choose(["presence", "computer", "off"], overlay.answers, base.answers),
45
54
  promptPresence: promptPresenceOf(overlay.promptPresence, base.promptPresence),
55
+ agentMode: choose(["auto", "ask"], overlay.agentMode, base.agentMode ?? "auto"),
46
56
  };
47
57
  }
48
58
  function promptPresenceOf(value, base) {
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentAsk } from \"./acp.js\";\nimport { jsonFile } from \"./json-file.js\";\nimport type { TrustedDevice } from \"./trust.js\";\n\n/**\n * What this computer enforces on remote turns, whatever the app or its backend says. Set\n * only on this computer (`parlor-host config` or the Mac app's settings).\n */\nexport interface RemotePolicy {\n /** `local`: an untrusted device is approved in a dialog here before its first prompt runs. */\n readonly deviceApproval: \"local\" | \"off\";\n /**\n * Where an answer to the agent's own permission prompts counts: on any trusted device\n * with presence, only on this computer, or (`parlor dev` only) anywhere.\n */\n readonly answers: \"presence\" | \"computer\" | \"off\";\n /**\n * How long a linked device with Face ID or Touch ID sends before its next prompt needs them\n * again. Absent: never.\n */\n readonly promptPresence?: { readonly maxAgeHours: number } | \"off\" | undefined;\n /**\n * `auto`: the agent's own safety review decides, asking only for what it flags, where the\n * agent has one. `ask`: it asks before every action. Absent: `auto`.\n */\n readonly agentMode?: \"auto\" | \"ask\" | undefined;\n}\n\nexport const DEFAULT_POLICY: RemotePolicy = {\n deviceApproval: \"local\",\n answers: \"presence\",\n promptPresence: { maxAgeHours: 18 },\n agentMode: \"auto\",\n};\n\nexport const DEV_POLICY: RemotePolicy = {\n deviceApproval: \"off\",\n answers: \"off\",\n promptPresence: \"off\",\n agentMode: \"auto\",\n};\n\n/** When `device`'s prompts need Face ID or Touch ID again; undefined when they never do. */\nexport function presenceDueAt(\n policy: RemotePolicy,\n device: TrustedDevice,\n): number | undefined {\n const setting = policy.promptPresence;\n if (setting === undefined || setting === \"off\" || !device.presenceKey) return undefined;\n return (device.presenceAt ?? device.approvedAt) + setting.maxAgeHours * 3_600_000;\n}\n\n/**\n * The app's own tools are allowed once without asking: the server already enforces the\n * app's `confirm: true`, and asking twice only teaches users to click through.\n */\nexport function isAppTool(ask: AgentAsk, appServer: string): boolean {\n return ask.kind === \"permission\" && ask.mcp?.server === appServer;\n}\n\n/**\n * The ask item's `approval`; `undefined` lets any trusted device answer without presence.\n * Where presence is wanted, the browser that approved `connect` here answers its own turn's\n * asks in the chat, since the loopback redirect put it on this computer; any other device\n * without presence leaves them to this computer.\n */\nexport function approvalFor(\n policy: RemotePolicy,\n ask: AgentAsk,\n device?: Pick<TrustedDevice, \"presenceKey\" | \"via\">,\n): \"presence\" | \"computer\" | \"device\" | undefined {\n if (ask.kind === \"question\" || policy.answers === \"off\") return undefined;\n if (policy.answers === \"computer\" || !device || device.presenceKey)\n return policy.answers;\n return device.via === \"pairing\" ? \"device\" : \"computer\";\n}\n\ntype Overlay = { readonly [K in keyof RemotePolicy]?: unknown };\n\nconst choose = <T extends string>(allowed: readonly T[], value: unknown, base: T): T =>\n allowed.find((candidate) => candidate === value) ?? base;\n\n/** `base` with the settings `parlor-host config` wrote to `file`; read afresh on every call. */\nexport async function loadPolicy(\n file: string,\n base: RemotePolicy,\n): Promise<RemotePolicy> {\n let overlay: Overlay;\n try {\n overlay = await jsonFile<Overlay>(file).read();\n } catch {\n return base;\n }\n return {\n deviceApproval: choose([\"local\", \"off\"], overlay.deviceApproval, base.deviceApproval),\n answers: choose([\"presence\", \"computer\", \"off\"], overlay.answers, base.answers),\n promptPresence: promptPresenceOf(overlay.promptPresence, base.promptPresence),\n agentMode: choose(\n [\"auto\", \"ask\"] as const,\n overlay.agentMode,\n base.agentMode ?? \"auto\",\n ),\n };\n}\n\nfunction promptPresenceOf(\n value: unknown,\n base: RemotePolicy[\"promptPresence\"],\n): RemotePolicy[\"promptPresence\"] {\n if (value === \"off\") return \"off\";\n const hours = (value as { readonly maxAgeHours?: unknown } | null)?.maxAgeHours;\n return typeof hours === \"number\" && Number.isFinite(hours) && hours > 0\n ? { maxAgeHours: hours }\n : base;\n}\n\nexport async function changePolicy(\n file: string,\n base: RemotePolicy,\n change: Partial<RemotePolicy>,\n): Promise<RemotePolicy> {\n await jsonFile<Overlay>(file).change((overlay) => Object.assign(overlay, change));\n return loadPolicy(file, base);\n}\n"]}
package/dist/pool.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentConnection, AgentSession } from \"./acp.js\";\nimport type { AppGrant } from \"./grants.js\";\nimport { jsonFile } from \"./json-file.js\";\nimport type { ProxySession } from \"./mcp-proxy.js\";\n\nexport interface LiveSession {\n readonly session: AgentSession;\n readonly proxy: ProxySession;\n}\n\nexport type PooledGrant = Pick<AppGrant, \"appOrigin\" | \"grantId\">;\n\n/**\n * Processes per (app, agent), so two apps never share an agent process or its MCP\n * servers; sessions per (grant, thread, agent), so a thread keeps its context across\n * turns and never carries it to another account.\n */\nexport interface SessionPool {\n process(appOrigin: string, agentId: string): AgentConnection | undefined;\n /**\n * The running process, or the one `start` launches for every turn that asks meanwhile.\n * A `drop` during the launch aborts `signal` and kills whatever `start` returns.\n */\n launch(\n appOrigin: string,\n agentId: string,\n start: (signal: AbortSignal) => Promise<AgentConnection>,\n ): Promise<AgentConnection>;\n session(grant: PooledGrant, threadId: string, agentId: string): LiveSession | undefined;\n remember(\n grant: PooledGrant,\n threadId: string,\n agentId: string,\n session: LiveSession,\n ): void;\n /** The last session id, from `sessions.json`, for `session/resume` after a restart. */\n resumable(\n grant: PooledGrant,\n threadId: string,\n agentId: string,\n ): Promise<string | undefined>;\n drop(appOrigin: string, agentId?: string): Promise<void>;\n /** Erases the grant's remembered session ids, once the grant is gone. */\n forget(grant: PooledGrant): Promise<void>;\n}\n\nconst keyOf = (...parts: readonly string[]) => parts.join(\"\\u0000\");\n\nconst sessionKeyOf = (grant: PooledGrant, threadId: string, agentId: string) =>\n keyOf(grant.appOrigin, grant.grantId, threadId, agentId);\n\ninterface Launching {\n readonly controller: AbortController;\n readonly connection: Promise<AgentConnection>;\n}\n\n/**\n * Sessions live inside their process: `launch()` hands out the connection with its\n * sessions tracked, so dropping a process forgets every session it held.\n */\nexport function createSessionPool(stateFile: string): SessionPool {\n const processes = new Map<string, AgentConnection>();\n const launching = new Map<string, Launching>();\n const owners = new WeakMap<AgentSession, string>();\n const sessions = new Map<\n string,\n { readonly live: LiveSession; readonly owner: string }\n >();\n const remembered = jsonFile<Record<string, string>>(stateFile);\n\n const discard = (owner: string) => {\n processes.delete(owner);\n for (const [key, entry] of sessions) {\n if (entry.owner !== owner) continue;\n entry.live.proxy.dispose();\n sessions.delete(key);\n }\n };\n\n const adopt = (owner: string, connection: AgentConnection): AgentConnection => {\n const tracked: AgentConnection = {\n capabilities: connection.capabilities,\n exited: connection.exited,\n kill: () => connection.kill(),\n openSession: async (input) => {\n const session = await connection.openSession(input);\n owners.set(session, owner);\n return session;\n },\n };\n processes.set(owner, tracked);\n void connection.exited.then(() => {\n if (processes.get(owner) === tracked) discard(owner);\n });\n return tracked;\n };\n\n const ownedBy = (appOrigin: string, agentId: string | undefined) => (owner: string) =>\n agentId === undefined\n ? owner.startsWith(keyOf(appOrigin, \"\"))\n : owner === keyOf(appOrigin, agentId);\n\n return {\n process: (appOrigin, agentId) => processes.get(keyOf(appOrigin, agentId)),\n launch(appOrigin, agentId, start) {\n const owner = keyOf(appOrigin, agentId);\n const running = processes.get(owner);\n if (running) return Promise.resolve(running);\n const pending = launching.get(owner);\n if (pending) return pending.connection;\n const controller = new AbortController();\n const connection = (async () => {\n try {\n const started = await start(controller.signal);\n if (controller.signal.aborted) {\n await started.kill();\n throw new Error(\n \"This computer stopped serving the app while the agent started.\",\n );\n }\n return adopt(owner, started);\n } finally {\n if (launching.get(owner)?.controller === controller) launching.delete(owner);\n }\n })();\n launching.set(owner, { controller, connection });\n return connection;\n },\n session: (grant, threadId, agentId) =>\n sessions.get(sessionKeyOf(grant, threadId, agentId))?.live,\n remember(grant, threadId, agentId, live) {\n const owner = keyOf(grant.appOrigin, agentId);\n if (owners.get(live.session) !== owner || processes.get(owner) === undefined) {\n throw new Error(\"Remember a session opened through the pool's own process.\");\n }\n const key = sessionKeyOf(grant, threadId, agentId);\n sessions.set(key, { live, owner });\n void remembered\n .change((all) => void (all[key] = live.session.id))\n .catch(() => undefined);\n },\n resumable: async (grant, threadId, agentId) => {\n const all = await remembered.read().catch(() => ({}) as Record<string, string>);\n return all[sessionKeyOf(grant, threadId, agentId)];\n },\n async drop(appOrigin, agentId) {\n const owned = ownedBy(appOrigin, agentId);\n for (const [owner, pending] of launching) {\n if (!owned(owner)) continue;\n launching.delete(owner);\n pending.controller.abort();\n }\n const dropped = [...processes].filter(([owner]) => owned(owner));\n for (const [owner] of dropped) discard(owner);\n await Promise.all(dropped.map(([, connection]) => connection.kill()));\n },\n async forget(grant) {\n const prefix = keyOf(grant.appOrigin, grant.grantId, \"\");\n await remembered.change((all) => {\n for (const key of Object.keys(all)) {\n if (key.startsWith(prefix)) delete all[key];\n }\n });\n },\n };\n}\n"]}
@@ -23,6 +23,11 @@ export interface LocalPrompter {
23
23
  readonly appName: string;
24
24
  readonly device: string;
25
25
  }): void;
26
+ /** Passive: the app ended this computer's connection, and the agents here lost it too. */
27
+ disconnected?(input: {
28
+ readonly appName: string;
29
+ readonly removedFrom?: string | undefined;
30
+ }): void;
26
31
  }
27
32
  export declare const printable: (text: string) => string;
28
33
  /** A `[y/N]` question on the terminal that ran a command; only yes is yes. */
@@ -1 +1 @@
1
- {"version":3,"file":"prompter.d.ts","sourceRoot":"","sources":["../src/prompter.ts"],"names":[],"mappings":"AAGA,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,UAAU,CAAC,KAAK,EAAE;QAChB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChC,6FAA6F;IAC7F,WAAW,CAAC,KAAK,EAAE;QACjB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,uDAAuD;IACvD,YAAY,CAAC,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF;AAID,eAAO,MAAM,SAAS,SAAU,MAAM,WAAkC,CAAC;AAmBzE,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,aAAoB,MAAM,KAAG,OAAO,CAAC,OAAO,CAChB,CAAC;AAElD,0DAA0D;AAC1D,wBAAgB,gBAAgB,IAAI,aAAa,CAsBhD;AAoDD,wBAAgB,iBAAiB,IAAI,aAAa,CAwCjD"}
1
+ {"version":3,"file":"prompter.d.ts","sourceRoot":"","sources":["../src/prompter.ts"],"names":[],"mappings":"AAGA,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,UAAU,CAAC,KAAK,EAAE;QAChB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;KAC3C,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChC,6FAA6F;IAC7F,WAAW,CAAC,KAAK,EAAE;QACjB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,uDAAuD;IACvD,YAAY,CAAC,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClF,0FAA0F;IAC1F,YAAY,CAAC,CAAC,KAAK,EAAE;QACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAC3C,GAAG,IAAI,CAAC;CACV;AAID,eAAO,MAAM,SAAS,SAAU,MAAM,WAAkC,CAAC;AAmBzE,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,aAAoB,MAAM,KAAG,OAAO,CAAC,OAAO,CAChB,CAAC;AAElD,0DAA0D;AAC1D,wBAAgB,gBAAgB,IAAI,aAAa,CA2BhD;AAoDD,wBAAgB,iBAAiB,IAAI,aAAa,CAyDjD"}
package/dist/prompter.js CHANGED
@@ -30,6 +30,9 @@ export function terminalPrompter() {
30
30
  const answer = await ask(`${printable(agent)} for ${printable(appName)} asks: ${printable(question)}\n${menu}\nChoice: `);
31
31
  return choices[Number(answer?.trim()) - 1]?.id;
32
32
  },
33
+ disconnected: ({ appName, removedFrom }) => {
34
+ process.stdout.write(`${printable(appName)} disconnected this computer.${removedFrom ? ` Removed it from ${printable(removedFrom)}.` : ""}\n`);
35
+ },
33
36
  deviceLinked: ({ appName, device }) => {
34
37
  process.stdout.write(`${printable(device)} was linked to your agents for ${printable(appName)}.\n`);
35
38
  },
@@ -82,6 +85,18 @@ export function macDialogPrompter() {
82
85
  clipped(`It can use your agents for ${appName}. Not you? Remove it under Devices in the app's Agent sidebar.`),
83
86
  ]);
84
87
  },
88
+ disconnected: ({ appName, removedFrom }) => {
89
+ void osascript([
90
+ "on run argv",
91
+ `display notification (item 2 of argv) with title "${DIALOG_TITLE}" subtitle (item 1 of argv)`,
92
+ "end run",
93
+ ], [
94
+ clipped(`${appName} disconnected this computer`),
95
+ clipped(removedFrom
96
+ ? `Its sidebar and ${removedFrom} here can no longer use it.`
97
+ : "Its sidebar can no longer use your agents here."),
98
+ ]);
99
+ },
85
100
  turnStarted: ({ appName, device, agent, preview }) => {
86
101
  void osascript([
87
102
  "on run argv",
@@ -1 +1 @@
1
- {"version":3,"file":"prompter.js","sourceRoot":"","sources":["../src/prompter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompter.js","sourceRoot":"","sources":["../src/prompter.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\n/** The computer's own surface, which no app, backend or web page can draw. */\nexport interface LocalPrompter {\n /** The chosen option id, or undefined when dismissed. */\n answerHere(input: {\n readonly appName: string;\n readonly agent: string;\n readonly question: string;\n readonly choices: readonly { readonly id: string; readonly label: string }[];\n readonly signal?: AbortSignal | undefined;\n }): Promise<string | undefined>;\n /** Passive: a turn from another device started here; none for a browser on this computer. */\n turnStarted(input: {\n readonly appName: string;\n readonly device: string;\n readonly agent: string;\n readonly preview: string;\n }): void;\n /** Passive: a device was linked to the agents here. */\n deviceLinked?(input: { readonly appName: string; readonly device: string }): void;\n /** Passive: the app ended this computer's connection, and the agents here lost it too. */\n disconnected?(input: {\n readonly appName: string;\n readonly removedFrom?: string | undefined;\n }): void;\n}\n\nconst UNPRINTABLE = /[\\p{Cc}\\u061c\\u200e\\u200f\\u202a-\\u202e\\u2066-\\u2069]/gu;\n\nexport const printable = (text: string) => text.replace(UNPRINTABLE, \"\");\n\nfunction ask(question: string): Promise<string | undefined> {\n return new Promise((resolve) => {\n const lines = createInterface({ input: process.stdin, output: process.stdout });\n let answered = false;\n lines.question(question, (answer) => {\n answered = true;\n lines.close();\n resolve(answer);\n });\n lines.once(\"close\", () => {\n if (!answered) resolve(undefined);\n });\n });\n}\n\nconst yes = (answer: string | undefined) => /^y(es)?$/i.test(answer?.trim() ?? \"\");\n\n/** A `[y/N]` question on the terminal that ran a command; only yes is yes. */\nexport const askYesNo = async (question: string): Promise<boolean> =>\n yes(await ask(`${printable(question)} [y/N] `));\n\n/** Interactive `connect`: asks on the TTY that ran it. */\nexport function terminalPrompter(): LocalPrompter {\n return {\n answerHere: async ({ appName, agent, question, choices }) => {\n const menu = choices\n .map((choice, at) => ` ${at + 1}. ${printable(choice.label)}`)\n .join(\"\\n\");\n const answer = await ask(\n `${printable(agent)} for ${printable(appName)} asks: ${printable(question)}\\n${menu}\\nChoice: `,\n );\n return choices[Number(answer?.trim()) - 1]?.id;\n },\n disconnected: ({ appName, removedFrom }) => {\n process.stdout.write(\n `${printable(appName)} disconnected this computer.${removedFrom ? ` Removed it from ${printable(removedFrom)}.` : \"\"}\\n`,\n );\n },\n deviceLinked: ({ appName, device }) => {\n process.stdout.write(\n `${printable(device)} was linked to your agents for ${printable(appName)}.\\n`,\n );\n },\n turnStarted: ({ appName, device, agent, preview }) => {\n process.stdout.write(\n `${printable(agent)} is working for ${printable(appName)} from ${printable(device)}: ${printable(preview)}\\n`,\n );\n },\n };\n}\n\nconst DIALOG_TITLE = \"Parlor Host\";\nconst MAX_DIALOG_BUTTONS = 3;\nconst MAX_DIALOG_TEXT = 600;\n\nconst clipped = (text: string) =>\n printable(text).length > MAX_DIALOG_TEXT\n ? `${printable(text).slice(0, MAX_DIALOG_TEXT)}...`\n : printable(text);\n\nfunction osascript(\n lines: readonly string[],\n args: readonly string[],\n signal?: AbortSignal,\n): Promise<string | undefined> {\n return new Promise((resolve) => {\n execFile(\n \"osascript\",\n [...lines.flatMap((line) => [\"-e\", line]), \"--\", ...args],\n { signal },\n (error, stdout) => resolve(error ? undefined : stdout.trim()),\n );\n });\n}\n\nfunction choose(\n text: string,\n labels: readonly string[],\n signal?: AbortSignal,\n): Promise<string | undefined> {\n const options = labels.map(clipped);\n return osascript(\n labels.length <= MAX_DIALOG_BUTTONS\n ? [\n \"on run argv\",\n `set reply to display dialog (item 1 of argv) with title \"${DIALOG_TITLE}\" buttons (rest of argv)`,\n \"return button returned of reply\",\n \"end run\",\n ]\n : [\n \"on run argv\",\n `set picked to choose from list (rest of argv) with title \"${DIALOG_TITLE}\" with prompt (item 1 of argv)`,\n \"if picked is false then error number -128\",\n \"return item 1 of picked\",\n \"end run\",\n ],\n [clipped(text), ...options],\n signal,\n );\n}\n\nexport function macDialogPrompter(): LocalPrompter {\n return {\n answerHere: async ({ appName, agent, question, choices, signal }) => {\n const label = await choose(\n `${agent} for ${appName} asks: ${question}`,\n choices.map((choice) => choice.label),\n signal,\n );\n return choices.find((choice) => clipped(choice.label) === label)?.id;\n },\n deviceLinked: ({ appName, device }) => {\n void osascript(\n [\n \"on run argv\",\n `display notification (item 2 of argv) with title \"${DIALOG_TITLE}\" subtitle (item 1 of argv)`,\n \"end run\",\n ],\n [\n clipped(`${device} was linked`),\n clipped(\n `It can use your agents for ${appName}. Not you? Remove it under Devices in the app's Agent sidebar.`,\n ),\n ],\n );\n },\n disconnected: ({ appName, removedFrom }) => {\n void osascript(\n [\n \"on run argv\",\n `display notification (item 2 of argv) with title \"${DIALOG_TITLE}\" subtitle (item 1 of argv)`,\n \"end run\",\n ],\n [\n clipped(`${appName} disconnected this computer`),\n clipped(\n removedFrom\n ? `Its sidebar and ${removedFrom} here can no longer use it.`\n : \"Its sidebar can no longer use your agents here.\",\n ),\n ],\n );\n },\n turnStarted: ({ appName, device, agent, preview }) => {\n void osascript(\n [\n \"on run argv\",\n `display notification (item 3 of argv) with title \"${DIALOG_TITLE}\" subtitle (item 1 of argv & \" from \" & item 2 of argv)`,\n \"end run\",\n ],\n [\n clipped(`${agent} is working for ${appName}`),\n clipped(device),\n clipped(preview),\n ],\n );\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"release-main.js","sourceRoot":"","sources":["../src/release-main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE7D,KAAK,UAAU,gBAAgB;IAC7B,MAAM,EAAE,qBAAqB,EAAE,GAC7B,MAAM,MAAM,CAAC,8DAA8D,CAAC,CAAC;IAC/E,MAAM,EAAE,QAAQ,EAAE,GAChB,MAAM,MAAM,CAAC,qDAAqD,CAAC,CAAC;IACtE,MAAM,qBAAqB,EAAE,CAAC;IAC9B,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;AACzB,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,MAAM,CAAC,8CAA8C,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,QAAQ,GAAkD;IAC9D,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,eAAe;CACvB,CAAC;AAEF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;IACrC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,EAAE,IAAI,QAAQ,EAAE,CAAC;QAChE,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClE,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,EAAE,CAAC;AACd,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"release-main.js","sourceRoot":"","sources":["../src/release-main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE7D,KAAK,UAAU,gBAAgB;IAC7B,MAAM,EAAE,qBAAqB,EAAE,GAC7B,MAAM,MAAM,CAAC,8DAA8D,CAAC,CAAC;IAC/E,MAAM,EAAE,QAAQ,EAAE,GAChB,MAAM,MAAM,CAAC,qDAAqD,CAAC,CAAC;IACtE,MAAM,qBAAqB,EAAE,CAAC;IAC9B,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;AACzB,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,MAAM,CAAC,8CAA8C,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,QAAQ,GAAkD;IAC9D,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,eAAe;CACvB,CAAC;AAEF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;IACrC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,EAAE,IAAI,QAAQ,EAAE,CAAC;QAChE,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClE,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,EAAE,CAAC;AACd,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC","sourcesContent":["import { AGENT_PROFILES } from \"./agents.js\";\nimport { adapterKey, embeddedAdapters } from \"./embedded.js\";\n\nasync function runClaudeAdapter(): Promise<void> {\n const { applyManagedPolicyEnv } =\n await import(\"@agentclientprotocol/claude-agent-acp/dist/managed-policy.js\");\n const { serveAcp } =\n await import(\"@agentclientprotocol/claude-agent-acp/dist/serve.js\");\n await applyManagedPolicyEnv();\n console.log = console.error;\n console.info = console.error;\n console.warn = console.error;\n console.debug = console.error;\n const acp = serveAcp(undefined, { experimentalV2: false });\n const shutdown = async () => {\n await acp.dispose().catch(() => undefined);\n process.exit(0);\n };\n void acp.closed.then(shutdown);\n process.on(\"SIGTERM\", shutdown);\n process.on(\"SIGINT\", shutdown);\n process.stdin.resume();\n}\n\nasync function runCodexAdapter(): Promise<void> {\n await import(\"@agentclientprotocol/codex-acp/dist/index.js\");\n}\n\nconst ADAPTERS: Readonly<Record<string, () => Promise<void>>> = {\n claude: runClaudeAdapter,\n codex: runCodexAdapter,\n};\n\nfor (const profile of AGENT_PROFILES) {\n if (profile.launch.kind === \"adapter\" && profile.id in ADAPTERS) {\n embeddedAdapters.set(adapterKey(profile.launch), profile.id);\n }\n}\n\nasync function main(): Promise<void> {\n const [command, adapter] = process.argv.slice(2);\n if (command !== \"adapter\") {\n await import(\"./main.js\");\n return;\n }\n const run = adapter === undefined ? undefined : ADAPTERS[adapter];\n if (!run) {\n process.stderr.write(`parlor-host adapter <${Object.keys(ADAPTERS).join(\"|\")}>\\n`);\n process.exit(2);\n }\n await run();\n}\n\nmain().catch((error: unknown) => {\n console.error(error);\n process.exit(1);\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, createPublicKey, verify } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\n\nimport { canonicalBytes } from \"@parlor/capabilities/encoding\";\n\ndeclare const __PARLOR_RELEASE_KEY__: string | undefined;\n\n/** The Parlor release public key, base64url, fixed at build time; a build without one trusts no handover. */\nexport const RELEASE_KEY: string | undefined =\n typeof __PARLOR_RELEASE_KEY__ === \"undefined\" ? undefined : __PARLOR_RELEASE_KEY__;\n\nexport const RELEASE_PLATFORM = `${process.platform}-${process.arch}`;\n\nconst VERSION = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/;\n\nexport interface ReleaseSignature {\n readonly v: 1;\n readonly version: string;\n readonly platform: string;\n readonly sha256: string;\n readonly signature: string;\n}\n\nexport const isVersion = (text: string) => VERSION.test(text);\n\nexport function compareVersions(a: string, b: string): number {\n const [left, right] = [a, b].map((version) => {\n const match = VERSION.exec(version);\n if (!match) throw new Error(`\"${version}\" is not a major.minor.patch version.`);\n return match.slice(1).map(Number);\n }) as [number[], number[]];\n for (let at = 0; at < 3; at += 1) {\n const difference = left[at]! - right[at]!;\n if (difference !== 0) return difference;\n }\n return 0;\n}\n\nexport function releaseBytes(signature: Omit<ReleaseSignature, \"signature\">): Uint8Array {\n const { v, version, platform, sha256 } = signature;\n return canonicalBytes({ v, version, platform, sha256 });\n}\n\nexport function parseReleaseSignature(text: string): ReleaseSignature | undefined {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (typeof value !== \"object\" || value === null) return undefined;\n const { v, version, platform, sha256, signature } = value as Record<string, unknown>;\n if (v !== 1) return undefined;\n if (typeof version !== \"string\" || !isVersion(version)) return undefined;\n if (typeof platform !== \"string\" || typeof signature !== \"string\") return undefined;\n if (typeof sha256 !== \"string\" || !/^[0-9a-f]{64}$/.test(sha256)) return undefined;\n return { v, version, platform, sha256, signature };\n}\n\nexport function signatureHolds(\n signature: ReleaseSignature,\n key: string | undefined,\n): boolean {\n if (key === undefined) return false;\n try {\n return verify(\n null,\n releaseBytes(signature),\n createPublicKey({ key: { kty: \"OKP\", crv: \"Ed25519\", x: key }, format: \"jwk\" }),\n Buffer.from(signature.signature, \"base64url\"),\n );\n } catch {\n return false;\n }\n}\n\nexport function sha256File(path: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const hash = createHash(\"sha256\");\n createReadStream(path)\n .on(\"data\", (chunk) => hash.update(chunk))\n .once(\"end\", () => resolve(hash.digest(\"hex\")))\n .once(\"error\", reject);\n });\n}\n\n/**\n * The signed release a binary is: its `.sig` verifies under `key`, names this platform,\n * and its hash is the binary's own. `undefined` for anything else.\n */\nexport async function signedRelease(\n binary: string,\n signatureFile: string,\n key: string | undefined,\n): Promise<ReleaseSignature | undefined> {\n const signature = parseReleaseSignature(\n await readFile(signatureFile, \"utf8\").catch(() => \"\"),\n );\n if (!signature || signature.platform !== RELEASE_PLATFORM) return undefined;\n if (!signatureHolds(signature, key)) return undefined;\n const actual = await sha256File(binary).catch(() => undefined);\n return actual === signature.sha256 ? signature : undefined;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"revoke.js","sourceRoot":"","sources":["../src/revoke.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAExD,MAAM,cAAc,GAAG,CAAC,QAAkB,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;AASvE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAkB;IAClD,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,WAAW,EAAE,CAAC;IAC/C,MAAM,aAAa,GAAG,cAAc,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAClF,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC9D,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,OAAO,oDAAoD,EACpE;YACE,KAAK,EAAE,KAAK;SACb,CACF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,OAAO,uDAAuD,QAAQ,CAAC,MAAM,GAAG,CAC1F,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"revoke.js","sourceRoot":"","sources":["../src/revoke.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAExD,MAAM,cAAc,GAAG,CAAC,QAAkB,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;AASvE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAkB;IAClD,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,WAAW,EAAE,CAAC;IAC/C,MAAM,aAAa,GAAG,cAAc,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAClF,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC9D,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,OAAO,oDAAoD,EACpE;YACE,KAAK,EAAE,KAAK;SACb,CACF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,OAAO,uDAAuD,QAAQ,CAAC,MAAM,GAAG,CAC1F,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import type { AssertionRequest } from \"./assertion.js\";\n\nexport const REVOKE_PATH = \"/_parlor/auth/hosts/revoke\";\n\nconst alreadyRevoked = (response: Response) => response.status === 401;\n\nexport interface RevokeInput {\n readonly appOrigin: string;\n readonly appName: string;\n readonly assert: (request: AssertionRequest) => Promise<string>;\n readonly fetch?: typeof fetch | undefined;\n}\n\nexport async function revokeGrant(input: RevokeInput): Promise<void> {\n const url = `${input.appOrigin}${REVOKE_PATH}`;\n const authorization = `ParlorHost ${await input.assert({ method: \"POST\", url })}`;\n let response: Response;\n try {\n response = await (input.fetch ?? fetch)(url, {\n method: \"POST\",\n headers: { authorization, \"content-type\": \"application/json\" },\n body: \"{}\",\n });\n } catch (error) {\n throw new Error(\n `${input.appName} could not be reached to disconnect this computer.`,\n {\n cause: error,\n },\n );\n }\n if (!response.ok && !alreadyRevoked(response)) {\n throw new Error(\n `${input.appName} did not disconnect this computer: it answered HTTP ${response.status}.`,\n );\n }\n}\n"]}
package/dist/self.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"self.js","sourceRoot":"","sources":["../src/self.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,UAAU,cAAc,CAAC,IAAuB;IAIpD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,KAAK,EAAE,IAAI,KAAK,KAAK,SAAS;QACnC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE;QACrC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAY,EAAE,CAAC,KAAK,EAAE,CAAC;AAE7D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAuB,EAAE,CAChD,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"self.js","sourceRoot":"","sources":["../src/self.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,UAAU,cAAc,CAAC,IAAuB;IAIpD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,KAAK,EAAE,IAAI,KAAK,KAAK,SAAS;QACnC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE;QACrC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAY,EAAE,CAAC,KAAK,EAAE,CAAC;AAE7D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAuB,EAAE,CAChD,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC","sourcesContent":["import { isSea } from \"node:sea\";\n\nexport function selfInvocation(args: readonly string[]): {\n readonly command: string;\n readonly args: readonly string[];\n} {\n const entry = process.argv[1];\n return isSea() || entry === undefined\n ? { command: process.execPath, args }\n : { command: process.execPath, args: [entry, ...args] };\n}\n\nexport const runsAsSingleExecutable = (): boolean => isSea();\n\nexport const selfEntry = (): string | undefined =>\n isSea() ? process.execPath : process.argv[1];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport {\n access,\n chmod,\n copyFile,\n mkdir,\n open,\n rename,\n rm,\n symlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport type { ProtocolRange } from \"@parlor/chat\";\n\nimport { connectControl } from \"./control.js\";\nimport { LOCK_TOKEN_ENV, withFileLock } from \"./lock.js\";\nimport type { HostPaths } from \"./paths.js\";\nimport {\n compareVersions,\n RELEASE_KEY,\n type ReleaseSignature,\n sha256File,\n signedRelease,\n} from \"./release.js\";\nimport { selfInvocation } from \"./self.js\";\n\nexport interface HostRelease {\n readonly version: string;\n /** Host protocols it speaks with app backends. */\n readonly protocols: ProtocolRange;\n /** The control protocol it speaks with CLIs and desktop sidecars. */\n readonly control: number;\n}\n\nexport type ServiceClient =\n | { readonly kind: \"cli\"; readonly release: HostRelease }\n | {\n readonly kind: \"desktop-sidecar\";\n readonly app: string;\n readonly release: HostRelease;\n /** The bundled binary, copied in when newer than what is installed. */\n readonly binary: string;\n /** Its `.sig`, `<binary>.sig` when the bundle keeps them together. */\n readonly signature?: string;\n };\n\nexport type AdoptOutcome =\n | { readonly kind: \"using\"; readonly running: HostRelease }\n | { readonly kind: \"installed\"; readonly release: HostRelease }\n /** The old service handed its links over; its running turns finish under it. */\n | { readonly kind: \"upgraded\"; readonly from: HostRelease; readonly to: HostRelease }\n | {\n readonly kind: \"refused\";\n readonly reason: \"unsigned\" | \"downgrade\" | \"legacy_service\";\n readonly running?: HostRelease;\n };\n\nexport type Situation =\n | { readonly service: \"absent\"; readonly installed: boolean }\n | { readonly service: \"legacy\" }\n | { readonly service: \"running\"; readonly running: HostRelease };\n\ntype Sidecar = Extract<ServiceClient, { readonly kind: \"desktop-sidecar\" }>;\n\nexport type Action =\n | { readonly do: \"start_installed\" }\n | { readonly do: \"spawn_self\" }\n | { readonly do: \"install_bundled\"; readonly client: Sidecar }\n | { readonly do: \"refuse_legacy\" }\n | { readonly do: \"use\"; readonly running: HostRelease }\n | { readonly do: \"refuse_downgrade\"; readonly running: HostRelease }\n | { readonly do: \"hand_over\"; readonly client: Sidecar; readonly running: HostRelease };\n\nexport function actionFor(situation: Situation, client: ServiceClient): Action {\n switch (situation.service) {\n case \"legacy\":\n return { do: \"refuse_legacy\" };\n case \"absent\":\n if (situation.installed) return { do: \"start_installed\" };\n return client.kind === \"cli\"\n ? { do: \"spawn_self\" }\n : { do: \"install_bundled\", client };\n case \"running\": {\n const { running } = situation;\n if (client.kind === \"cli\") return { do: \"use\", running };\n const order = compareVersions(client.release.version, running.version);\n if (order > 0) return { do: \"hand_over\", client, running };\n return order === 0 ? { do: \"use\", running } : { do: \"refuse_downgrade\", running };\n }\n }\n}\n\nexport interface ServiceDeps {\n readonly releaseKey: string | undefined;\n readonly readyMs: number;\n readonly pollMs: number;\n readonly start?:\n | ((\n paths: HostPaths,\n command: string,\n args: readonly string[],\n lockToken: string,\n ) => Promise<void>)\n | undefined;\n}\n\nconst DEFAULTS: ServiceDeps = { releaseKey: RELEASE_KEY, readyMs: 15_000, pollMs: 100 };\n\nconst startWith = (deps: ServiceDeps) => deps.start ?? spawnService;\nconst SERVICE_BINARY = \"parlor-host\";\nconst SIGNATURE_FILE = \"parlor-host.sig\";\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst exists = (path: string) =>\n access(path).then(\n () => true,\n () => false,\n );\n\nasync function observe(paths: HostPaths, client: ServiceClient): Promise<Situation> {\n const control = await connectControl(paths.control);\n if (!control) {\n return {\n service: \"absent\",\n installed: await exists(join(paths.current, SERVICE_BINARY)),\n };\n }\n const reply = await control.send({ op: \"hello\", client });\n control.close();\n return reply.ok\n ? { service: \"running\", running: reply.release }\n : { service: \"legacy\" };\n}\n\nasync function spawnService(\n paths: HostPaths,\n command: string,\n args: readonly string[],\n lockToken: string,\n): Promise<void> {\n await mkdir(paths.logs, { recursive: true, mode: 0o700 });\n const output = await open(join(paths.logs, \"daemon.out\"), \"a\", 0o600);\n const child = spawn(command, args, {\n cwd: paths.root,\n detached: true,\n stdio: [\"ignore\", output.fd, output.fd],\n env: { ...process.env, [LOCK_TOKEN_ENV]: lockToken },\n });\n child.unref();\n await output.close();\n}\n\nasync function untilRunning(\n paths: HostPaths,\n client: ServiceClient,\n deps: ServiceDeps,\n ready: (running: HostRelease) => boolean = () => true,\n): Promise<HostRelease> {\n for (const deadline = Date.now() + deps.readyMs; Date.now() < deadline;) {\n const situation = await observe(paths, client);\n if (situation.service === \"running\" && ready(situation.running)) {\n return situation.running;\n }\n await sleep(deps.pollMs);\n }\n throw new Error(`Parlor Host did not start; see ${join(paths.logs, \"daemon.out\")}.`);\n}\n\n/**\n * Copies a verified binary into `versions/<version>/` and repoints `current`, each step\n * atomic and repeatable; false when the copy is not the binary the signature describes.\n */\nexport async function installRelease(\n paths: HostPaths,\n source: { readonly binary: string; readonly signature: string },\n release: ReleaseSignature,\n): Promise<boolean> {\n const target = join(paths.versions, release.version);\n const installed = join(target, SERVICE_BINARY);\n const present = (await sha256File(installed).catch(() => undefined)) === release.sha256;\n if (!present) {\n const staged = join(paths.versions, `.${release.version}.tmp-${process.pid}`);\n await rm(staged, { recursive: true, force: true });\n await mkdir(staged, { recursive: true, mode: 0o700 });\n await copyFile(source.binary, join(staged, SERVICE_BINARY));\n await chmod(join(staged, SERVICE_BINARY), 0o755);\n await copyFile(source.signature, join(staged, SIGNATURE_FILE));\n if ((await sha256File(join(staged, SERVICE_BINARY))) !== release.sha256) {\n await rm(staged, { recursive: true, force: true });\n return false;\n }\n await rm(target, { recursive: true, force: true });\n await rename(staged, target);\n }\n const link = `${paths.current}.tmp-${process.pid}`;\n await rm(link, { force: true });\n await symlink(join(\"versions\", release.version), link);\n await rename(link, paths.current);\n return true;\n}\n\nconst escapeXml = (text: string) =>\n text.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\");\n\n/** LaunchAgent, systemd user unit or Task Scheduler, pointing at `paths.current`. */\nexport async function installLoginItem(paths: HostPaths): Promise<void> {\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>dev.parlor.host</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escapeXml(join(paths.current, SERVICE_BINARY))}</string>\n <string>daemon</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>StandardOutPath</key>\n <string>${escapeXml(join(paths.logs, \"daemon.out\"))}</string>\n <key>StandardErrorPath</key>\n <string>${escapeXml(join(paths.logs, \"daemon.out\"))}</string>\n</dict>\n</plist>\n`;\n await mkdir(dirname(paths.launchAgent), { recursive: true });\n const staged = `${paths.launchAgent}.${process.pid}.tmp`;\n await writeFile(staged, plist, { mode: 0o644 });\n await rename(staged, paths.launchAgent);\n}\n\nasync function installBundled(\n paths: HostPaths,\n client: Sidecar,\n deps: ServiceDeps,\n lockToken: string,\n): Promise<AdoptOutcome> {\n const source = {\n binary: client.binary,\n signature: client.signature ?? `${client.binary}.sig`,\n };\n const release = await signedRelease(source.binary, source.signature, deps.releaseKey);\n if (\n !release ||\n release.version !== client.release.version ||\n !(await installRelease(paths, source, release))\n ) {\n return { kind: \"refused\", reason: \"unsigned\" };\n }\n await installLoginItem(paths);\n await startWith(deps)(\n paths,\n join(paths.current, SERVICE_BINARY),\n [\"daemon\"],\n lockToken,\n );\n return { kind: \"installed\", release: await untilRunning(paths, client, deps) };\n}\n\nasync function handOver(\n paths: HostPaths,\n client: Sidecar,\n running: HostRelease,\n deps: ServiceDeps,\n lockToken: string,\n): Promise<AdoptOutcome> {\n const control = await connectControl(paths.control);\n if (!control) throw new Error(\"Parlor Host stopped answering during the upgrade.\");\n const reply = await control.send({\n op: \"handover\",\n binary: client.binary,\n signature: client.signature ?? `${client.binary}.sig`,\n });\n control.close();\n if (!reply.ok) {\n return reply.error === \"unsigned\" || reply.error === \"downgrade\"\n ? { kind: \"refused\", reason: reply.error, running }\n : (() => {\n throw new Error(reply.error);\n })();\n }\n await startWith(deps)(\n paths,\n join(paths.current, SERVICE_BINARY),\n [\"daemon\"],\n lockToken,\n );\n const to = await untilRunning(\n paths,\n client,\n deps,\n (release) => compareVersions(release.version, running.version) > 0,\n );\n return { kind: \"upgraded\", from: running, to };\n}\n\n/**\n * Leaves exactly one per-user service running, the newest: adopt, install or upgrade.\n * Only binaries signed by the Parlor release key, never a downgrade; installs hold a lock\n * under `paths.root`, so two apps can run it at once.\n */\nexport async function ensureServiceWith(\n deps: ServiceDeps,\n paths: HostPaths,\n client: ServiceClient,\n): Promise<AdoptOutcome> {\n await mkdir(paths.root, { recursive: true, mode: 0o700 });\n return withFileLock(paths.lock, async (lockToken) => {\n for (;;) {\n const action = actionFor(await observe(paths, client), client);\n switch (action.do) {\n case \"refuse_legacy\":\n return { kind: \"refused\", reason: \"legacy_service\" };\n case \"use\":\n return { kind: \"using\", running: action.running };\n case \"refuse_downgrade\":\n return { kind: \"refused\", reason: \"downgrade\", running: action.running };\n case \"hand_over\":\n return handOver(paths, action.client, action.running, deps, lockToken);\n case \"install_bundled\":\n return installBundled(paths, action.client, deps, lockToken);\n case \"start_installed\":\n await startWith(deps)(\n paths,\n join(paths.current, SERVICE_BINARY),\n [\"daemon\"],\n lockToken,\n );\n await untilRunning(paths, client, deps);\n continue;\n case \"spawn_self\": {\n const self = selfInvocation([\"daemon\"]);\n await startWith(deps)(paths, self.command, self.args, lockToken);\n return { kind: \"installed\", release: await untilRunning(paths, client, deps) };\n }\n }\n }\n });\n}\n\nexport function ensureService(\n paths: HostPaths,\n client: ServiceClient,\n): Promise<AdoptOutcome> {\n return ensureServiceWith(DEFAULTS, paths, client);\n}\n"]}