@agimon-ai/po-core 0.0.0-alpha.102 → 0.0.0-alpha.104

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 (73) hide show
  1. package/dist/apiContracts.d.mts +64 -0
  2. package/dist/apiContracts.d.mts.map +1 -1
  3. package/dist/headlessProtocol.cjs +2 -1
  4. package/dist/headlessProtocol.cjs.map +1 -1
  5. package/dist/headlessProtocol.mjs +2 -1
  6. package/dist/headlessProtocol.mjs.map +1 -1
  7. package/dist/headlessServer.cjs +20 -1
  8. package/dist/headlessServer.cjs.map +1 -1
  9. package/dist/headlessServer.mjs +20 -1
  10. package/dist/headlessServer.mjs.map +1 -1
  11. package/dist/machineApi.cjs +2 -46
  12. package/dist/machineApi.cjs.map +1 -1
  13. package/dist/machineApi.d.mts.map +1 -1
  14. package/dist/machineApi.mjs +2 -46
  15. package/dist/machineApi.mjs.map +1 -1
  16. package/dist/platform.cjs +2 -0
  17. package/dist/platform.d.mts +2 -2
  18. package/dist/platform.mjs +2 -2
  19. package/dist/providerAuth.cjs +8 -0
  20. package/dist/providerAuth.d.mts +4 -0
  21. package/dist/providerAuth.mjs +3 -0
  22. package/dist/src/pi/piSessionRuntime.cjs +13 -2
  23. package/dist/src/pi/piSessionRuntime.cjs.map +1 -1
  24. package/dist/src/pi/piSessionRuntime.d.mts +1 -1
  25. package/dist/src/pi/piSessionRuntime.mjs +13 -2
  26. package/dist/src/pi/piSessionRuntime.mjs.map +1 -1
  27. package/dist/src/schemas/platform.cjs +6 -0
  28. package/dist/src/schemas/platform.cjs.map +1 -1
  29. package/dist/src/schemas/platform.d.mts +68 -0
  30. package/dist/src/schemas/platform.d.mts.map +1 -1
  31. package/dist/src/schemas/platform.mjs +5 -1
  32. package/dist/src/schemas/platform.mjs.map +1 -1
  33. package/dist/src/server/conversationEvents.cjs +3 -2
  34. package/dist/src/server/conversationEvents.cjs.map +1 -1
  35. package/dist/src/server/conversationEvents.mjs +3 -2
  36. package/dist/src/server/conversationEvents.mjs.map +1 -1
  37. package/dist/src/server/directHarnessRuntime.cjs +55 -5
  38. package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
  39. package/dist/src/server/directHarnessRuntime.d.mts.map +1 -1
  40. package/dist/src/server/directHarnessRuntime.mjs +55 -5
  41. package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
  42. package/dist/src/server/providerRoutes.cjs +58 -0
  43. package/dist/src/server/providerRoutes.cjs.map +1 -0
  44. package/dist/src/server/providerRoutes.d.mts +16 -0
  45. package/dist/src/server/providerRoutes.d.mts.map +1 -0
  46. package/dist/src/server/providerRoutes.mjs +58 -0
  47. package/dist/src/server/providerRoutes.mjs.map +1 -0
  48. package/dist/src/server/serverScope.cjs +1 -0
  49. package/dist/src/server/serverScope.cjs.map +1 -1
  50. package/dist/src/server/serverScope.d.mts.map +1 -1
  51. package/dist/src/server/serverScope.mjs +2 -1
  52. package/dist/src/server/serverScope.mjs.map +1 -1
  53. package/dist/src/services/edgeModelRuntime/index.cjs +363 -0
  54. package/dist/src/services/edgeModelRuntime/index.cjs.map +1 -0
  55. package/dist/src/services/edgeModelRuntime/index.d.mts +24 -0
  56. package/dist/src/services/edgeModelRuntime/index.d.mts.map +1 -0
  57. package/dist/src/services/edgeModelRuntime/index.mjs +360 -0
  58. package/dist/src/services/edgeModelRuntime/index.mjs.map +1 -0
  59. package/dist/src/services/edgeModelRuntime/type.d.mts +32 -0
  60. package/dist/src/services/edgeModelRuntime/type.d.mts.map +1 -0
  61. package/dist/src/services/providerAuth/index.cjs +1 -4
  62. package/dist/src/services/providerAuth/index.cjs.map +1 -1
  63. package/dist/src/services/providerAuth/index.mjs +0 -1
  64. package/dist/src/services/providerAuth/index.mjs.map +1 -1
  65. package/dist/src/systems/main/adapters/headlessSessionHost.cjs +3 -0
  66. package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
  67. package/dist/src/systems/main/adapters/headlessSessionHost.mjs +3 -0
  68. package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
  69. package/dist/src/types/server/auth.d.mts +99 -0
  70. package/dist/src/types/server/auth.d.mts.map +1 -0
  71. package/dist/src/types/server/directHarnessRuntime.d.mts +10 -0
  72. package/dist/src/types/server/directHarnessRuntime.d.mts.map +1 -1
  73. package/package.json +9 -4
@@ -1,6 +1,7 @@
1
1
  import { Static, TSchema, Type } from "typebox";
2
2
  import { Context, method } from "@earendil-works/chord";
3
3
  import { Events } from "@deepseek-ai/cordis";
4
+ import { AuthResult, ModelType, ModelsStoreEntry } from "@earendil-works/pi-ai";
4
5
  import { Storage } from "@earendil-works/pi-durable";
5
6
  import { FileSystem, Shell } from "@earendil-works/pi-durable/env";
6
7
  import { SqliteDatabase } from "@earendil-works/pi-durable/storage/sqlite";
@@ -332,6 +333,68 @@ interface PoIsolateService {
332
333
  readonly liveObjects: boolean;
333
334
  run(request: PoIsolateRequest): Promise<PoIsolateResult>;
334
335
  }
336
+ /** An OpenAI- or Anthropic-compatible endpoint added by hand. Holds no secret: its key is a stored credential. */
337
+ interface PoCustomProviderDefinition {
338
+ readonly id: string;
339
+ readonly name: string;
340
+ /** `http:` or `https:`, without userinfo or a query string. */
341
+ readonly baseUrl: string;
342
+ readonly api: 'openai-completions' | 'openai-responses' | 'anthropic-messages';
343
+ readonly models: readonly {
344
+ readonly id: string;
345
+ readonly name?: string;
346
+ readonly reasoning?: boolean;
347
+ readonly input?: readonly ('text' | 'image')[];
348
+ readonly contextWindow?: number;
349
+ readonly maxTokens?: number;
350
+ }[];
351
+ }
352
+ /** What the credential owner tells sessions: never a key, token, header or URL secret. */
353
+ interface PoProviderAuthSnapshot {
354
+ /** Changes whenever anything below changes; compare with `!==`, as an owner restart starts afresh. */
355
+ readonly version: number;
356
+ /** Configured providers only; every other provider is unconfigured. */
357
+ readonly providers: readonly {
358
+ readonly id: string;
359
+ readonly type: 'api_key' | 'oauth';
360
+ readonly source?: string;
361
+ readonly subscription: boolean;
362
+ }[];
363
+ /** Models of every type the deployment target can use, after each provider's credential filter. */
364
+ readonly available: readonly {
365
+ readonly provider: string;
366
+ readonly id: string;
367
+ readonly type: ModelType;
368
+ }[];
369
+ /** Dynamic catalogs by provider id, with headers and URL secrets removed. */
370
+ readonly models: Readonly<Record<string, ModelsStoreEntry>>;
371
+ readonly customProviders: readonly PoCustomProviderDefinition[];
372
+ }
373
+ /**
374
+ * Provider credentials held by one owner per deployment target (the org on hosted Po), for hosts
375
+ * whose sessions must never store them. Node leaves it unbound: `auth.json` is the authority there.
376
+ */
377
+ interface PoProviderAuth {
378
+ readonly abiVersion: 1;
379
+ /**
380
+ * Provider-level auth for one request, resolved like local `Models.getAuth` (stored OAuth refreshed,
381
+ * then the stored key) and never persisted by the caller. `version` is the owner's snapshot version.
382
+ */
383
+ resolveAuth(provider: string): Promise<{
384
+ readonly version: number;
385
+ readonly auth?: AuthResult;
386
+ }>;
387
+ /** The full snapshot, or just `{ version }` while `sinceVersion` is still current. */
388
+ snapshot(sinceVersion?: number): Promise<PoProviderAuthSnapshot | {
389
+ readonly version: number;
390
+ }>;
391
+ refresh(options?: {
392
+ readonly allowNetwork?: boolean;
393
+ }): Promise<{
394
+ readonly version: number;
395
+ readonly errors: Readonly<Record<string, string>>;
396
+ }>;
397
+ }
335
398
  declare module '@deepseek-ai/cordis' {
336
399
  interface Context {
337
400
  'po/fs': FileSystem;
@@ -342,6 +405,7 @@ declare module '@deepseek-ai/cordis' {
342
405
  'po/npm': PoNpm;
343
406
  'po/electron': PoElectronService;
344
407
  'po/browser': PoBrowserService;
408
+ 'po/provider-auth': PoProviderAuth;
345
409
  'po/session-files': {
346
410
  readonly temporaryDirectory: string;
347
411
  };
@@ -1 +1 @@
1
- {"version":3,"file":"apiContracts.d.mts","names":["_0","_0","_0","IoContext","_0","_$__hubChannel0.PoHubSessionUsage","_0","_$__protocolContracts0.ChordMethods"],"sources":["../src/schemas/serverScope.ts","../src/schemas/approvalPrompt.ts","../src/schemas/approval.ts","../src/schemas/backgroundWork.ts","../src/schemas/platform.ts","../src/schemas/workflow.ts","../src/schemas/hubChannel.ts","../src/schemas/packageApi.ts","../src/schemas/serverBundle.ts","../src/schemas/apiContracts.ts","../src/services/apiContracts/index.ts","../src/schemas/builtinApiContracts.ts","../src/schemas/httpApiContracts.ts","../src/schemas/protocolContracts.ts","../src/schemas/sessionProtocol.ts","../src/schemas/sessionApiContracts.ts","../src/schemas/transportApiContracts.ts"],"mappings":"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"}
1
+ {"version":3,"file":"apiContracts.d.mts","names":["_0","_0","_0","IoContext","_0","_$__hubChannel0.PoHubSessionUsage","_0","_$__protocolContracts0.ChordMethods"],"sources":["../src/schemas/serverScope.ts","../src/schemas/approvalPrompt.ts","../src/schemas/approval.ts","../src/schemas/backgroundWork.ts","../src/schemas/platform.ts","../src/schemas/workflow.ts","../src/schemas/hubChannel.ts","../src/schemas/packageApi.ts","../src/schemas/serverBundle.ts","../src/schemas/apiContracts.ts","../src/services/apiContracts/index.ts","../src/schemas/builtinApiContracts.ts","../src/schemas/httpApiContracts.ts","../src/schemas/protocolContracts.ts","../src/schemas/sessionProtocol.ts","../src/schemas/sessionApiContracts.ts","../src/schemas/transportApiContracts.ts"],"mappings":"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"}
@@ -291,7 +291,7 @@ function createHeadlessProtocol(options) {
291
291
  }
292
292
  };
293
293
  });
294
- require_piSessionRuntime.serveAgentSessions(host, { resolve(sessionId, principal) {
294
+ const clearSessionBindings = require_piSessionRuntime.serveAgentSessions(host, { resolve(sessionId, principal) {
295
295
  const connection = connectionOf(principal);
296
296
  const session = hub.session(sessionId);
297
297
  if (!session || !reachable(connection, session.id)) return void 0;
@@ -358,6 +358,7 @@ function createHeadlessProtocol(options) {
358
358
  closing ??= (async () => {
359
359
  stopClaims?.();
360
360
  threads.close();
361
+ clearSessionBindings();
361
362
  await host.close();
362
363
  })();
363
364
  return closing;
@@ -1 +1 @@
1
- {"version":3,"file":"headlessProtocol.cjs","names":["createThreadJournals","createHost","PO_SERVER_HOST","harnessErrorMessage","forbidden","PoHubContract","chordSchema","Type","SessionSummarySchema","HubWorkspaceSchema","HubNoticeSchema","HubCompositionsSchema","randomUUID","PoHubRevisionsContract","HubRevisionsSchema","PoThreadContract","PoThreadFrameSchema","PoChannelsContract","PoChannelsStateSchema","reportingLargeFrames"],"sources":["../src/server/headlessProtocol.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createHost, forbidden, type Link, type Subscribable } from '@earendil-works/chord';\nimport { Type } from 'typebox';\n\nimport type { PoPluginCall } from '../exports/pluginProtocol';\nimport {\n HubCompositionsSchema,\n HubNoticeSchema,\n HubRevisionsSchema,\n PO_SERVER_HOST,\n PoChannelsContract,\n PoHubContract,\n PoHubRevisionsContract,\n PoThreadContract,\n type HubNotice,\n type HubSessionView,\n type HubWorkspaceView,\n type JsonValue,\n} from '../exports/sessionProtocol';\nimport { serveAgentSessions, type AgentSessionBinding } from '../pi/piSessionRuntime';\nimport { SessionSummarySchema } from '../schemas/httpApiContracts';\nimport type { PoSocketMount } from '../schemas/packageApi';\nimport { PoChannelsStateSchema } from '../schemas/protocolChannelsContract';\nimport { chordSchema } from '../schemas/protocolContracts';\nimport { HubWorkspaceSchema } from '../schemas/protocolHubContract';\nimport { PoThreadFrameSchema } from '../schemas/protocolThreadContract';\nimport type { OpenSessionRecord } from '../services/openSessionRegistry';\nimport type { ServerTelemetry } from '../services/serverTelemetry';\nimport { harnessErrorMessage } from './harnessErrorMessage';\nimport type { HeadlessHub, HeadlessHubEvent, HeadlessHubSession } from './headlessHub';\nimport { reportingLargeFrames } from './largeFrameLink';\nimport { createThreadJournals } from './threadJournals';\n\n// ponytail: unacknowledged notices beyond this drop oldest first; raise it if a client misses dialogs.\nconst MAX_PENDING_NOTICES = 64;\n/** A browser switching back to a thread quickly keeps its tail open. */\nconst THREAD_LINGER_MS = 5_000;\n\nfunction sessionView(session: HeadlessHubSession): HubSessionView {\n return {\n id: session.id,\n ...(session.workspaceId === undefined ? {} : { workspaceId: session.workspaceId }),\n ...(session.webComposition === undefined ? {} : { webComposition: { ...session.webComposition } }),\n ...(session.nativeComposition === undefined ? {} : { nativeComposition: { ...session.nativeComposition } }),\n name: session.name,\n cwd: session.cwd,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt ?? session.createdAt,\n phase: session.phase ?? 'idle',\n phaseSince: session.phaseSince ?? session.createdAt,\n attach: 'attached',\n pendingMessageCount: session.pendingMessageCount ?? 0,\n everPrompted: session.everPrompted ?? false,\n awaitingInput: session.awaitingInput ?? false,\n ...(session.lastSettledAt === undefined ? {} : { lastSettledAt: session.lastSettledAt }),\n // null: the host has not reported yet.\n ...(session.backgroundWorkActive == null ? {} : { backgroundWorkActive: session.backgroundWorkActive }),\n ...(session.git === undefined ? {} : { git: { branch: session.git.branch, dirty: session.git.dirty } }),\n ...(session.profile === undefined\n ? {}\n : {\n profile: {\n name: session.profile.name,\n ...(session.profile.displayName === undefined ? {} : { displayName: session.profile.displayName }),\n ...(session.profile.iconVersion === undefined ? {} : { iconVersion: session.profile.iconVersion }),\n },\n }),\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n ...(session.interaction === undefined ? {} : { interaction: session.interaction }),\n ...(session.groups === undefined || session.groups.length === 0 ? {} : { groups: [...session.groups] }),\n ...(session.pendingSetups === undefined\n ? {}\n : {\n pendingSetups: session.pendingSetups.map((setup) => ({\n id: setup.id,\n name: setup.name,\n createdAt: setup.createdAt,\n ...(setup.cwd === undefined ? {} : { cwd: setup.cwd }),\n ...(setup.setupKind === undefined ? {} : { setupKind: setup.setupKind }),\n ...(setup.status === undefined ? {} : { status: setup.status }),\n ...(setup.errorCode === undefined ? {} : { errorCode: setup.errorCode }),\n })),\n }),\n ...(session.activity === undefined\n ? {}\n : {\n activity: {\n label: session.activity.label,\n ...(session.activity.attention === true ? { attention: true } : {}),\n ...(session.activity.since === undefined ? {} : { since: session.activity.since }),\n },\n }),\n ...(session.pendingApprovalCount === undefined ? {} : { pendingApprovalCount: session.pendingApprovalCount }),\n };\n}\n\n/**\n * A recorded session with no runtime behind it yet.\n *\n * Carries the same field set as a live session so the rail keys both by id and\n * swaps one for the other in place once the server reopens the journal.\n */\nfunction dormantView(record: OpenSessionRecord, pendingApprovalCount?: number): HubSessionView {\n return {\n id: record.sessionId,\n workspaceId: record.workspaceId,\n name: record.name,\n cwd: record.cwd,\n createdAt: record.createdAt,\n updatedAt: record.createdAt,\n phase: 'idle',\n phaseSince: record.createdAt,\n attach: 'attached',\n pendingMessageCount: 0,\n everPrompted: false,\n awaitingInput: false,\n dormant: true,\n ...(pendingApprovalCount === undefined ? {} : { pendingApprovalCount }),\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n ...(record.interaction === undefined ? {} : { interaction: record.interaction }),\n ...(record.groups === undefined || record.groups.length === 0 ? {} : { groups: [...record.groups] }),\n };\n}\n\n/** Each restarted session host gets a new generation, so its projection starts fresh. */\nconst generations = new WeakMap<object, number>();\nlet nextGeneration = 0;\nfunction generationOf(host: object): number {\n let generation = generations.get(host);\n if (generation === undefined) {\n generation = nextGeneration++;\n generations.set(host, generation);\n }\n return generation;\n}\n\nfunction permitsSession(\n hub: HeadlessHub,\n mount: PoSocketMount,\n sessionId: string,\n authorize: (id: string) => boolean = () => true,\n): boolean {\n const session = hub.session(sessionId);\n return (\n session !== undefined &&\n authorize(sessionId) &&\n (mount.scope === 'global' ||\n (session.workspaceId === mount.workspaceId && (mount.scope === 'workspace' || mount.sessionId === sessionId)))\n );\n}\n\nfunction permitsDormant(mount: PoSocketMount, record: OpenSessionRecord): boolean {\n if (mount.scope === 'global') return true;\n if (record.workspaceId !== mount.workspaceId) return false;\n return mount.scope === 'workspace' || mount.sessionId === record.sessionId;\n}\n\n/** What one upgraded connection may reach, decided from its request when it connected. */\nexport interface ConnectionAccess {\n readonly mount: PoSocketMount;\n /** Evaluated for every call, including references taken before a Desktop claim. */\n authorizeSession(sessionId: string): boolean;\n authorizeDesktop(): boolean;\n authorizeComputerUse(sessionId: string): boolean;\n}\n\ninterface Connection extends ConnectionAccess {\n /** Sessions this connection reached, rechecked when computer-use ownership changes. */\n readonly sessions: Set<string>;\n}\n\ninterface Principal {\n connectionId: string;\n}\n\nexport interface HeadlessProtocol {\n /** Hands an authenticated link to the shared host. Without `access` it sees everything Desktop does not own. */\n accept(link: Link, access?: Partial<ConnectionAccess>): void;\n close(): Promise<void>;\n}\n\nconst eventsOf = (hub: HeadlessHub): Subscribable<HeadlessHubEvent> => ({\n subscribe: (listener) => hub.onEvent(listener),\n});\n\n/** One Chord host for every browser, native and relayed connection over the process-local hub. */\nexport function createHeadlessProtocol(options: {\n hub: HeadlessHub;\n telemetry?: ServerTelemetry;\n onNotice?: (message: string) => void;\n /** Recorded sessions the server has not reopened. */\n dormantSessions?: () => readonly OpenSessionRecord[];\n}): HeadlessProtocol {\n const hub = options.hub;\n const dormantSessions = () => (options.dormantSessions === undefined ? [] : options.dormantSessions());\n const connections = new Map<string, Connection>();\n const threads = createThreadJournals({\n resolve: (sessionId, threadId) => hub.childThread(sessionId, threadId),\n });\n const host = createHost<Principal>({\n name: PO_SERVER_HOST,\n self: { connectionId: PO_SERVER_HOST },\n principalKey: (principal) => principal.connectionId,\n onError: (error) => options.onNotice?.(`headless protocol error (${harnessErrorMessage(error)})`),\n });\n const connectionOf = (principal: Principal): Connection & { connectionId: string } => {\n const connection = connections.get(principal.connectionId);\n if (connection === undefined) throw forbidden('This connection has closed.');\n return { ...connection, connectionId: principal.connectionId };\n };\n const reachable = (connection: Connection, sessionId: string): boolean =>\n permitsSession(hub, connection.mount, sessionId, (id) => connection.authorizeSession(id));\n\n // A Desktop claim makes every reference the connection holds to that session gone at once.\n const stopClaims = hub.computerUse?.subscribe?.(() => {\n for (const [connectionId, connection] of connections) {\n let revoked = false;\n for (const sessionId of connection.sessions) if (!connection.authorizeSession(sessionId)) revoked = true;\n if (!revoked) continue;\n connection.sessions.clear();\n void host.invalidatePrincipal((principal) => principal.connectionId === connectionId);\n }\n });\n\n host.serve(PoHubContract, (_input, principal, self) => {\n const connection = connectionOf(principal);\n const { mount } = connection;\n const visibleSessions = (): Record<string, HubSessionView> => {\n const views: Record<string, HubSessionView> = {};\n for (const session of hub.snapshot())\n if (reachable(connection, session.id)) views[session.id] = sessionView(session);\n // A dormant record of a removed workspace has no HTTP list to come from, so clients would never agree on it.\n const registered = new Set(hub.workspaces().map((workspace) => workspace.id));\n for (const record of dormantSessions())\n if (\n views[record.sessionId] === undefined &&\n registered.has(record.workspaceId) &&\n connection.authorizeSession(record.sessionId) &&\n permitsDormant(mount, record)\n )\n views[record.sessionId] = dormantView(record, hub.sessionPendingApprovalCount?.(record.sessionId));\n return views;\n };\n const visibleWorkspaces = (): Record<string, HubWorkspaceView> => {\n const views: Record<string, HubWorkspaceView> = {};\n for (const workspace of hub.workspaces())\n if (mount.scope === 'global' || workspace.id === mount.workspaceId)\n views[workspace.id] = {\n id: workspace.id,\n root: workspace.root,\n ...(workspace.kind === undefined ? {} : { kind: workspace.kind }),\n ...(workspace.name === undefined ? {} : { name: workspace.name }),\n ...(workspace.sandbox === undefined ? {} : { sandbox: workspace.sandbox }),\n ...(workspace.sandboxState === undefined ? {} : { sandboxState: workspace.sandboxState }),\n ...(workspace.sandboxReason === undefined ? {} : { sandboxReason: workspace.sandboxReason }),\n available: workspace.available !== false,\n };\n return views;\n };\n const sessions = self.state('sessions', chordSchema(Type.Record(Type.String(), SessionSummarySchema)), {\n init: visibleSessions,\n });\n const workspaces = self.state('workspaces', chordSchema(Type.Record(Type.String(), HubWorkspaceSchema)), {\n init: visibleWorkspaces,\n });\n const pending = self.state('pending', chordSchema(Type.Array(HubNoticeSchema)), [] as HubNotice[]);\n const visibleCompositions = (): Record<string, number> => {\n const revisions = hub.compositionRevisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}`;\n return Object.fromEntries(Object.entries(revisions).filter(([key]) => key === 'global' || key === own));\n };\n const compositions = self.state('compositions', chordSchema(HubCompositionsSchema), { init: visibleCompositions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n switch (event.kind) {\n case 'upsert':\n case 'removed':\n case 'dormant_changed':\n // Recomputed rather than patched, so an event before this listener started cannot leave a stale row.\n sessions.replace(ctx, visibleSessions(), { diff: true });\n return;\n case 'workspace_upsert':\n case 'workspace_removed':\n workspaces.replace(ctx, visibleWorkspaces(), { diff: true });\n return;\n case 'compositions':\n compositions.replace(ctx, visibleCompositions(), { diff: true });\n return;\n case 'frame':\n if (!reachable(connection, event.sessionId)) return;\n pending.change(ctx, (draft) => {\n draft.push({\n id: randomUUID(),\n sessionId: event.sessionId,\n frame: event.frame as Record<string, JsonValue>,\n });\n if (draft.length > MAX_PENDING_NOTICES) draft.splice(0, draft.length - MAX_PENDING_NOTICES);\n });\n return;\n case 'channel':\n return;\n }\n });\n return {\n variant: 'default',\n sessions,\n workspaces,\n pending,\n compositions,\n readHome: async (request) => {\n if (!hub.readHome) throw new Error('Home read is unavailable.');\n return hub.readHome(request, (id) => reachable(connection, id));\n },\n invoke: async (call: PoPluginCall, ctx) => {\n if (call.mount.scope === 'session' && !connection.authorizeSession(call.mount.sessionId))\n throw forbidden('This session belongs to its Desktop instance.');\n if (mount.scope !== 'global') {\n const permitted =\n call.mount.scope === 'session'\n ? permitsSession(hub, mount, call.mount.sessionId)\n : mount.scope === 'workspace' &&\n call.mount.scope === 'workspace' &&\n call.mount.workspaceId === mount.workspaceId;\n if (!permitted) throw forbidden('Plugin is outside this WebSocket scope.');\n }\n return (await hub.invokePlugin(call, 'client-to-server', {\n connectionId: connection.connectionId,\n signal: ctx.signal,\n })) as JsonValue;\n },\n ackNotice: async ({ id }, ctx) => {\n pending.change(ctx, (draft) => draft.filter((notice) => notice.id !== id));\n },\n };\n });\n\n host.serve(PoHubRevisionsContract, (_input, principal, self) => {\n const { mount } = connectionOf(principal);\n const visibleRevisions = (): Record<string, number> => {\n const revisions = hub.revisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}:`;\n return Object.fromEntries(\n Object.entries(revisions).filter(([topic]) => topic.startsWith('global:') || topic.startsWith(own)),\n );\n };\n const revisions = self.state('revisions', chordSchema(HubRevisionsSchema), { init: visibleRevisions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind === 'revisions') revisions.replace(ctx, visibleRevisions(), { diff: true });\n });\n return { variant: 'default', revisions };\n });\n\n host.serve(\n PoThreadContract,\n ({ sessionId, threadId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const tail = self.resource('tail', {\n version: 1,\n open: () => threads.subscribe(sessionId, threadId),\n close: () => threads.unsubscribe(sessionId, threadId),\n });\n const frame = self.state('frame', chordSchema(PoThreadFrameSchema), {\n init: () => (tail.value?.at(-1) ?? null) as never,\n });\n self.on(\n 'frames',\n { subscribe: (listener) => threads.onFrame(listener) } as Subscribable<{\n sessionId: string;\n threadId: string;\n frame: Record<string, unknown>;\n }>,\n (event, ctx) => {\n // Each frame is a fresh wrapper around the child's state, so only an explicit diff sends ops, not the whole state.\n if (event.sessionId === sessionId && event.threadId === threadId)\n frame.replace(ctx, event.frame as never, { diff: true });\n },\n );\n return { variant: 'default', frame };\n },\n { linger: THREAD_LINGER_MS },\n );\n\n host.serve(PoChannelsContract, ({ sessionId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const visible = (frameType: string): boolean =>\n frameType !== 'computer_use_state' || connection.authorizeComputerUse(sessionId);\n const latest = self.state('latest', chordSchema(PoChannelsStateSchema), {\n init: () => {\n const payloads: Record<string, JsonValue> = {};\n for (const channelFrame of hub.channelFrames(sessionId))\n if (visible(channelFrame.type)) payloads[channelFrame.type] = channelFrame.payload as JsonValue;\n return payloads;\n },\n });\n // ponytail: a channel keeps only its latest payload; a package that needs every event must carry a sequence.\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind !== 'channel' || event.sessionId !== sessionId || !visible(event.frameType)) return;\n if (event.connectionId !== undefined && event.connectionId !== connection.connectionId) return;\n latest.change(ctx, (draft) => {\n draft[event.frameType] = event.payload as JsonValue;\n });\n });\n return {\n variant: 'default',\n latest,\n receive: async ({ type, payload }) => {\n if (!connection.authorizeSession(sessionId)) throw forbidden('This session belongs to Desktop.');\n hub.receiveChannel(\n sessionId,\n type,\n payload,\n connection.connectionId,\n connection.authorizeDesktop(),\n connection.authorizeComputerUse(sessionId),\n );\n },\n };\n });\n\n serveAgentSessions(host, {\n resolve(sessionId, principal): AgentSessionBinding | undefined {\n const connection = connectionOf(principal as Principal);\n const session = hub.session(sessionId);\n if (!session || !reachable(connection, session.id)) return undefined;\n connection.sessions.add(sessionId);\n const permitted = () => hub.session(session.id)?.host === session.host && connection.authorizeSession(session.id);\n // A mirror of a session another host runs forwards there; keyed by its host object, never by session id.\n const forward = session.host.agentSession;\n if (forward !== undefined)\n return { generation: generationOf(session.host), exited: session.host.runtime.exited, permitted, forward };\n return {\n generation: generationOf(session.host),\n exited: session.host.runtime.exited,\n permitted,\n options: {\n runtime: session.host.runtime,\n onPresentationFrame: (listen) =>\n session.host.onPresentationFrame((frame) => {\n if (permitted()) listen(frame);\n }),\n respondToExtensionUi: (frame) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return session.host.respondToExtensionUi(frame);\n },\n readThreadTranscript: (threadId, request, readContext) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return threads.readPage(session.id, threadId, request, readContext);\n },\n sessionId: session.id,\n sessionName: session.name,\n cwd: session.cwd,\n telemetry: options.telemetry,\n },\n };\n },\n });\n\n let closing: Promise<void> | undefined;\n return {\n accept(link, access = {}) {\n if (closing !== undefined) {\n link.close();\n return;\n }\n const connectionId = randomUUID();\n const authorizeSession = access.authorizeSession ?? ((id: string) => !hub.computerUse?.ownsSession?.(id));\n const authorizeDesktop = access.authorizeDesktop ?? (() => false);\n connections.set(connectionId, {\n mount: access.mount ?? { scope: 'global' },\n authorizeSession,\n authorizeDesktop,\n authorizeComputerUse: access.authorizeComputerUse ?? (() => authorizeDesktop()),\n sessions: new Set(),\n });\n link.onClose(() => {\n connections.delete(connectionId);\n hub.disconnectChannels(connectionId);\n });\n host.accept(reportingLargeFrames(link, options.onNotice, options.telemetry), {\n principal: { connectionId },\n kind: 'client',\n });\n },\n close() {\n closing ??= (async () => {\n stopClaims?.();\n threads.close();\n await host.close();\n })();\n return closing;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmCA,MAAM,sBAAsB;;AAE5B,MAAM,mBAAmB;AAEzB,SAAS,YAAY,SAA6C;CAChE,OAAO;EACL,IAAI,QAAQ;EACZ,GAAI,QAAQ,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;EAChF,GAAI,QAAQ,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,QAAQ,eAAe,EAAE;EAChG,GAAI,QAAQ,sBAAsB,KAAA,IAAY,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,QAAQ,kBAAkB,EAAE;EACzG,MAAM,QAAQ;EACd,KAAK,QAAQ;EACb,WAAW,QAAQ;EACnB,WAAW,QAAQ,aAAa,QAAQ;EACxC,OAAO,QAAQ,SAAS;EACxB,YAAY,QAAQ,cAAc,QAAQ;EAC1C,QAAQ;EACR,qBAAqB,QAAQ,uBAAuB;EACpD,cAAc,QAAQ,gBAAgB;EACtC,eAAe,QAAQ,iBAAiB;EACxC,GAAI,QAAQ,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,cAAc;EAEtF,GAAI,QAAQ,wBAAwB,OAAO,CAAC,IAAI,EAAE,sBAAsB,QAAQ,qBAAqB;EACrG,GAAI,QAAQ,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;GAAE,QAAQ,QAAQ,IAAI;GAAQ,OAAO,QAAQ,IAAI;EAAM,EAAE;EACrG,GAAI,QAAQ,YAAY,KAAA,IACpB,CAAC,IACD,EACE,SAAS;GACP,MAAM,QAAQ,QAAQ;GACtB,GAAI,QAAQ,QAAQ,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,QAAQ,YAAY;GAChG,GAAI,QAAQ,QAAQ,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,QAAQ,YAAY;EAClG,EACF;EACJ,GAAI,QAAQ,oBAAoB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB,QAAQ,gBAAgB;EAC5F,GAAI,QAAQ,sBAAsB,KAAA,IAAY,CAAC,IAAI,EAAE,mBAAmB,QAAQ,kBAAkB;EAClG,GAAI,QAAQ,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;EAChF,GAAI,QAAQ,WAAW,KAAA,KAAa,QAAQ,OAAO,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,QAAQ,MAAM,EAAE;EACrG,GAAI,QAAQ,kBAAkB,KAAA,IAC1B,CAAC,IACD,EACE,eAAe,QAAQ,cAAc,KAAK,WAAW;GACnD,IAAI,MAAM;GACV,MAAM,MAAM;GACZ,WAAW,MAAM;GACjB,GAAI,MAAM,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK,MAAM,IAAI;GACpD,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM,UAAU;GACtE,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;GAC7D,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM,UAAU;EACxE,EAAE,EACJ;EACJ,GAAI,QAAQ,aAAa,KAAA,IACrB,CAAC,IACD,EACE,UAAU;GACR,OAAO,QAAQ,SAAS;GACxB,GAAI,QAAQ,SAAS,cAAc,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;GACjE,GAAI,QAAQ,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,SAAS,MAAM;EAClF,EACF;EACJ,GAAI,QAAQ,yBAAyB,KAAA,IAAY,CAAC,IAAI,EAAE,sBAAsB,QAAQ,qBAAqB;CAC7G;AACF;;;;;;;AAQA,SAAS,YAAY,QAA2B,sBAA+C;CAC7F,OAAO;EACL,IAAI,OAAO;EACX,aAAa,OAAO;EACpB,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,OAAO;EACP,YAAY,OAAO;EACnB,QAAQ;EACR,qBAAqB;EACrB,cAAc;EACd,eAAe;EACf,SAAS;EACT,GAAI,yBAAyB,KAAA,IAAY,CAAC,IAAI,EAAE,qBAAqB;EACrE,GAAI,OAAO,oBAAoB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB,OAAO,gBAAgB;EAC1F,GAAI,OAAO,sBAAsB,KAAA,IAAY,CAAC,IAAI,EAAE,mBAAmB,OAAO,kBAAkB;EAChG,GAAI,OAAO,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,OAAO,YAAY;EAC9E,GAAI,OAAO,WAAW,KAAA,KAAa,OAAO,OAAO,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,OAAO,MAAM,EAAE;CACpG;AACF;;AAGA,MAAM,8BAAc,IAAI,QAAwB;AAChD,IAAI,iBAAiB;AACrB,SAAS,aAAa,MAAsB;CAC1C,IAAI,aAAa,YAAY,IAAI,IAAI;CACrC,IAAI,eAAe,KAAA,GAAW;EAC5B,aAAa;EACb,YAAY,IAAI,MAAM,UAAU;CAClC;CACA,OAAO;AACT;AAEA,SAAS,eACP,KACA,OACA,WACA,kBAA2C,MAClC;CACT,MAAM,UAAU,IAAI,QAAQ,SAAS;CACrC,OACE,YAAY,KAAA,KACZ,UAAU,SAAS,MAClB,MAAM,UAAU,YACd,QAAQ,gBAAgB,MAAM,gBAAgB,MAAM,UAAU,eAAe,MAAM,cAAc;AAExG;AAEA,SAAS,eAAe,OAAsB,QAAoC;CAChF,IAAI,MAAM,UAAU,UAAU,OAAO;CACrC,IAAI,OAAO,gBAAgB,MAAM,aAAa,OAAO;CACrD,OAAO,MAAM,UAAU,eAAe,MAAM,cAAc,OAAO;AACnE;AA0BA,MAAM,YAAY,SAAsD,EACtE,YAAY,aAAa,IAAI,QAAQ,QAAQ,EAC/C;;AAGA,SAAgB,uBAAuB,SAMlB;CACnB,MAAM,MAAM,QAAQ;CACpB,MAAM,wBAAyB,QAAQ,oBAAoB,KAAA,IAAY,CAAC,IAAI,QAAQ,gBAAgB;CACpG,MAAM,8BAAc,IAAI,IAAwB;CAChD,MAAM,UAAUA,uBAAAA,qBAAqB,EACnC,UAAU,WAAW,aAAa,IAAI,YAAY,WAAW,QAAQ,EACvE,CAAC;CACD,MAAM,QAAA,GAAOC,uBAAAA,WAAAA,CAAsB;EACjC,MAAMC,0BAAAA;EACN,MAAM,EAAE,cAAcA,0BAAAA,eAAe;EACrC,eAAe,cAAc,UAAU;EACvC,UAAU,UAAU,QAAQ,WAAW,4BAA4BC,4BAAAA,oBAAoB,KAAK,EAAE,EAAE;CAClG,CAAC;CACD,MAAM,gBAAgB,cAAgE;EACpF,MAAM,aAAa,YAAY,IAAI,UAAU,YAAY;EACzD,IAAI,eAAe,KAAA,GAAW,OAAA,GAAMC,uBAAAA,UAAAA,CAAU,6BAA6B;EAC3E,OAAO;GAAE,GAAG;GAAY,cAAc,UAAU;EAAa;CAC/D;CACA,MAAM,aAAa,YAAwB,cACzC,eAAe,KAAK,WAAW,OAAO,YAAY,OAAO,WAAW,iBAAiB,EAAE,CAAC;CAG1F,MAAM,aAAa,IAAI,aAAa,kBAAkB;EACpD,KAAK,MAAM,CAAC,cAAc,eAAe,aAAa;GACpD,IAAI,UAAU;GACd,KAAK,MAAM,aAAa,WAAW,UAAU,IAAI,CAAC,WAAW,iBAAiB,SAAS,GAAG,UAAU;GACpG,IAAI,CAAC,SAAS;GACd,WAAW,SAAS,MAAM;GAC1B,KAAU,qBAAqB,cAAc,UAAU,iBAAiB,YAAY;EACtF;CACF,CAAC;CAED,KAAK,MAAMC,4BAAAA,gBAAgB,QAAQ,WAAW,SAAS;EACrD,MAAM,aAAa,aAAa,SAAS;EACzC,MAAM,EAAE,UAAU;EAClB,MAAM,wBAAwD;GAC5D,MAAM,QAAwC,CAAC;GAC/C,KAAK,MAAM,WAAW,IAAI,SAAS,GACjC,IAAI,UAAU,YAAY,QAAQ,EAAE,GAAG,MAAM,QAAQ,MAAM,YAAY,OAAO;GAEhF,MAAM,aAAa,IAAI,IAAI,IAAI,WAAW,CAAC,CAAC,KAAK,cAAc,UAAU,EAAE,CAAC;GAC5E,KAAK,MAAM,UAAU,gBAAgB,GACnC,IACE,MAAM,OAAO,eAAe,KAAA,KAC5B,WAAW,IAAI,OAAO,WAAW,KACjC,WAAW,iBAAiB,OAAO,SAAS,KAC5C,eAAe,OAAO,MAAM,GAE5B,MAAM,OAAO,aAAa,YAAY,QAAQ,IAAI,8BAA8B,OAAO,SAAS,CAAC;GACrG,OAAO;EACT;EACA,MAAM,0BAA4D;GAChE,MAAM,QAA0C,CAAC;GACjD,KAAK,MAAM,aAAa,IAAI,WAAW,GACrC,IAAI,MAAM,UAAU,YAAY,UAAU,OAAO,MAAM,aACrD,MAAM,UAAU,MAAM;IACpB,IAAI,UAAU;IACd,MAAM,UAAU;IAChB,GAAI,UAAU,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,UAAU,KAAK;IAC/D,GAAI,UAAU,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,UAAU,KAAK;IAC/D,GAAI,UAAU,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,UAAU,QAAQ;IACxE,GAAI,UAAU,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,UAAU,aAAa;IACvF,GAAI,UAAU,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,UAAU,cAAc;IAC1F,WAAW,UAAU,cAAc;GACrC;GACJ,OAAO;EACT;EACA,MAAM,WAAW,KAAK,MAAM,YAAYC,0BAAAA,YAAYC,QAAAA,KAAK,OAAOA,QAAAA,KAAK,OAAO,GAAGC,yBAAAA,oBAAoB,CAAC,GAAG,EACrG,MAAM,gBACR,CAAC;EACD,MAAM,aAAa,KAAK,MAAM,cAAcF,0BAAAA,YAAYC,QAAAA,KAAK,OAAOA,QAAAA,KAAK,OAAO,GAAGE,4BAAAA,kBAAkB,CAAC,GAAG,EACvG,MAAM,kBACR,CAAC;EACD,MAAM,UAAU,KAAK,MAAM,WAAWH,0BAAAA,YAAYC,QAAAA,KAAK,MAAMG,4BAAAA,eAAe,CAAC,GAAG,CAAC,CAAgB;EACjG,MAAM,4BAAoD;GACxD,MAAM,YAAY,IAAI,uBAAuB,KAAK,CAAC;GACnD,IAAI,MAAM,UAAU,UAAU,OAAO,EAAE,GAAG,UAAU;GACpD,MAAM,MAAM,aAAa,MAAM;GAC/B,OAAO,OAAO,YAAY,OAAO,QAAQ,SAAS,CAAC,CAAC,QAAQ,CAAC,SAAS,QAAQ,YAAY,QAAQ,GAAG,CAAC;EACxG;EACA,MAAM,eAAe,KAAK,MAAM,gBAAgBJ,0BAAAA,YAAYK,4BAAAA,qBAAqB,GAAG,EAAE,MAAM,oBAAoB,CAAC;EACjH,KAAK,GAAG,OAAO,SAAS,GAAG,IAAI,OAAO,QAAQ;GAC5C,QAAQ,MAAM,MAAd;IACE,KAAK;IACL,KAAK;IACL,KAAK;KAEH,SAAS,QAAQ,KAAK,gBAAgB,GAAG,EAAE,MAAM,KAAK,CAAC;KACvD;IACF,KAAK;IACL,KAAK;KACH,WAAW,QAAQ,KAAK,kBAAkB,GAAG,EAAE,MAAM,KAAK,CAAC;KAC3D;IACF,KAAK;KACH,aAAa,QAAQ,KAAK,oBAAoB,GAAG,EAAE,MAAM,KAAK,CAAC;KAC/D;IACF,KAAK;KACH,IAAI,CAAC,UAAU,YAAY,MAAM,SAAS,GAAG;KAC7C,QAAQ,OAAO,MAAM,UAAU;MAC7B,MAAM,KAAK;OACT,KAAA,GAAIC,YAAAA,WAAAA,CAAW;OACf,WAAW,MAAM;OACjB,OAAO,MAAM;MACf,CAAC;MACD,IAAI,MAAM,SAAS,qBAAqB,MAAM,OAAO,GAAG,MAAM,SAAS,mBAAmB;KAC5F,CAAC;KACD;IACF,KAAK,WACH;GACJ;EACF,CAAC;EACD,OAAO;GACL,SAAS;GACT;GACA;GACA;GACA;GACA,UAAU,OAAO,YAAY;IAC3B,IAAI,CAAC,IAAI,UAAU,MAAM,IAAI,MAAM,2BAA2B;IAC9D,OAAO,IAAI,SAAS,UAAU,OAAO,UAAU,YAAY,EAAE,CAAC;GAChE;GACA,QAAQ,OAAO,MAAoB,QAAQ;IACzC,IAAI,KAAK,MAAM,UAAU,aAAa,CAAC,WAAW,iBAAiB,KAAK,MAAM,SAAS,GACrF,OAAA,GAAMR,uBAAAA,UAAAA,CAAU,+CAA+C;IACjE,IAAI,MAAM,UAAU,UAOd;SAAA,EALF,KAAK,MAAM,UAAU,YACjB,eAAe,KAAK,OAAO,KAAK,MAAM,SAAS,IAC/C,MAAM,UAAU,eAChB,KAAK,MAAM,UAAU,eACrB,KAAK,MAAM,gBAAgB,MAAM,cACvB,OAAA,GAAMA,uBAAAA,UAAAA,CAAU,yCAAyC;IAAA;IAE3E,OAAQ,MAAM,IAAI,aAAa,MAAM,oBAAoB;KACvD,cAAc,WAAW;KACzB,QAAQ,IAAI;IACd,CAAC;GACH;GACA,WAAW,OAAO,EAAE,MAAM,QAAQ;IAChC,QAAQ,OAAO,MAAM,UAAU,MAAM,QAAQ,WAAW,OAAO,OAAO,EAAE,CAAC;GAC3E;EACF;CACF,CAAC;CAED,KAAK,MAAMS,4BAAAA,yBAAyB,QAAQ,WAAW,SAAS;EAC9D,MAAM,EAAE,UAAU,aAAa,SAAS;EACxC,MAAM,yBAAiD;GACrD,MAAM,YAAY,IAAI,YAAY,KAAK,CAAC;GACxC,IAAI,MAAM,UAAU,UAAU,OAAO,EAAE,GAAG,UAAU;GACpD,MAAM,MAAM,aAAa,MAAM,YAAY;GAC3C,OAAO,OAAO,YACZ,OAAO,QAAQ,SAAS,CAAC,CAAC,QAAQ,CAAC,WAAW,MAAM,WAAW,SAAS,KAAK,MAAM,WAAW,GAAG,CAAC,CACpG;EACF;EACA,MAAM,YAAY,KAAK,MAAM,aAAaP,0BAAAA,YAAYQ,4BAAAA,kBAAkB,GAAG,EAAE,MAAM,iBAAiB,CAAC;EACrG,KAAK,GAAG,OAAO,SAAS,GAAG,IAAI,OAAO,QAAQ;GAC5C,IAAI,MAAM,SAAS,aAAa,UAAU,QAAQ,KAAK,iBAAiB,GAAG,EAAE,MAAM,KAAK,CAAC;EAC3F,CAAC;EACD,OAAO;GAAE,SAAS;GAAW;EAAU;CACzC,CAAC;CAED,KAAK,MACHC,+BAAAA,mBACC,EAAE,WAAW,YAAY,WAAW,SAAS;EAC5C,MAAM,aAAa,aAAa,SAAS;EACzC,IAAI,CAAC,UAAU,YAAY,SAAS,GAAG,OAAA,GAAMX,uBAAAA,UAAAA,CAAU,cAAc,WAAW;EAChF,WAAW,SAAS,IAAI,SAAS;EACjC,MAAM,OAAO,KAAK,SAAS,QAAQ;GACjC,SAAS;GACT,YAAY,QAAQ,UAAU,WAAW,QAAQ;GACjD,aAAa,QAAQ,YAAY,WAAW,QAAQ;EACtD,CAAC;EACD,MAAM,QAAQ,KAAK,MAAM,SAASE,0BAAAA,YAAYU,+BAAAA,mBAAmB,GAAG,EAClE,YAAa,KAAK,OAAO,GAAG,EAAE,KAAK,KACrC,CAAC;EACD,KAAK,GACH,UACA,EAAE,YAAY,aAAa,QAAQ,QAAQ,QAAQ,EAAE,IAKpD,OAAO,QAAQ;GAEd,IAAI,MAAM,cAAc,aAAa,MAAM,aAAa,UACtD,MAAM,QAAQ,KAAK,MAAM,OAAgB,EAAE,MAAM,KAAK,CAAC;EAC3D,CACF;EACA,OAAO;GAAE,SAAS;GAAW;EAAM;CACrC,GACA,EAAE,QAAQ,iBAAiB,CAC7B;CAEA,KAAK,MAAMC,iCAAAA,qBAAqB,EAAE,aAAa,WAAW,SAAS;EACjE,MAAM,aAAa,aAAa,SAAS;EACzC,IAAI,CAAC,UAAU,YAAY,SAAS,GAAG,OAAA,GAAMb,uBAAAA,UAAAA,CAAU,cAAc,WAAW;EAChF,WAAW,SAAS,IAAI,SAAS;EACjC,MAAM,WAAW,cACf,cAAc,wBAAwB,WAAW,qBAAqB,SAAS;EACjF,MAAM,SAAS,KAAK,MAAM,UAAUE,0BAAAA,YAAYY,iCAAAA,qBAAqB,GAAG,EACtE,YAAY;GACV,MAAM,WAAsC,CAAC;GAC7C,KAAK,MAAM,gBAAgB,IAAI,cAAc,SAAS,GACpD,IAAI,QAAQ,aAAa,IAAI,GAAG,SAAS,aAAa,QAAQ,aAAa;GAC7E,OAAO;EACT,EACF,CAAC;EAED,KAAK,GAAG,OAAO,SAAS,GAAG,IAAI,OAAO,QAAQ;GAC5C,IAAI,MAAM,SAAS,aAAa,MAAM,cAAc,aAAa,CAAC,QAAQ,MAAM,SAAS,GAAG;GAC5F,IAAI,MAAM,iBAAiB,KAAA,KAAa,MAAM,iBAAiB,WAAW,cAAc;GACxF,OAAO,OAAO,MAAM,UAAU;IAC5B,MAAM,MAAM,aAAa,MAAM;GACjC,CAAC;EACH,CAAC;EACD,OAAO;GACL,SAAS;GACT;GACA,SAAS,OAAO,EAAE,MAAM,cAAc;IACpC,IAAI,CAAC,WAAW,iBAAiB,SAAS,GAAG,OAAA,GAAMd,uBAAAA,UAAAA,CAAU,kCAAkC;IAC/F,IAAI,eACF,WACA,MACA,SACA,WAAW,cACX,WAAW,iBAAiB,GAC5B,WAAW,qBAAqB,SAAS,CAC3C;GACF;EACF;CACF,CAAC;CAED,yBAAA,mBAAmB,MAAM,EACvB,QAAQ,WAAW,WAA4C;EAC7D,MAAM,aAAa,aAAa,SAAsB;EACtD,MAAM,UAAU,IAAI,QAAQ,SAAS;EACrC,IAAI,CAAC,WAAW,CAAC,UAAU,YAAY,QAAQ,EAAE,GAAG,OAAO,KAAA;EAC3D,WAAW,SAAS,IAAI,SAAS;EACjC,MAAM,kBAAkB,IAAI,QAAQ,QAAQ,EAAE,CAAC,EAAE,SAAS,QAAQ,QAAQ,WAAW,iBAAiB,QAAQ,EAAE;EAEhH,MAAM,UAAU,QAAQ,KAAK;EAC7B,IAAI,YAAY,KAAA,GACd,OAAO;GAAE,YAAY,aAAa,QAAQ,IAAI;GAAG,QAAQ,QAAQ,KAAK,QAAQ;GAAQ;GAAW;EAAQ;EAC3G,OAAO;GACL,YAAY,aAAa,QAAQ,IAAI;GACrC,QAAQ,QAAQ,KAAK,QAAQ;GAC7B;GACA,SAAS;IACP,SAAS,QAAQ,KAAK;IACtB,sBAAsB,WACpB,QAAQ,KAAK,qBAAqB,UAAU;KAC1C,IAAI,UAAU,GAAG,OAAO,KAAK;IAC/B,CAAC;IACH,uBAAuB,UAAU;KAC/B,IAAI,CAAC,UAAU,GAAG,OAAA,GAAMA,uBAAAA,UAAAA,CAAU,kCAAkC;KACpE,OAAO,QAAQ,KAAK,qBAAqB,KAAK;IAChD;IACA,uBAAuB,UAAU,SAAS,gBAAgB;KACxD,IAAI,CAAC,UAAU,GAAG,OAAA,GAAMA,uBAAAA,UAAAA,CAAU,kCAAkC;KACpE,OAAO,QAAQ,SAAS,QAAQ,IAAI,UAAU,SAAS,WAAW;IACpE;IACA,WAAW,QAAQ;IACnB,aAAa,QAAQ;IACrB,KAAK,QAAQ;IACb,WAAW,QAAQ;GACrB;EACF;CACF,EACF,CAAC;CAED,IAAI;CACJ,OAAO;EACL,OAAO,MAAM,SAAS,CAAC,GAAG;GACxB,IAAI,YAAY,KAAA,GAAW;IACzB,KAAK,MAAM;IACX;GACF;GACA,MAAM,gBAAA,GAAeQ,YAAAA,WAAAA,CAAW;GAChC,MAAM,mBAAmB,OAAO,sBAAsB,OAAe,CAAC,IAAI,aAAa,cAAc,EAAE;GACvG,MAAM,mBAAmB,OAAO,2BAA2B;GAC3D,YAAY,IAAI,cAAc;IAC5B,OAAO,OAAO,SAAS,EAAE,OAAO,SAAS;IACzC;IACA;IACA,sBAAsB,OAAO,+BAA+B,iBAAiB;IAC7E,0BAAU,IAAI,IAAI;GACpB,CAAC;GACD,KAAK,cAAc;IACjB,YAAY,OAAO,YAAY;IAC/B,IAAI,mBAAmB,YAAY;GACrC,CAAC;GACD,KAAK,OAAOO,uBAAAA,qBAAqB,MAAM,QAAQ,UAAU,QAAQ,SAAS,GAAG;IAC3E,WAAW,EAAE,aAAa;IAC1B,MAAM;GACR,CAAC;EACH;EACA,QAAQ;GACN,aAAa,YAAY;IACvB,aAAa;IACb,QAAQ,MAAM;IACd,MAAM,KAAK,MAAM;GACnB,EAAA,CAAG;GACH,OAAO;EACT;CACF;AACF"}
1
+ {"version":3,"file":"headlessProtocol.cjs","names":["createThreadJournals","createHost","PO_SERVER_HOST","harnessErrorMessage","forbidden","PoHubContract","chordSchema","Type","SessionSummarySchema","HubWorkspaceSchema","HubNoticeSchema","HubCompositionsSchema","randomUUID","PoHubRevisionsContract","HubRevisionsSchema","PoThreadContract","PoThreadFrameSchema","PoChannelsContract","PoChannelsStateSchema","serveAgentSessions","reportingLargeFrames"],"sources":["../src/server/headlessProtocol.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createHost, forbidden, type Link, type Subscribable } from '@earendil-works/chord';\nimport { Type } from 'typebox';\n\nimport type { PoPluginCall } from '../exports/pluginProtocol';\nimport {\n HubCompositionsSchema,\n HubNoticeSchema,\n HubRevisionsSchema,\n PO_SERVER_HOST,\n PoChannelsContract,\n PoHubContract,\n PoHubRevisionsContract,\n PoThreadContract,\n type HubNotice,\n type HubSessionView,\n type HubWorkspaceView,\n type JsonValue,\n} from '../exports/sessionProtocol';\nimport { serveAgentSessions, type AgentSessionBinding } from '../pi/piSessionRuntime';\nimport { SessionSummarySchema } from '../schemas/httpApiContracts';\nimport type { PoSocketMount } from '../schemas/packageApi';\nimport { PoChannelsStateSchema } from '../schemas/protocolChannelsContract';\nimport { chordSchema } from '../schemas/protocolContracts';\nimport { HubWorkspaceSchema } from '../schemas/protocolHubContract';\nimport { PoThreadFrameSchema } from '../schemas/protocolThreadContract';\nimport type { OpenSessionRecord } from '../services/openSessionRegistry';\nimport type { ServerTelemetry } from '../services/serverTelemetry';\nimport { harnessErrorMessage } from './harnessErrorMessage';\nimport type { HeadlessHub, HeadlessHubEvent, HeadlessHubSession } from './headlessHub';\nimport { reportingLargeFrames } from './largeFrameLink';\nimport { createThreadJournals } from './threadJournals';\n\n// ponytail: unacknowledged notices beyond this drop oldest first; raise it if a client misses dialogs.\nconst MAX_PENDING_NOTICES = 64;\n/** A browser switching back to a thread quickly keeps its tail open. */\nconst THREAD_LINGER_MS = 5_000;\n\nfunction sessionView(session: HeadlessHubSession): HubSessionView {\n return {\n id: session.id,\n ...(session.workspaceId === undefined ? {} : { workspaceId: session.workspaceId }),\n ...(session.webComposition === undefined ? {} : { webComposition: { ...session.webComposition } }),\n ...(session.nativeComposition === undefined ? {} : { nativeComposition: { ...session.nativeComposition } }),\n name: session.name,\n cwd: session.cwd,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt ?? session.createdAt,\n phase: session.phase ?? 'idle',\n phaseSince: session.phaseSince ?? session.createdAt,\n attach: 'attached',\n pendingMessageCount: session.pendingMessageCount ?? 0,\n everPrompted: session.everPrompted ?? false,\n awaitingInput: session.awaitingInput ?? false,\n ...(session.lastSettledAt === undefined ? {} : { lastSettledAt: session.lastSettledAt }),\n // null: the host has not reported yet.\n ...(session.backgroundWorkActive == null ? {} : { backgroundWorkActive: session.backgroundWorkActive }),\n ...(session.git === undefined ? {} : { git: { branch: session.git.branch, dirty: session.git.dirty } }),\n ...(session.profile === undefined\n ? {}\n : {\n profile: {\n name: session.profile.name,\n ...(session.profile.displayName === undefined ? {} : { displayName: session.profile.displayName }),\n ...(session.profile.iconVersion === undefined ? {} : { iconVersion: session.profile.iconVersion }),\n },\n }),\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n ...(session.interaction === undefined ? {} : { interaction: session.interaction }),\n ...(session.groups === undefined || session.groups.length === 0 ? {} : { groups: [...session.groups] }),\n ...(session.pendingSetups === undefined\n ? {}\n : {\n pendingSetups: session.pendingSetups.map((setup) => ({\n id: setup.id,\n name: setup.name,\n createdAt: setup.createdAt,\n ...(setup.cwd === undefined ? {} : { cwd: setup.cwd }),\n ...(setup.setupKind === undefined ? {} : { setupKind: setup.setupKind }),\n ...(setup.status === undefined ? {} : { status: setup.status }),\n ...(setup.errorCode === undefined ? {} : { errorCode: setup.errorCode }),\n })),\n }),\n ...(session.activity === undefined\n ? {}\n : {\n activity: {\n label: session.activity.label,\n ...(session.activity.attention === true ? { attention: true } : {}),\n ...(session.activity.since === undefined ? {} : { since: session.activity.since }),\n },\n }),\n ...(session.pendingApprovalCount === undefined ? {} : { pendingApprovalCount: session.pendingApprovalCount }),\n };\n}\n\n/**\n * A recorded session with no runtime behind it yet.\n *\n * Carries the same field set as a live session so the rail keys both by id and\n * swaps one for the other in place once the server reopens the journal.\n */\nfunction dormantView(record: OpenSessionRecord, pendingApprovalCount?: number): HubSessionView {\n return {\n id: record.sessionId,\n workspaceId: record.workspaceId,\n name: record.name,\n cwd: record.cwd,\n createdAt: record.createdAt,\n updatedAt: record.createdAt,\n phase: 'idle',\n phaseSince: record.createdAt,\n attach: 'attached',\n pendingMessageCount: 0,\n everPrompted: false,\n awaitingInput: false,\n dormant: true,\n ...(pendingApprovalCount === undefined ? {} : { pendingApprovalCount }),\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n ...(record.interaction === undefined ? {} : { interaction: record.interaction }),\n ...(record.groups === undefined || record.groups.length === 0 ? {} : { groups: [...record.groups] }),\n };\n}\n\n/** Each restarted session host gets a new generation, so its projection starts fresh. */\nconst generations = new WeakMap<object, number>();\nlet nextGeneration = 0;\nfunction generationOf(host: object): number {\n let generation = generations.get(host);\n if (generation === undefined) {\n generation = nextGeneration++;\n generations.set(host, generation);\n }\n return generation;\n}\n\nfunction permitsSession(\n hub: HeadlessHub,\n mount: PoSocketMount,\n sessionId: string,\n authorize: (id: string) => boolean = () => true,\n): boolean {\n const session = hub.session(sessionId);\n return (\n session !== undefined &&\n authorize(sessionId) &&\n (mount.scope === 'global' ||\n (session.workspaceId === mount.workspaceId && (mount.scope === 'workspace' || mount.sessionId === sessionId)))\n );\n}\n\nfunction permitsDormant(mount: PoSocketMount, record: OpenSessionRecord): boolean {\n if (mount.scope === 'global') return true;\n if (record.workspaceId !== mount.workspaceId) return false;\n return mount.scope === 'workspace' || mount.sessionId === record.sessionId;\n}\n\n/** What one upgraded connection may reach, decided from its request when it connected. */\nexport interface ConnectionAccess {\n readonly mount: PoSocketMount;\n /** Evaluated for every call, including references taken before a Desktop claim. */\n authorizeSession(sessionId: string): boolean;\n authorizeDesktop(): boolean;\n authorizeComputerUse(sessionId: string): boolean;\n}\n\ninterface Connection extends ConnectionAccess {\n /** Sessions this connection reached, rechecked when computer-use ownership changes. */\n readonly sessions: Set<string>;\n}\n\ninterface Principal {\n connectionId: string;\n}\n\nexport interface HeadlessProtocol {\n /** Hands an authenticated link to the shared host. Without `access` it sees everything Desktop does not own. */\n accept(link: Link, access?: Partial<ConnectionAccess>): void;\n close(): Promise<void>;\n}\n\nconst eventsOf = (hub: HeadlessHub): Subscribable<HeadlessHubEvent> => ({\n subscribe: (listener) => hub.onEvent(listener),\n});\n\n/** One Chord host for every browser, native and relayed connection over the process-local hub. */\nexport function createHeadlessProtocol(options: {\n hub: HeadlessHub;\n telemetry?: ServerTelemetry;\n onNotice?: (message: string) => void;\n /** Recorded sessions the server has not reopened. */\n dormantSessions?: () => readonly OpenSessionRecord[];\n}): HeadlessProtocol {\n const hub = options.hub;\n const dormantSessions = () => (options.dormantSessions === undefined ? [] : options.dormantSessions());\n const connections = new Map<string, Connection>();\n const threads = createThreadJournals({\n resolve: (sessionId, threadId) => hub.childThread(sessionId, threadId),\n });\n const host = createHost<Principal>({\n name: PO_SERVER_HOST,\n self: { connectionId: PO_SERVER_HOST },\n principalKey: (principal) => principal.connectionId,\n onError: (error) => options.onNotice?.(`headless protocol error (${harnessErrorMessage(error)})`),\n });\n const connectionOf = (principal: Principal): Connection & { connectionId: string } => {\n const connection = connections.get(principal.connectionId);\n if (connection === undefined) throw forbidden('This connection has closed.');\n return { ...connection, connectionId: principal.connectionId };\n };\n const reachable = (connection: Connection, sessionId: string): boolean =>\n permitsSession(hub, connection.mount, sessionId, (id) => connection.authorizeSession(id));\n\n // A Desktop claim makes every reference the connection holds to that session gone at once.\n const stopClaims = hub.computerUse?.subscribe?.(() => {\n for (const [connectionId, connection] of connections) {\n let revoked = false;\n for (const sessionId of connection.sessions) if (!connection.authorizeSession(sessionId)) revoked = true;\n if (!revoked) continue;\n connection.sessions.clear();\n void host.invalidatePrincipal((principal) => principal.connectionId === connectionId);\n }\n });\n\n host.serve(PoHubContract, (_input, principal, self) => {\n const connection = connectionOf(principal);\n const { mount } = connection;\n const visibleSessions = (): Record<string, HubSessionView> => {\n const views: Record<string, HubSessionView> = {};\n for (const session of hub.snapshot())\n if (reachable(connection, session.id)) views[session.id] = sessionView(session);\n // A dormant record of a removed workspace has no HTTP list to come from, so clients would never agree on it.\n const registered = new Set(hub.workspaces().map((workspace) => workspace.id));\n for (const record of dormantSessions())\n if (\n views[record.sessionId] === undefined &&\n registered.has(record.workspaceId) &&\n connection.authorizeSession(record.sessionId) &&\n permitsDormant(mount, record)\n )\n views[record.sessionId] = dormantView(record, hub.sessionPendingApprovalCount?.(record.sessionId));\n return views;\n };\n const visibleWorkspaces = (): Record<string, HubWorkspaceView> => {\n const views: Record<string, HubWorkspaceView> = {};\n for (const workspace of hub.workspaces())\n if (mount.scope === 'global' || workspace.id === mount.workspaceId)\n views[workspace.id] = {\n id: workspace.id,\n root: workspace.root,\n ...(workspace.kind === undefined ? {} : { kind: workspace.kind }),\n ...(workspace.name === undefined ? {} : { name: workspace.name }),\n ...(workspace.sandbox === undefined ? {} : { sandbox: workspace.sandbox }),\n ...(workspace.sandboxState === undefined ? {} : { sandboxState: workspace.sandboxState }),\n ...(workspace.sandboxReason === undefined ? {} : { sandboxReason: workspace.sandboxReason }),\n available: workspace.available !== false,\n };\n return views;\n };\n const sessions = self.state('sessions', chordSchema(Type.Record(Type.String(), SessionSummarySchema)), {\n init: visibleSessions,\n });\n const workspaces = self.state('workspaces', chordSchema(Type.Record(Type.String(), HubWorkspaceSchema)), {\n init: visibleWorkspaces,\n });\n const pending = self.state('pending', chordSchema(Type.Array(HubNoticeSchema)), [] as HubNotice[]);\n const visibleCompositions = (): Record<string, number> => {\n const revisions = hub.compositionRevisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}`;\n return Object.fromEntries(Object.entries(revisions).filter(([key]) => key === 'global' || key === own));\n };\n const compositions = self.state('compositions', chordSchema(HubCompositionsSchema), { init: visibleCompositions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n switch (event.kind) {\n case 'upsert':\n case 'removed':\n case 'dormant_changed':\n // Recomputed rather than patched, so an event before this listener started cannot leave a stale row.\n sessions.replace(ctx, visibleSessions(), { diff: true });\n return;\n case 'workspace_upsert':\n case 'workspace_removed':\n workspaces.replace(ctx, visibleWorkspaces(), { diff: true });\n return;\n case 'compositions':\n compositions.replace(ctx, visibleCompositions(), { diff: true });\n return;\n case 'frame':\n if (!reachable(connection, event.sessionId)) return;\n pending.change(ctx, (draft) => {\n draft.push({\n id: randomUUID(),\n sessionId: event.sessionId,\n frame: event.frame as Record<string, JsonValue>,\n });\n if (draft.length > MAX_PENDING_NOTICES) draft.splice(0, draft.length - MAX_PENDING_NOTICES);\n });\n return;\n case 'channel':\n return;\n }\n });\n return {\n variant: 'default',\n sessions,\n workspaces,\n pending,\n compositions,\n readHome: async (request) => {\n if (!hub.readHome) throw new Error('Home read is unavailable.');\n return hub.readHome(request, (id) => reachable(connection, id));\n },\n invoke: async (call: PoPluginCall, ctx) => {\n if (call.mount.scope === 'session' && !connection.authorizeSession(call.mount.sessionId))\n throw forbidden('This session belongs to its Desktop instance.');\n if (mount.scope !== 'global') {\n const permitted =\n call.mount.scope === 'session'\n ? permitsSession(hub, mount, call.mount.sessionId)\n : mount.scope === 'workspace' &&\n call.mount.scope === 'workspace' &&\n call.mount.workspaceId === mount.workspaceId;\n if (!permitted) throw forbidden('Plugin is outside this WebSocket scope.');\n }\n return (await hub.invokePlugin(call, 'client-to-server', {\n connectionId: connection.connectionId,\n signal: ctx.signal,\n })) as JsonValue;\n },\n ackNotice: async ({ id }, ctx) => {\n pending.change(ctx, (draft) => draft.filter((notice) => notice.id !== id));\n },\n };\n });\n\n host.serve(PoHubRevisionsContract, (_input, principal, self) => {\n const { mount } = connectionOf(principal);\n const visibleRevisions = (): Record<string, number> => {\n const revisions = hub.revisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}:`;\n return Object.fromEntries(\n Object.entries(revisions).filter(([topic]) => topic.startsWith('global:') || topic.startsWith(own)),\n );\n };\n const revisions = self.state('revisions', chordSchema(HubRevisionsSchema), { init: visibleRevisions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind === 'revisions') revisions.replace(ctx, visibleRevisions(), { diff: true });\n });\n return { variant: 'default', revisions };\n });\n\n host.serve(\n PoThreadContract,\n ({ sessionId, threadId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const tail = self.resource('tail', {\n version: 1,\n open: () => threads.subscribe(sessionId, threadId),\n close: () => threads.unsubscribe(sessionId, threadId),\n });\n const frame = self.state('frame', chordSchema(PoThreadFrameSchema), {\n init: () => (tail.value?.at(-1) ?? null) as never,\n });\n self.on(\n 'frames',\n { subscribe: (listener) => threads.onFrame(listener) } as Subscribable<{\n sessionId: string;\n threadId: string;\n frame: Record<string, unknown>;\n }>,\n (event, ctx) => {\n // Each frame is a fresh wrapper around the child's state, so only an explicit diff sends ops, not the whole state.\n if (event.sessionId === sessionId && event.threadId === threadId)\n frame.replace(ctx, event.frame as never, { diff: true });\n },\n );\n return { variant: 'default', frame };\n },\n { linger: THREAD_LINGER_MS },\n );\n\n host.serve(PoChannelsContract, ({ sessionId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const visible = (frameType: string): boolean =>\n frameType !== 'computer_use_state' || connection.authorizeComputerUse(sessionId);\n const latest = self.state('latest', chordSchema(PoChannelsStateSchema), {\n init: () => {\n const payloads: Record<string, JsonValue> = {};\n for (const channelFrame of hub.channelFrames(sessionId))\n if (visible(channelFrame.type)) payloads[channelFrame.type] = channelFrame.payload as JsonValue;\n return payloads;\n },\n });\n // ponytail: a channel keeps only its latest payload; a package that needs every event must carry a sequence.\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind !== 'channel' || event.sessionId !== sessionId || !visible(event.frameType)) return;\n if (event.connectionId !== undefined && event.connectionId !== connection.connectionId) return;\n latest.change(ctx, (draft) => {\n draft[event.frameType] = event.payload as JsonValue;\n });\n });\n return {\n variant: 'default',\n latest,\n receive: async ({ type, payload }) => {\n if (!connection.authorizeSession(sessionId)) throw forbidden('This session belongs to Desktop.');\n hub.receiveChannel(\n sessionId,\n type,\n payload,\n connection.connectionId,\n connection.authorizeDesktop(),\n connection.authorizeComputerUse(sessionId),\n );\n },\n };\n });\n\n const clearSessionBindings = serveAgentSessions(host, {\n resolve(sessionId, principal): AgentSessionBinding | undefined {\n const connection = connectionOf(principal as Principal);\n const session = hub.session(sessionId);\n if (!session || !reachable(connection, session.id)) return undefined;\n connection.sessions.add(sessionId);\n const permitted = () => hub.session(session.id)?.host === session.host && connection.authorizeSession(session.id);\n // A mirror of a session another host runs forwards there; keyed by its host object, never by session id.\n const forward = session.host.agentSession;\n if (forward !== undefined)\n return { generation: generationOf(session.host), exited: session.host.runtime.exited, permitted, forward };\n return {\n generation: generationOf(session.host),\n exited: session.host.runtime.exited,\n permitted,\n options: {\n runtime: session.host.runtime,\n onPresentationFrame: (listen) =>\n session.host.onPresentationFrame((frame) => {\n if (permitted()) listen(frame);\n }),\n respondToExtensionUi: (frame) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return session.host.respondToExtensionUi(frame);\n },\n readThreadTranscript: (threadId, request, readContext) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return threads.readPage(session.id, threadId, request, readContext);\n },\n sessionId: session.id,\n sessionName: session.name,\n cwd: session.cwd,\n telemetry: options.telemetry,\n },\n };\n },\n });\n\n let closing: Promise<void> | undefined;\n return {\n accept(link, access = {}) {\n if (closing !== undefined) {\n link.close();\n return;\n }\n const connectionId = randomUUID();\n const authorizeSession = access.authorizeSession ?? ((id: string) => !hub.computerUse?.ownsSession?.(id));\n const authorizeDesktop = access.authorizeDesktop ?? (() => false);\n connections.set(connectionId, {\n mount: access.mount ?? { scope: 'global' },\n authorizeSession,\n authorizeDesktop,\n authorizeComputerUse: access.authorizeComputerUse ?? (() => authorizeDesktop()),\n sessions: new Set(),\n });\n link.onClose(() => {\n connections.delete(connectionId);\n hub.disconnectChannels(connectionId);\n });\n host.accept(reportingLargeFrames(link, options.onNotice, options.telemetry), {\n principal: { connectionId },\n kind: 'client',\n });\n },\n close() {\n closing ??= (async () => {\n stopClaims?.();\n threads.close();\n clearSessionBindings();\n await host.close();\n })();\n return closing;\n },\n };\n}\n"],"mappings":"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"}
@@ -290,7 +290,7 @@ function createHeadlessProtocol(options) {
290
290
  }
291
291
  };
292
292
  });
293
- serveAgentSessions(host, { resolve(sessionId, principal) {
293
+ const clearSessionBindings = serveAgentSessions(host, { resolve(sessionId, principal) {
294
294
  const connection = connectionOf(principal);
295
295
  const session = hub.session(sessionId);
296
296
  if (!session || !reachable(connection, session.id)) return void 0;
@@ -357,6 +357,7 @@ function createHeadlessProtocol(options) {
357
357
  closing ??= (async () => {
358
358
  stopClaims?.();
359
359
  threads.close();
360
+ clearSessionBindings();
360
361
  await host.close();
361
362
  })();
362
363
  return closing;
@@ -1 +1 @@
1
- {"version":3,"file":"headlessProtocol.mjs","names":[],"sources":["../src/server/headlessProtocol.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createHost, forbidden, type Link, type Subscribable } from '@earendil-works/chord';\nimport { Type } from 'typebox';\n\nimport type { PoPluginCall } from '../exports/pluginProtocol';\nimport {\n HubCompositionsSchema,\n HubNoticeSchema,\n HubRevisionsSchema,\n PO_SERVER_HOST,\n PoChannelsContract,\n PoHubContract,\n PoHubRevisionsContract,\n PoThreadContract,\n type HubNotice,\n type HubSessionView,\n type HubWorkspaceView,\n type JsonValue,\n} from '../exports/sessionProtocol';\nimport { serveAgentSessions, type AgentSessionBinding } from '../pi/piSessionRuntime';\nimport { SessionSummarySchema } from '../schemas/httpApiContracts';\nimport type { PoSocketMount } from '../schemas/packageApi';\nimport { PoChannelsStateSchema } from '../schemas/protocolChannelsContract';\nimport { chordSchema } from '../schemas/protocolContracts';\nimport { HubWorkspaceSchema } from '../schemas/protocolHubContract';\nimport { PoThreadFrameSchema } from '../schemas/protocolThreadContract';\nimport type { OpenSessionRecord } from '../services/openSessionRegistry';\nimport type { ServerTelemetry } from '../services/serverTelemetry';\nimport { harnessErrorMessage } from './harnessErrorMessage';\nimport type { HeadlessHub, HeadlessHubEvent, HeadlessHubSession } from './headlessHub';\nimport { reportingLargeFrames } from './largeFrameLink';\nimport { createThreadJournals } from './threadJournals';\n\n// ponytail: unacknowledged notices beyond this drop oldest first; raise it if a client misses dialogs.\nconst MAX_PENDING_NOTICES = 64;\n/** A browser switching back to a thread quickly keeps its tail open. */\nconst THREAD_LINGER_MS = 5_000;\n\nfunction sessionView(session: HeadlessHubSession): HubSessionView {\n return {\n id: session.id,\n ...(session.workspaceId === undefined ? {} : { workspaceId: session.workspaceId }),\n ...(session.webComposition === undefined ? {} : { webComposition: { ...session.webComposition } }),\n ...(session.nativeComposition === undefined ? {} : { nativeComposition: { ...session.nativeComposition } }),\n name: session.name,\n cwd: session.cwd,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt ?? session.createdAt,\n phase: session.phase ?? 'idle',\n phaseSince: session.phaseSince ?? session.createdAt,\n attach: 'attached',\n pendingMessageCount: session.pendingMessageCount ?? 0,\n everPrompted: session.everPrompted ?? false,\n awaitingInput: session.awaitingInput ?? false,\n ...(session.lastSettledAt === undefined ? {} : { lastSettledAt: session.lastSettledAt }),\n // null: the host has not reported yet.\n ...(session.backgroundWorkActive == null ? {} : { backgroundWorkActive: session.backgroundWorkActive }),\n ...(session.git === undefined ? {} : { git: { branch: session.git.branch, dirty: session.git.dirty } }),\n ...(session.profile === undefined\n ? {}\n : {\n profile: {\n name: session.profile.name,\n ...(session.profile.displayName === undefined ? {} : { displayName: session.profile.displayName }),\n ...(session.profile.iconVersion === undefined ? {} : { iconVersion: session.profile.iconVersion }),\n },\n }),\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n ...(session.interaction === undefined ? {} : { interaction: session.interaction }),\n ...(session.groups === undefined || session.groups.length === 0 ? {} : { groups: [...session.groups] }),\n ...(session.pendingSetups === undefined\n ? {}\n : {\n pendingSetups: session.pendingSetups.map((setup) => ({\n id: setup.id,\n name: setup.name,\n createdAt: setup.createdAt,\n ...(setup.cwd === undefined ? {} : { cwd: setup.cwd }),\n ...(setup.setupKind === undefined ? {} : { setupKind: setup.setupKind }),\n ...(setup.status === undefined ? {} : { status: setup.status }),\n ...(setup.errorCode === undefined ? {} : { errorCode: setup.errorCode }),\n })),\n }),\n ...(session.activity === undefined\n ? {}\n : {\n activity: {\n label: session.activity.label,\n ...(session.activity.attention === true ? { attention: true } : {}),\n ...(session.activity.since === undefined ? {} : { since: session.activity.since }),\n },\n }),\n ...(session.pendingApprovalCount === undefined ? {} : { pendingApprovalCount: session.pendingApprovalCount }),\n };\n}\n\n/**\n * A recorded session with no runtime behind it yet.\n *\n * Carries the same field set as a live session so the rail keys both by id and\n * swaps one for the other in place once the server reopens the journal.\n */\nfunction dormantView(record: OpenSessionRecord, pendingApprovalCount?: number): HubSessionView {\n return {\n id: record.sessionId,\n workspaceId: record.workspaceId,\n name: record.name,\n cwd: record.cwd,\n createdAt: record.createdAt,\n updatedAt: record.createdAt,\n phase: 'idle',\n phaseSince: record.createdAt,\n attach: 'attached',\n pendingMessageCount: 0,\n everPrompted: false,\n awaitingInput: false,\n dormant: true,\n ...(pendingApprovalCount === undefined ? {} : { pendingApprovalCount }),\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n ...(record.interaction === undefined ? {} : { interaction: record.interaction }),\n ...(record.groups === undefined || record.groups.length === 0 ? {} : { groups: [...record.groups] }),\n };\n}\n\n/** Each restarted session host gets a new generation, so its projection starts fresh. */\nconst generations = new WeakMap<object, number>();\nlet nextGeneration = 0;\nfunction generationOf(host: object): number {\n let generation = generations.get(host);\n if (generation === undefined) {\n generation = nextGeneration++;\n generations.set(host, generation);\n }\n return generation;\n}\n\nfunction permitsSession(\n hub: HeadlessHub,\n mount: PoSocketMount,\n sessionId: string,\n authorize: (id: string) => boolean = () => true,\n): boolean {\n const session = hub.session(sessionId);\n return (\n session !== undefined &&\n authorize(sessionId) &&\n (mount.scope === 'global' ||\n (session.workspaceId === mount.workspaceId && (mount.scope === 'workspace' || mount.sessionId === sessionId)))\n );\n}\n\nfunction permitsDormant(mount: PoSocketMount, record: OpenSessionRecord): boolean {\n if (mount.scope === 'global') return true;\n if (record.workspaceId !== mount.workspaceId) return false;\n return mount.scope === 'workspace' || mount.sessionId === record.sessionId;\n}\n\n/** What one upgraded connection may reach, decided from its request when it connected. */\nexport interface ConnectionAccess {\n readonly mount: PoSocketMount;\n /** Evaluated for every call, including references taken before a Desktop claim. */\n authorizeSession(sessionId: string): boolean;\n authorizeDesktop(): boolean;\n authorizeComputerUse(sessionId: string): boolean;\n}\n\ninterface Connection extends ConnectionAccess {\n /** Sessions this connection reached, rechecked when computer-use ownership changes. */\n readonly sessions: Set<string>;\n}\n\ninterface Principal {\n connectionId: string;\n}\n\nexport interface HeadlessProtocol {\n /** Hands an authenticated link to the shared host. Without `access` it sees everything Desktop does not own. */\n accept(link: Link, access?: Partial<ConnectionAccess>): void;\n close(): Promise<void>;\n}\n\nconst eventsOf = (hub: HeadlessHub): Subscribable<HeadlessHubEvent> => ({\n subscribe: (listener) => hub.onEvent(listener),\n});\n\n/** One Chord host for every browser, native and relayed connection over the process-local hub. */\nexport function createHeadlessProtocol(options: {\n hub: HeadlessHub;\n telemetry?: ServerTelemetry;\n onNotice?: (message: string) => void;\n /** Recorded sessions the server has not reopened. */\n dormantSessions?: () => readonly OpenSessionRecord[];\n}): HeadlessProtocol {\n const hub = options.hub;\n const dormantSessions = () => (options.dormantSessions === undefined ? [] : options.dormantSessions());\n const connections = new Map<string, Connection>();\n const threads = createThreadJournals({\n resolve: (sessionId, threadId) => hub.childThread(sessionId, threadId),\n });\n const host = createHost<Principal>({\n name: PO_SERVER_HOST,\n self: { connectionId: PO_SERVER_HOST },\n principalKey: (principal) => principal.connectionId,\n onError: (error) => options.onNotice?.(`headless protocol error (${harnessErrorMessage(error)})`),\n });\n const connectionOf = (principal: Principal): Connection & { connectionId: string } => {\n const connection = connections.get(principal.connectionId);\n if (connection === undefined) throw forbidden('This connection has closed.');\n return { ...connection, connectionId: principal.connectionId };\n };\n const reachable = (connection: Connection, sessionId: string): boolean =>\n permitsSession(hub, connection.mount, sessionId, (id) => connection.authorizeSession(id));\n\n // A Desktop claim makes every reference the connection holds to that session gone at once.\n const stopClaims = hub.computerUse?.subscribe?.(() => {\n for (const [connectionId, connection] of connections) {\n let revoked = false;\n for (const sessionId of connection.sessions) if (!connection.authorizeSession(sessionId)) revoked = true;\n if (!revoked) continue;\n connection.sessions.clear();\n void host.invalidatePrincipal((principal) => principal.connectionId === connectionId);\n }\n });\n\n host.serve(PoHubContract, (_input, principal, self) => {\n const connection = connectionOf(principal);\n const { mount } = connection;\n const visibleSessions = (): Record<string, HubSessionView> => {\n const views: Record<string, HubSessionView> = {};\n for (const session of hub.snapshot())\n if (reachable(connection, session.id)) views[session.id] = sessionView(session);\n // A dormant record of a removed workspace has no HTTP list to come from, so clients would never agree on it.\n const registered = new Set(hub.workspaces().map((workspace) => workspace.id));\n for (const record of dormantSessions())\n if (\n views[record.sessionId] === undefined &&\n registered.has(record.workspaceId) &&\n connection.authorizeSession(record.sessionId) &&\n permitsDormant(mount, record)\n )\n views[record.sessionId] = dormantView(record, hub.sessionPendingApprovalCount?.(record.sessionId));\n return views;\n };\n const visibleWorkspaces = (): Record<string, HubWorkspaceView> => {\n const views: Record<string, HubWorkspaceView> = {};\n for (const workspace of hub.workspaces())\n if (mount.scope === 'global' || workspace.id === mount.workspaceId)\n views[workspace.id] = {\n id: workspace.id,\n root: workspace.root,\n ...(workspace.kind === undefined ? {} : { kind: workspace.kind }),\n ...(workspace.name === undefined ? {} : { name: workspace.name }),\n ...(workspace.sandbox === undefined ? {} : { sandbox: workspace.sandbox }),\n ...(workspace.sandboxState === undefined ? {} : { sandboxState: workspace.sandboxState }),\n ...(workspace.sandboxReason === undefined ? {} : { sandboxReason: workspace.sandboxReason }),\n available: workspace.available !== false,\n };\n return views;\n };\n const sessions = self.state('sessions', chordSchema(Type.Record(Type.String(), SessionSummarySchema)), {\n init: visibleSessions,\n });\n const workspaces = self.state('workspaces', chordSchema(Type.Record(Type.String(), HubWorkspaceSchema)), {\n init: visibleWorkspaces,\n });\n const pending = self.state('pending', chordSchema(Type.Array(HubNoticeSchema)), [] as HubNotice[]);\n const visibleCompositions = (): Record<string, number> => {\n const revisions = hub.compositionRevisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}`;\n return Object.fromEntries(Object.entries(revisions).filter(([key]) => key === 'global' || key === own));\n };\n const compositions = self.state('compositions', chordSchema(HubCompositionsSchema), { init: visibleCompositions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n switch (event.kind) {\n case 'upsert':\n case 'removed':\n case 'dormant_changed':\n // Recomputed rather than patched, so an event before this listener started cannot leave a stale row.\n sessions.replace(ctx, visibleSessions(), { diff: true });\n return;\n case 'workspace_upsert':\n case 'workspace_removed':\n workspaces.replace(ctx, visibleWorkspaces(), { diff: true });\n return;\n case 'compositions':\n compositions.replace(ctx, visibleCompositions(), { diff: true });\n return;\n case 'frame':\n if (!reachable(connection, event.sessionId)) return;\n pending.change(ctx, (draft) => {\n draft.push({\n id: randomUUID(),\n sessionId: event.sessionId,\n frame: event.frame as Record<string, JsonValue>,\n });\n if (draft.length > MAX_PENDING_NOTICES) draft.splice(0, draft.length - MAX_PENDING_NOTICES);\n });\n return;\n case 'channel':\n return;\n }\n });\n return {\n variant: 'default',\n sessions,\n workspaces,\n pending,\n compositions,\n readHome: async (request) => {\n if (!hub.readHome) throw new Error('Home read is unavailable.');\n return hub.readHome(request, (id) => reachable(connection, id));\n },\n invoke: async (call: PoPluginCall, ctx) => {\n if (call.mount.scope === 'session' && !connection.authorizeSession(call.mount.sessionId))\n throw forbidden('This session belongs to its Desktop instance.');\n if (mount.scope !== 'global') {\n const permitted =\n call.mount.scope === 'session'\n ? permitsSession(hub, mount, call.mount.sessionId)\n : mount.scope === 'workspace' &&\n call.mount.scope === 'workspace' &&\n call.mount.workspaceId === mount.workspaceId;\n if (!permitted) throw forbidden('Plugin is outside this WebSocket scope.');\n }\n return (await hub.invokePlugin(call, 'client-to-server', {\n connectionId: connection.connectionId,\n signal: ctx.signal,\n })) as JsonValue;\n },\n ackNotice: async ({ id }, ctx) => {\n pending.change(ctx, (draft) => draft.filter((notice) => notice.id !== id));\n },\n };\n });\n\n host.serve(PoHubRevisionsContract, (_input, principal, self) => {\n const { mount } = connectionOf(principal);\n const visibleRevisions = (): Record<string, number> => {\n const revisions = hub.revisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}:`;\n return Object.fromEntries(\n Object.entries(revisions).filter(([topic]) => topic.startsWith('global:') || topic.startsWith(own)),\n );\n };\n const revisions = self.state('revisions', chordSchema(HubRevisionsSchema), { init: visibleRevisions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind === 'revisions') revisions.replace(ctx, visibleRevisions(), { diff: true });\n });\n return { variant: 'default', revisions };\n });\n\n host.serve(\n PoThreadContract,\n ({ sessionId, threadId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const tail = self.resource('tail', {\n version: 1,\n open: () => threads.subscribe(sessionId, threadId),\n close: () => threads.unsubscribe(sessionId, threadId),\n });\n const frame = self.state('frame', chordSchema(PoThreadFrameSchema), {\n init: () => (tail.value?.at(-1) ?? null) as never,\n });\n self.on(\n 'frames',\n { subscribe: (listener) => threads.onFrame(listener) } as Subscribable<{\n sessionId: string;\n threadId: string;\n frame: Record<string, unknown>;\n }>,\n (event, ctx) => {\n // Each frame is a fresh wrapper around the child's state, so only an explicit diff sends ops, not the whole state.\n if (event.sessionId === sessionId && event.threadId === threadId)\n frame.replace(ctx, event.frame as never, { diff: true });\n },\n );\n return { variant: 'default', frame };\n },\n { linger: THREAD_LINGER_MS },\n );\n\n host.serve(PoChannelsContract, ({ sessionId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const visible = (frameType: string): boolean =>\n frameType !== 'computer_use_state' || connection.authorizeComputerUse(sessionId);\n const latest = self.state('latest', chordSchema(PoChannelsStateSchema), {\n init: () => {\n const payloads: Record<string, JsonValue> = {};\n for (const channelFrame of hub.channelFrames(sessionId))\n if (visible(channelFrame.type)) payloads[channelFrame.type] = channelFrame.payload as JsonValue;\n return payloads;\n },\n });\n // ponytail: a channel keeps only its latest payload; a package that needs every event must carry a sequence.\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind !== 'channel' || event.sessionId !== sessionId || !visible(event.frameType)) return;\n if (event.connectionId !== undefined && event.connectionId !== connection.connectionId) return;\n latest.change(ctx, (draft) => {\n draft[event.frameType] = event.payload as JsonValue;\n });\n });\n return {\n variant: 'default',\n latest,\n receive: async ({ type, payload }) => {\n if (!connection.authorizeSession(sessionId)) throw forbidden('This session belongs to Desktop.');\n hub.receiveChannel(\n sessionId,\n type,\n payload,\n connection.connectionId,\n connection.authorizeDesktop(),\n connection.authorizeComputerUse(sessionId),\n );\n },\n };\n });\n\n serveAgentSessions(host, {\n resolve(sessionId, principal): AgentSessionBinding | undefined {\n const connection = connectionOf(principal as Principal);\n const session = hub.session(sessionId);\n if (!session || !reachable(connection, session.id)) return undefined;\n connection.sessions.add(sessionId);\n const permitted = () => hub.session(session.id)?.host === session.host && connection.authorizeSession(session.id);\n // A mirror of a session another host runs forwards there; keyed by its host object, never by session id.\n const forward = session.host.agentSession;\n if (forward !== undefined)\n return { generation: generationOf(session.host), exited: session.host.runtime.exited, permitted, forward };\n return {\n generation: generationOf(session.host),\n exited: session.host.runtime.exited,\n permitted,\n options: {\n runtime: session.host.runtime,\n onPresentationFrame: (listen) =>\n session.host.onPresentationFrame((frame) => {\n if (permitted()) listen(frame);\n }),\n respondToExtensionUi: (frame) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return session.host.respondToExtensionUi(frame);\n },\n readThreadTranscript: (threadId, request, readContext) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return threads.readPage(session.id, threadId, request, readContext);\n },\n sessionId: session.id,\n sessionName: session.name,\n cwd: session.cwd,\n telemetry: options.telemetry,\n },\n };\n },\n });\n\n let closing: Promise<void> | undefined;\n return {\n accept(link, access = {}) {\n if (closing !== undefined) {\n link.close();\n return;\n }\n const connectionId = randomUUID();\n const authorizeSession = access.authorizeSession ?? ((id: string) => !hub.computerUse?.ownsSession?.(id));\n const authorizeDesktop = access.authorizeDesktop ?? (() => false);\n connections.set(connectionId, {\n mount: access.mount ?? { scope: 'global' },\n authorizeSession,\n authorizeDesktop,\n authorizeComputerUse: access.authorizeComputerUse ?? (() => authorizeDesktop()),\n sessions: new Set(),\n });\n link.onClose(() => {\n connections.delete(connectionId);\n hub.disconnectChannels(connectionId);\n });\n host.accept(reportingLargeFrames(link, options.onNotice, options.telemetry), {\n principal: { connectionId },\n kind: 'client',\n });\n },\n close() {\n closing ??= (async () => {\n stopClaims?.();\n threads.close();\n await host.close();\n })();\n return closing;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"headlessProtocol.mjs","names":[],"sources":["../src/server/headlessProtocol.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { createHost, forbidden, type Link, type Subscribable } from '@earendil-works/chord';\nimport { Type } from 'typebox';\n\nimport type { PoPluginCall } from '../exports/pluginProtocol';\nimport {\n HubCompositionsSchema,\n HubNoticeSchema,\n HubRevisionsSchema,\n PO_SERVER_HOST,\n PoChannelsContract,\n PoHubContract,\n PoHubRevisionsContract,\n PoThreadContract,\n type HubNotice,\n type HubSessionView,\n type HubWorkspaceView,\n type JsonValue,\n} from '../exports/sessionProtocol';\nimport { serveAgentSessions, type AgentSessionBinding } from '../pi/piSessionRuntime';\nimport { SessionSummarySchema } from '../schemas/httpApiContracts';\nimport type { PoSocketMount } from '../schemas/packageApi';\nimport { PoChannelsStateSchema } from '../schemas/protocolChannelsContract';\nimport { chordSchema } from '../schemas/protocolContracts';\nimport { HubWorkspaceSchema } from '../schemas/protocolHubContract';\nimport { PoThreadFrameSchema } from '../schemas/protocolThreadContract';\nimport type { OpenSessionRecord } from '../services/openSessionRegistry';\nimport type { ServerTelemetry } from '../services/serverTelemetry';\nimport { harnessErrorMessage } from './harnessErrorMessage';\nimport type { HeadlessHub, HeadlessHubEvent, HeadlessHubSession } from './headlessHub';\nimport { reportingLargeFrames } from './largeFrameLink';\nimport { createThreadJournals } from './threadJournals';\n\n// ponytail: unacknowledged notices beyond this drop oldest first; raise it if a client misses dialogs.\nconst MAX_PENDING_NOTICES = 64;\n/** A browser switching back to a thread quickly keeps its tail open. */\nconst THREAD_LINGER_MS = 5_000;\n\nfunction sessionView(session: HeadlessHubSession): HubSessionView {\n return {\n id: session.id,\n ...(session.workspaceId === undefined ? {} : { workspaceId: session.workspaceId }),\n ...(session.webComposition === undefined ? {} : { webComposition: { ...session.webComposition } }),\n ...(session.nativeComposition === undefined ? {} : { nativeComposition: { ...session.nativeComposition } }),\n name: session.name,\n cwd: session.cwd,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt ?? session.createdAt,\n phase: session.phase ?? 'idle',\n phaseSince: session.phaseSince ?? session.createdAt,\n attach: 'attached',\n pendingMessageCount: session.pendingMessageCount ?? 0,\n everPrompted: session.everPrompted ?? false,\n awaitingInput: session.awaitingInput ?? false,\n ...(session.lastSettledAt === undefined ? {} : { lastSettledAt: session.lastSettledAt }),\n // null: the host has not reported yet.\n ...(session.backgroundWorkActive == null ? {} : { backgroundWorkActive: session.backgroundWorkActive }),\n ...(session.git === undefined ? {} : { git: { branch: session.git.branch, dirty: session.git.dirty } }),\n ...(session.profile === undefined\n ? {}\n : {\n profile: {\n name: session.profile.name,\n ...(session.profile.displayName === undefined ? {} : { displayName: session.profile.displayName }),\n ...(session.profile.iconVersion === undefined ? {} : { iconVersion: session.profile.iconVersion }),\n },\n }),\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n ...(session.interaction === undefined ? {} : { interaction: session.interaction }),\n ...(session.groups === undefined || session.groups.length === 0 ? {} : { groups: [...session.groups] }),\n ...(session.pendingSetups === undefined\n ? {}\n : {\n pendingSetups: session.pendingSetups.map((setup) => ({\n id: setup.id,\n name: setup.name,\n createdAt: setup.createdAt,\n ...(setup.cwd === undefined ? {} : { cwd: setup.cwd }),\n ...(setup.setupKind === undefined ? {} : { setupKind: setup.setupKind }),\n ...(setup.status === undefined ? {} : { status: setup.status }),\n ...(setup.errorCode === undefined ? {} : { errorCode: setup.errorCode }),\n })),\n }),\n ...(session.activity === undefined\n ? {}\n : {\n activity: {\n label: session.activity.label,\n ...(session.activity.attention === true ? { attention: true } : {}),\n ...(session.activity.since === undefined ? {} : { since: session.activity.since }),\n },\n }),\n ...(session.pendingApprovalCount === undefined ? {} : { pendingApprovalCount: session.pendingApprovalCount }),\n };\n}\n\n/**\n * A recorded session with no runtime behind it yet.\n *\n * Carries the same field set as a live session so the rail keys both by id and\n * swaps one for the other in place once the server reopens the journal.\n */\nfunction dormantView(record: OpenSessionRecord, pendingApprovalCount?: number): HubSessionView {\n return {\n id: record.sessionId,\n workspaceId: record.workspaceId,\n name: record.name,\n cwd: record.cwd,\n createdAt: record.createdAt,\n updatedAt: record.createdAt,\n phase: 'idle',\n phaseSince: record.createdAt,\n attach: 'attached',\n pendingMessageCount: 0,\n everPrompted: false,\n awaitingInput: false,\n dormant: true,\n ...(pendingApprovalCount === undefined ? {} : { pendingApprovalCount }),\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n ...(record.interaction === undefined ? {} : { interaction: record.interaction }),\n ...(record.groups === undefined || record.groups.length === 0 ? {} : { groups: [...record.groups] }),\n };\n}\n\n/** Each restarted session host gets a new generation, so its projection starts fresh. */\nconst generations = new WeakMap<object, number>();\nlet nextGeneration = 0;\nfunction generationOf(host: object): number {\n let generation = generations.get(host);\n if (generation === undefined) {\n generation = nextGeneration++;\n generations.set(host, generation);\n }\n return generation;\n}\n\nfunction permitsSession(\n hub: HeadlessHub,\n mount: PoSocketMount,\n sessionId: string,\n authorize: (id: string) => boolean = () => true,\n): boolean {\n const session = hub.session(sessionId);\n return (\n session !== undefined &&\n authorize(sessionId) &&\n (mount.scope === 'global' ||\n (session.workspaceId === mount.workspaceId && (mount.scope === 'workspace' || mount.sessionId === sessionId)))\n );\n}\n\nfunction permitsDormant(mount: PoSocketMount, record: OpenSessionRecord): boolean {\n if (mount.scope === 'global') return true;\n if (record.workspaceId !== mount.workspaceId) return false;\n return mount.scope === 'workspace' || mount.sessionId === record.sessionId;\n}\n\n/** What one upgraded connection may reach, decided from its request when it connected. */\nexport interface ConnectionAccess {\n readonly mount: PoSocketMount;\n /** Evaluated for every call, including references taken before a Desktop claim. */\n authorizeSession(sessionId: string): boolean;\n authorizeDesktop(): boolean;\n authorizeComputerUse(sessionId: string): boolean;\n}\n\ninterface Connection extends ConnectionAccess {\n /** Sessions this connection reached, rechecked when computer-use ownership changes. */\n readonly sessions: Set<string>;\n}\n\ninterface Principal {\n connectionId: string;\n}\n\nexport interface HeadlessProtocol {\n /** Hands an authenticated link to the shared host. Without `access` it sees everything Desktop does not own. */\n accept(link: Link, access?: Partial<ConnectionAccess>): void;\n close(): Promise<void>;\n}\n\nconst eventsOf = (hub: HeadlessHub): Subscribable<HeadlessHubEvent> => ({\n subscribe: (listener) => hub.onEvent(listener),\n});\n\n/** One Chord host for every browser, native and relayed connection over the process-local hub. */\nexport function createHeadlessProtocol(options: {\n hub: HeadlessHub;\n telemetry?: ServerTelemetry;\n onNotice?: (message: string) => void;\n /** Recorded sessions the server has not reopened. */\n dormantSessions?: () => readonly OpenSessionRecord[];\n}): HeadlessProtocol {\n const hub = options.hub;\n const dormantSessions = () => (options.dormantSessions === undefined ? [] : options.dormantSessions());\n const connections = new Map<string, Connection>();\n const threads = createThreadJournals({\n resolve: (sessionId, threadId) => hub.childThread(sessionId, threadId),\n });\n const host = createHost<Principal>({\n name: PO_SERVER_HOST,\n self: { connectionId: PO_SERVER_HOST },\n principalKey: (principal) => principal.connectionId,\n onError: (error) => options.onNotice?.(`headless protocol error (${harnessErrorMessage(error)})`),\n });\n const connectionOf = (principal: Principal): Connection & { connectionId: string } => {\n const connection = connections.get(principal.connectionId);\n if (connection === undefined) throw forbidden('This connection has closed.');\n return { ...connection, connectionId: principal.connectionId };\n };\n const reachable = (connection: Connection, sessionId: string): boolean =>\n permitsSession(hub, connection.mount, sessionId, (id) => connection.authorizeSession(id));\n\n // A Desktop claim makes every reference the connection holds to that session gone at once.\n const stopClaims = hub.computerUse?.subscribe?.(() => {\n for (const [connectionId, connection] of connections) {\n let revoked = false;\n for (const sessionId of connection.sessions) if (!connection.authorizeSession(sessionId)) revoked = true;\n if (!revoked) continue;\n connection.sessions.clear();\n void host.invalidatePrincipal((principal) => principal.connectionId === connectionId);\n }\n });\n\n host.serve(PoHubContract, (_input, principal, self) => {\n const connection = connectionOf(principal);\n const { mount } = connection;\n const visibleSessions = (): Record<string, HubSessionView> => {\n const views: Record<string, HubSessionView> = {};\n for (const session of hub.snapshot())\n if (reachable(connection, session.id)) views[session.id] = sessionView(session);\n // A dormant record of a removed workspace has no HTTP list to come from, so clients would never agree on it.\n const registered = new Set(hub.workspaces().map((workspace) => workspace.id));\n for (const record of dormantSessions())\n if (\n views[record.sessionId] === undefined &&\n registered.has(record.workspaceId) &&\n connection.authorizeSession(record.sessionId) &&\n permitsDormant(mount, record)\n )\n views[record.sessionId] = dormantView(record, hub.sessionPendingApprovalCount?.(record.sessionId));\n return views;\n };\n const visibleWorkspaces = (): Record<string, HubWorkspaceView> => {\n const views: Record<string, HubWorkspaceView> = {};\n for (const workspace of hub.workspaces())\n if (mount.scope === 'global' || workspace.id === mount.workspaceId)\n views[workspace.id] = {\n id: workspace.id,\n root: workspace.root,\n ...(workspace.kind === undefined ? {} : { kind: workspace.kind }),\n ...(workspace.name === undefined ? {} : { name: workspace.name }),\n ...(workspace.sandbox === undefined ? {} : { sandbox: workspace.sandbox }),\n ...(workspace.sandboxState === undefined ? {} : { sandboxState: workspace.sandboxState }),\n ...(workspace.sandboxReason === undefined ? {} : { sandboxReason: workspace.sandboxReason }),\n available: workspace.available !== false,\n };\n return views;\n };\n const sessions = self.state('sessions', chordSchema(Type.Record(Type.String(), SessionSummarySchema)), {\n init: visibleSessions,\n });\n const workspaces = self.state('workspaces', chordSchema(Type.Record(Type.String(), HubWorkspaceSchema)), {\n init: visibleWorkspaces,\n });\n const pending = self.state('pending', chordSchema(Type.Array(HubNoticeSchema)), [] as HubNotice[]);\n const visibleCompositions = (): Record<string, number> => {\n const revisions = hub.compositionRevisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}`;\n return Object.fromEntries(Object.entries(revisions).filter(([key]) => key === 'global' || key === own));\n };\n const compositions = self.state('compositions', chordSchema(HubCompositionsSchema), { init: visibleCompositions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n switch (event.kind) {\n case 'upsert':\n case 'removed':\n case 'dormant_changed':\n // Recomputed rather than patched, so an event before this listener started cannot leave a stale row.\n sessions.replace(ctx, visibleSessions(), { diff: true });\n return;\n case 'workspace_upsert':\n case 'workspace_removed':\n workspaces.replace(ctx, visibleWorkspaces(), { diff: true });\n return;\n case 'compositions':\n compositions.replace(ctx, visibleCompositions(), { diff: true });\n return;\n case 'frame':\n if (!reachable(connection, event.sessionId)) return;\n pending.change(ctx, (draft) => {\n draft.push({\n id: randomUUID(),\n sessionId: event.sessionId,\n frame: event.frame as Record<string, JsonValue>,\n });\n if (draft.length > MAX_PENDING_NOTICES) draft.splice(0, draft.length - MAX_PENDING_NOTICES);\n });\n return;\n case 'channel':\n return;\n }\n });\n return {\n variant: 'default',\n sessions,\n workspaces,\n pending,\n compositions,\n readHome: async (request) => {\n if (!hub.readHome) throw new Error('Home read is unavailable.');\n return hub.readHome(request, (id) => reachable(connection, id));\n },\n invoke: async (call: PoPluginCall, ctx) => {\n if (call.mount.scope === 'session' && !connection.authorizeSession(call.mount.sessionId))\n throw forbidden('This session belongs to its Desktop instance.');\n if (mount.scope !== 'global') {\n const permitted =\n call.mount.scope === 'session'\n ? permitsSession(hub, mount, call.mount.sessionId)\n : mount.scope === 'workspace' &&\n call.mount.scope === 'workspace' &&\n call.mount.workspaceId === mount.workspaceId;\n if (!permitted) throw forbidden('Plugin is outside this WebSocket scope.');\n }\n return (await hub.invokePlugin(call, 'client-to-server', {\n connectionId: connection.connectionId,\n signal: ctx.signal,\n })) as JsonValue;\n },\n ackNotice: async ({ id }, ctx) => {\n pending.change(ctx, (draft) => draft.filter((notice) => notice.id !== id));\n },\n };\n });\n\n host.serve(PoHubRevisionsContract, (_input, principal, self) => {\n const { mount } = connectionOf(principal);\n const visibleRevisions = (): Record<string, number> => {\n const revisions = hub.revisions?.() ?? {};\n if (mount.scope === 'global') return { ...revisions };\n const own = `workspace:${mount.workspaceId}:`;\n return Object.fromEntries(\n Object.entries(revisions).filter(([topic]) => topic.startsWith('global:') || topic.startsWith(own)),\n );\n };\n const revisions = self.state('revisions', chordSchema(HubRevisionsSchema), { init: visibleRevisions });\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind === 'revisions') revisions.replace(ctx, visibleRevisions(), { diff: true });\n });\n return { variant: 'default', revisions };\n });\n\n host.serve(\n PoThreadContract,\n ({ sessionId, threadId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const tail = self.resource('tail', {\n version: 1,\n open: () => threads.subscribe(sessionId, threadId),\n close: () => threads.unsubscribe(sessionId, threadId),\n });\n const frame = self.state('frame', chordSchema(PoThreadFrameSchema), {\n init: () => (tail.value?.at(-1) ?? null) as never,\n });\n self.on(\n 'frames',\n { subscribe: (listener) => threads.onFrame(listener) } as Subscribable<{\n sessionId: string;\n threadId: string;\n frame: Record<string, unknown>;\n }>,\n (event, ctx) => {\n // Each frame is a fresh wrapper around the child's state, so only an explicit diff sends ops, not the whole state.\n if (event.sessionId === sessionId && event.threadId === threadId)\n frame.replace(ctx, event.frame as never, { diff: true });\n },\n );\n return { variant: 'default', frame };\n },\n { linger: THREAD_LINGER_MS },\n );\n\n host.serve(PoChannelsContract, ({ sessionId }, principal, self) => {\n const connection = connectionOf(principal);\n if (!reachable(connection, sessionId)) throw forbidden(`No session ${sessionId}`);\n connection.sessions.add(sessionId);\n const visible = (frameType: string): boolean =>\n frameType !== 'computer_use_state' || connection.authorizeComputerUse(sessionId);\n const latest = self.state('latest', chordSchema(PoChannelsStateSchema), {\n init: () => {\n const payloads: Record<string, JsonValue> = {};\n for (const channelFrame of hub.channelFrames(sessionId))\n if (visible(channelFrame.type)) payloads[channelFrame.type] = channelFrame.payload as JsonValue;\n return payloads;\n },\n });\n // ponytail: a channel keeps only its latest payload; a package that needs every event must carry a sequence.\n self.on('hub', eventsOf(hub), (event, ctx) => {\n if (event.kind !== 'channel' || event.sessionId !== sessionId || !visible(event.frameType)) return;\n if (event.connectionId !== undefined && event.connectionId !== connection.connectionId) return;\n latest.change(ctx, (draft) => {\n draft[event.frameType] = event.payload as JsonValue;\n });\n });\n return {\n variant: 'default',\n latest,\n receive: async ({ type, payload }) => {\n if (!connection.authorizeSession(sessionId)) throw forbidden('This session belongs to Desktop.');\n hub.receiveChannel(\n sessionId,\n type,\n payload,\n connection.connectionId,\n connection.authorizeDesktop(),\n connection.authorizeComputerUse(sessionId),\n );\n },\n };\n });\n\n const clearSessionBindings = serveAgentSessions(host, {\n resolve(sessionId, principal): AgentSessionBinding | undefined {\n const connection = connectionOf(principal as Principal);\n const session = hub.session(sessionId);\n if (!session || !reachable(connection, session.id)) return undefined;\n connection.sessions.add(sessionId);\n const permitted = () => hub.session(session.id)?.host === session.host && connection.authorizeSession(session.id);\n // A mirror of a session another host runs forwards there; keyed by its host object, never by session id.\n const forward = session.host.agentSession;\n if (forward !== undefined)\n return { generation: generationOf(session.host), exited: session.host.runtime.exited, permitted, forward };\n return {\n generation: generationOf(session.host),\n exited: session.host.runtime.exited,\n permitted,\n options: {\n runtime: session.host.runtime,\n onPresentationFrame: (listen) =>\n session.host.onPresentationFrame((frame) => {\n if (permitted()) listen(frame);\n }),\n respondToExtensionUi: (frame) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return session.host.respondToExtensionUi(frame);\n },\n readThreadTranscript: (threadId, request, readContext) => {\n if (!permitted()) throw forbidden('This session belongs to Desktop.');\n return threads.readPage(session.id, threadId, request, readContext);\n },\n sessionId: session.id,\n sessionName: session.name,\n cwd: session.cwd,\n telemetry: options.telemetry,\n },\n };\n },\n });\n\n let closing: Promise<void> | undefined;\n return {\n accept(link, access = {}) {\n if (closing !== undefined) {\n link.close();\n return;\n }\n const connectionId = randomUUID();\n const authorizeSession = access.authorizeSession ?? ((id: string) => !hub.computerUse?.ownsSession?.(id));\n const authorizeDesktop = access.authorizeDesktop ?? (() => false);\n connections.set(connectionId, {\n mount: access.mount ?? { scope: 'global' },\n authorizeSession,\n authorizeDesktop,\n authorizeComputerUse: access.authorizeComputerUse ?? (() => authorizeDesktop()),\n sessions: new Set(),\n });\n link.onClose(() => {\n connections.delete(connectionId);\n hub.disconnectChannels(connectionId);\n });\n host.accept(reportingLargeFrames(link, options.onNotice, options.telemetry), {\n principal: { connectionId },\n kind: 'client',\n });\n },\n close() {\n closing ??= (async () => {\n stopClaims?.();\n threads.close();\n clearSessionBindings();\n await host.close();\n })();\n return closing;\n },\n };\n}\n"],"mappings":"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"}
@@ -1018,7 +1018,26 @@ async function serveHeadlessServer(options) {
1018
1018
  const attributes = {
1019
1019
  scope: mount.scope,
1020
1020
  "plugin.name": basePath,
1021
- "http.operation": request.method,
1021
+ "http.operation": `${[
1022
+ "GET",
1023
+ "HEAD",
1024
+ "POST",
1025
+ "PUT",
1026
+ "PATCH",
1027
+ "DELETE",
1028
+ "OPTIONS"
1029
+ ].includes(request.method ?? "") ? request.method : "other"} ${[
1030
+ "status",
1031
+ "current",
1032
+ "runs",
1033
+ "artifacts",
1034
+ "settings",
1035
+ "refresh",
1036
+ "events",
1037
+ "history",
1038
+ "sessions",
1039
+ "files"
1040
+ ].includes((pluginMatch[4] ?? "").split("/")[0]) ? (pluginMatch[4] ?? "").split("/")[0] : "other"}`,
1022
1041
  ...mount.scope === "workspace" ? { "workspace.id": mount.workspaceId } : {},
1023
1042
  ...mount.scope === "session" ? { "session.id": mount.sessionId } : {}
1024
1043
  };