@parlor/agent-host 0.2.0 → 0.3.1

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 (76) 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/agent-options.d.ts +22 -0
  6. package/dist/agent-options.d.ts.map +1 -0
  7. package/dist/agent-options.js +105 -0
  8. package/dist/agent-options.js.map +1 -0
  9. package/dist/agent-survey.d.ts +15 -0
  10. package/dist/agent-survey.d.ts.map +1 -0
  11. package/dist/agent-survey.js +51 -0
  12. package/dist/agent-survey.js.map +1 -0
  13. package/dist/agent-tools.d.ts +30 -0
  14. package/dist/agent-tools.d.ts.map +1 -0
  15. package/dist/agent-tools.js +71 -0
  16. package/dist/agent-tools.js.map +1 -0
  17. package/dist/codex-app-server.d.ts +7 -0
  18. package/dist/codex-app-server.d.ts.map +1 -0
  19. package/dist/codex-app-server.js +46 -0
  20. package/dist/codex-app-server.js.map +1 -0
  21. package/dist/control.d.ts +15 -0
  22. package/dist/control.d.ts.map +1 -1
  23. package/dist/control.js.map +1 -1
  24. package/dist/daemon.d.ts +10 -2
  25. package/dist/daemon.d.ts.map +1 -1
  26. package/dist/daemon.js +217 -16
  27. package/dist/daemon.js.map +1 -1
  28. package/dist/fold.d.ts.map +1 -1
  29. package/dist/fold.js +2 -0
  30. package/dist/fold.js.map +1 -1
  31. package/dist/grants.d.ts +9 -0
  32. package/dist/grants.d.ts.map +1 -1
  33. package/dist/grants.js.map +1 -1
  34. package/dist/learned.d.ts +25 -0
  35. package/dist/learned.d.ts.map +1 -0
  36. package/dist/learned.js +37 -0
  37. package/dist/learned.js.map +1 -0
  38. package/dist/link.d.ts +3 -1
  39. package/dist/link.d.ts.map +1 -1
  40. package/dist/link.js +23 -1
  41. package/dist/link.js.map +1 -1
  42. package/dist/main.js +105 -9
  43. package/dist/main.js.map +1 -1
  44. package/dist/mcp-proxy.d.ts +26 -3
  45. package/dist/mcp-proxy.d.ts.map +1 -1
  46. package/dist/mcp-proxy.js +288 -25
  47. package/dist/mcp-proxy.js.map +1 -1
  48. package/dist/pairing.d.ts +2 -0
  49. package/dist/pairing.d.ts.map +1 -1
  50. package/dist/pairing.js +25 -3
  51. package/dist/pairing.js.map +1 -1
  52. package/dist/paths.d.ts +2 -0
  53. package/dist/paths.d.ts.map +1 -1
  54. package/dist/paths.js +1 -0
  55. package/dist/paths.js.map +1 -1
  56. package/dist/policy.d.ts +12 -2
  57. package/dist/policy.d.ts.map +1 -1
  58. package/dist/policy.js +13 -3
  59. package/dist/policy.js.map +1 -1
  60. package/dist/prompter.d.ts +5 -0
  61. package/dist/prompter.d.ts.map +1 -1
  62. package/dist/prompter.js +15 -0
  63. package/dist/prompter.js.map +1 -1
  64. package/dist/spec-kit.d.ts +4 -1
  65. package/dist/spec-kit.d.ts.map +1 -1
  66. package/dist/spec-kit.js +12 -2
  67. package/dist/spec-kit.js.map +1 -1
  68. package/dist/testing/fake-agent.d.ts +12 -0
  69. package/dist/testing/fake-agent.d.ts.map +1 -1
  70. package/dist/testing/fake-agent.js +11 -1
  71. package/dist/testing/fake-agent.js.map +1 -1
  72. package/dist/turn.d.ts +7 -1
  73. package/dist/turn.d.ts.map +1 -1
  74. package/dist/turn.js +16 -3
  75. package/dist/turn.js.map +1 -1
  76. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n chmod,\n mkdir,\n readlink,\n realpath,\n rm,\n symlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { createServer, type Server, type Socket } from \"node:net\";\nimport { basename, delimiter, dirname, join } from \"node:path\";\n\nimport type { LocalHostStatus } from \"@parlor/capabilities\";\nimport {\n type AgentInfo,\n type ClaimedTurn,\n HOST_PROTOCOL,\n type HostWelcome,\n} from \"@parlor/chat\";\nimport { ActionError, asId, DEV_USER_ID } from \"@parlor/core\";\n\nimport type { AgentLauncher } from \"./acp.js\";\nimport { type AgentProfile, detectAgents, loadProfiles } from \"./agents.js\";\nimport { connectControl, type ControlRequest } from \"./control.js\";\nimport { requestDevHostToken } from \"./dev-host.js\";\nimport { type AppGrant, devHostKeys, type GrantStore, type HostKeys } from \"./grants.js\";\nimport { onLines } from \"./lines.js\";\nimport { type AppLink, createAppLink } from \"./link.js\";\nimport { withInheritedLock } from \"./lock.js\";\nimport { logEvent, openHostLog } from \"./log.js\";\nimport type { McpProxy } from \"./mcp-proxy.js\";\nimport { computerName, platformName, workspaceOf } from \"./naming.js\";\nimport {\n type LocalPairing,\n pairingDeviceOf,\n startLocalPairing,\n UnrevokedGrant,\n} from \"./pairing.js\";\nimport type { HostPaths } from \"./paths.js\";\nimport { DEV_POLICY, loadPolicy, presenceDueAt, type RemotePolicy } from \"./policy.js\";\nimport type { SessionPool } from \"./pool.js\";\nimport { type LocalPrompter, printable } from \"./prompter.js\";\nimport { compareVersions, RELEASE_KEY, signedRelease } from \"./release.js\";\nimport { revokeGrant } from \"./revoke.js\";\nimport { selfEntry } from \"./self.js\";\nimport { type HostRelease, installLoginItem, installRelease } from \"./service.js\";\nimport type { TrustStore } from \"./trust.js\";\nimport { runTurn } from \"./turn.js\";\n\nexport interface DaemonDeps {\n readonly release: HostRelease;\n readonly paths: HostPaths;\n readonly grants: GrantStore;\n readonly keys: HostKeys;\n readonly trust: TrustStore;\n readonly pool: SessionPool;\n readonly proxy: McpProxy;\n readonly launcher: AgentLauncher;\n readonly prompter: LocalPrompter;\n readonly policy: RemotePolicy;\n /** The `service.lock` token of the `ensureService` that spawned this daemon, which holds the lock for it. */\n readonly lockToken?: string | undefined;\n}\n\n/**\n * One per user per computer, for every app: an `AppLink` per grant, the session pool,\n * the proxy socket and the control socket. Started only through `ensureService`.\n */\nexport interface HostDaemon {\n start(): Promise<void>;\n connect(appOrigin: string): Promise<void>;\n disconnect(appOrigin: string): Promise<void>;\n /** Hands links over to a newer release; running turns finish here first. */\n handover(): Promise<void>;\n stop(): Promise<void>;\n}\n\nconst CONNECT_TIMEOUT_MS = 15_000;\nconst OFFLINE_REPORT_MS = 1_000;\nfunction incompatibleMessage(\n grant: AppGrant,\n welcome: Extract<HostWelcome, { readonly accepted: false }>,\n): string {\n return welcome.reason === \"host_too_old\"\n ? `Update Parlor Host to use ${grant.appName}: it speaks host protocol ${HOST_PROTOCOL}, and ${grant.appName} needs ${welcome.protocols.min}.`\n : `${grant.appName} is older than this Parlor Host: it speaks host protocol ${welcome.protocols.max}, and this computer needs ${HOST_PROTOCOL}.`;\n}\n\nconst shellQuote = (value: string) => `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n\n/**\n * Agents start `parlor-host mcp-proxy` by name. An entry named otherwise, such as the\n * published `dist/main.js` that `parlor dev` runs with node, gets a shim instead of a link.\n */\nexport async function putHostCommandFirstOnPath(\n root: string,\n entry: string | undefined = selfEntry(),\n): Promise<void> {\n if (!entry) return;\n const bin = join(root, \"bin\");\n const link = join(bin, \"parlor-host\");\n await mkdir(bin, { recursive: true, mode: 0o700 });\n const target = await realpath(entry);\n if (basename(entry).startsWith(\"parlor-host\")) {\n if ((await readlink(link).catch(() => undefined)) !== target) {\n await rm(link, { force: true });\n await symlink(target, link);\n }\n } else {\n await rm(link, { force: true });\n await writeFile(\n link,\n `#!/bin/sh\\nexec ${shellQuote(process.execPath)} ${shellQuote(target)} \"$@\"\\n`,\n { mode: 0o700 },\n );\n }\n const path = (process.env.PATH ?? \"\").split(delimiter).filter((dir) => dir !== bin);\n process.env.PATH = [bin, ...path].join(delimiter);\n}\n\ninterface LinkState {\n readonly link: AppLink;\n readonly keys: HostKeys;\n claiming: Promise<void> | undefined;\n again: boolean;\n incompatible: string | undefined;\n turns: number;\n}\n\n/** The daemon a service runs: once it handed over, `drained` settles after its last turn. */\nexport interface ServiceDaemon extends HostDaemon {\n readonly drained: Promise<void>;\n}\n\nexport class HostAlreadyRunning extends Error {\n override readonly name = \"HostAlreadyRunning\";\n constructor() {\n super(\"Parlor Host is already running on this computer.\");\n }\n}\n\nexport function createHostDaemon(deps: DaemonDeps): ServiceDaemon {\n const { paths } = deps;\n const links = new Map<string, LinkState>();\n const devTokens = new Map<string, string>();\n const name = computerName();\n const platform = platformName();\n let profiles: readonly AgentProfile[] = [];\n let agents: AgentInfo[] = [];\n let control: Server | undefined;\n let startup: Promise<void> = Promise.resolve();\n const clients = new Set<Socket>();\n\n const claim = async (link: AppLink): Promise<ClaimedTurn | undefined> => {\n try {\n return await link.api.calls.call(\"hostClaim\", {});\n } catch (error) {\n if (!(error instanceof ActionError && error.code === \"not_found\")) {\n logEvent(\"claim_failed\", {\n appOrigin: link.grant.appOrigin,\n error: String(error),\n });\n }\n return undefined;\n }\n };\n\n const running = new Set<Promise<void>>();\n let handedOver = false;\n let finishing = false;\n let finishHandover: () => void = () => undefined;\n const drained = new Promise<void>((resolve) => (finishHandover = resolve));\n\n const run = (state: LinkState, claimed: ClaimedTurn) => {\n const { link } = state;\n logEvent(\"turn_claimed\", { appOrigin: link.grant.appOrigin, turnId: claimed.turnId });\n state.turns += 1;\n const turn = (\n link.grant.dev ? Promise.resolve(DEV_POLICY) : loadPolicy(paths.policy, deps.policy)\n )\n .then((policy) =>\n runTurn(claimed, {\n link,\n profiles,\n launcher: deps.launcher,\n pool: deps.pool,\n proxy: deps.proxy,\n trust: {\n ...deps.trust,\n pin: async (appOrigin, device) => {\n await deps.trust.pin(appOrigin, device);\n void report(state).catch(() => undefined);\n },\n forget: async (appOrigin, deviceId) => {\n await deps.trust.forget(appOrigin, deviceId);\n void report(state).catch(() => undefined);\n },\n },\n policy,\n prompter: deps.prompter,\n now: Date.now,\n pairing: {\n secret: async () =>\n (await deps.grants.get(link.grant.appOrigin))?.pairingSecret,\n forget: async () => {\n const saved = await deps.grants.get(link.grant.appOrigin);\n if (!saved?.pairingSecret) return;\n const { pairingSecret: _used, ...rest } = saved;\n await deps.grants.save(rest);\n },\n },\n }),\n )\n .then(\n (outcome) => logEvent(\"turn_finished\", { turnId: claimed.turnId, outcome }),\n (error: unknown) =>\n logEvent(\"turn_finished\", { turnId: claimed.turnId, error: String(error) }),\n )\n .finally(() => {\n state.turns -= 1;\n running.delete(turn);\n settleHandover();\n });\n running.add(turn);\n };\n\n const claimLoop = async (state: LinkState) => {\n do {\n state.again = false;\n for (\n let claimed = await claim(state.link);\n claimed;\n claimed = state.link.mode === \"serving\" ? await claim(state.link) : undefined\n ) {\n run(state, claimed);\n }\n } while (state.again && state.link.mode === \"serving\");\n };\n\n const wake = (state: LinkState) => {\n if (state.link.mode !== \"serving\") return;\n if (state.claiming) {\n state.again = true;\n return;\n }\n state.claiming = claimLoop(state).finally(() => {\n state.claiming = undefined;\n });\n };\n\n const closeLink = async (origin: string, reason: string) => {\n const state = links.get(origin);\n links.delete(origin);\n await state?.link.stop();\n await deps.pool.drop(origin);\n if (state) logEvent(\"link_closed\", { appOrigin: origin, reason });\n };\n\n const forget = async (grant: AppGrant) => {\n devTokens.delete(grant.appOrigin);\n await deps.grants.remove(grant.appOrigin);\n await deps.keys.remove(grant.appOrigin);\n await deps.trust.forget(grant.appOrigin);\n await deps.pool.forget(grant);\n };\n\n const open = (grant: AppGrant, keys: HostKeys): LinkState => {\n const origin = grant.appOrigin;\n let state: LinkState;\n const link = createAppLink(grant, {\n keys,\n hostVersion: deps.release.version,\n hostName: name,\n platform,\n fetch: (input, init) => fetch(input, init),\n onWake: () => wake(state),\n busy: () => state.turns > 0,\n onRevoked: () => {\n if (links.get(origin) !== state) return;\n if (grant.dev) void reattach(grant);\n else void closeLink(origin, \"revoked\").then(() => forget(grant));\n },\n onIncompatible: (refused, welcome) => {\n state.incompatible = incompatibleMessage(refused, welcome);\n process.stderr.write(`${printable(state.incompatible)}\\n`);\n },\n });\n state = {\n link,\n keys,\n claiming: undefined,\n again: false,\n incompatible: undefined,\n turns: 0,\n };\n links.set(origin, state);\n link.start();\n return state;\n };\n\n const pinnedDevices = async (state: LinkState) => {\n if (state.link.grant.dev) return {};\n const [pinned, policy] = await Promise.all([\n deps.trust.list(state.link.grant.appOrigin),\n loadPolicy(paths.policy, deps.policy),\n ]);\n const presenceDue: Record<string, number> = {};\n for (const device of pinned) {\n const due = presenceDueAt(policy, device);\n if (due !== undefined) presenceDue[device.deviceId] = due;\n }\n return { devices: pinned.map((device) => device.deviceId), presenceDue };\n };\n\n const report = async (state: LinkState) => {\n const reported = state.link.api.calls.call(\"hostReport\", {\n online: true,\n agents,\n ...(await pinnedDevices(state)),\n });\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"The app did not answer in time.\")),\n CONNECT_TIMEOUT_MS,\n ),\n );\n try {\n await Promise.race([reported, timeout]);\n } catch (error) {\n throw new Error(\n state.incompatible ?? (error instanceof Error ? error.message : String(error)),\n { cause: error },\n );\n }\n };\n\n const devGrant = async (origin: string): Promise<AppGrant> => {\n const manifest = await fetch(`${origin}/_parlor/manifest`)\n .then((response) => response.json() as Promise<{ app?: { name?: string } }>)\n .catch(() => undefined);\n return {\n appOrigin: origin,\n appName: manifest?.app?.name ?? new URL(origin).host,\n grantId: asId(\"grant\", \"dev\"),\n hostId: asId(\"host\", \"dev\"),\n account: { userId: DEV_USER_ID, name: \"Developer\" },\n workspace: workspaceOf(paths.workspaces, origin),\n createdAt: Date.now(),\n dev: true,\n };\n };\n\n const attach = async (origin: string, hostToken: string) => {\n await closeLink(origin, \"replaced\");\n devTokens.set(origin, hostToken);\n await report(open(await devGrant(origin), devHostKeys(hostToken)));\n };\n\n const reattach = async (grant: AppGrant) => {\n await closeLink(grant.appOrigin, \"dev_server_restarted\");\n if (!devTokens.has(grant.appOrigin)) return;\n try {\n const token = await requestDevHostToken(grant.appOrigin);\n if (devTokens.has(grant.appOrigin)) await attach(grant.appOrigin, token);\n } catch (error) {\n logEvent(\"dev_attach_failed\", { appOrigin: grant.appOrigin, error: String(error) });\n }\n };\n\n const status = (): LocalHostStatus => ({\n state: \"running\",\n version: deps.release.version,\n apps: [...links.keys()],\n });\n\n const grantsOf = () =>\n [...links.values()].map(({ link: { grant } }) => ({\n appOrigin: grant.appOrigin,\n appName: grant.appName,\n grantId: grant.grantId,\n }));\n\n const daemon: ServiceDaemon = {\n drained,\n async start() {\n let finishStartup!: () => void;\n let failStartup!: (error: unknown) => void;\n startup = new Promise<void>((resolve, reject) => {\n finishStartup = resolve;\n failStartup = reject;\n });\n startup.catch(() => undefined);\n try {\n await mkdir(paths.root, { recursive: true, mode: 0o700 });\n await withInheritedLock(paths.lock, deps.lockToken, async () => {\n const answering = await connectControl(paths.control);\n if (answering) {\n answering.close();\n throw new HostAlreadyRunning();\n }\n await mkdir(dirname(paths.control), { recursive: true, mode: 0o700 });\n control = createServer(serve);\n await rm(paths.control, { force: true });\n await new Promise<void>((resolve, reject) => {\n control!.once(\"error\", reject);\n control!.listen(paths.control, () => resolve());\n });\n await chmod(paths.control, 0o600);\n });\n openHostLog(join(paths.root, \"logs\", \"daemon.log\"));\n await putHostCommandFirstOnPath(paths.root);\n await deps.proxy.listen(paths.proxy);\n profiles = await loadProfiles(paths.agents);\n agents = await detectAgents(profiles);\n finishStartup();\n } catch (error) {\n failStartup(error);\n throw error;\n }\n logEvent(\"daemon_started\", {\n version: deps.release.version,\n agents: agents.map((a) => a.id),\n });\n for (const grant of await deps.grants.list()) {\n if (grant.declined) continue;\n void report(open(grant, deps.keys)).catch((error: unknown) =>\n logEvent(\"link_failed\", { appOrigin: grant.appOrigin, error: String(error) }),\n );\n }\n },\n async connect(appOrigin) {\n const grant = await deps.grants.get(appOrigin);\n if (!grant || grant.declined) {\n throw new Error(`This computer is not connected to ${appOrigin}.`);\n }\n const current = links.get(appOrigin);\n if (current?.link.grant.grantId === grant.grantId) {\n await report(current);\n return;\n }\n await closeLink(appOrigin, \"replaced\");\n if (current) await deps.pool.forget(current.link.grant);\n await report(open(grant, deps.keys));\n },\n async disconnect(appOrigin) {\n const state = links.get(appOrigin);\n const grant = state?.link.grant ?? (await deps.grants.get(appOrigin));\n if (!grant) throw new Error(`This computer is not connected to ${appOrigin}.`);\n if (state) {\n await state.link.stop({ revoke: true });\n } else {\n await revokeGrant({\n appOrigin,\n appName: grant.appName,\n assert: (request) => deps.keys.assert(appOrigin, request),\n });\n }\n await closeLink(appOrigin, \"disconnected\");\n await forget(grant);\n },\n async handover() {\n if (handedOver) return;\n handedOver = true;\n for (const state of links.values()) state.link.drain();\n await Promise.all([...links.values()].map((state) => state.claiming));\n const closing = control;\n control = undefined;\n closing?.close();\n await Promise.all([rm(paths.control, { force: true }), deps.proxy.stopListening()]);\n logEvent(\"handover_started\", { version: deps.release.version });\n },\n async stop() {\n if (!handedOver) {\n await Promise.all(\n [...links.values()].map((state) =>\n Promise.race([\n state.link.api.calls.call(\"hostReport\", { online: false, agents }),\n new Promise((resolve) => setTimeout(resolve, OFFLINE_REPORT_MS)),\n ]).catch(() => undefined),\n ),\n );\n }\n for (const origin of [...links.keys()]) await closeLink(origin, \"stopped\");\n for (const socket of clients) socket.destroy();\n const closing = control;\n control = undefined;\n if (closing) await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (!handedOver) await rm(paths.control, { force: true });\n await deps.proxy.close();\n },\n };\n\n const settleHandover = () => {\n if (!handedOver || running.size > 0 || finishing) return;\n finishing = true;\n void (async () => {\n for (const origin of [...links.keys()]) await closeLink(origin, \"handed_over\");\n await Promise.all(\n [...clients].map(\n (socket) =>\n new Promise<void>((resolve) => {\n socket.end(() => resolve());\n setTimeout(resolve, OFFLINE_REPORT_MS).unref();\n }),\n ),\n );\n logEvent(\"handover_finished\", { version: deps.release.version });\n finishHandover();\n })();\n };\n\n const handOverTo = async (binary: string, signature: string): Promise<unknown> => {\n const release = await signedRelease(binary, signature, RELEASE_KEY);\n if (!release) return { ok: false, error: \"unsigned\" };\n if (compareVersions(release.version, deps.release.version) <= 0) {\n return { ok: false, error: \"downgrade\" };\n }\n if (!(await installRelease(paths, { binary, signature }, release))) {\n return { ok: false, error: \"unsigned\" };\n }\n await installLoginItem(paths);\n await daemon.handover();\n setImmediate(settleHandover);\n return { ok: true };\n };\n\n const pairings = new Map<string, LocalPairing>();\n\n const pendingPairing = (appOrigin: string) => {\n const origin = new URL(appOrigin).origin;\n return { origin, pairing: pairings.get(origin) };\n };\n\n const confirmPairing = async (\n request: Extract<ControlRequest, { readonly op: \"confirm_local_pairing\" }>,\n ): Promise<unknown> => {\n const { origin, pairing } = pendingPairing(request.appOrigin);\n if (!pairing) return { ok: false, error: \"No pairing was started for this app.\" };\n pairings.delete(origin);\n let outcome: Awaited<ReturnType<LocalPairing[\"confirm\"]>>;\n try {\n outcome = await pairing.confirm(request.connect);\n } catch (error) {\n if (!(error instanceof UnrevokedGrant)) throw error;\n await deps.grants.save(error.grant);\n return { ok: false, error: \"declined_locally\" };\n }\n if (!outcome.paired) return { ok: false, error: outcome.reason };\n const { grant } = outcome;\n await deps.grants.save(grant);\n const device = pairingDeviceOf(request.device);\n if (device) {\n await deps.trust.pin(grant.appOrigin, {\n deviceId: asId(\"device\", device.deviceId),\n signingKey: device.signingKey,\n presenceKey: device.presenceKey,\n name: device.name,\n platform: device.platform,\n approvedAt: Date.now(),\n via: \"pairing\",\n });\n }\n await daemon.connect(grant.appOrigin);\n return { ok: true };\n };\n\n const handle = async (request: ControlRequest): Promise<unknown> => {\n if (request.op !== \"hello\") await startup;\n switch (request.op) {\n case \"hello\":\n return { ok: true, release: deps.release };\n case \"handover\":\n return handOverTo(request.binary, request.signature);\n case \"status\":\n return { ok: true, status: status(), grants: grantsOf() };\n case \"begin_local_pairing\": {\n const { origin } = pendingPairing(request.appOrigin);\n const existing = await deps.grants.get(origin);\n if (existing && !existing.declined) {\n return {\n ok: false,\n error: `This computer is already connected to ${existing.appName}.`,\n };\n }\n const pairing = startLocalPairing({\n appOrigin: origin,\n hostName: name,\n platform,\n keys: deps.keys,\n workspaceRoot: paths.workspaces,\n });\n pairings.set(origin, pairing);\n const begun = await pairing.pairing;\n logEvent(\"local_pairing_begun\", {\n appOrigin: origin,\n matchingCode: begun.matchingCode,\n });\n return { ok: true, pairing: begun };\n }\n case \"finish_local_pairing\": {\n const { pairing } = pendingPairing(request.appOrigin);\n if (!pairing) return { ok: false, error: \"No pairing was started for this app.\" };\n return { ok: true, ...(await pairing.finish(request.code)) };\n }\n case \"confirm_local_pairing\":\n return confirmPairing(request);\n case \"connect\":\n await daemon.connect(request.appOrigin);\n return { ok: true };\n case \"disconnect\":\n await daemon.disconnect(request.appOrigin);\n return { ok: true };\n case \"dev_attach\":\n await attach(request.appOrigin, request.hostToken);\n return { ok: true };\n case \"dev_detach\":\n devTokens.delete(request.appOrigin);\n await closeLink(request.appOrigin, \"detached\");\n return { ok: true };\n }\n };\n\n function serve(socket: Socket) {\n clients.add(socket);\n socket.on(\"close\", () => clients.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n onLines(socket, (line) => {\n let request: ControlRequest;\n try {\n request = JSON.parse(line) as ControlRequest;\n } catch {\n socket.write(`${JSON.stringify({ ok: false, error: \"Not JSON.\" })}\\n`);\n return;\n }\n void handle(request)\n .catch((error: unknown) => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n }))\n .then((reply) => {\n if (!socket.destroyed)\n socket.write(\n `${JSON.stringify(reply ?? { ok: false, error: \"Unknown op.\" })}\\n`,\n );\n });\n });\n }\n\n return daemon;\n}\n"]}
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n chmod,\n mkdir,\n readlink,\n realpath,\n rm,\n symlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { createServer, type Server, type Socket } from \"node:net\";\nimport { basename, delimiter, dirname, join } from \"node:path\";\n\nimport type { LocalHostStatus } from \"@parlor/capabilities\";\nimport {\n type AgentInfo,\n type ClaimedTurn,\n HOST_PROTOCOL,\n type HostWelcome,\n} from \"@parlor/chat\";\nimport { ActionError, asId, DEV_USER_ID } from \"@parlor/core\";\n\nimport type { AgentLauncher } from \"./acp.js\";\nimport { readUsage, surveyOptions } from \"./agent-survey.js\";\nimport {\n agentNames,\n type AgentToolsDeps,\n registerAgentTools,\n unregisterAgentTools,\n} from \"./agent-tools.js\";\nimport { type AgentProfile, detectAgents, loadProfiles } from \"./agents.js\";\nimport { connectControl, type ControlRequest } from \"./control.js\";\nimport { requestDevHostToken } from \"./dev-host.js\";\nimport { type AppGrant, devHostKeys, type GrantStore, type HostKeys } from \"./grants.js\";\nimport { type LearnedNews, learnedStore } from \"./learned.js\";\nimport { onLines } from \"./lines.js\";\nimport { type AppLink, createAppLink } from \"./link.js\";\nimport { withInheritedLock } from \"./lock.js\";\nimport { logEvent, openHostLog } from \"./log.js\";\nimport type { McpProxy } from \"./mcp-proxy.js\";\nimport { computerName, platformName, workspaceOf } from \"./naming.js\";\nimport {\n type LocalPairing,\n pairingDeviceOf,\n startLocalPairing,\n UnrevokedGrant,\n} from \"./pairing.js\";\nimport type { HostPaths } from \"./paths.js\";\nimport { DEV_POLICY, loadPolicy, presenceDueAt, type RemotePolicy } from \"./policy.js\";\nimport type { SessionPool } from \"./pool.js\";\nimport { type LocalPrompter, printable } from \"./prompter.js\";\nimport { compareVersions, RELEASE_KEY, signedRelease } from \"./release.js\";\nimport { revokeGrant } from \"./revoke.js\";\nimport { selfEntry } from \"./self.js\";\nimport { type HostRelease, installLoginItem, installRelease } from \"./service.js\";\nimport { agentEnvironment } from \"./shell-path.js\";\nimport type { TrustStore } from \"./trust.js\";\nimport { runTurn } from \"./turn.js\";\n\nexport interface DaemonDeps {\n readonly release: HostRelease;\n readonly paths: HostPaths;\n readonly grants: GrantStore;\n readonly keys: HostKeys;\n readonly trust: TrustStore;\n readonly pool: SessionPool;\n readonly proxy: McpProxy;\n readonly launcher: AgentLauncher;\n readonly prompter: LocalPrompter;\n readonly policy: RemotePolicy;\n /** The `service.lock` token of the `ensureService` that spawned this daemon, which holds the lock for it. */\n readonly lockToken?: string | undefined;\n}\n\n/**\n * One per user per computer, for every app: an `AppLink` per grant, the session pool,\n * the proxy socket and the control socket. Started only through `ensureService`.\n */\nexport interface HostDaemon {\n start(): Promise<void>;\n /** What the coding agents here know the app by, when the user let them use it. */\n connect(appOrigin: string): Promise<ConnectedTools | undefined>;\n disconnect(appOrigin: string): Promise<ConnectedTools | undefined>;\n /** Lets the coding agents here use the app outside its sidebar, or stops them. */\n agentTools(appOrigin: string, on: boolean): Promise<ConnectedTools | undefined>;\n /** Hands links over to a newer release; running turns finish here first. */\n handover(): Promise<void>;\n stop(): Promise<void>;\n}\n\n/** The app's MCP server name in the coding agents here, and which of them have it. */\nexport interface ConnectedTools {\n readonly name: string;\n readonly agents: string;\n}\n\nconst CONNECT_TIMEOUT_MS = 15_000;\n/** An agent token is asked for again this long before it runs out. */\nconst AGENT_TOKEN_MARGIN_MS = 60_000;\nconst OFFLINE_REPORT_MS = 1_000;\nfunction incompatibleMessage(\n grant: AppGrant,\n welcome: Extract<HostWelcome, { readonly accepted: false }>,\n): string {\n return welcome.reason === \"host_too_old\"\n ? `Update Parlor Host to use ${grant.appName}: it speaks host protocol ${HOST_PROTOCOL}, and ${grant.appName} needs ${welcome.protocols.min}.`\n : `${grant.appName} is older than this Parlor Host: it speaks host protocol ${welcome.protocols.max}, and this computer needs ${HOST_PROTOCOL}.`;\n}\n\nconst shellQuote = (value: string) => `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n\n/**\n * Agents start `parlor-host mcp-proxy` by name. An entry named otherwise, such as the\n * published `dist/main.js` that `parlor dev` runs with node, gets a shim instead of a link.\n */\nexport async function putHostCommandFirstOnPath(\n root: string,\n entry: string | undefined = selfEntry(),\n): Promise<void> {\n if (!entry) return;\n const bin = join(root, \"bin\");\n const link = join(bin, \"parlor-host\");\n await mkdir(bin, { recursive: true, mode: 0o700 });\n const target = await realpath(entry);\n if (basename(entry).startsWith(\"parlor-host\")) {\n if ((await readlink(link).catch(() => undefined)) !== target) {\n await rm(link, { force: true });\n await symlink(target, link);\n }\n } else {\n await rm(link, { force: true });\n await writeFile(\n link,\n `#!/bin/sh\\nexec ${shellQuote(process.execPath)} ${shellQuote(target)} \"$@\"\\n`,\n { mode: 0o700 },\n );\n }\n const path = (process.env.PATH ?? \"\").split(delimiter).filter((dir) => dir !== bin);\n process.env.PATH = [bin, ...path].join(delimiter);\n}\n\ninterface LinkState {\n readonly link: AppLink;\n readonly keys: HostKeys;\n claiming: Promise<void> | undefined;\n again: boolean;\n incompatible: string | undefined;\n turns: number;\n}\n\n/** The daemon a service runs: once it handed over, `drained` settles after its last turn. */\nexport interface ServiceDaemon extends HostDaemon {\n readonly drained: Promise<void>;\n}\n\nexport class HostAlreadyRunning extends Error {\n override readonly name = \"HostAlreadyRunning\";\n constructor() {\n super(\"Parlor Host is already running on this computer.\");\n }\n}\n\n/** Codex's own CLI throttles its rate-limit reports on the same interval. */\nconst USAGE_READ_FLOOR_MS = 30_000;\n\nexport function createHostDaemon(deps: DaemonDeps): ServiceDaemon {\n const { paths } = deps;\n const links = new Map<string, LinkState>();\n const devTokens = new Map<string, string>();\n const name = computerName();\n const platform = platformName();\n let profiles: readonly AgentProfile[] = [];\n let agents: AgentInfo[] = [];\n const learned = learnedStore(paths.learned);\n let control: Server | undefined;\n let startup: Promise<void> = Promise.resolve();\n const clients = new Set<Socket>();\n\n const claim = async (link: AppLink): Promise<ClaimedTurn | undefined> => {\n try {\n return await link.api.calls.call(\"hostClaim\", {});\n } catch (error) {\n if (!(error instanceof ActionError && error.code === \"not_found\")) {\n logEvent(\"claim_failed\", {\n appOrigin: link.grant.appOrigin,\n error: String(error),\n });\n }\n return undefined;\n }\n };\n\n /** What an agent said about itself, told to every linked app when it changes what they show. */\n const learn = (agentId: string, news: LearnedNews) => {\n void learned\n .learn(agentId, news)\n .then((changed) => {\n if (!changed) return;\n for (const linked of links.values()) void report(linked).catch(() => undefined);\n })\n .catch(() => undefined);\n };\n\n /** Ends the reads below on stop or handover, so nothing outlives the daemon. */\n const stopping = new AbortController();\n\n const usageReadAt = new Map<string, number>();\n /** The allowance from the agent's own CLI where ACP carries none, at most every 30s per agent. */\n const refreshUsage = async (agentId: string) => {\n const profile = profiles.find((candidate) => candidate.id === agentId);\n const now = Date.now();\n if (!profile || stopping.signal.aborted) return;\n if (now - (usageReadAt.get(agentId) ?? 0) < USAGE_READ_FLOOR_MS) return;\n usageReadAt.set(agentId, now);\n const usage = await readUsage(profile, await agentEnvironment(), now).catch(\n () => undefined,\n );\n if (usage && !stopping.signal.aborted) learn(agentId, { usage });\n };\n\n let surveyed = false;\n /**\n * Options for every agent that has not run a turn yet, so the sidebar can offer a model first.\n * Once per run, when an app first links: a computer no app uses never starts its agents.\n */\n const surveyAgents = async () => {\n if (surveyed) return;\n surveyed = true;\n const env = await agentEnvironment();\n for (const agent of agents) {\n const profile = profiles.find((candidate) => candidate.id === agent.id);\n if (!profile || stopping.signal.aborted) continue;\n void refreshUsage(agent.id);\n if (learned.knows(agent.id)) continue;\n const options = await surveyOptions(profile, deps.launcher, env, stopping.signal);\n if (stopping.signal.aborted) return;\n logEvent(\"agent_surveyed\", { agentId: agent.id, options: options?.length ?? 0 });\n if (options && options.length > 0) learn(agent.id, { options });\n }\n };\n\n const running = new Set<Promise<void>>();\n let handedOver = false;\n let finishing = false;\n let finishHandover: () => void = () => undefined;\n const drained = new Promise<void>((resolve) => (finishHandover = resolve));\n\n /** A turn runs once here, even when a pushed turn its app took back is claimed again. */\n const runningTurns = new Set<string>();\n\n const run = (\n state: LinkState,\n claimed: ClaimedTurn,\n how: \"claimed\" | \"pushed\" = \"claimed\",\n ) => {\n const { link } = state;\n if (runningTurns.has(claimed.turnId)) return;\n runningTurns.add(claimed.turnId);\n logEvent(how === \"pushed\" ? \"turn_pushed\" : \"turn_claimed\", {\n appOrigin: link.grant.appOrigin,\n turnId: claimed.turnId,\n });\n state.turns += 1;\n const turn = (\n link.grant.dev ? Promise.resolve(DEV_POLICY) : loadPolicy(paths.policy, deps.policy)\n )\n .then((policy) =>\n runTurn(claimed, {\n link,\n profiles,\n launcher: deps.launcher,\n pool: deps.pool,\n proxy: deps.proxy,\n trust: {\n ...deps.trust,\n pin: async (appOrigin, device) => {\n await deps.trust.pin(appOrigin, device);\n void report(state).catch(() => undefined);\n },\n forget: async (appOrigin, deviceId) => {\n await deps.trust.forget(appOrigin, deviceId);\n void report(state).catch(() => undefined);\n },\n },\n policy,\n prompter: deps.prompter,\n now: Date.now,\n learned: learn,\n pairing: {\n secret: async () =>\n (await deps.grants.get(link.grant.appOrigin))?.pairingSecret,\n forget: async () => {\n const saved = await deps.grants.get(link.grant.appOrigin);\n if (!saved?.pairingSecret) return;\n const { pairingSecret: _used, ...rest } = saved;\n await deps.grants.save(rest);\n },\n },\n }),\n )\n .then(\n (outcome) => logEvent(\"turn_finished\", { turnId: claimed.turnId, outcome }),\n (error: unknown) =>\n logEvent(\"turn_finished\", { turnId: claimed.turnId, error: String(error) }),\n )\n .finally(() => {\n runningTurns.delete(claimed.turnId);\n void refreshUsage(claimed.agent.agentId);\n state.turns -= 1;\n running.delete(turn);\n settleHandover();\n });\n running.add(turn);\n };\n\n const claimLoop = async (state: LinkState) => {\n do {\n state.again = false;\n for (\n let claimed = await claim(state.link);\n claimed;\n claimed = state.link.mode === \"serving\" ? await claim(state.link) : undefined\n ) {\n run(state, claimed);\n }\n } while (state.again && state.link.mode === \"serving\");\n };\n\n const wake = (state: LinkState) => {\n if (state.link.mode !== \"serving\") return;\n if (state.claiming) {\n state.again = true;\n return;\n }\n state.claiming = claimLoop(state).finally(() => {\n state.claiming = undefined;\n });\n };\n\n const closeLink = async (origin: string, reason: string) => {\n const state = links.get(origin);\n links.delete(origin);\n await state?.link.stop();\n await deps.pool.drop(origin);\n if (state) logEvent(\"link_closed\", { appOrigin: origin, reason });\n };\n\n const toolsDeps = (): AgentToolsDeps => ({\n profiles: profiles.filter((profile) =>\n agents.some((agent) => agent.id === profile.id),\n ),\n hostCommand: join(paths.root, \"bin\", \"parlor-host\"),\n env: agentEnvironment,\n });\n\n const toolsOf = (grant: AppGrant | undefined): ConnectedTools | undefined => {\n const tools = grant?.agentTools;\n if (!tools?.on || !tools.name || !tools.agents?.length) return undefined;\n return {\n name: tools.name,\n agents: agentNames(profiles, { name: tools.name, agents: tools.agents }),\n };\n };\n\n /** Registers the app with the agents here once the user chose it and it is not yet. */\n const ensureAgentTools = async (grant: AppGrant): Promise<AppGrant> => {\n if (!grant.agentTools?.on || grant.dev || grant.agentTools.agents) return grant;\n const registered = await registerAgentTools(toolsDeps(), grant);\n const next: AppGrant = { ...grant, agentTools: { on: true, ...registered } };\n await deps.grants.save(next);\n return next;\n };\n\n const removeAgentTools = async (grant: AppGrant | undefined) => {\n const tools = grant?.agentTools;\n if (!tools?.name || !tools.agents?.length) return;\n await unregisterAgentTools(toolsDeps(), { name: tools.name, agents: tools.agents });\n };\n\n const agentTokens = new Map<\n string,\n { readonly token: string; readonly expiresAt: number }\n >();\n /** The grant as last saved, which a link opened before a change still holds the old copy of. */\n const latest = new Map<string, AppGrant>();\n\n deps.proxy.serveOutside((appOrigin) => {\n const state = links.get(appOrigin);\n if (!state || state.link.grant.dev) return undefined;\n const grant = latest.get(appOrigin) ?? state.link.grant;\n if (!grant.agentTools?.on || !grant.agentTools.name) return undefined;\n return {\n appOrigin,\n appName: grant.appName,\n name: grant.agentTools.name,\n account: grant.account.email ?? grant.account.name,\n token: async (agent) => {\n const key = `${grant.grantId}\\n${agent}`;\n const held = agentTokens.get(key);\n if (held && held.expiresAt - AGENT_TOKEN_MARGIN_MS > Date.now())\n return held.token;\n const fresh = await state.link.api.calls.call(\"hostAgentToken\", {\n agent: `${agent} on ${name}`.slice(0, 120),\n });\n agentTokens.set(key, fresh);\n return fresh.token;\n },\n askHere: async (question) =>\n (await deps.prompter.answerHere({\n appName: grant.appName,\n agent: \"Parlor Host\",\n question,\n choices: [\n { id: \"allow\", label: \"Allow\" },\n { id: \"deny\", label: \"Don't allow\" },\n ],\n })) === \"allow\",\n };\n });\n\n const forget = async (grant: AppGrant) => {\n await removeAgentTools((await deps.grants.get(grant.appOrigin)) ?? grant);\n latest.delete(grant.appOrigin);\n for (const key of agentTokens.keys()) {\n if (key.startsWith(`${grant.grantId}\\n`)) agentTokens.delete(key);\n }\n devTokens.delete(grant.appOrigin);\n await deps.grants.remove(grant.appOrigin);\n await deps.keys.remove(grant.appOrigin);\n await deps.trust.forget(grant.appOrigin);\n await deps.pool.forget(grant);\n };\n\n const open = (grant: AppGrant, keys: HostKeys): LinkState => {\n void surveyAgents().catch(() => undefined);\n const origin = grant.appOrigin;\n latest.set(origin, grant);\n let state: LinkState;\n const link = createAppLink(grant, {\n keys,\n hostVersion: deps.release.version,\n hostName: name,\n platform,\n fetch: (input, init) => fetch(input, init),\n onWake: () => wake(state),\n onPushed: (_link, turn) => {\n // Tells the app this computer has the turn, while it already starts on it.\n void link.api.calls\n .call(\"hostAppend\", { turnId: turn.turnId, items: [] })\n .catch(() => undefined);\n run(state, turn, \"pushed\");\n },\n busy: () => state.turns > 0,\n onRevoked: () => {\n if (links.get(origin) !== state) return;\n if (grant.dev) void reattach(grant);\n else {\n const removedFrom = toolsOf(latest.get(origin) ?? grant)?.agents;\n void closeLink(origin, \"revoked\")\n .then(() => forget(grant))\n .then(() =>\n deps.prompter.disconnected?.({ appName: grant.appName, removedFrom }),\n );\n }\n },\n onIncompatible: (refused, welcome) => {\n state.incompatible = incompatibleMessage(refused, welcome);\n process.stderr.write(`${printable(state.incompatible)}\\n`);\n },\n });\n state = {\n link,\n keys,\n claiming: undefined,\n again: false,\n incompatible: undefined,\n turns: 0,\n };\n links.set(origin, state);\n link.start();\n return state;\n };\n\n const pinnedDevices = async (state: LinkState) => {\n if (state.link.grant.dev) return {};\n const [pinned, policy] = await Promise.all([\n deps.trust.list(state.link.grant.appOrigin),\n loadPolicy(paths.policy, deps.policy),\n ]);\n const presenceDue: Record<string, number> = {};\n for (const device of pinned) {\n const due = presenceDueAt(policy, device);\n if (due !== undefined) presenceDue[device.deviceId] = due;\n }\n return { devices: pinned.map((device) => device.deviceId), presenceDue };\n };\n\n /** The agents with what they said about themselves, and the name they use the app by outside. */\n const describeFor = (origin: string) => {\n const tools = latest.get(origin)?.agentTools;\n return learned\n .describe(agents, Date.now())\n .map((agent) =>\n tools?.on && tools.name && tools.agents?.includes(agent.id)\n ? { ...agent, outsideName: tools.name }\n : agent,\n );\n };\n\n const report = async (state: LinkState) => {\n const reported = state.link.api.calls.call(\"hostReport\", {\n online: true,\n agents: describeFor(state.link.grant.appOrigin),\n ...(await pinnedDevices(state)),\n });\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"The app did not answer in time.\")),\n CONNECT_TIMEOUT_MS,\n ),\n );\n try {\n await Promise.race([reported, timeout]);\n } catch (error) {\n throw new Error(\n state.incompatible ?? (error instanceof Error ? error.message : String(error)),\n { cause: error },\n );\n }\n };\n\n const devGrant = async (origin: string): Promise<AppGrant> => {\n const manifest = await fetch(`${origin}/_parlor/manifest`)\n .then((response) => response.json() as Promise<{ app?: { name?: string } }>)\n .catch(() => undefined);\n return {\n appOrigin: origin,\n appName: manifest?.app?.name ?? new URL(origin).host,\n grantId: asId(\"grant\", \"dev\"),\n hostId: asId(\"host\", \"dev\"),\n account: { userId: DEV_USER_ID, name: \"Developer\" },\n workspace: workspaceOf(paths.workspaces, origin),\n createdAt: Date.now(),\n dev: true,\n };\n };\n\n const attach = async (origin: string, hostToken: string) => {\n await closeLink(origin, \"replaced\");\n devTokens.set(origin, hostToken);\n await report(open(await devGrant(origin), devHostKeys(hostToken)));\n };\n\n const reattach = async (grant: AppGrant) => {\n await closeLink(grant.appOrigin, \"dev_server_restarted\");\n if (!devTokens.has(grant.appOrigin)) return;\n try {\n const token = await requestDevHostToken(grant.appOrigin);\n if (devTokens.has(grant.appOrigin)) await attach(grant.appOrigin, token);\n } catch (error) {\n logEvent(\"dev_attach_failed\", { appOrigin: grant.appOrigin, error: String(error) });\n }\n };\n\n const status = (): LocalHostStatus => ({\n state: \"running\",\n version: deps.release.version,\n apps: [...links.keys()],\n });\n\n const grantsOf = () =>\n [...links.values()].map(({ link: { grant } }) => ({\n appOrigin: grant.appOrigin,\n appName: grant.appName,\n grantId: grant.grantId,\n }));\n\n const daemon: ServiceDaemon = {\n drained,\n async start() {\n let finishStartup!: () => void;\n let failStartup!: (error: unknown) => void;\n startup = new Promise<void>((resolve, reject) => {\n finishStartup = resolve;\n failStartup = reject;\n });\n startup.catch(() => undefined);\n try {\n await mkdir(paths.root, { recursive: true, mode: 0o700 });\n await withInheritedLock(paths.lock, deps.lockToken, async () => {\n const answering = await connectControl(paths.control);\n if (answering) {\n answering.close();\n throw new HostAlreadyRunning();\n }\n await mkdir(dirname(paths.control), { recursive: true, mode: 0o700 });\n control = createServer(serve);\n await rm(paths.control, { force: true });\n await new Promise<void>((resolve, reject) => {\n control!.once(\"error\", reject);\n control!.listen(paths.control, () => resolve());\n });\n await chmod(paths.control, 0o600);\n });\n openHostLog(join(paths.root, \"logs\", \"daemon.log\"));\n await putHostCommandFirstOnPath(paths.root);\n await deps.proxy.listen(paths.proxy);\n profiles = await loadProfiles(paths.agents);\n agents = await detectAgents(profiles);\n await learned.load();\n finishStartup();\n } catch (error) {\n failStartup(error);\n throw error;\n }\n logEvent(\"daemon_started\", {\n version: deps.release.version,\n agents: agents.map((a) => a.id),\n });\n for (const grant of await deps.grants.list()) {\n if (grant.declined) continue;\n void report(open(grant, deps.keys)).catch((error: unknown) =>\n logEvent(\"link_failed\", { appOrigin: grant.appOrigin, error: String(error) }),\n );\n }\n },\n async connect(appOrigin) {\n const saved = await deps.grants.get(appOrigin);\n if (!saved || saved.declined) {\n throw new Error(`This computer is not connected to ${appOrigin}.`);\n }\n const grant = await ensureAgentTools(saved);\n const current = links.get(appOrigin);\n if (current?.link.grant.grantId === grant.grantId) {\n latest.set(appOrigin, grant);\n await report(current);\n return toolsOf(grant);\n }\n await closeLink(appOrigin, \"replaced\");\n if (current) await deps.pool.forget(current.link.grant);\n latest.set(appOrigin, grant);\n await report(open(grant, deps.keys));\n return toolsOf(grant);\n },\n async agentTools(appOrigin, on) {\n const saved = await deps.grants.get(appOrigin);\n if (!saved || saved.declined || saved.dev) {\n throw new Error(`This computer is not connected to ${appOrigin}.`);\n }\n if (!on) await removeAgentTools(saved);\n const grant = await ensureAgentTools({ ...saved, agentTools: { on } });\n if (!on) await deps.grants.save(grant);\n latest.set(appOrigin, grant);\n const state = links.get(appOrigin);\n if (state) await report(state).catch(() => undefined);\n return toolsOf(grant);\n },\n async disconnect(appOrigin) {\n const state = links.get(appOrigin);\n const grant = (await deps.grants.get(appOrigin)) ?? state?.link.grant;\n if (!grant) throw new Error(`This computer is not connected to ${appOrigin}.`);\n const removed = toolsOf(grant);\n if (state) {\n await state.link.stop({ revoke: true });\n } else {\n await revokeGrant({\n appOrigin,\n appName: grant.appName,\n assert: (request) => deps.keys.assert(appOrigin, request),\n });\n }\n await closeLink(appOrigin, \"disconnected\");\n await forget(grant);\n return removed;\n },\n async handover() {\n if (handedOver) return;\n handedOver = true;\n stopping.abort();\n for (const state of links.values()) state.link.drain();\n await Promise.all([...links.values()].map((state) => state.claiming));\n const closing = control;\n control = undefined;\n closing?.close();\n await Promise.all([rm(paths.control, { force: true }), deps.proxy.stopListening()]);\n logEvent(\"handover_started\", { version: deps.release.version });\n },\n async stop() {\n stopping.abort();\n if (!handedOver) {\n await Promise.all(\n [...links.values()].map((state) =>\n Promise.race([\n state.link.api.calls.call(\"hostReport\", {\n online: false,\n agents: describeFor(state.link.grant.appOrigin),\n }),\n new Promise((resolve) => setTimeout(resolve, OFFLINE_REPORT_MS)),\n ]).catch(() => undefined),\n ),\n );\n }\n for (const origin of [...links.keys()]) await closeLink(origin, \"stopped\");\n for (const socket of clients) socket.destroy();\n const closing = control;\n control = undefined;\n if (closing) await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (!handedOver) await rm(paths.control, { force: true });\n await deps.proxy.close();\n },\n };\n\n const settleHandover = () => {\n if (!handedOver || running.size > 0 || finishing) return;\n finishing = true;\n void (async () => {\n for (const origin of [...links.keys()]) await closeLink(origin, \"handed_over\");\n await Promise.all(\n [...clients].map(\n (socket) =>\n new Promise<void>((resolve) => {\n socket.end(() => resolve());\n setTimeout(resolve, OFFLINE_REPORT_MS).unref();\n }),\n ),\n );\n logEvent(\"handover_finished\", { version: deps.release.version });\n finishHandover();\n })();\n };\n\n const handOverTo = async (binary: string, signature: string): Promise<unknown> => {\n const release = await signedRelease(binary, signature, RELEASE_KEY);\n if (!release) return { ok: false, error: \"unsigned\" };\n if (compareVersions(release.version, deps.release.version) <= 0) {\n return { ok: false, error: \"downgrade\" };\n }\n if (!(await installRelease(paths, { binary, signature }, release))) {\n return { ok: false, error: \"unsigned\" };\n }\n await installLoginItem(paths);\n await daemon.handover();\n setImmediate(settleHandover);\n return { ok: true };\n };\n\n const pairings = new Map<string, LocalPairing>();\n\n const pendingPairing = (appOrigin: string) => {\n const origin = new URL(appOrigin).origin;\n return { origin, pairing: pairings.get(origin) };\n };\n\n const confirmPairing = async (\n request: Extract<ControlRequest, { readonly op: \"confirm_local_pairing\" }>,\n ): Promise<unknown> => {\n const { origin, pairing } = pendingPairing(request.appOrigin);\n if (!pairing) return { ok: false, error: \"No pairing was started for this app.\" };\n pairings.delete(origin);\n let outcome: Awaited<ReturnType<LocalPairing[\"confirm\"]>>;\n try {\n outcome = await pairing.confirm(request.connect);\n } catch (error) {\n if (!(error instanceof UnrevokedGrant)) throw error;\n await deps.grants.save(error.grant);\n return { ok: false, error: \"declined_locally\" };\n }\n if (!outcome.paired) return { ok: false, error: outcome.reason };\n const { grant } = outcome;\n await deps.grants.save(grant);\n const device = pairingDeviceOf(request.device);\n if (device) {\n await deps.trust.pin(grant.appOrigin, {\n deviceId: asId(\"device\", device.deviceId),\n signingKey: device.signingKey,\n presenceKey: device.presenceKey,\n name: device.name,\n platform: device.platform,\n approvedAt: Date.now(),\n via: \"pairing\",\n });\n }\n await daemon.connect(grant.appOrigin);\n return { ok: true };\n };\n\n const handle = async (request: ControlRequest): Promise<unknown> => {\n if (request.op !== \"hello\") await startup;\n switch (request.op) {\n case \"hello\":\n return { ok: true, release: deps.release };\n case \"handover\":\n return handOverTo(request.binary, request.signature);\n case \"status\":\n return { ok: true, status: status(), grants: grantsOf() };\n case \"begin_local_pairing\": {\n const { origin } = pendingPairing(request.appOrigin);\n const existing = await deps.grants.get(origin);\n if (existing && !existing.declined) {\n return {\n ok: false,\n error: `This computer is already connected to ${existing.appName}.`,\n };\n }\n const pairing = startLocalPairing({\n appOrigin: origin,\n hostName: name,\n platform,\n keys: deps.keys,\n workspaceRoot: paths.workspaces,\n });\n pairings.set(origin, pairing);\n const begun = await pairing.pairing;\n logEvent(\"local_pairing_begun\", {\n appOrigin: origin,\n matchingCode: begun.matchingCode,\n });\n return { ok: true, pairing: begun };\n }\n case \"finish_local_pairing\": {\n const { pairing } = pendingPairing(request.appOrigin);\n if (!pairing) return { ok: false, error: \"No pairing was started for this app.\" };\n return { ok: true, ...(await pairing.finish(request.code)) };\n }\n case \"confirm_local_pairing\":\n return confirmPairing(request);\n case \"connect\": {\n const agentTools = await daemon.connect(request.appOrigin);\n return { ok: true, ...(agentTools ? { agentTools } : {}) };\n }\n case \"disconnect\": {\n const agentTools = await daemon.disconnect(request.appOrigin);\n return { ok: true, ...(agentTools ? { agentTools } : {}) };\n }\n case \"agent_tools\": {\n const agentTools = await daemon.agentTools(request.appOrigin, request.on);\n return { ok: true, ...(agentTools ? { agentTools } : {}) };\n }\n case \"dev_attach\":\n await attach(request.appOrigin, request.hostToken);\n return { ok: true };\n case \"dev_detach\":\n devTokens.delete(request.appOrigin);\n await closeLink(request.appOrigin, \"detached\");\n return { ok: true };\n }\n };\n\n function serve(socket: Socket) {\n clients.add(socket);\n socket.on(\"close\", () => clients.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n onLines(socket, (line) => {\n let request: ControlRequest;\n try {\n request = JSON.parse(line) as ControlRequest;\n } catch {\n socket.write(`${JSON.stringify({ ok: false, error: \"Not JSON.\" })}\\n`);\n return;\n }\n void handle(request)\n .catch((error: unknown) => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n }))\n .then((reply) => {\n if (!socket.destroyed)\n socket.write(\n `${JSON.stringify(reply ?? { ok: false, error: \"Unknown op.\" })}\\n`,\n );\n });\n });\n }\n\n return daemon;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AA+ID,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAElD;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,GAChB,QAAQ,CA4BV;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,GAAG,QAAQ,CAazE"}
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AA+ID,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAElD;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,GAChB,QAAQ,CA8BV;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,GAAG,QAAQ,CAazE"}
package/dist/fold.js CHANGED
@@ -146,6 +146,8 @@ export function foldUpdate(fold, update, appServer) {
146
146
  closed: [],
147
147
  };
148
148
  case "mode":
149
+ case "options":
150
+ case "usage":
149
151
  return unchanged(fold);
150
152
  }
151
153
  }
package/dist/fold.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatItemBody, HostFrame, HostItemDraft } from \"@parlor/chat\";\nimport { asId, type ItemId, type TurnId } from \"@parlor/core\";\n\nimport type { AgentUpdate } from \"./acp.js\";\n\ninterface OpenText {\n readonly id: string;\n readonly kind: \"reply\" | \"reasoning\";\n readonly text: string;\n}\n\ninterface OpenTool {\n readonly id: string;\n readonly title: string;\n readonly app: boolean;\n readonly name: string;\n}\n\nexport interface TurnFold {\n readonly turnId: TurnId;\n readonly open: OpenText | undefined;\n readonly tools: ReadonlyMap<string, OpenTool>;\n readonly plan: Extract<AgentUpdate, { kind: \"plan\" }>[\"entries\"] | undefined;\n readonly nextId: number;\n}\n\nexport interface FoldStep {\n readonly fold: TurnFold;\n /** Ephemeral, streamed now. */\n readonly frames: readonly HostFrame[];\n /** Finished, appended durably. */\n readonly closed: readonly HostItemDraft[];\n}\n\nconst MAX_DETAIL_CHARS = 4_000;\n\ntype ToolFrameStatus = \"pending\" | \"running\";\n\nconst itemId = (id: string): ItemId => asId(\"item\", id);\n\nconst entriesOf = (\n entries: Extract<AgentUpdate, { kind: \"plan\" }>[\"entries\"],\n): ChatItemBody<\"plan\">[\"entries\"] => entries.map((entry) => ({ ...entry }));\n\nconst unchanged = (fold: TurnFold): FoldStep => ({ fold, frames: [], closed: [] });\n\nconst planItemOf = (fold: TurnFold) => itemId(`${fold.turnId}.0`);\n\nfunction allocate(fold: TurnFold): { readonly id: string; readonly fold: TurnFold } {\n return {\n id: `${fold.turnId}.${fold.nextId}`,\n fold: { ...fold, nextId: fold.nextId + 1 },\n };\n}\n\nfunction closeText(fold: TurnFold, interrupted = false): FoldStep {\n const open = fold.open;\n if (!open) return unchanged(fold);\n const closed: HostItemDraft =\n open.kind === \"reply\"\n ? {\n id: itemId(open.id),\n kind: \"reply\",\n body: {\n text: open.text,\n ...(interrupted ? { interrupted: true as const } : {}),\n },\n }\n : { id: itemId(open.id), kind: \"reasoning\", body: { text: open.text } };\n return { fold: { ...fold, open: undefined }, frames: [], closed: [closed] };\n}\n\nfunction toolFrame(tool: OpenTool, status: ToolFrameStatus): HostFrame {\n return {\n type: \"item\",\n item: { id: itemId(tool.id), kind: \"tool\", title: tool.title, status },\n };\n}\n\nfunction toolDraft(\n tool: OpenTool,\n status: ChatItemBody<\"tool\">[\"status\"],\n detail: string | undefined,\n): HostItemDraft {\n return {\n id: itemId(tool.id),\n kind: \"tool\",\n body: {\n title: tool.title,\n tool: { kind: tool.app ? \"app\" : \"local\", name: tool.name },\n status,\n ...(detail ? { detail: detail.slice(0, MAX_DETAIL_CHARS) } : {}),\n },\n };\n}\n\nfunction withTool(fold: TurnFold, toolCallId: string, tool: OpenTool | undefined) {\n const tools = new Map(fold.tools);\n if (tool) tools.set(toolCallId, tool);\n else tools.delete(toolCallId);\n return { ...fold, tools };\n}\n\nfunction appendText(fold: TurnFold, kind: OpenText[\"kind\"], text: string): FoldStep {\n if (text === \"\") return unchanged(fold);\n const switched =\n fold.open && fold.open.kind !== kind ? closeText(fold) : unchanged(fold);\n let current = switched.fold;\n let open = current.open;\n if (!open) {\n const next = allocate(current);\n current = next.fold;\n open = { id: next.id, kind, text: \"\" };\n }\n return {\n fold: { ...current, open: { ...open, text: open.text + text } },\n frames: [\n { type: \"delta\", itemId: itemId(open.id), kind, offset: open.text.length, text },\n ],\n closed: switched.closed,\n };\n}\n\nfunction startTool(\n fold: TurnFold,\n update: Extract<AgentUpdate, { kind: \"tool_start\" }>,\n appServer: string,\n): FoldStep {\n const known = fold.tools.get(update.toolCallId);\n if (known) {\n const tool = { ...known, title: update.title || known.title };\n return {\n fold: withTool(fold, update.toolCallId, tool),\n frames: [toolFrame(tool, \"pending\")],\n closed: [],\n };\n }\n const text = closeText(fold);\n const next = allocate(text.fold);\n const tool: OpenTool = {\n id: next.id,\n title: update.title,\n app: update.mcp !== undefined && update.mcp.server === appServer,\n name: update.mcp?.tool ?? update.toolKind,\n };\n return {\n fold: withTool(next.fold, update.toolCallId, tool),\n frames: [toolFrame(tool, \"pending\")],\n closed: text.closed,\n };\n}\n\nfunction updateTool(\n fold: TurnFold,\n update: Extract<AgentUpdate, { kind: \"tool_update\" }>,\n): FoldStep {\n const known = fold.tools.get(update.toolCallId);\n if (!known) return unchanged(fold);\n const tool = { ...known, title: update.title || known.title };\n if (update.status === \"completed\" || update.status === \"failed\") {\n return {\n fold: withTool(fold, update.toolCallId, undefined),\n frames: [],\n closed: [\n toolDraft(tool, update.status === \"completed\" ? \"done\" : \"failed\", update.detail),\n ],\n };\n }\n return {\n fold: withTool(fold, update.toolCallId, tool),\n frames: [toolFrame(tool, update.status === \"in_progress\" ? \"running\" : \"pending\")],\n closed: [],\n };\n}\n\n/** Pure: knows no ACP, HTTP or time. Item ids are `<turnId>.<n>`. */\nexport function startFold(turnId: TurnId): TurnFold {\n return { turnId, open: undefined, tools: new Map(), plan: undefined, nextId: 1 };\n}\n\n/** `appServer` is the MCP server name the host gave the agent for this app. */\nexport function foldUpdate(\n fold: TurnFold,\n update: AgentUpdate,\n appServer: string,\n): FoldStep {\n switch (update.kind) {\n case \"text\":\n return appendText(fold, \"reply\", update.text);\n case \"thought\":\n return appendText(fold, \"reasoning\", update.text);\n case \"tool_start\":\n return startTool(fold, update, appServer);\n case \"tool_update\":\n return updateTool(fold, update);\n case \"plan\":\n return {\n fold: { ...fold, plan: update.entries },\n frames: [\n {\n type: \"item\",\n item: {\n id: planItemOf(fold),\n kind: \"plan\",\n entries: entriesOf(update.entries),\n },\n },\n ],\n closed: [],\n };\n case \"mode\":\n return unchanged(fold);\n }\n}\n\n/** Closes what is open; `interrupted` marks the last reply when the user stopped the turn. */\nexport function finishFold(fold: TurnFold, interrupted: boolean): FoldStep {\n const text = closeText(fold, interrupted);\n const tools = [...fold.tools.values()].map((tool) =>\n toolDraft(tool, interrupted ? \"cancelled\" : \"done\", undefined),\n );\n const plan: HostItemDraft[] = fold.plan\n ? [{ id: planItemOf(fold), kind: \"plan\", body: { entries: entriesOf(fold.plan) } }]\n : [];\n return {\n fold: { ...text.fold, tools: new Map(), plan: undefined },\n frames: [],\n closed: [...text.closed, ...tools, ...plan],\n };\n}\n"]}
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatItemBody, HostFrame, HostItemDraft } from \"@parlor/chat\";\nimport { asId, type ItemId, type TurnId } from \"@parlor/core\";\n\nimport type { AgentUpdate } from \"./acp.js\";\n\ninterface OpenText {\n readonly id: string;\n readonly kind: \"reply\" | \"reasoning\";\n readonly text: string;\n}\n\ninterface OpenTool {\n readonly id: string;\n readonly title: string;\n readonly app: boolean;\n readonly name: string;\n}\n\nexport interface TurnFold {\n readonly turnId: TurnId;\n readonly open: OpenText | undefined;\n readonly tools: ReadonlyMap<string, OpenTool>;\n readonly plan: Extract<AgentUpdate, { kind: \"plan\" }>[\"entries\"] | undefined;\n readonly nextId: number;\n}\n\nexport interface FoldStep {\n readonly fold: TurnFold;\n /** Ephemeral, streamed now. */\n readonly frames: readonly HostFrame[];\n /** Finished, appended durably. */\n readonly closed: readonly HostItemDraft[];\n}\n\nconst MAX_DETAIL_CHARS = 4_000;\n\ntype ToolFrameStatus = \"pending\" | \"running\";\n\nconst itemId = (id: string): ItemId => asId(\"item\", id);\n\nconst entriesOf = (\n entries: Extract<AgentUpdate, { kind: \"plan\" }>[\"entries\"],\n): ChatItemBody<\"plan\">[\"entries\"] => entries.map((entry) => ({ ...entry }));\n\nconst unchanged = (fold: TurnFold): FoldStep => ({ fold, frames: [], closed: [] });\n\nconst planItemOf = (fold: TurnFold) => itemId(`${fold.turnId}.0`);\n\nfunction allocate(fold: TurnFold): { readonly id: string; readonly fold: TurnFold } {\n return {\n id: `${fold.turnId}.${fold.nextId}`,\n fold: { ...fold, nextId: fold.nextId + 1 },\n };\n}\n\nfunction closeText(fold: TurnFold, interrupted = false): FoldStep {\n const open = fold.open;\n if (!open) return unchanged(fold);\n const closed: HostItemDraft =\n open.kind === \"reply\"\n ? {\n id: itemId(open.id),\n kind: \"reply\",\n body: {\n text: open.text,\n ...(interrupted ? { interrupted: true as const } : {}),\n },\n }\n : { id: itemId(open.id), kind: \"reasoning\", body: { text: open.text } };\n return { fold: { ...fold, open: undefined }, frames: [], closed: [closed] };\n}\n\nfunction toolFrame(tool: OpenTool, status: ToolFrameStatus): HostFrame {\n return {\n type: \"item\",\n item: { id: itemId(tool.id), kind: \"tool\", title: tool.title, status },\n };\n}\n\nfunction toolDraft(\n tool: OpenTool,\n status: ChatItemBody<\"tool\">[\"status\"],\n detail: string | undefined,\n): HostItemDraft {\n return {\n id: itemId(tool.id),\n kind: \"tool\",\n body: {\n title: tool.title,\n tool: { kind: tool.app ? \"app\" : \"local\", name: tool.name },\n status,\n ...(detail ? { detail: detail.slice(0, MAX_DETAIL_CHARS) } : {}),\n },\n };\n}\n\nfunction withTool(fold: TurnFold, toolCallId: string, tool: OpenTool | undefined) {\n const tools = new Map(fold.tools);\n if (tool) tools.set(toolCallId, tool);\n else tools.delete(toolCallId);\n return { ...fold, tools };\n}\n\nfunction appendText(fold: TurnFold, kind: OpenText[\"kind\"], text: string): FoldStep {\n if (text === \"\") return unchanged(fold);\n const switched =\n fold.open && fold.open.kind !== kind ? closeText(fold) : unchanged(fold);\n let current = switched.fold;\n let open = current.open;\n if (!open) {\n const next = allocate(current);\n current = next.fold;\n open = { id: next.id, kind, text: \"\" };\n }\n return {\n fold: { ...current, open: { ...open, text: open.text + text } },\n frames: [\n { type: \"delta\", itemId: itemId(open.id), kind, offset: open.text.length, text },\n ],\n closed: switched.closed,\n };\n}\n\nfunction startTool(\n fold: TurnFold,\n update: Extract<AgentUpdate, { kind: \"tool_start\" }>,\n appServer: string,\n): FoldStep {\n const known = fold.tools.get(update.toolCallId);\n if (known) {\n const tool = { ...known, title: update.title || known.title };\n return {\n fold: withTool(fold, update.toolCallId, tool),\n frames: [toolFrame(tool, \"pending\")],\n closed: [],\n };\n }\n const text = closeText(fold);\n const next = allocate(text.fold);\n const tool: OpenTool = {\n id: next.id,\n title: update.title,\n app: update.mcp !== undefined && update.mcp.server === appServer,\n name: update.mcp?.tool ?? update.toolKind,\n };\n return {\n fold: withTool(next.fold, update.toolCallId, tool),\n frames: [toolFrame(tool, \"pending\")],\n closed: text.closed,\n };\n}\n\nfunction updateTool(\n fold: TurnFold,\n update: Extract<AgentUpdate, { kind: \"tool_update\" }>,\n): FoldStep {\n const known = fold.tools.get(update.toolCallId);\n if (!known) return unchanged(fold);\n const tool = { ...known, title: update.title || known.title };\n if (update.status === \"completed\" || update.status === \"failed\") {\n return {\n fold: withTool(fold, update.toolCallId, undefined),\n frames: [],\n closed: [\n toolDraft(tool, update.status === \"completed\" ? \"done\" : \"failed\", update.detail),\n ],\n };\n }\n return {\n fold: withTool(fold, update.toolCallId, tool),\n frames: [toolFrame(tool, update.status === \"in_progress\" ? \"running\" : \"pending\")],\n closed: [],\n };\n}\n\n/** Pure: knows no ACP, HTTP or time. Item ids are `<turnId>.<n>`. */\nexport function startFold(turnId: TurnId): TurnFold {\n return { turnId, open: undefined, tools: new Map(), plan: undefined, nextId: 1 };\n}\n\n/** `appServer` is the MCP server name the host gave the agent for this app. */\nexport function foldUpdate(\n fold: TurnFold,\n update: AgentUpdate,\n appServer: string,\n): FoldStep {\n switch (update.kind) {\n case \"text\":\n return appendText(fold, \"reply\", update.text);\n case \"thought\":\n return appendText(fold, \"reasoning\", update.text);\n case \"tool_start\":\n return startTool(fold, update, appServer);\n case \"tool_update\":\n return updateTool(fold, update);\n case \"plan\":\n return {\n fold: { ...fold, plan: update.entries },\n frames: [\n {\n type: \"item\",\n item: {\n id: planItemOf(fold),\n kind: \"plan\",\n entries: entriesOf(update.entries),\n },\n },\n ],\n closed: [],\n };\n case \"mode\":\n case \"options\":\n case \"usage\":\n return unchanged(fold);\n }\n}\n\n/** Closes what is open; `interrupted` marks the last reply when the user stopped the turn. */\nexport function finishFold(fold: TurnFold, interrupted: boolean): FoldStep {\n const text = closeText(fold, interrupted);\n const tools = [...fold.tools.values()].map((tool) =>\n toolDraft(tool, interrupted ? \"cancelled\" : \"done\", undefined),\n );\n const plan: HostItemDraft[] = fold.plan\n ? [{ id: planItemOf(fold), kind: \"plan\", body: { entries: entriesOf(fold.plan) } }]\n : [];\n return {\n fold: { ...text.fold, tools: new Map(), plan: undefined },\n frames: [],\n closed: [...text.closed, ...tools, ...plan],\n };\n}\n"]}
package/dist/grants.d.ts CHANGED
@@ -19,6 +19,15 @@ export interface AppGrant {
19
19
  * browser proves it on its first prompt and is trusted without asking, then this is dropped.
20
20
  */
21
21
  readonly pairingSecret?: string | undefined;
22
+ /**
23
+ * Whether the coding agents on this computer may use the app outside its sidebar, as the
24
+ * user chose when connecting, and the name and agents it is registered under once it is.
25
+ */
26
+ readonly agentTools?: {
27
+ readonly on: boolean;
28
+ readonly name?: string | undefined;
29
+ readonly agents?: readonly string[] | undefined;
30
+ } | undefined;
22
31
  }
23
32
  /** One key per app grant in the OS keychain; the server holds only its public half. */
24
33
  export interface HostKeys {
@@ -1 +1 @@
1
- {"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAKpD,sFAAsF;AACtF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAChC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED,uFAAuF;AACvF,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,sDAAsD;IACtD,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,qEAAqE;IACrE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,IAAI,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAcvD;AA0JD,kGAAkG;AAClG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAE1D;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAMvD"}
1
+ {"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAKpD,sFAAsF;AACtF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAChC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAChB;QACE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;KACjD,GACD,SAAS,CAAC;CACf;AAED,uFAAuF;AACvF,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,sDAAsD;IACtD,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,qEAAqE;IACrE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,IAAI,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAcvD;AA0JD,kGAAkG;AAClG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAE1D;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAMvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"grants.js","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile, spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { promisify } from \"node:util\";\n\nimport type { AccountSummary } from \"@parlor/auth\";\nimport type { GrantId, HostId } from \"@parlor/core\";\n\nimport { hostAssertion } from \"./assertion.js\";\nimport { jsonFile } from \"./json-file.js\";\n\n/** One app this computer is connected to. Its key lives in `HostKeys`, never here. */\nexport interface AppGrant {\n readonly appOrigin: string;\n readonly appName: string;\n readonly grantId: GrantId;\n readonly hostId: HostId;\n readonly account: AccountSummary;\n /** The agents' working directory for this app; only the user changes it, here. */\n readonly workspace: string;\n readonly createdAt: number;\n /** A `parlor dev` grant: in memory only. */\n readonly dev?: true | undefined;\n /** Refused here but not yet revoked by the app: kept only to retry the revoke, never served. */\n readonly declined?: true | undefined;\n /**\n * Handed only to the browser that approved `connect`, through the loopback redirect; that\n * browser proves it on its first prompt and is trusted without asking, then this is dropped.\n */\n readonly pairingSecret?: string | undefined;\n}\n\n/** One key per app grant in the OS keychain; the server holds only its public half. */\nexport interface HostKeys {\n /** A pairing's new key pair, kept only once the pairing completes. */\n create(appOrigin: string): Promise<HostKeyPair>;\n /** A fresh `ParlorHost` assertion for one request. */\n assert(\n appOrigin: string,\n request: { readonly method: \"GET\" | \"POST\"; readonly url: string },\n ): Promise<string>;\n remove(appOrigin: string): Promise<void>;\n}\n\nexport interface HostKeyPair {\n readonly publicKey: JsonWebKey;\n /** RFC 7638, the assertion's `kid`. */\n readonly thumbprint: string;\n sign(payload: Uint8Array): Promise<string>;\n /** Binds the key to the grant the pairing produced and stores it. */\n keep(grantId: GrantId): Promise<void>;\n}\n\nexport interface GrantStore {\n list(): Promise<readonly AppGrant[]>;\n get(appOrigin: string): Promise<AppGrant | undefined>;\n save(grant: AppGrant): Promise<void>;\n remove(appOrigin: string): Promise<void>;\n}\n\n/** `~/.parlor/host/grants.json`, 0600, written atomically. */\nexport function fileGrantStore(file: string): GrantStore {\n const grants = jsonFile<Record<string, AppGrant>>(file);\n return {\n list: async () => Object.values(await grants.read()),\n get: async (appOrigin) => (await grants.read())[appOrigin],\n save: (grant) =>\n grants.change((all) => {\n all[grant.appOrigin] = grant;\n }),\n remove: (appOrigin) =>\n grants.change((all) => {\n delete all[appOrigin];\n }),\n };\n}\n\nconst EC_P256 = { name: \"ECDSA\", namedCurve: \"P-256\" } as const;\nconst ES256 = { name: \"ECDSA\", hash: \"SHA-256\" } as const;\nconst ORIGIN = /^https?:\\/\\/[A-Za-z0-9.\\-[\\]:]+$/;\n\ninterface StoredKey {\n readonly jwk: JsonWebKey;\n readonly kid: string;\n readonly grantId: string;\n}\n\ninterface LoadedKey {\n readonly key: CryptoKey;\n readonly kid: string;\n readonly grantId: string;\n}\n\ninterface SecretStore {\n read(account: string): Promise<string | undefined>;\n write(account: string, secret: string): Promise<void>;\n remove(account: string): Promise<void>;\n}\n\nfunction thumbprintOf({ crv, kty, x, y }: JsonWebKey): string {\n return createHash(\"sha256\")\n .update(JSON.stringify({ crv, kty, x, y }))\n .digest(\"base64url\");\n}\n\nconst signer = (key: CryptoKey) => async (payload: Uint8Array) =>\n Buffer.from(await crypto.subtle.sign(ES256, key, new Uint8Array(payload))).toString(\n \"base64url\",\n );\n\nfunction keysIn(secrets: SecretStore): HostKeys {\n const loaded = new Map<string, Promise<LoadedKey | undefined>>();\n const load = (appOrigin: string) => {\n let entry = loaded.get(appOrigin);\n if (!entry) {\n entry = (async () => {\n const secret = await secrets.read(appOrigin);\n if (secret === undefined) return undefined;\n const stored = JSON.parse(\n Buffer.from(secret, \"base64url\").toString(\"utf8\"),\n ) as StoredKey;\n const key = await crypto.subtle.importKey(\"jwk\", stored.jwk, EC_P256, false, [\n \"sign\",\n ]);\n return { key, kid: stored.kid, grantId: stored.grantId };\n })();\n entry.catch(() => loaded.delete(appOrigin));\n loaded.set(appOrigin, entry);\n }\n return entry;\n };\n return {\n async create(appOrigin) {\n const pair = await crypto.subtle.generateKey(EC_P256, true, [\"sign\", \"verify\"]);\n const exported = await crypto.subtle.exportKey(\"jwk\", pair.publicKey);\n const publicKey: JsonWebKey = {\n kty: exported.kty!,\n crv: exported.crv!,\n x: exported.x!,\n y: exported.y!,\n };\n const thumbprint = thumbprintOf(publicKey);\n return {\n publicKey,\n thumbprint,\n sign: signer(pair.privateKey),\n keep: async (grantId) => {\n const jwk = await crypto.subtle.exportKey(\"jwk\", pair.privateKey);\n const stored: StoredKey = { jwk, kid: thumbprint, grantId };\n await secrets.write(\n appOrigin,\n Buffer.from(JSON.stringify(stored)).toString(\"base64url\"),\n );\n loaded.delete(appOrigin);\n },\n };\n },\n async assert(appOrigin, request) {\n const key = await load(appOrigin);\n if (!key) throw new Error(`This computer holds no key for ${appOrigin}.`);\n return hostAssertion(signer(key.key), key, request);\n },\n async remove(appOrigin) {\n loaded.delete(appOrigin);\n await secrets.remove(appOrigin);\n },\n };\n}\n\nconst run = promisify(execFile);\nconst NOT_FOUND = 44;\n\nfunction macKeychain(service: string): SecretStore {\n const checked = (account: string) => {\n if (!ORIGIN.test(account)) throw new Error(`${account} is not an app origin.`);\n return account;\n };\n return {\n async read(account) {\n try {\n const { stdout } = await run(\"security\", [\n \"find-generic-password\",\n \"-s\",\n service,\n \"-a\",\n checked(account),\n \"-w\",\n ]);\n return stdout.trim();\n } catch (error) {\n if ((error as { code?: unknown }).code === NOT_FOUND) return undefined;\n throw error;\n }\n },\n async write(account, secret) {\n // Through `security -i` on stdin, so the private key never shows in a process list.\n const command = `add-generic-password -U -s ${service} -a ${checked(account)} -w ${secret}\\n`;\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"security\", [\"-i\"], { stdio: [\"pipe\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n child.stderr.on(\"data\", (chunk: Buffer) => (stderr += chunk.toString()));\n child.once(\"error\", reject);\n child.once(\"exit\", (code) =>\n code === 0 && stderr.trim() === \"\"\n ? resolve()\n : reject(new Error(`The Keychain refused the key: ${stderr.trim() || code}`)),\n );\n child.stdin.end(command);\n });\n if ((await this.read(account)) !== secret) {\n throw new Error(\"The Keychain did not keep the key.\");\n }\n },\n async remove(account) {\n try {\n await run(\"security\", [\n \"delete-generic-password\",\n \"-s\",\n service,\n \"-a\",\n checked(account),\n ]);\n } catch (error) {\n if ((error as { code?: unknown }).code !== NOT_FOUND) throw error;\n }\n },\n };\n}\n\n/** The macOS Keychain; other platforms are refused before pairing (`unsupportedHostPlatform`). */\nexport function keychainHostKeys(service: string): HostKeys {\n return keysIn(macKeychain(service));\n}\n\n/** For `parlor-host dev`: one dev host token for every request, nothing on disk. */\nexport function devHostKeys(hostToken: string): HostKeys {\n return {\n create: () => Promise.reject(new Error(\"A parlor dev server needs no pairing.\")),\n assert: async () => hostToken,\n remove: async () => undefined,\n };\n}\n"]}
1
+ {"version":3,"file":"grants.js","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile, spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { promisify } from \"node:util\";\n\nimport type { AccountSummary } from \"@parlor/auth\";\nimport type { GrantId, HostId } from \"@parlor/core\";\n\nimport { hostAssertion } from \"./assertion.js\";\nimport { jsonFile } from \"./json-file.js\";\n\n/** One app this computer is connected to. Its key lives in `HostKeys`, never here. */\nexport interface AppGrant {\n readonly appOrigin: string;\n readonly appName: string;\n readonly grantId: GrantId;\n readonly hostId: HostId;\n readonly account: AccountSummary;\n /** The agents' working directory for this app; only the user changes it, here. */\n readonly workspace: string;\n readonly createdAt: number;\n /** A `parlor dev` grant: in memory only. */\n readonly dev?: true | undefined;\n /** Refused here but not yet revoked by the app: kept only to retry the revoke, never served. */\n readonly declined?: true | undefined;\n /**\n * Handed only to the browser that approved `connect`, through the loopback redirect; that\n * browser proves it on its first prompt and is trusted without asking, then this is dropped.\n */\n readonly pairingSecret?: string | undefined;\n /**\n * Whether the coding agents on this computer may use the app outside its sidebar, as the\n * user chose when connecting, and the name and agents it is registered under once it is.\n */\n readonly agentTools?:\n | {\n readonly on: boolean;\n readonly name?: string | undefined;\n readonly agents?: readonly string[] | undefined;\n }\n | undefined;\n}\n\n/** One key per app grant in the OS keychain; the server holds only its public half. */\nexport interface HostKeys {\n /** A pairing's new key pair, kept only once the pairing completes. */\n create(appOrigin: string): Promise<HostKeyPair>;\n /** A fresh `ParlorHost` assertion for one request. */\n assert(\n appOrigin: string,\n request: { readonly method: \"GET\" | \"POST\"; readonly url: string },\n ): Promise<string>;\n remove(appOrigin: string): Promise<void>;\n}\n\nexport interface HostKeyPair {\n readonly publicKey: JsonWebKey;\n /** RFC 7638, the assertion's `kid`. */\n readonly thumbprint: string;\n sign(payload: Uint8Array): Promise<string>;\n /** Binds the key to the grant the pairing produced and stores it. */\n keep(grantId: GrantId): Promise<void>;\n}\n\nexport interface GrantStore {\n list(): Promise<readonly AppGrant[]>;\n get(appOrigin: string): Promise<AppGrant | undefined>;\n save(grant: AppGrant): Promise<void>;\n remove(appOrigin: string): Promise<void>;\n}\n\n/** `~/.parlor/host/grants.json`, 0600, written atomically. */\nexport function fileGrantStore(file: string): GrantStore {\n const grants = jsonFile<Record<string, AppGrant>>(file);\n return {\n list: async () => Object.values(await grants.read()),\n get: async (appOrigin) => (await grants.read())[appOrigin],\n save: (grant) =>\n grants.change((all) => {\n all[grant.appOrigin] = grant;\n }),\n remove: (appOrigin) =>\n grants.change((all) => {\n delete all[appOrigin];\n }),\n };\n}\n\nconst EC_P256 = { name: \"ECDSA\", namedCurve: \"P-256\" } as const;\nconst ES256 = { name: \"ECDSA\", hash: \"SHA-256\" } as const;\nconst ORIGIN = /^https?:\\/\\/[A-Za-z0-9.\\-[\\]:]+$/;\n\ninterface StoredKey {\n readonly jwk: JsonWebKey;\n readonly kid: string;\n readonly grantId: string;\n}\n\ninterface LoadedKey {\n readonly key: CryptoKey;\n readonly kid: string;\n readonly grantId: string;\n}\n\ninterface SecretStore {\n read(account: string): Promise<string | undefined>;\n write(account: string, secret: string): Promise<void>;\n remove(account: string): Promise<void>;\n}\n\nfunction thumbprintOf({ crv, kty, x, y }: JsonWebKey): string {\n return createHash(\"sha256\")\n .update(JSON.stringify({ crv, kty, x, y }))\n .digest(\"base64url\");\n}\n\nconst signer = (key: CryptoKey) => async (payload: Uint8Array) =>\n Buffer.from(await crypto.subtle.sign(ES256, key, new Uint8Array(payload))).toString(\n \"base64url\",\n );\n\nfunction keysIn(secrets: SecretStore): HostKeys {\n const loaded = new Map<string, Promise<LoadedKey | undefined>>();\n const load = (appOrigin: string) => {\n let entry = loaded.get(appOrigin);\n if (!entry) {\n entry = (async () => {\n const secret = await secrets.read(appOrigin);\n if (secret === undefined) return undefined;\n const stored = JSON.parse(\n Buffer.from(secret, \"base64url\").toString(\"utf8\"),\n ) as StoredKey;\n const key = await crypto.subtle.importKey(\"jwk\", stored.jwk, EC_P256, false, [\n \"sign\",\n ]);\n return { key, kid: stored.kid, grantId: stored.grantId };\n })();\n entry.catch(() => loaded.delete(appOrigin));\n loaded.set(appOrigin, entry);\n }\n return entry;\n };\n return {\n async create(appOrigin) {\n const pair = await crypto.subtle.generateKey(EC_P256, true, [\"sign\", \"verify\"]);\n const exported = await crypto.subtle.exportKey(\"jwk\", pair.publicKey);\n const publicKey: JsonWebKey = {\n kty: exported.kty!,\n crv: exported.crv!,\n x: exported.x!,\n y: exported.y!,\n };\n const thumbprint = thumbprintOf(publicKey);\n return {\n publicKey,\n thumbprint,\n sign: signer(pair.privateKey),\n keep: async (grantId) => {\n const jwk = await crypto.subtle.exportKey(\"jwk\", pair.privateKey);\n const stored: StoredKey = { jwk, kid: thumbprint, grantId };\n await secrets.write(\n appOrigin,\n Buffer.from(JSON.stringify(stored)).toString(\"base64url\"),\n );\n loaded.delete(appOrigin);\n },\n };\n },\n async assert(appOrigin, request) {\n const key = await load(appOrigin);\n if (!key) throw new Error(`This computer holds no key for ${appOrigin}.`);\n return hostAssertion(signer(key.key), key, request);\n },\n async remove(appOrigin) {\n loaded.delete(appOrigin);\n await secrets.remove(appOrigin);\n },\n };\n}\n\nconst run = promisify(execFile);\nconst NOT_FOUND = 44;\n\nfunction macKeychain(service: string): SecretStore {\n const checked = (account: string) => {\n if (!ORIGIN.test(account)) throw new Error(`${account} is not an app origin.`);\n return account;\n };\n return {\n async read(account) {\n try {\n const { stdout } = await run(\"security\", [\n \"find-generic-password\",\n \"-s\",\n service,\n \"-a\",\n checked(account),\n \"-w\",\n ]);\n return stdout.trim();\n } catch (error) {\n if ((error as { code?: unknown }).code === NOT_FOUND) return undefined;\n throw error;\n }\n },\n async write(account, secret) {\n // Through `security -i` on stdin, so the private key never shows in a process list.\n const command = `add-generic-password -U -s ${service} -a ${checked(account)} -w ${secret}\\n`;\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"security\", [\"-i\"], { stdio: [\"pipe\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n child.stderr.on(\"data\", (chunk: Buffer) => (stderr += chunk.toString()));\n child.once(\"error\", reject);\n child.once(\"exit\", (code) =>\n code === 0 && stderr.trim() === \"\"\n ? resolve()\n : reject(new Error(`The Keychain refused the key: ${stderr.trim() || code}`)),\n );\n child.stdin.end(command);\n });\n if ((await this.read(account)) !== secret) {\n throw new Error(\"The Keychain did not keep the key.\");\n }\n },\n async remove(account) {\n try {\n await run(\"security\", [\n \"delete-generic-password\",\n \"-s\",\n service,\n \"-a\",\n checked(account),\n ]);\n } catch (error) {\n if ((error as { code?: unknown }).code !== NOT_FOUND) throw error;\n }\n },\n };\n}\n\n/** The macOS Keychain; other platforms are refused before pairing (`unsupportedHostPlatform`). */\nexport function keychainHostKeys(service: string): HostKeys {\n return keysIn(macKeychain(service));\n}\n\n/** For `parlor-host dev`: one dev host token for every request, nothing on disk. */\nexport function devHostKeys(hostToken: string): HostKeys {\n return {\n create: () => Promise.reject(new Error(\"A parlor dev server needs no pairing.\")),\n assert: async () => hostToken,\n remove: async () => undefined,\n };\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import type { AgentInfo, AgentOption, AgentUsage } from "@parlor/chat";
2
+ export interface Learned {
3
+ readonly options?: readonly AgentOption[] | undefined;
4
+ readonly usage?: AgentUsage | undefined;
5
+ }
6
+ export type LearnedNews = {
7
+ readonly options: readonly AgentOption[];
8
+ } | {
9
+ readonly usage: AgentUsage;
10
+ };
11
+ /**
12
+ * What each agent last said about itself, kept across restarts: the allowance only arrives
13
+ * on a turn, and a computer that forgot it would show nothing until the next one.
14
+ */
15
+ export interface LearnedStore {
16
+ load(): Promise<void>;
17
+ /** Whether it changed what `describe` returns. */
18
+ learn(agentId: string, news: LearnedNews): Promise<boolean>;
19
+ /** Whether the agent has said which options it offers. */
20
+ knows(agentId: string): boolean;
21
+ /** `agents` with what each said about itself, minus usage windows that rolled over. */
22
+ describe(agents: readonly AgentInfo[], now: number): AgentInfo[];
23
+ }
24
+ export declare function learnedStore(file: string): LearnedStore;
25
+ //# sourceMappingURL=learned.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learned.d.ts","sourceRoot":"","sources":["../src/learned.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAKvE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;CAAE,GAC5C;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,kDAAkD;IAClD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,0DAA0D;IAC1D,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;CAClE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAoCvD"}
@@ -0,0 +1,37 @@
1
+ import { mergeUsage } from "./agent-options.js";
2
+ import { jsonFile } from "./json-file.js";
3
+ export function learnedStore(file) {
4
+ const stored = jsonFile(file);
5
+ let known = {};
6
+ return {
7
+ load: async () => {
8
+ known = await stored.read().catch(() => ({}));
9
+ },
10
+ learn: async (agentId, news) => {
11
+ const held = known[agentId] ?? {};
12
+ const next = "options" in news
13
+ ? { ...held, options: news.options }
14
+ : { ...held, usage: mergeUsage(held.usage, news.usage) };
15
+ if (JSON.stringify(next) === JSON.stringify(held))
16
+ return false;
17
+ known = { ...known, [agentId]: next };
18
+ await stored.change((all) => {
19
+ all[agentId] = next;
20
+ });
21
+ return true;
22
+ },
23
+ knows: (agentId) => (known[agentId]?.options?.length ?? 0) > 0,
24
+ describe: (agents, now) => agents.map((agent) => {
25
+ const { options, usage } = known[agent.id] ?? {};
26
+ const windows = usage?.windows.filter((window) => window.resetsAt === undefined || window.resetsAt > now);
27
+ return {
28
+ ...agent,
29
+ ...(options && options.length > 0 ? { options } : {}),
30
+ ...(usage && windows && windows.length > 0
31
+ ? { usage: { ...usage, windows } }
32
+ : {}),
33
+ };
34
+ }),
35
+ };
36
+ }
37
+ //# sourceMappingURL=learned.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learned.js","sourceRoot":"","sources":["../src/learned.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAyB1C,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,MAAM,GAAG,QAAQ,CAA0B,IAAI,CAAC,CAAC;IACvD,IAAI,KAAK,GAA4B,EAAE,CAAC;IACxC,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,GACR,SAAS,IAAI,IAAI;gBACf,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;gBACpC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;YAChE,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1B,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QAC9D,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CACxB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACjD,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,CAAC,MAAM,CACnC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,GAAG,GAAG,CACnE,CAAC;YACF,OAAO;gBACL,GAAG,KAAK;gBACR,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,GAAG,CAAC,KAAK,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;oBACxC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE;oBAClC,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;QACJ,CAAC,CAAC;KACL,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentInfo, AgentOption, AgentUsage } from \"@parlor/chat\";\n\nimport { mergeUsage } from \"./agent-options.js\";\nimport { jsonFile } from \"./json-file.js\";\n\nexport interface Learned {\n readonly options?: readonly AgentOption[] | undefined;\n readonly usage?: AgentUsage | undefined;\n}\n\nexport type LearnedNews =\n | { readonly options: readonly AgentOption[] }\n | { readonly usage: AgentUsage };\n\n/**\n * What each agent last said about itself, kept across restarts: the allowance only arrives\n * on a turn, and a computer that forgot it would show nothing until the next one.\n */\nexport interface LearnedStore {\n load(): Promise<void>;\n /** Whether it changed what `describe` returns. */\n learn(agentId: string, news: LearnedNews): Promise<boolean>;\n /** Whether the agent has said which options it offers. */\n knows(agentId: string): boolean;\n /** `agents` with what each said about itself, minus usage windows that rolled over. */\n describe(agents: readonly AgentInfo[], now: number): AgentInfo[];\n}\n\nexport function learnedStore(file: string): LearnedStore {\n const stored = jsonFile<Record<string, Learned>>(file);\n let known: Record<string, Learned> = {};\n return {\n load: async () => {\n known = await stored.read().catch(() => ({}));\n },\n learn: async (agentId, news) => {\n const held = known[agentId] ?? {};\n const next: Learned =\n \"options\" in news\n ? { ...held, options: news.options }\n : { ...held, usage: mergeUsage(held.usage, news.usage) };\n if (JSON.stringify(next) === JSON.stringify(held)) return false;\n known = { ...known, [agentId]: next };\n await stored.change((all) => {\n all[agentId] = next;\n });\n return true;\n },\n knows: (agentId) => (known[agentId]?.options?.length ?? 0) > 0,\n describe: (agents, now) =>\n agents.map((agent) => {\n const { options, usage } = known[agent.id] ?? {};\n const windows = usage?.windows.filter(\n (window) => window.resetsAt === undefined || window.resetsAt > now,\n );\n return {\n ...agent,\n ...(options && options.length > 0 ? { options } : {}),\n ...(usage && windows && windows.length > 0\n ? { usage: { ...usage, windows } }\n : {}),\n };\n }),\n };\n}\n"]}
package/dist/link.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type HostStreamBatch, type HostWelcome } from "@parlor/chat";
1
+ import { type ClaimedTurn, type HostStreamBatch, type HostWelcome } from "@parlor/chat";
2
2
  import { type ChatHostActionMap } from "@parlor/chat/server";
3
3
  import { type PluginClient } from "@parlor/client";
4
4
  import type { AppGrant, HostKeys } from "./grants.js";
@@ -19,6 +19,8 @@ export interface AppLinkDeps {
19
19
  readonly fetch: typeof fetch;
20
20
  /** A turn may be waiting: claim until not_found, then ask for running turns' signals. */
21
21
  readonly onWake: (link: AppLink) => void;
22
+ /** The app claimed a turn for this computer and pushed it, saving the claim. */
23
+ readonly onPushed?: ((link: AppLink, turn: ClaimedTurn) => void) | undefined;
22
24
  /** Whether a turn runs on this link, which keeps a poll deployment's `/sync` at the active interval. */
23
25
  readonly busy?: (() => boolean) | undefined;
24
26
  /** Any 401, or the stream closed for revocation. */
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../src/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,iBAAiB,EAAyB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAItD,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,eAAO,MAAM,cAAc,OAAQ,CAAC;AACpC,eAAO,MAAM,YAAY,QAAS,CAAC;AAKnC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAChD,6FAA6F;IAC7F,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wGAAwG;IACxG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,CAAC;IAC5C,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC9C,qFAAqF;IACrF,QAAQ,CAAC,cAAc,EAAE,CACvB,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;KAAE,CAAC,KACxD,IAAI,CAAC;CACX;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAElE,2FAA2F;AAC3F,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,6FAA6F;IAC7F,KAAK,IAAI,IAAI,CAAC;IACd,0EAA0E;IAC1E,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAuFD,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAyMzE"}
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../src/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAGhB,KAAK,eAAe,EACpB,KAAK,WAAW,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,iBAAiB,EAAyB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAItD,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,eAAO,MAAM,cAAc,OAAQ,CAAC;AACpC,eAAO,MAAM,YAAY,QAAS,CAAC;AAKnC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAChD,6FAA6F;IAC7F,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7E,wGAAwG;IACxG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,CAAC;IAC5C,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC9C,qFAAqF;IACrF,QAAQ,CAAC,cAAc,EAAE,CACvB,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;KAAE,CAAC,KACxD,IAAI,CAAC;CACX;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAElE,2FAA2F;AAC3F,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,6FAA6F;IAC7F,KAAK,IAAI,IAAI,CAAC;IACd,0EAA0E;IAC1E,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAiGD,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAoNzE"}