@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.
- package/dist/apiContracts.d.mts +64 -0
- package/dist/apiContracts.d.mts.map +1 -1
- package/dist/headlessProtocol.cjs +2 -1
- package/dist/headlessProtocol.cjs.map +1 -1
- package/dist/headlessProtocol.mjs +2 -1
- package/dist/headlessProtocol.mjs.map +1 -1
- package/dist/headlessServer.cjs +20 -1
- package/dist/headlessServer.cjs.map +1 -1
- package/dist/headlessServer.mjs +20 -1
- package/dist/headlessServer.mjs.map +1 -1
- package/dist/machineApi.cjs +2 -46
- package/dist/machineApi.cjs.map +1 -1
- package/dist/machineApi.d.mts.map +1 -1
- package/dist/machineApi.mjs +2 -46
- package/dist/machineApi.mjs.map +1 -1
- package/dist/platform.cjs +2 -0
- package/dist/platform.d.mts +2 -2
- package/dist/platform.mjs +2 -2
- package/dist/providerAuth.cjs +8 -0
- package/dist/providerAuth.d.mts +4 -0
- package/dist/providerAuth.mjs +3 -0
- package/dist/src/pi/piSessionRuntime.cjs +13 -2
- package/dist/src/pi/piSessionRuntime.cjs.map +1 -1
- package/dist/src/pi/piSessionRuntime.d.mts +1 -1
- package/dist/src/pi/piSessionRuntime.mjs +13 -2
- package/dist/src/pi/piSessionRuntime.mjs.map +1 -1
- package/dist/src/schemas/platform.cjs +6 -0
- package/dist/src/schemas/platform.cjs.map +1 -1
- package/dist/src/schemas/platform.d.mts +68 -0
- package/dist/src/schemas/platform.d.mts.map +1 -1
- package/dist/src/schemas/platform.mjs +5 -1
- package/dist/src/schemas/platform.mjs.map +1 -1
- package/dist/src/server/conversationEvents.cjs +3 -2
- package/dist/src/server/conversationEvents.cjs.map +1 -1
- package/dist/src/server/conversationEvents.mjs +3 -2
- package/dist/src/server/conversationEvents.mjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.cjs +55 -5
- package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.d.mts.map +1 -1
- package/dist/src/server/directHarnessRuntime.mjs +55 -5
- package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
- package/dist/src/server/providerRoutes.cjs +58 -0
- package/dist/src/server/providerRoutes.cjs.map +1 -0
- package/dist/src/server/providerRoutes.d.mts +16 -0
- package/dist/src/server/providerRoutes.d.mts.map +1 -0
- package/dist/src/server/providerRoutes.mjs +58 -0
- package/dist/src/server/providerRoutes.mjs.map +1 -0
- package/dist/src/server/serverScope.cjs +1 -0
- package/dist/src/server/serverScope.cjs.map +1 -1
- package/dist/src/server/serverScope.d.mts.map +1 -1
- package/dist/src/server/serverScope.mjs +2 -1
- package/dist/src/server/serverScope.mjs.map +1 -1
- package/dist/src/services/edgeModelRuntime/index.cjs +363 -0
- package/dist/src/services/edgeModelRuntime/index.cjs.map +1 -0
- package/dist/src/services/edgeModelRuntime/index.d.mts +24 -0
- package/dist/src/services/edgeModelRuntime/index.d.mts.map +1 -0
- package/dist/src/services/edgeModelRuntime/index.mjs +360 -0
- package/dist/src/services/edgeModelRuntime/index.mjs.map +1 -0
- package/dist/src/services/edgeModelRuntime/type.d.mts +32 -0
- package/dist/src/services/edgeModelRuntime/type.d.mts.map +1 -0
- package/dist/src/services/providerAuth/index.cjs +1 -4
- package/dist/src/services/providerAuth/index.cjs.map +1 -1
- package/dist/src/services/providerAuth/index.mjs +0 -1
- package/dist/src/services/providerAuth/index.mjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs +3 -0
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs +3 -0
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
- package/dist/src/types/server/auth.d.mts +99 -0
- package/dist/src/types/server/auth.d.mts.map +1 -0
- package/dist/src/types/server/directHarnessRuntime.d.mts +10 -0
- package/dist/src/types/server/directHarnessRuntime.d.mts.map +1 -1
- package/package.json +9 -4
package/dist/apiContracts.d.mts
CHANGED
|
@@ -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":"
|
|
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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"}
|
package/dist/headlessServer.cjs
CHANGED
|
@@ -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":
|
|
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
|
};
|