@agimon-ai/po-core 0.0.0-alpha.0 → 0.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/chatgptAuth.cjs +9 -0
  2. package/dist/chatgptAuth.d.mts +2 -0
  3. package/dist/chatgptAuth.mjs +2 -0
  4. package/dist/headlessServer.cjs +58 -9
  5. package/dist/headlessServer.cjs.map +1 -1
  6. package/dist/headlessServer.d.mts.map +1 -1
  7. package/dist/headlessServer.mjs +58 -9
  8. package/dist/headlessServer.mjs.map +1 -1
  9. package/dist/headlessSessionHost.d.mts +1 -1
  10. package/dist/machineApi.cjs +7 -5
  11. package/dist/machineApi.cjs.map +1 -1
  12. package/dist/machineApi.d.mts.map +1 -1
  13. package/dist/machineApi.mjs +2 -0
  14. package/dist/machineApi.mjs.map +1 -1
  15. package/dist/native.cjs +12 -0
  16. package/dist/native.d.mts +9 -6
  17. package/dist/native.mjs +5 -2
  18. package/dist/piSettings.cjs +1 -0
  19. package/dist/piSettings.d.mts +2 -2
  20. package/dist/piSettings.mjs +2 -2
  21. package/dist/remoteRuntime.cjs +1 -1
  22. package/dist/remoteRuntime.cjs.map +1 -1
  23. package/dist/remoteRuntime.mjs +2 -2
  24. package/dist/remoteRuntime.mjs.map +1 -1
  25. package/dist/runtimeCordisHost.d.mts +1 -1
  26. package/dist/runtimePackages.cjs +19 -4
  27. package/dist/runtimePackages.cjs.map +1 -1
  28. package/dist/runtimePackages.d.mts.map +1 -1
  29. package/dist/runtimePackages.mjs +15 -1
  30. package/dist/runtimePackages.mjs.map +1 -1
  31. package/dist/runtimePiSettings.cjs +8 -1
  32. package/dist/runtimePiSettings.cjs.map +1 -1
  33. package/dist/runtimePiSettings.d.mts +3 -1
  34. package/dist/runtimePiSettings.d.mts.map +1 -1
  35. package/dist/runtimePiSettings.mjs +8 -2
  36. package/dist/runtimePiSettings.mjs.map +1 -1
  37. package/dist/src/schemas/headless.cjs.map +1 -1
  38. package/dist/src/schemas/headless.d.mts +39 -0
  39. package/dist/src/schemas/headless.d.mts.map +1 -1
  40. package/dist/src/schemas/headless.mjs.map +1 -1
  41. package/dist/src/server/directHarnessRuntime.cjs +8 -2
  42. package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
  43. package/dist/src/server/directHarnessRuntime.mjs +8 -2
  44. package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
  45. package/dist/src/server/sessionMcpRoutes.cjs +12 -0
  46. package/dist/src/server/sessionMcpRoutes.cjs.map +1 -1
  47. package/dist/src/server/sessionMcpRoutes.mjs +12 -1
  48. package/dist/src/server/sessionMcpRoutes.mjs.map +1 -1
  49. package/dist/src/services/chatgptAuth/index.cjs +287 -0
  50. package/dist/src/services/chatgptAuth/index.cjs.map +1 -0
  51. package/dist/src/services/chatgptAuth/index.d.mts +41 -0
  52. package/dist/src/services/chatgptAuth/index.d.mts.map +1 -0
  53. package/dist/src/services/chatgptAuth/index.mjs +279 -0
  54. package/dist/src/services/chatgptAuth/index.mjs.map +1 -0
  55. package/dist/src/services/chatgptImages/index.cjs +113 -0
  56. package/dist/src/services/chatgptImages/index.cjs.map +1 -0
  57. package/dist/src/services/chatgptImages/index.mjs +113 -0
  58. package/dist/src/services/chatgptImages/index.mjs.map +1 -0
  59. package/dist/src/services/chatgptWebSearch/index.cjs +123 -0
  60. package/dist/src/services/chatgptWebSearch/index.cjs.map +1 -0
  61. package/dist/src/services/chatgptWebSearch/index.mjs +123 -0
  62. package/dist/src/services/chatgptWebSearch/index.mjs.map +1 -0
  63. package/dist/src/services/piExtensionHost/index.cjs +5 -2
  64. package/dist/src/services/piExtensionHost/index.cjs.map +1 -1
  65. package/dist/src/services/piExtensionHost/index.mjs +5 -2
  66. package/dist/src/services/piExtensionHost/index.mjs.map +1 -1
  67. package/dist/src/services/providerAuth/index.cjs +4 -2
  68. package/dist/src/services/providerAuth/index.cjs.map +1 -1
  69. package/dist/src/services/providerAuth/index.mjs +2 -0
  70. package/dist/src/services/providerAuth/index.mjs.map +1 -1
  71. package/dist/src/services/webauthnPolicy/index.cjs +10 -0
  72. package/dist/src/services/webauthnPolicy/index.cjs.map +1 -1
  73. package/dist/src/services/webauthnPolicy/index.d.mts.map +1 -1
  74. package/dist/src/services/webauthnPolicy/index.mjs +10 -0
  75. package/dist/src/services/webauthnPolicy/index.mjs.map +1 -1
  76. package/dist/src/systems/child/adapters/headlessChildSessionService.cjs +1 -1
  77. package/dist/src/systems/child/adapters/headlessChildSessionService.mjs +1 -1
  78. package/dist/src/systems/main/adapters/headlessSessionHost.cjs +48 -12
  79. package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
  80. package/dist/src/systems/main/adapters/headlessSessionHost.d.mts.map +1 -1
  81. package/dist/src/systems/main/adapters/headlessSessionHost.mjs +40 -4
  82. package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
  83. package/dist/src/types/server/directHarnessRuntime.d.mts +1 -0
  84. package/dist/src/types/server/directHarnessRuntime.d.mts.map +1 -1
  85. package/dist/src/web/services/nativeApiTransport/index.cjs +38 -0
  86. package/dist/src/web/services/nativeApiTransport/index.cjs.map +1 -0
  87. package/dist/src/web/services/nativeApiTransport/index.d.mts +10 -0
  88. package/dist/src/web/services/nativeApiTransport/index.d.mts.map +1 -0
  89. package/dist/src/web/services/nativeApiTransport/index.mjs +36 -0
  90. package/dist/src/web/services/nativeApiTransport/index.mjs.map +1 -0
  91. package/dist/src/web/services/testing/slotProps.cjs +6 -0
  92. package/dist/src/web/services/testing/slotProps.cjs.map +1 -1
  93. package/dist/src/web/services/testing/slotProps.d.mts +2 -2
  94. package/dist/src/web/services/testing/slotProps.d.mts.map +1 -1
  95. package/dist/src/web/services/testing/slotProps.mjs +6 -0
  96. package/dist/src/web/services/testing/slotProps.mjs.map +1 -1
  97. package/dist/src/web/types/nativeTemplate.d.mts +8 -1
  98. package/dist/src/web/types/nativeTemplate.d.mts.map +1 -1
  99. package/dist/src/web/types/webPlugin.d.mts +115 -0
  100. package/dist/src/web/types/webPlugin.d.mts.map +1 -1
  101. package/dist/terminalPiChildSessionService.cjs +1 -1
  102. package/dist/terminalPiChildSessionService.mjs +1 -1
  103. package/dist/vendor/upm/LICENSE +21 -0
  104. package/dist/vendor/upm/_chunks/cli.mjs +112 -0
  105. package/dist/vendor/upm/_chunks/exec.mjs +1 -0
  106. package/dist/vendor/upm/_chunks/foreign-lock.mjs +1 -0
  107. package/dist/vendor/upm/_chunks/index-upgrade.mjs +1 -0
  108. package/dist/vendor/upm/_chunks/limit.mjs +1 -0
  109. package/dist/vendor/upm/_chunks/link-pool.mjs +1 -0
  110. package/dist/vendor/upm/_chunks/lock.d.mts +429 -0
  111. package/dist/vendor/upm/_chunks/main.mjs +8 -0
  112. package/dist/vendor/upm/_chunks/metadata.mjs +1 -0
  113. package/dist/vendor/upm/_chunks/metadata2.mjs +1 -0
  114. package/dist/vendor/upm/_chunks/mirror.mjs +1 -0
  115. package/dist/vendor/upm/_chunks/newer.mjs +1 -0
  116. package/dist/vendor/upm/_chunks/overrides.mjs +3 -0
  117. package/dist/vendor/upm/_chunks/overrides2.mjs +1 -0
  118. package/dist/vendor/upm/_chunks/progress.mjs +1 -0
  119. package/dist/vendor/upm/_chunks/registry-pool.mjs +1 -0
  120. package/dist/vendor/upm/_chunks/registry.mjs +1 -0
  121. package/dist/vendor/upm/_chunks/resolve.mjs +1 -0
  122. package/dist/vendor/upm/_chunks/shim.mjs +4 -0
  123. package/dist/vendor/upm/_chunks/store-backend.mjs +1 -0
  124. package/dist/vendor/upm/_chunks/tarball-deps.mjs +1 -0
  125. package/dist/vendor/upm/_chunks/trace.mjs +3 -0
  126. package/dist/vendor/upm/_chunks/tree-lock.mjs +1 -0
  127. package/dist/vendor/upm/_chunks/unpack-pool.mjs +1 -0
  128. package/dist/vendor/upm/_chunks/unpack.mjs +1 -0
  129. package/dist/vendor/upm/_chunks/verify.mjs +1 -0
  130. package/dist/vendor/upm/_chunks/vouch.mjs +1 -0
  131. package/dist/vendor/upm/_chunks/workspaces.mjs +1 -0
  132. package/dist/vendor/upm/index.d.mts +406 -0
  133. package/dist/vendor/upm/index.mjs +1 -0
  134. package/dist/vendor/upm/resolver.d.mts +2 -0
  135. package/dist/vendor/upm/resolver.mjs +1 -0
  136. package/dist/vendor/upm/upm.d.mts +1 -0
  137. package/dist/vendor/upm/upm.mjs +2 -0
  138. package/dist/vendor/upm/upx.d.mts +1 -0
  139. package/dist/vendor/upm/upx.mjs +2 -0
  140. package/dist/web.cjs +21 -17
  141. package/dist/web.d.mts +6 -5
  142. package/dist/web.mjs +4 -3
  143. package/package.json +13 -8
@@ -0,0 +1,9 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_index = require("./src/services/chatgptAuth/index.cjs");
3
+ exports.CHATGPT_AUTH_PROVIDER_ID = require_index.CHATGPT_AUTH_PROVIDER_ID;
4
+ exports.CHATGPT_AUTH_PROVIDER_NAME = require_index.CHATGPT_AUTH_PROVIDER_NAME;
5
+ exports.CHATGPT_SIGN_IN_HINT = require_index.CHATGPT_SIGN_IN_HINT;
6
+ exports.chatgptCredentials = require_index.chatgptCredentials;
7
+ exports.createChatgptAuthReader = require_index.createChatgptAuthReader;
8
+ exports.readBoundedJson = require_index.readBoundedJson;
9
+ exports.registerChatgptAuthProvider = require_index.registerChatgptAuthProvider;
@@ -0,0 +1,2 @@
1
+ import { CHATGPT_AUTH_PROVIDER_ID, CHATGPT_AUTH_PROVIDER_NAME, CHATGPT_SIGN_IN_HINT, ChatgptAuthSource, chatgptCredentials, createChatgptAuthReader, readBoundedJson, registerChatgptAuthProvider } from "./src/services/chatgptAuth/index.mjs";
2
+ export { CHATGPT_AUTH_PROVIDER_ID, CHATGPT_AUTH_PROVIDER_NAME, CHATGPT_SIGN_IN_HINT, ChatgptAuthSource, chatgptCredentials, createChatgptAuthReader, readBoundedJson, registerChatgptAuthProvider };
@@ -0,0 +1,2 @@
1
+ import { CHATGPT_AUTH_PROVIDER_ID, CHATGPT_AUTH_PROVIDER_NAME, CHATGPT_SIGN_IN_HINT, chatgptCredentials, createChatgptAuthReader, readBoundedJson, registerChatgptAuthProvider } from "./src/services/chatgptAuth/index.mjs";
2
+ export { CHATGPT_AUTH_PROVIDER_ID, CHATGPT_AUTH_PROVIDER_NAME, CHATGPT_SIGN_IN_HINT, chatgptCredentials, createChatgptAuthReader, readBoundedJson, registerChatgptAuthProvider };
@@ -21,8 +21,8 @@ let node_os = require("node:os");
21
21
  node_os = require_runtime.__toESM(node_os, 1);
22
22
  let node_path = require("node:path");
23
23
  node_path = require_runtime.__toESM(node_path, 1);
24
- let _earendil_works_chord_context = require("@earendil-works/chord/context");
25
24
  let node_http = require("node:http");
25
+ let _earendil_works_chord_context = require("@earendil-works/chord/context");
26
26
  let node_stream = require("node:stream");
27
27
  let node_stream_promises = require("node:stream/promises");
28
28
  let ws = require("ws");
@@ -137,7 +137,7 @@ function parseTranscriptRequest(url) {
137
137
  }
138
138
  return request;
139
139
  }
140
- async function sessionFile(session, requestedPath) {
140
+ async function sessionFile(session, requestedPath, range, expectedVersion) {
141
141
  if (!requestedPath || requestedPath.includes("\0")) return Response.json({ error: "Invalid session file path." }, { status: 400 });
142
142
  let root;
143
143
  let filePath;
@@ -159,14 +159,63 @@ async function sessionFile(session, requestedPath) {
159
159
  const stat = await handle.stat();
160
160
  if (!stat.isFile()) return Response.json({ error: "Session file not found." }, { status: 404 });
161
161
  if (stat.size > 26214400) return Response.json({ error: "Session file is too large." }, { status: 413 });
162
- const bytes = await handle.readFile();
163
- if (bytes.byteLength > 26214400) return Response.json({ error: "Session file is too large." }, { status: 413 });
164
- return new Response(bytes, { headers: {
162
+ const version = `"${stat.dev}-${stat.ino}-${stat.size}-${stat.mtimeMs}-${stat.ctimeMs}"`;
163
+ const headers = new Headers({
165
164
  "content-type": require_sessionFiles.SESSION_FILE_CONTENT_TYPES[node_path.default.extname(filePath).toLowerCase()] ?? "application/octet-stream",
166
- "content-length": String(bytes.byteLength),
167
165
  "cache-control": "no-store",
168
- "x-content-type-options": "nosniff"
169
- } });
166
+ "x-content-type-options": "nosniff",
167
+ "accept-ranges": "bytes",
168
+ etag: version
169
+ });
170
+ if (expectedVersion !== void 0 && expectedVersion !== version) return new Response(null, {
171
+ status: 412,
172
+ headers
173
+ });
174
+ let start = 0;
175
+ let end = stat.size - 1;
176
+ if (range !== void 0) {
177
+ const match = /^bytes=(\d*)-(\d*)$/u.exec(range);
178
+ if (!match || !match[1] && !match[2] || [match[1], match[2]].some((value) => value !== "" && !Number.isSafeInteger(Number(value))) || stat.size === 0) {
179
+ headers.set("content-range", `bytes */${stat.size}`);
180
+ return new Response(null, {
181
+ status: 416,
182
+ headers
183
+ });
184
+ }
185
+ if (!match[1]) start = Math.max(0, stat.size - Number(match[2]));
186
+ else {
187
+ start = Number(match[1]);
188
+ if (match[2]) end = Math.min(Number(match[2]), end);
189
+ }
190
+ if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || start > end) {
191
+ headers.set("content-range", `bytes */${stat.size}`);
192
+ return new Response(null, {
193
+ status: 416,
194
+ headers
195
+ });
196
+ }
197
+ headers.set("content-range", `bytes ${start}-${end}/${stat.size}`);
198
+ }
199
+ const bytes = new Uint8Array(Math.max(0, end - start + 1));
200
+ let read = 0;
201
+ while (read < bytes.length) {
202
+ const part = await handle.read(bytes, read, bytes.length - read, start + read);
203
+ if (part.bytesRead === 0) return new Response(null, {
204
+ status: 412,
205
+ headers
206
+ });
207
+ read += part.bytesRead;
208
+ }
209
+ const after = await handle.stat();
210
+ if (after.size !== stat.size || after.mtimeMs !== stat.mtimeMs || after.ctimeMs !== stat.ctimeMs) return new Response(null, {
211
+ status: 412,
212
+ headers
213
+ });
214
+ headers.set("content-length", String(bytes.length));
215
+ return new Response(bytes, {
216
+ status: range === void 0 ? 200 : 206,
217
+ headers
218
+ });
170
219
  } finally {
171
220
  await handle.close();
172
221
  }
@@ -792,7 +841,7 @@ async function serveHeadlessServer(options) {
792
841
  return;
793
842
  }
794
843
  if (suffix === "/file" && request.method === "GET") {
795
- await writeResponse(response, await sessionFile(session, url.searchParams.get("path")));
844
+ await writeResponse(response, await sessionFile(session, url.searchParams.get("path"), request.headers.range, request.headers["if-match"]));
796
845
  return;
797
846
  }
798
847
  if (suffix === "/attachments" && request.method === "POST") {
@@ -1 +1 @@
1
- {"version":3,"file":"headlessServer.cjs","names":["fs","path","SESSION_FILE_CONTENT_TYPES","os","Readable","pipeline","WebSocketServer","createHeadlessProtocol","createSessionMcpRoutes","createSessionMcpActivityStore","createSessionMcpConversationStore","createSessionMcpRegistrationStore","createServer","harnessErrorMessage","isDoomSessionSetupError","isPublicSessionMcpRoute","isSessionMcpHostRoute","createContextApi","readContextDetail","DOOM_API_CALLER_HEADERS","DOOM_API_CALLER_LOCALITY_HEADER","DOOM_API_CALLER_STEP_UP_HEADER","BACKGROUND_CONTEXT","writeSessionAttachment","parseDoomSocketPath"],"sources":["../src/server/headlessServer.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport type { Context } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { WebSocket } from 'ws';\nimport { WebSocketServer } from 'ws';\n\nimport { API_BASE_PATH as CONTEXT_API_BASE_PATH } from '../constants/contextApi';\nimport {\n MAX_SESSION_FILE_BYTES,\n SESSION_FILE_CONTENT_TYPES,\n SESSION_FILE_DEFAULT_CONTENT_TYPE,\n} from '../constants/sessionFiles';\nimport {\n DOOM_API_CALLER_HEADERS,\n DOOM_API_CALLER_LOCALITY_HEADER,\n DOOM_API_CALLER_STEP_UP_HEADER,\n parseDoomSocketPath,\n type DoomApiMount,\n} from '../exports/packageApi';\nimport type { TranscriptPage, TranscriptPageRequest } from '../exports/sessionProtocol';\nimport { isDoomSessionSetupError } from '../schemas/headless';\nimport type { DoomHubSessionReservations } from '../schemas/hubChannel';\nimport { readContextDetail } from '../services/contextDetailStore';\nimport type { OpenSessionRecord } from '../services/openSessionRegistry';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { writeSessionAttachment } from '../services/sessionAttachments';\nimport { createSessionMcpActivityStore } from '../services/sessionMcpActivity';\nimport { createSessionMcpConversationStore } from '../services/sessionMcpConversations';\nimport { createSessionMcpRegistrationStore } from '../services/sessionMcpRegistrationStore';\nimport type { SavedSession } from '../services/sqliteSessionHistory';\nimport { createContextApi } from './contextApi';\nimport { harnessErrorMessage } from './harnessErrorMessage';\nimport type { HeadlessHub, HeadlessHubEvent, HeadlessHubSession, HeadlessWorkspaceAdmission } from './headlessHub';\nimport { createHeadlessProtocol } from './headlessProtocol';\nimport { createSessionMcpRoutes, isPublicSessionMcpRoute, isSessionMcpHostRoute } from './sessionMcpRoutes';\n\n/**\n * The canonical public shape of a package API request, as dispatch reads it.\n *\n * Groups: workspace id, session id, plugin base path, and the remainder handed\n * to the package. `settings` is the host's own API and sits beside `plugins`\n * rather than under it.\n *\n * Exported so the browser's URL construction can be pinned against it. The two\n * are written independently, in halves of this package that may not import each\n * other, and a disagreement between them is not a 404 from the route: the\n * service worker answers an unrecognised path out of the signed bundle cache,\n * so the symptom appears nowhere near the cause.\n */\nexport const DOOM_PACKAGE_API_PATH_PATTERN =\n /^\\/api(?:\\/workspaces\\/([^/]+)(?:\\/sessions\\/([^/]+))?)?\\/(?:plugins\\/([^/]+)|settings)(?:\\/(.*))?$/u;\n\nconst HEALTH_ROLE = 'hub';\nconst PROTOCOL_VERSION = 1;\nconst MAX_BODY_BYTES = 8 * 1024 * 1024;\nconst DIRECTORY_SUGGESTION_LIMIT = 12;\nconst DIRECTORY_CHILDREN_LIMIT = 500;\nconst HOME_PREFIX = '~';\nconst WORKSPACE_NAME_MAX_LENGTH = 80;\nconst WORKSPACE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9 ._-]*$/u;\n/** Restart closes the session host, which aborts a running turn, so it waits for idle. */\nexport const RESTART_WHILE_RUNNING_ERROR =\n 'The session is running a turn. Stop it or wait for it to finish before reloading extensions.';\n\nexport interface HeadlessServerOptions {\n headlessHub: HeadlessHub;\n port: number;\n host?: string;\n /** Requests other than health require this bearer token when set. */\n token?: string;\n telemetry?: ServerTelemetry;\n onNotice?: (message: string) => void;\n compositions?: () => unknown;\n requestAsset?: (request: Request) => Promise<Response | undefined>;\n sessionHistory?: (session: HeadlessHubSession) => Promise<SavedSession[]>;\n workspaceHistory?: (workspaceId: string) => Promise<SavedSession[]>;\n resumeWorkspaceSession?: (workspaceId: string, targetSessionId: string) => Promise<string>;\n readDormantTranscript?: (\n record: OpenSessionRecord,\n request: TranscriptPageRequest,\n context: Context,\n ) => Promise<TranscriptPage>;\n restartSession?: (session: HeadlessHubSession) => Promise<void>;\n resumeSession?: (session: HeadlessHubSession, targetSessionId: string) => Promise<string>;\n /** Recorded sessions this server has not reopened, surfaced so a client can ask for one. */\n dormantSessions?: () => readonly OpenSessionRecord[];\n removeDormantSession?: (record: OpenSessionRecord) => void | Promise<void>;\n reviveSession?: (record: OpenSessionRecord) => Promise<void>;\n /** Trusted HTTPS origin advertised for public session MCP and OAuth endpoints. */\n sessionMcpPublicOrigin?: () => string | undefined;\n /** Durable state directory for verified Session MCP clients. */\n sessionMcpStateDir?: string;\n /** Monotonic exposure revision, including disable/re-enable cycles. */\n sessionMcpPublicOriginRevision?: () => number;\n isSessionPersisted?: (sessionId: string, cwd: string) => boolean;\n}\n\nexport interface HeadlessServer {\n readonly url: string;\n readonly sessionReservations: DoomHubSessionReservations;\n close(): Promise<void>;\n}\n\ntype ProtocolHandler = NonNullable<ReturnType<Awaited<ReturnType<typeof createHeadlessProtocol>>['accept']>>;\ntype Client = { socket: WebSocket; handler: ProtocolHandler };\n\nfunction sessionView(session: HeadlessHubSession): Record<string, unknown> {\n return {\n id: session.id,\n workspaceId: session.workspaceId,\n webComposition: session.webComposition,\n 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 ...(session.git === undefined ? {} : { git: { ...session.git } }),\n ...(session.profile === undefined ? {} : { profile: { ...session.profile } }),\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n ...(session.pendingSetups === undefined ? {} : { pendingSetups: session.pendingSetups }),\n ...(session.activity === undefined ? {} : { activity: { ...session.activity } }),\n };\n}\n\n/** The dormant counterpart of `sessionView`; same shape, no runtime behind it. */\nfunction dormantView(record: OpenSessionRecord): Record<string, unknown> {\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: 'detached',\n pendingMessageCount: 0,\n everPrompted: false,\n awaitingInput: false,\n dormant: true,\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n };\n}\n\nfunction json(response: ServerResponse, status: number, value: unknown): void {\n const body = JSON.stringify(value);\n response.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(body),\n });\n response.end(body);\n}\n\nfunction authorized(request: IncomingMessage, token: string | undefined): boolean {\n if (token === undefined) return true;\n const authorization = request.headers.authorization;\n if (authorization?.startsWith('Bearer ') && authorization.slice('Bearer '.length) === token) return true;\n const header = request.headers['x-po-token'];\n if (typeof header === 'string' && header === token) return true;\n try {\n return new URL(request.url ?? '/', 'http://po.local').searchParams.get('token') === token;\n } catch {\n return false;\n }\n}\n\nfunction requestPath(request: IncomingMessage): URL {\n return new URL(request.url ?? '/', 'http://po.local');\n}\n\nfunction parseTranscriptRequest(url: URL): TranscriptPageRequest {\n const request: TranscriptPageRequest = {};\n const cursor = url.searchParams.get('cursor');\n const direction = url.searchParams.get('direction');\n const limit = url.searchParams.get('limit');\n if (cursor !== null) request.cursor = cursor;\n if (direction !== null) {\n if (direction !== 'older' && direction !== 'newer') throw new Error('Invalid transcript direction');\n request.direction = direction;\n }\n if (limit !== null) {\n if (!/^\\d+$/u.test(limit)) throw new Error('Invalid transcript page limit');\n const parsed = Number(limit);\n if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > 100) throw new Error('Invalid transcript page limit');\n request.limit = parsed;\n }\n return request;\n}\n\nasync function sessionFile(session: HeadlessHubSession, requestedPath: string | null): Promise<Response> {\n if (!requestedPath || requestedPath.includes('\\0'))\n return Response.json({ error: 'Invalid session file path.' }, { status: 400 });\n let root: string;\n let filePath: string;\n try {\n root = await fs.promises.realpath(session.cwd);\n filePath = await fs.promises.realpath(path.resolve(root, requestedPath));\n } catch {\n return Response.json({ error: 'Session file not found.' }, { status: 404 });\n }\n const contained = path.relative(root, filePath);\n if (contained === '..' || contained.startsWith(`..${path.sep}`) || path.isAbsolute(contained))\n return Response.json({ error: 'Session file is outside the working directory.' }, { status: 403 });\n let handle: fs.promises.FileHandle;\n try {\n handle = await fs.promises.open(filePath, 'r');\n } catch {\n return Response.json({ error: 'Session file not found.' }, { status: 404 });\n }\n try {\n const stat = await handle.stat();\n if (!stat.isFile()) return Response.json({ error: 'Session file not found.' }, { status: 404 });\n if (stat.size > MAX_SESSION_FILE_BYTES)\n return Response.json({ error: 'Session file is too large.' }, { status: 413 });\n const bytes = await handle.readFile();\n if (bytes.byteLength > MAX_SESSION_FILE_BYTES)\n return Response.json({ error: 'Session file is too large.' }, { status: 413 });\n return new Response(bytes, {\n headers: {\n 'content-type':\n SESSION_FILE_CONTENT_TYPES[path.extname(filePath).toLowerCase()] ?? SESSION_FILE_DEFAULT_CONTENT_TYPE,\n 'content-length': String(bytes.byteLength),\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n },\n });\n } finally {\n await handle.close();\n }\n}\n\n/** Expands a leading `~` the way a shell would, so typed paths match what the user sees in a terminal. */\nfunction expandHome(value: string): string {\n if (value === HOME_PREFIX) return os.homedir();\n return value.startsWith(`${HOME_PREFIX}${path.sep}`) ? path.join(os.homedir(), value.slice(2)) : value;\n}\n\n/**\n * Validates an add-workspace request. A name alone asks for a new default folder,\n * so it must be safe to use as one folder name.\n */\nfunction parseWorkspaceAdmission(body: unknown): HeadlessWorkspaceAdmission | { error: string } {\n if (typeof body !== 'object' || body === null) return { error: 'A workspace root or name is required.' };\n const record = body as Record<string, unknown>;\n if (record.root !== undefined && typeof record.root !== 'string')\n return { error: 'The workspace root must be text.' };\n if (record.name !== undefined && typeof record.name !== 'string')\n return { error: 'The workspace name must be text.' };\n const root =\n typeof record.root === 'string' && record.root.trim() !== '' ? expandHome(record.root.trim()) : undefined;\n const name = typeof record.name === 'string' && record.name.trim() !== '' ? record.name.trim() : undefined;\n if (root === undefined && name === undefined) return { error: 'A workspace root or name is required.' };\n if (\n name !== undefined &&\n (name.length > WORKSPACE_NAME_MAX_LENGTH || !WORKSPACE_NAME_PATTERN.test(name) || name.includes('..'))\n )\n return {\n error: `Workspace names use letters, numbers, spaces, dots, dashes, or underscores (up to ${String(WORKSPACE_NAME_MAX_LENGTH)} characters).`,\n };\n return { ...(root === undefined ? {} : { root }), ...(name === undefined ? {} : { name }) };\n}\n\nasync function directorySuggestions(query: string, sessions: readonly HeadlessHubSession[]): Promise<string[]> {\n const typed = expandHome(query.trim());\n if (typed === '') return [];\n const matches = (value: string): boolean => value.toLowerCase().includes(typed.toLowerCase());\n const known = [...new Set([process.cwd(), ...sessions.map((session) => session.cwd)])].filter(matches);\n const candidates = path.isAbsolute(typed)\n ? [typed]\n : typed.includes(path.sep)\n ? [path.resolve(process.cwd(), typed)]\n : [path.join(path.dirname(process.cwd()), typed), path.join(process.cwd(), typed)];\n const completed: string[] = [];\n for (const candidate of candidates) {\n const drilling = typed.endsWith(path.sep);\n const parent = drilling ? candidate : path.dirname(candidate);\n const partial = drilling ? '' : path.basename(candidate).toLowerCase();\n try {\n const entries = await fs.promises.readdir(parent, { withFileTypes: true });\n completed.push(\n ...entries\n .filter((entry) => entry.isDirectory() && entry.name.toLowerCase().includes(partial))\n .map((entry) => path.join(parent, entry.name)),\n );\n } catch {\n // A missing or unreadable parent simply has no completions.\n }\n }\n return [...new Set([...known, ...completed.sort((left, right) => left.localeCompare(right))])].slice(\n 0,\n DIRECTORY_SUGGESTION_LIMIT,\n );\n}\n\n/**\n * Lists the visible child directories of one folder for the workspace folder browser.\n * Resolves undefined for a relative, missing, or unreadable path.\n */\nasync function directoryChildren(\n requested: string | null,\n): Promise<{ path: string; parent?: string; directories: string[] } | undefined> {\n const directory = requested === null || requested.trim() === '' ? os.homedir() : expandHome(requested.trim());\n if (!path.isAbsolute(directory)) return undefined;\n const resolved = path.resolve(directory);\n let entries: fs.Dirent[];\n try {\n entries = await fs.promises.readdir(resolved, { withFileTypes: true });\n } catch {\n return undefined;\n }\n const directories = entries\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))\n .map((entry) => path.join(resolved, entry.name))\n .sort((left, right) => left.localeCompare(right))\n .slice(0, DIRECTORY_CHILDREN_LIMIT);\n const parent = path.dirname(resolved);\n return { path: resolved, ...(parent === resolved ? {} : { parent }), directories };\n}\n\nclass RequestBodyTooLargeError extends Error {\n constructor() {\n super('Request body is too large.');\n }\n}\n\nasync function readBody(request: IncomingMessage): Promise<Uint8Array> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of request) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n size += buffer.byteLength;\n if (size > MAX_BODY_BYTES) throw new RequestBodyTooLargeError();\n chunks.push(buffer);\n }\n return Buffer.concat(chunks);\n}\n\nfunction parseJson(body: Uint8Array): unknown {\n if (body.byteLength === 0) return {};\n return JSON.parse(Buffer.from(body).toString('utf8')) as unknown;\n}\n\nfunction webRequest(request: IncomingMessage, url: URL, signal?: AbortSignal): Request {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n }\n return new Request(url, {\n method: request.method,\n headers,\n signal,\n ...(request.method === 'GET' || request.method === 'HEAD'\n ? {}\n : {\n body: Readable.toWeb(request) as never,\n duplex: 'half' as const,\n }),\n });\n}\n\nasync function writeResponse(response: ServerResponse, result: Response): Promise<void> {\n response.writeHead(result.status, Object.fromEntries(result.headers.entries()));\n if (result.body === null) {\n response.end();\n return;\n }\n await pipeline(Readable.fromWeb(result.body as import('node:stream/web').ReadableStream), response);\n}\n\nfunction eventFrame(event: HeadlessHubEvent): Record<string, unknown> {\n switch (event.kind) {\n case 'upsert':\n return { type: 'session_upsert', session: sessionView(event.session) };\n case 'removed':\n return { type: 'session_removed', sessionId: event.sessionId };\n case 'workspace_upsert':\n return { type: 'workspace_upsert', workspace: event.workspace };\n case 'workspace_removed':\n return { type: 'workspace_removed', workspaceId: event.workspaceId };\n case 'channel':\n return {\n type: 'channel_frame',\n frameType: event.frameType,\n sessionId: event.sessionId,\n payload: event.payload,\n ...(event.connectionId === undefined ? {} : { connectionId: event.connectionId }),\n };\n case 'frame':\n return { type: 'session_frame', sessionId: event.sessionId, frame: event.frame };\n }\n}\n\nfunction writeSse(response: ServerResponse, event: string, value: unknown): void {\n response.write(`event: ${event}\\ndata: ${JSON.stringify(value)}\\n\\n`);\n}\n\n/**\n * Client-neutral HTTP and WebSocket boundary for the process-local headless hub.\n * It deliberately delegates every session operation to HeadlessHub, so transport\n * clients cannot create a second session backend or bypass its lifecycle.\n */\nexport async function serveHeadlessServer(options: HeadlessServerOptions): Promise<HeadlessServer> {\n const clients = new Set<Client>();\n const scopedProtocols = new Set<Awaited<ReturnType<typeof createHeadlessProtocol>>>();\n const sse = new Map<ServerResponse, (sessionId: string | undefined) => boolean>();\n const desktopAuthorized = (request: IncomingMessage): boolean => {\n const proof = request.headers['x-po-desktop'];\n return (\n typeof proof === 'string' &&\n options.headlessHub.computerUse?.authorize?.(new Headers({ 'x-po-desktop': proof })) === true\n );\n };\n const computerUseAuthorized = (sessionId: string, request: IncomingMessage): boolean => {\n if (desktopAuthorized(request)) return true;\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizeSession?.(sessionId, headers) === true;\n };\n const activationAuthorized = (request: IncomingMessage): boolean => {\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizeActivation?.(headers) === true;\n };\n const pendingAuthorized = (sessionId: string, request: IncomingMessage): boolean => {\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizePending?.(sessionId, headers) === true;\n };\n const recordingAuthorized = (sessionId: string, request: IncomingMessage): boolean => {\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizeRecording?.(sessionId, headers) === true;\n };\n let closed = false;\n const webSockets = new WebSocketServer({ noServer: true });\n /**\n * A recorded session is dormant exactly while the hub has no session for its\n * id, so reviving one needs no bookkeeping beyond the hub itself.\n */\n const dormant = (): readonly OpenSessionRecord[] =>\n (options.dormantSessions?.() ?? []).filter((record) => options.headlessHub.session(record.sessionId) === undefined);\n const protocol = await createHeadlessProtocol({\n hub: options.headlessHub,\n telemetry: options.telemetry,\n onNotice: options.onNotice,\n dormantSessions: dormant,\n });\n const sessionMcpStateDir = options.sessionMcpStateDir ?? fs.mkdtempSync(path.join(os.tmpdir(), 'po-session-mcp-'));\n const sessionMcp = createSessionMcpRoutes({\n headlessHub: options.headlessHub,\n publicOrigin: options.sessionMcpPublicOrigin ?? (() => undefined),\n publicOriginRevision: options.sessionMcpPublicOriginRevision,\n onNotice: options.onNotice,\n isSessionPersisted: options.isSessionPersisted,\n activityStore: createSessionMcpActivityStore(sessionMcpStateDir),\n conversationStore: createSessionMcpConversationStore(sessionMcpStateDir),\n registrationStore: createSessionMcpRegistrationStore({ stateDir: sessionMcpStateDir, onNotice: options.onNotice }),\n });\n /** Sessions being restarted, keyed by id, settled once the reopen succeeds or fails. */\n const restarting = new Map<string, Promise<void>>();\n const server = createServer((request, response) => {\n void handleRequest(request, response).catch((error: unknown) => {\n if (response.headersSent) {\n response.destroy();\n return;\n }\n options.onNotice?.(`Headless request failed: ${harnessErrorMessage(error)}`);\n // A setup problem the user must fix carries its own instructions; anything else stays generic.\n if (isDoomSessionSetupError(error)) json(response, 422, { error: error.message });\n else json(response, 500, { error: 'Internal server error.' });\n });\n });\n\n const unsubscribe = options.headlessHub.onEvent((event) => {\n const frame = eventFrame(event);\n const sessionId = event.kind === 'upsert' ? event.session.id : 'sessionId' in event ? event.sessionId : undefined;\n for (const [response, native] of sse) {\n if (\n (sessionId !== undefined && options.headlessHub.computerUse?.ownsSession?.(sessionId)) ||\n frame.type === 'computer_use_state'\n ) {\n if (!native(sessionId)) continue;\n }\n writeSse(response, String(frame.type), frame);\n }\n });\n\n async function handleRequest(request: IncomingMessage, response: ServerResponse): Promise<void> {\n const url = requestPath(request);\n if (url.pathname === '/api/health' && request.method === 'GET') {\n json(response, 200, {\n ok: true,\n role: HEALTH_ROLE,\n protocol: PROTOCOL_VERSION,\n sessions: options.headlessHub.snapshot().length,\n });\n return;\n }\n const scopedSession = /^\\/api\\/workspaces\\/[^/]+\\/sessions\\/([^/]+)(?:\\/|$)/u.exec(url.pathname)?.[1];\n if (\n scopedSession &&\n options.headlessHub.computerUse?.ownsSession?.(decodeURIComponent(scopedSession)) &&\n !computerUseAuthorized(decodeURIComponent(scopedSession), request) &&\n !(\n request.method === 'GET' &&\n url.pathname.endsWith('/plugins/computer-use/artifact') &&\n recordingAuthorized(decodeURIComponent(scopedSession), request)\n ) &&\n !(\n request.method === 'POST' &&\n url.pathname.endsWith('/plugins/computer-use/activate') &&\n activationAuthorized(request)\n ) &&\n !(\n url.pathname.endsWith('/plugins/computer-use/activate') &&\n ((request.method === 'GET' &&\n (pendingAuthorized(decodeURIComponent(scopedSession), request) ||\n recordingAuthorized(decodeURIComponent(scopedSession), request))) ||\n (request.method === 'DELETE' && pendingAuthorized(decodeURIComponent(scopedSession), request)))\n )\n ) {\n json(response, 404, { error: 'This session belongs to its Desktop instance.' });\n return;\n }\n if (isPublicSessionMcpRoute(request.method ?? 'GET', url.pathname)) {\n const sessionMcpAbort = new AbortController();\n const abortSessionMcp = (): void => {\n if (!response.writableEnded) sessionMcpAbort.abort();\n };\n response.once('close', abortSessionMcp);\n const publicSessionMcp = await sessionMcp.handlePublic(webRequest(request, url, sessionMcpAbort.signal));\n if (publicSessionMcp !== undefined) {\n try {\n await writeResponse(response, publicSessionMcp);\n } finally {\n response.off('close', abortSessionMcp);\n }\n return;\n }\n response.off('close', abortSessionMcp);\n }\n if (!authorized(request, options.token)) {\n json(response, 401, { error: 'Unauthorized.' });\n return;\n }\n // A restart closes the session before reopening it under the same id. Any session-scoped\n // request that lands in that gap, such as a plugin's poll, waits for the reopened session.\n const reopening = scopedSession === undefined ? undefined : restarting.get(decodeURIComponent(scopedSession));\n if (reopening !== undefined && options.headlessHub.session(decodeURIComponent(scopedSession!)) === undefined)\n await reopening;\n if (isSessionMcpHostRoute(url.pathname)) {\n const hostSessionMcp = await sessionMcp.handleHost(webRequest(request, url));\n if (hostSessionMcp !== undefined) {\n await writeResponse(response, hostSessionMcp);\n return;\n }\n }\n if (url.pathname === '/api/remote' || url.pathname.startsWith('/api/remote/')) {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value !== undefined && name !== 'authorization' && name !== 'x-po-token')\n headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n }\n const result = await options.headlessHub.requestApi(\n { scope: 'global' },\n 'remote',\n new Request(`http://po.local${url.pathname.slice('/api/remote'.length)}${url.search}`, {\n method: request.method,\n headers,\n ...(request.method === 'GET' || request.method === 'HEAD'\n ? {}\n : { body: Buffer.from(await readBody(request)) }),\n }),\n );\n await writeResponse(response, result);\n return;\n }\n if (url.pathname === '/api/telemetry/browser' && request.method === 'POST') {\n const body = JSON.parse(new TextDecoder().decode(await readBody(request))) as { v?: unknown; events?: unknown };\n if (body.v !== 1 || !Array.isArray(body.events) || body.events.length > 10) {\n json(response, 400, { error: 'Invalid browser telemetry batch.' });\n return;\n }\n for (const event of body.events) {\n if (\n !event ||\n typeof event !== 'object' ||\n typeof event.name !== 'string' ||\n !/^web\\.browser\\.[a-z_]{1,40}$/u.test(event.name)\n )\n continue;\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent(event.name, {\n ...(typeof event.duration_ms === 'number' && Number.isFinite(event.duration_ms) && event.duration_ms >= 0\n ? { duration_ms: event.duration_ms }\n : {}),\n ...(typeof event.count === 'number' && Number.isFinite(event.count) && event.count >= 0\n ? { count: event.count }\n : {}),\n }),\n );\n }\n json(response, 200, { ok: true });\n return;\n }\n if (url.pathname === '/api/compositions' && request.method === 'GET') {\n json(response, 200, options.compositions?.() ?? { workspaces: [] });\n return;\n }\n if (\n (url.pathname.startsWith('/api/web-plugins/') ||\n url.pathname === '/bundle-manifest.json' ||\n url.pathname.startsWith('/bundle-assets/')) &&\n options.requestAsset\n ) {\n const result = await options.requestAsset(new Request(url, { method: request.method }));\n if (result) {\n await writeResponse(response, result);\n return;\n }\n }\n if (url.pathname === '/api/directories/children' && request.method === 'GET') {\n const listing = await directoryChildren(url.searchParams.get('path'));\n if (listing === undefined) json(response, 404, { error: 'That folder cannot be read.' });\n else json(response, 200, listing);\n return;\n }\n if (url.pathname === '/api/directories' && request.method === 'GET') {\n json(response, 200, {\n directories: await directorySuggestions(url.searchParams.get('q') ?? '', options.headlessHub.snapshot()),\n });\n return;\n }\n // Verified browser bundles can remain active across a server upgrade. Keep\n // their former create route working while they refresh to workspace routes.\n if (url.pathname === '/api/sessions' && request.method === 'POST') {\n const body = parseJson(await readBody(request));\n if (\n !body ||\n typeof body !== 'object' ||\n !('cwd' in body) ||\n typeof body.cwd !== 'string' ||\n !body.cwd.trim() ||\n ('name' in body && typeof body.name !== 'string')\n ) {\n json(response, 400, { error: 'A session needs a working directory and an optional name.' });\n return;\n }\n const created = await options.headlessHub.sessionService.create({\n cwd: body.cwd,\n name: 'name' in body ? String(body.name) : path.basename(body.cwd),\n });\n json(response, 201, { sessionId: created.sessionId });\n return;\n }\n const workspaceSessions = /^\\/api\\/workspaces\\/([^/]+)\\/sessions$/u.exec(url.pathname);\n if (workspaceSessions) {\n const workspaceId = decodeURIComponent(workspaceSessions[1]);\n const workspace = options.headlessHub.workspaces().find((entry) => entry.id === workspaceId);\n if (!workspace) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (request.method === 'GET') {\n json(response, 200, {\n sessions: [\n ...options.headlessHub\n .snapshot()\n .filter(\n (session) =>\n session.workspaceId === workspaceId &&\n (!options.headlessHub.computerUse?.ownsSession?.(session.id) ||\n computerUseAuthorized(session.id, request)),\n )\n .map(sessionView),\n ...dormant()\n .filter(\n (record) =>\n record.workspaceId === workspaceId &&\n (!options.headlessHub.computerUse?.ownsSession?.(record.sessionId) ||\n computerUseAuthorized(record.sessionId, request)),\n )\n .map(dormantView),\n ],\n });\n return;\n }\n if (request.method === 'POST') {\n if (workspace.available === false) {\n json(response, 409, { error: 'Workspace is unavailable.' });\n return;\n }\n const body = parseJson(await readBody(request));\n if (!body || typeof body !== 'object' || ('name' in body && typeof body.name !== 'string')) {\n json(response, 400, { error: 'A session accepts an optional name.' });\n return;\n }\n const created = await options.headlessHub.sessionService.create({\n cwd: workspace.root,\n name: 'name' in body ? String(body.name) : path.basename(workspace.root),\n });\n json(response, 201, { sessionId: created.sessionId });\n return;\n }\n }\n if (url.pathname === '/api/events' && request.method === 'GET') {\n response.writeHead(200, {\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n 'content-type': 'text/event-stream; charset=utf-8',\n });\n sse.set(response, (sessionId) =>\n sessionId === undefined ? desktopAuthorized(request) : computerUseAuthorized(sessionId, request),\n );\n response.on('close', () => sse.delete(response));\n writeSse(response, 'sessions_snapshot', {\n type: 'sessions_snapshot',\n sessions: [\n ...options.headlessHub\n .snapshot()\n .filter(\n (session) =>\n !options.headlessHub.computerUse?.ownsSession?.(session.id) ||\n computerUseAuthorized(session.id, request),\n )\n .map(sessionView),\n ...dormant()\n .filter(\n (record) =>\n !options.headlessHub.computerUse?.ownsSession?.(record.sessionId) ||\n computerUseAuthorized(record.sessionId, request),\n )\n .map(dormantView),\n ],\n });\n writeSse(response, 'workspaces_snapshot', {\n type: 'workspaces_snapshot',\n workspaces: options.headlessHub.workspaces(),\n });\n return;\n }\n if (url.pathname === '/api/workspaces') {\n if (request.method === 'GET') {\n json(response, 200, { workspaces: options.headlessHub.workspaces() });\n return;\n }\n if (request.method === 'POST') {\n const admission = parseWorkspaceAdmission(parseJson(await readBody(request)));\n if ('error' in admission) {\n json(response, 400, admission);\n return;\n }\n let workspace: Awaited<ReturnType<HeadlessHub['admitWorkspace']>>;\n try {\n workspace = await options.headlessHub.admitWorkspace(admission);\n } catch (error) {\n json(response, 422, { error: error instanceof Error ? error.message : String(error) });\n return;\n }\n json(response, 201, { workspace });\n return;\n }\n }\n const workspaceHistoryMatch = /^\\/api\\/workspaces\\/([^/]+)\\/history$/u.exec(url.pathname);\n if (workspaceHistoryMatch && request.method === 'GET' && options.workspaceHistory) {\n const workspaceId = decodeURIComponent(workspaceHistoryMatch[1]);\n const workspace = options.headlessHub.workspaces().find((entry) => entry.id === workspaceId);\n if (!workspace) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (workspace.available === false) {\n json(response, 409, { error: 'Workspace is unavailable.' });\n return;\n }\n json(response, 200, { sessions: await options.workspaceHistory(workspaceId) });\n return;\n }\n const workspaceResumeMatch = /^\\/api\\/workspaces\\/([^/]+)\\/resume$/u.exec(url.pathname);\n if (workspaceResumeMatch && request.method === 'POST' && options.resumeWorkspaceSession) {\n const workspaceId = decodeURIComponent(workspaceResumeMatch[1]);\n const workspace = options.headlessHub.workspaces().find((entry) => entry.id === workspaceId);\n if (!workspace) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (workspace.available === false) {\n json(response, 409, { error: 'Workspace is unavailable.' });\n return;\n }\n const body = parseJson(await readBody(request));\n const targetSessionId =\n body && typeof body === 'object' && 'targetSessionId' in body ? body.targetSessionId : undefined;\n if (typeof targetSessionId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(targetSessionId)) {\n json(response, 400, { error: 'Invalid target session id.' });\n return;\n }\n json(response, 200, { sessionId: await options.resumeWorkspaceSession(workspaceId, targetSessionId) });\n return;\n }\n const workspaceMatch = /^\\/api\\/workspaces\\/([^/]+)$/u.exec(url.pathname);\n if (workspaceMatch && request.method === 'GET') {\n const workspace = options.headlessHub\n .workspaces()\n .find((entry) => entry.id === decodeURIComponent(workspaceMatch[1]));\n json(response, workspace ? 200 : 404, workspace ? { workspace } : { error: 'Workspace not found.' });\n return;\n }\n if (workspaceMatch && request.method === 'DELETE') {\n const id = decodeURIComponent(workspaceMatch[1]);\n if (!options.headlessHub.workspaces().some((workspace) => workspace.id === id)) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (\n options.headlessHub.snapshot().some((session) => session.workspaceId === id) ||\n dormant().some((session) => session.workspaceId === id)\n ) {\n json(response, 409, { error: 'Workspace still has sessions.' });\n return;\n }\n await options.headlessHub.removeWorkspace(id);\n json(response, 200, { ok: true });\n return;\n }\n const pluginMatch = DOOM_PACKAGE_API_PATH_PATTERN.exec(url.pathname);\n if (pluginMatch !== null && request.method !== 'CONNECT') {\n const workspaceId = pluginMatch[1] === undefined ? undefined : decodeURIComponent(pluginMatch[1]);\n const sessionId = pluginMatch[2] === undefined ? undefined : decodeURIComponent(pluginMatch[2]);\n if (workspaceId !== undefined && !options.headlessHub.workspaces().some((entry) => entry.id === workspaceId)) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (sessionId !== undefined && options.headlessHub.session(sessionId)?.workspaceId !== workspaceId) {\n // A stopped session still shows the composition it last published, so its context detail\n // is served from the file it wrote. Nothing else answers until it is woken.\n const stopped = dormant().some(\n (record) => record.sessionId === sessionId && record.workspaceId === workspaceId,\n );\n if (stopped && pluginMatch[3] === CONTEXT_API_BASE_PATH && request.method === 'GET') {\n const detail = await createContextApi({ sessionId, environment: process.env }).fetch(\n new Request(`http://po.local/${pluginMatch[4] ?? ''}${url.search}`),\n );\n const body = (await detail.json()) as { error?: string };\n // The detail file is only kept while the session runs, so a stopped session usually has none.\n if (readContextDetail(sessionId, process.env) === undefined)\n json(response, 404, { error: 'This session is stopped. Wake it to read this item.' });\n else json(response, detail.status, body);\n return;\n }\n json(response, 404, { error: 'Session not found.' });\n return;\n }\n const mount: DoomApiMount =\n sessionId !== undefined\n ? { scope: 'session', sessionId }\n : workspaceId !== undefined\n ? { scope: 'workspace', workspaceId }\n : { scope: 'global' };\n const basePath = pluginMatch[3] === undefined ? 'settings' : decodeURIComponent(pluginMatch[3]);\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(basePath)) {\n json(response, 400, { error: 'Invalid package API base path.' });\n return;\n }\n if (pluginMatch[3] === 'settings' || (sessionId !== undefined && basePath === 'settings')) {\n json(response, 404, { error: 'Not found.' });\n return;\n }\n const headers = new Headers();\n // Only the authenticated loopback proxy knows the server token and may\n // forward caller stamps. Browser-supplied stamps remain untrusted.\n const trustedCaller = options.token !== undefined && authorized(request, options.token);\n for (const [name, value] of Object.entries(request.headers)) {\n if (\n value !== undefined &&\n !['host', 'authorization', 'x-po-token'].includes(name) &&\n (trustedCaller || !DOOM_API_CALLER_HEADERS.includes(name as (typeof DOOM_API_CALLER_HEADERS)[number]))\n )\n headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n }\n if (!trustedCaller) {\n headers.set(DOOM_API_CALLER_LOCALITY_HEADER, 'local');\n headers.set(DOOM_API_CALLER_STEP_UP_HEADER, 'not-required');\n }\n const abort = new AbortController();\n const disconnected = (): void => {\n if (!response.writableEnded) abort.abort();\n };\n response.once('close', disconnected);\n try {\n const started = performance.now();\n const attributes = {\n scope: mount.scope,\n 'plugin.name': basePath,\n 'http.operation': request.method,\n ...(mount.scope === 'workspace' ? { 'workspace.id': mount.workspaceId } : {}),\n ...(mount.scope === 'session' ? { 'session.id': mount.sessionId } : {}),\n };\n const dispatch = async () =>\n options.headlessHub.requestApi(\n mount,\n basePath,\n new Request(`http://po.local/${pluginMatch[4] ?? ''}${url.search}`, {\n method: request.method,\n headers,\n signal: abort.signal,\n ...(request.method === 'GET' || request.method === 'HEAD'\n ? {}\n : { body: Buffer.from(await readBody(request)) }),\n }),\n );\n const result = options.telemetry\n ? await options.telemetry.runInSpan('po_server.plugin.request', attributes, dispatch)\n : await dispatch();\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent('po_server.plugin.response', {\n ...attributes,\n status: result.status,\n durationMs: performance.now() - started,\n }),\n options.onNotice,\n );\n await writeResponse(response, result);\n } finally {\n response.off('close', disconnected);\n }\n return;\n }\n const sessionMatch = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)(?:\\/(.*))?$/u.exec(url.pathname);\n if (sessionMatch === null) {\n json(response, 404, { error: 'Not found.' });\n return;\n }\n const sessionId = decodeURIComponent(sessionMatch[2]);\n const workspaceId = decodeURIComponent(sessionMatch[1]);\n const session = options.headlessHub.session(sessionId);\n const suffix = sessionMatch[3] === undefined ? '' : `/${sessionMatch[3]}`;\n if (suffix === '/transcript' && request.method === 'GET' && options.readDormantTranscript) {\n const record = dormant().find(\n (candidate) => candidate.sessionId === sessionId && candidate.workspaceId === workspaceId,\n );\n if (record === undefined) {\n json(response, 404, { error: 'Dormant session not found.' });\n return;\n }\n let transcriptRequest: TranscriptPageRequest;\n try {\n transcriptRequest = parseTranscriptRequest(url);\n } catch (error) {\n json(response, 400, { error: error instanceof Error ? error.message : 'Invalid transcript request.' });\n return;\n }\n try {\n const page = await options.readDormantTranscript(record, transcriptRequest, BACKGROUND_CONTEXT);\n json(response, 200, page);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message === 'STALE_TRANSCRIPT_CURSOR' ? 409 : 422;\n json(response, status, {\n error: status === 409 ? 'STALE_TRANSCRIPT_CURSOR' : 'Saved transcript is unavailable.',\n });\n }\n return;\n }\n // Revive is the one session route that answers before a runtime exists: it\n // is what creates one.\n if (sessionMatch[3] === 'revive' && request.method === 'POST' && options.reviveSession) {\n const record = dormant().find(\n (candidate) => candidate.sessionId === sessionId && candidate.workspaceId === workspaceId,\n );\n if (record === undefined) {\n json(response, 404, { error: 'Dormant session not found.' });\n return;\n }\n await options.reviveSession(record);\n json(response, 200, { ok: true });\n return;\n }\n if (session === undefined || session.workspaceId !== workspaceId) {\n const record = dormant().find(\n (candidate) => candidate.sessionId === sessionId && candidate.workspaceId === workspaceId,\n );\n if (request.method === 'DELETE' && record !== undefined && options.removeDormantSession !== undefined) {\n sessionMcp.closeSessionBinding(record.sessionId);\n await options.removeDormantSession(record);\n options.headlessHub.notifySessionRemoved(record.sessionId);\n json(response, 200, { ok: true });\n return;\n }\n json(response, 404, { error: 'Session not found.' });\n return;\n }\n if (suffix === '' && request.method === 'GET') {\n json(response, 200, sessionView(session));\n return;\n }\n if (suffix === '' && request.method === 'DELETE') {\n sessionMcp.closeSessionBinding(sessionId);\n await options.headlessHub.closeSession(sessionId);\n json(response, 200, { ok: true });\n return;\n }\n if (suffix === '/history' && request.method === 'GET' && options.sessionHistory) {\n json(response, 200, { sessions: await options.sessionHistory(session) });\n return;\n }\n if (suffix === '/avatar' && request.method === 'GET') {\n const avatar = options.headlessHub.sessionAvatar(sessionId);\n if (avatar === undefined) {\n json(response, 404, { error: 'This session has no avatar.' });\n return;\n }\n const current = url.searchParams.get('v') === session.profile?.iconVersion;\n response.writeHead(200, {\n 'content-type': avatar.mimeType,\n 'content-length': String(avatar.bytes.byteLength),\n 'cache-control': current ? 'private, max-age=31536000, immutable' : 'no-store',\n 'x-content-type-options': 'nosniff',\n });\n response.end(avatar.bytes);\n return;\n }\n if (suffix === '/file' && request.method === 'GET') {\n await writeResponse(response, await sessionFile(session, url.searchParams.get('path')));\n return;\n }\n if (suffix === '/attachments' && request.method === 'POST') {\n let bytes: Uint8Array;\n try {\n bytes = await readBody(request);\n } catch (error) {\n if (!(error instanceof RequestBodyTooLargeError)) throw error;\n json(response, 413, { error: 'The attachment exceeds the 8 MB upload limit.' });\n return;\n }\n json(response, 201, await writeSessionAttachment(sessionId, url.searchParams.get('name') ?? 'file', bytes));\n return;\n }\n if (suffix === '/restart' && request.method === 'POST' && options.restartSession) {\n // A restart closes the host, and closing aborts the running turn.\n if ((session.phase ?? 'idle') !== 'idle') {\n json(response, 409, { error: RESTART_WHILE_RUNNING_ERROR });\n return;\n }\n const restart = options.restartSession(session);\n // Settled either way: a failed restart leaves the session dormant, and waiters then see that.\n const settled = restart.then(\n () => undefined,\n () => undefined,\n );\n restarting.set(sessionId, settled);\n try {\n await restart;\n } finally {\n if (restarting.get(sessionId) === settled) restarting.delete(sessionId);\n }\n json(response, 200, { ok: true });\n return;\n }\n if (suffix === '/resume' && request.method === 'POST' && options.resumeSession) {\n const body = parseJson(await readBody(request));\n const targetSessionId =\n body && typeof body === 'object' && 'targetSessionId' in body ? body.targetSessionId : undefined;\n if (typeof targetSessionId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(targetSessionId)) {\n json(response, 400, { error: 'Invalid target session id.' });\n return;\n }\n if (\n options.headlessHub.computerUse?.ownsSession?.(targetSessionId) &&\n !computerUseAuthorized(targetSessionId, request)\n ) {\n json(response, 404, { error: 'This session belongs to its Desktop instance.' });\n return;\n }\n json(response, 200, { sessionId: await options.resumeSession(session, targetSessionId) });\n return;\n }\n if (suffix === '/channels' && request.method === 'GET') {\n json(response, 200, {\n channels: options.headlessHub\n .channelFrames(sessionId)\n .filter((frame) => frame.type !== 'computer_use_state' || computerUseAuthorized(sessionId, request)),\n });\n return;\n }\n const channelMatch = /^\\/channel\\/([^/]+)$/u.exec(suffix);\n if (channelMatch !== null && request.method === 'POST') {\n const frameType = decodeURIComponent(channelMatch[1]);\n const connectionId = request.headers['x-po-connection'];\n options.headlessHub.receiveChannel(\n sessionId,\n frameType,\n parseJson(await readBody(request)),\n typeof connectionId === 'string' ? connectionId : 'http',\n desktopAuthorized(request),\n computerUseAuthorized(sessionId, request),\n );\n json(response, 202, { ok: true });\n return;\n }\n json(response, 404, { error: 'Not found.' });\n }\n\n server.on('upgrade', (request, socket, head) => {\n const url = requestPath(request);\n const mount = parseDoomSocketPath(url.pathname);\n if (!mount) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n if (!authorized(request, options.token)) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n if (\n mount.scope !== 'global' &&\n (!options.headlessHub.workspaces().some((entry) => entry.id === mount.workspaceId && entry.available !== false) ||\n (mount.scope === 'session' && options.headlessHub.session(mount.sessionId)?.workspaceId !== mount.workspaceId))\n ) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n const prepare =\n mount.scope === 'global' && options.headlessHub.computerUse === undefined\n ? Promise.resolve(protocol)\n : createHeadlessProtocol({\n hub: options.headlessHub,\n mount,\n telemetry: options.telemetry,\n onNotice: options.onNotice,\n dormantSessions: dormant,\n authorizeSession: (id) =>\n !options.headlessHub.computerUse?.ownsSession?.(id) || computerUseAuthorized(id, request),\n authorizeComputerUse: (id) => computerUseAuthorized(id, request),\n authorizeDesktop: () => desktopAuthorized(request),\n });\n void prepare\n .then(async (selected) => {\n if (closed || socket.destroyed) {\n if (selected !== protocol) await selected.close();\n socket.destroy();\n return;\n }\n if (selected !== protocol) {\n scopedProtocols.add(selected);\n socket.once('close', () => {\n void selected.close().finally(() => scopedProtocols.delete(selected));\n });\n }\n webSockets.handleUpgrade(request, socket, head, (client) => {\n webSockets.emit('connection', client, selected);\n });\n })\n .catch(() => {\n socket.destroy();\n });\n });\n webSockets.on('connection', (socket, selected: typeof protocol) => {\n const handler = selected.accept(socket);\n if (!handler) return;\n const client: Client = { socket, handler };\n clients.add(client);\n socket.on('message', (data) => {\n if (Buffer.isBuffer(data)) handler.onData(data);\n else if (Array.isArray(data)) handler.onData(Buffer.concat(data));\n else handler.onData(new Uint8Array(data as ArrayBuffer));\n });\n socket.on('close', () => {\n clients.delete(client);\n handler.onClose();\n });\n socket.on('error', (error) => handler.onError(error));\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(options.port, options.host ?? '127.0.0.1', () => resolve());\n });\n const address = server.address();\n if (address === null || typeof address === 'string') {\n await new Promise<void>((resolve) => server.close(() => resolve()));\n throw new Error('The headless server did not expose a TCP address.');\n }\n const host = options.host ?? '127.0.0.1';\n const url = `http://${host}:${address.port}`;\n return {\n url,\n sessionReservations: sessionMcp.reservations,\n async close() {\n if (closed) return;\n closed = true;\n unsubscribe();\n for (const response of sse.keys()) response.end();\n sse.clear();\n for (const client of clients) client.socket.terminate();\n clients.clear();\n sessionMcp.close();\n if (options.sessionMcpStateDir === undefined)\n await fs.promises.rm(sessionMcpStateDir, { recursive: true, force: true });\n await Promise.all([protocol.close(), ...[...scopedProtocols].map((selected) => selected.close())]);\n webSockets.close();\n server.closeAllConnections();\n await new Promise<void>((resolve, reject) =>\n server.close((error) => (error === undefined ? resolve() : reject(error))),\n );\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"headlessServer.cjs","names":["fs","path","SESSION_FILE_CONTENT_TYPES","os","Readable","pipeline","WebSocketServer","createHeadlessProtocol","createSessionMcpRoutes","createSessionMcpActivityStore","createSessionMcpConversationStore","createSessionMcpRegistrationStore","createServer","harnessErrorMessage","isDoomSessionSetupError","isPublicSessionMcpRoute","isSessionMcpHostRoute","createContextApi","readContextDetail","DOOM_API_CALLER_HEADERS","DOOM_API_CALLER_LOCALITY_HEADER","DOOM_API_CALLER_STEP_UP_HEADER","BACKGROUND_CONTEXT","writeSessionAttachment","parseDoomSocketPath"],"sources":["../src/server/headlessServer.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport type { Context } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { WebSocket } from 'ws';\nimport { WebSocketServer } from 'ws';\n\nimport { API_BASE_PATH as CONTEXT_API_BASE_PATH } from '../constants/contextApi';\nimport {\n MAX_SESSION_FILE_BYTES,\n SESSION_FILE_CONTENT_TYPES,\n SESSION_FILE_DEFAULT_CONTENT_TYPE,\n} from '../constants/sessionFiles';\nimport {\n DOOM_API_CALLER_HEADERS,\n DOOM_API_CALLER_LOCALITY_HEADER,\n DOOM_API_CALLER_STEP_UP_HEADER,\n parseDoomSocketPath,\n type DoomApiMount,\n} from '../exports/packageApi';\nimport type { TranscriptPage, TranscriptPageRequest } from '../exports/sessionProtocol';\nimport { isDoomSessionSetupError } from '../schemas/headless';\nimport type { DoomHubSessionReservations } from '../schemas/hubChannel';\nimport { readContextDetail } from '../services/contextDetailStore';\nimport type { OpenSessionRecord } from '../services/openSessionRegistry';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { writeSessionAttachment } from '../services/sessionAttachments';\nimport { createSessionMcpActivityStore } from '../services/sessionMcpActivity';\nimport { createSessionMcpConversationStore } from '../services/sessionMcpConversations';\nimport { createSessionMcpRegistrationStore } from '../services/sessionMcpRegistrationStore';\nimport type { SavedSession } from '../services/sqliteSessionHistory';\nimport { createContextApi } from './contextApi';\nimport { harnessErrorMessage } from './harnessErrorMessage';\nimport type { HeadlessHub, HeadlessHubEvent, HeadlessHubSession, HeadlessWorkspaceAdmission } from './headlessHub';\nimport { createHeadlessProtocol } from './headlessProtocol';\nimport { createSessionMcpRoutes, isPublicSessionMcpRoute, isSessionMcpHostRoute } from './sessionMcpRoutes';\n\n/**\n * The canonical public shape of a package API request, as dispatch reads it.\n *\n * Groups: workspace id, session id, plugin base path, and the remainder handed\n * to the package. `settings` is the host's own API and sits beside `plugins`\n * rather than under it.\n *\n * Exported so the browser's URL construction can be pinned against it. The two\n * are written independently, in halves of this package that may not import each\n * other, and a disagreement between them is not a 404 from the route: the\n * service worker answers an unrecognised path out of the signed bundle cache,\n * so the symptom appears nowhere near the cause.\n */\nexport const DOOM_PACKAGE_API_PATH_PATTERN =\n /^\\/api(?:\\/workspaces\\/([^/]+)(?:\\/sessions\\/([^/]+))?)?\\/(?:plugins\\/([^/]+)|settings)(?:\\/(.*))?$/u;\n\nconst HEALTH_ROLE = 'hub';\nconst PROTOCOL_VERSION = 1;\nconst MAX_BODY_BYTES = 8 * 1024 * 1024;\nconst DIRECTORY_SUGGESTION_LIMIT = 12;\nconst DIRECTORY_CHILDREN_LIMIT = 500;\nconst HOME_PREFIX = '~';\nconst WORKSPACE_NAME_MAX_LENGTH = 80;\nconst WORKSPACE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9 ._-]*$/u;\n/** Restart closes the session host, which aborts a running turn, so it waits for idle. */\nexport const RESTART_WHILE_RUNNING_ERROR =\n 'The session is running a turn. Stop it or wait for it to finish before reloading extensions.';\n\nexport interface HeadlessServerOptions {\n headlessHub: HeadlessHub;\n port: number;\n host?: string;\n /** Requests other than health require this bearer token when set. */\n token?: string;\n telemetry?: ServerTelemetry;\n onNotice?: (message: string) => void;\n compositions?: () => unknown;\n requestAsset?: (request: Request) => Promise<Response | undefined>;\n sessionHistory?: (session: HeadlessHubSession) => Promise<SavedSession[]>;\n workspaceHistory?: (workspaceId: string) => Promise<SavedSession[]>;\n resumeWorkspaceSession?: (workspaceId: string, targetSessionId: string) => Promise<string>;\n readDormantTranscript?: (\n record: OpenSessionRecord,\n request: TranscriptPageRequest,\n context: Context,\n ) => Promise<TranscriptPage>;\n restartSession?: (session: HeadlessHubSession) => Promise<void>;\n resumeSession?: (session: HeadlessHubSession, targetSessionId: string) => Promise<string>;\n /** Recorded sessions this server has not reopened, surfaced so a client can ask for one. */\n dormantSessions?: () => readonly OpenSessionRecord[];\n removeDormantSession?: (record: OpenSessionRecord) => void | Promise<void>;\n reviveSession?: (record: OpenSessionRecord) => Promise<void>;\n /** Trusted HTTPS origin advertised for public session MCP and OAuth endpoints. */\n sessionMcpPublicOrigin?: () => string | undefined;\n /** Durable state directory for verified Session MCP clients. */\n sessionMcpStateDir?: string;\n /** Monotonic exposure revision, including disable/re-enable cycles. */\n sessionMcpPublicOriginRevision?: () => number;\n isSessionPersisted?: (sessionId: string, cwd: string) => boolean;\n}\n\nexport interface HeadlessServer {\n readonly url: string;\n readonly sessionReservations: DoomHubSessionReservations;\n close(): Promise<void>;\n}\n\ntype ProtocolHandler = NonNullable<ReturnType<Awaited<ReturnType<typeof createHeadlessProtocol>>['accept']>>;\ntype Client = { socket: WebSocket; handler: ProtocolHandler };\n\nfunction sessionView(session: HeadlessHubSession): Record<string, unknown> {\n return {\n id: session.id,\n workspaceId: session.workspaceId,\n webComposition: session.webComposition,\n 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 ...(session.git === undefined ? {} : { git: { ...session.git } }),\n ...(session.profile === undefined ? {} : { profile: { ...session.profile } }),\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n ...(session.pendingSetups === undefined ? {} : { pendingSetups: session.pendingSetups }),\n ...(session.activity === undefined ? {} : { activity: { ...session.activity } }),\n };\n}\n\n/** The dormant counterpart of `sessionView`; same shape, no runtime behind it. */\nfunction dormantView(record: OpenSessionRecord): Record<string, unknown> {\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: 'detached',\n pendingMessageCount: 0,\n everPrompted: false,\n awaitingInput: false,\n dormant: true,\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n };\n}\n\nfunction json(response: ServerResponse, status: number, value: unknown): void {\n const body = JSON.stringify(value);\n response.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(body),\n });\n response.end(body);\n}\n\nfunction authorized(request: IncomingMessage, token: string | undefined): boolean {\n if (token === undefined) return true;\n const authorization = request.headers.authorization;\n if (authorization?.startsWith('Bearer ') && authorization.slice('Bearer '.length) === token) return true;\n const header = request.headers['x-po-token'];\n if (typeof header === 'string' && header === token) return true;\n try {\n return new URL(request.url ?? '/', 'http://po.local').searchParams.get('token') === token;\n } catch {\n return false;\n }\n}\n\nfunction requestPath(request: IncomingMessage): URL {\n return new URL(request.url ?? '/', 'http://po.local');\n}\n\nfunction parseTranscriptRequest(url: URL): TranscriptPageRequest {\n const request: TranscriptPageRequest = {};\n const cursor = url.searchParams.get('cursor');\n const direction = url.searchParams.get('direction');\n const limit = url.searchParams.get('limit');\n if (cursor !== null) request.cursor = cursor;\n if (direction !== null) {\n if (direction !== 'older' && direction !== 'newer') throw new Error('Invalid transcript direction');\n request.direction = direction;\n }\n if (limit !== null) {\n if (!/^\\d+$/u.test(limit)) throw new Error('Invalid transcript page limit');\n const parsed = Number(limit);\n if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > 100) throw new Error('Invalid transcript page limit');\n request.limit = parsed;\n }\n return request;\n}\n\nasync function sessionFile(\n session: HeadlessHubSession,\n requestedPath: string | null,\n range?: string,\n expectedVersion?: string,\n): Promise<Response> {\n if (!requestedPath || requestedPath.includes('\\0'))\n return Response.json({ error: 'Invalid session file path.' }, { status: 400 });\n let root: string;\n let filePath: string;\n try {\n root = await fs.promises.realpath(session.cwd);\n filePath = await fs.promises.realpath(path.resolve(root, requestedPath));\n } catch {\n return Response.json({ error: 'Session file not found.' }, { status: 404 });\n }\n const contained = path.relative(root, filePath);\n if (contained === '..' || contained.startsWith(`..${path.sep}`) || path.isAbsolute(contained))\n return Response.json({ error: 'Session file is outside the working directory.' }, { status: 403 });\n let handle: fs.promises.FileHandle;\n try {\n handle = await fs.promises.open(filePath, 'r');\n } catch {\n return Response.json({ error: 'Session file not found.' }, { status: 404 });\n }\n try {\n const stat = await handle.stat();\n if (!stat.isFile()) return Response.json({ error: 'Session file not found.' }, { status: 404 });\n if (stat.size > MAX_SESSION_FILE_BYTES)\n return Response.json({ error: 'Session file is too large.' }, { status: 413 });\n const version = `\"${stat.dev}-${stat.ino}-${stat.size}-${stat.mtimeMs}-${stat.ctimeMs}\"`;\n const headers = new Headers({\n 'content-type':\n SESSION_FILE_CONTENT_TYPES[path.extname(filePath).toLowerCase()] ?? SESSION_FILE_DEFAULT_CONTENT_TYPE,\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n 'accept-ranges': 'bytes',\n etag: version,\n });\n if (expectedVersion !== undefined && expectedVersion !== version)\n return new Response(null, { status: 412, headers });\n let start = 0;\n let end = stat.size - 1;\n if (range !== undefined) {\n const match = /^bytes=(\\d*)-(\\d*)$/u.exec(range);\n if (\n !match ||\n (!match[1] && !match[2]) ||\n [match[1], match[2]].some((value) => value !== '' && !Number.isSafeInteger(Number(value))) ||\n stat.size === 0\n ) {\n headers.set('content-range', `bytes */${stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n if (!match[1]) start = Math.max(0, stat.size - Number(match[2]));\n else {\n start = Number(match[1]);\n if (match[2]) end = Math.min(Number(match[2]), end);\n }\n if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || start > end) {\n headers.set('content-range', `bytes */${stat.size}`);\n return new Response(null, { status: 416, headers });\n }\n headers.set('content-range', `bytes ${start}-${end}/${stat.size}`);\n }\n const bytes = new Uint8Array(Math.max(0, end - start + 1));\n let read = 0;\n while (read < bytes.length) {\n const part = await handle.read(bytes, read, bytes.length - read, start + read);\n if (part.bytesRead === 0) return new Response(null, { status: 412, headers });\n read += part.bytesRead;\n }\n const after = await handle.stat();\n if (after.size !== stat.size || after.mtimeMs !== stat.mtimeMs || after.ctimeMs !== stat.ctimeMs)\n return new Response(null, { status: 412, headers });\n headers.set('content-length', String(bytes.length));\n return new Response(bytes, { status: range === undefined ? 200 : 206, headers });\n } finally {\n await handle.close();\n }\n}\n\n/** Expands a leading `~` the way a shell would, so typed paths match what the user sees in a terminal. */\nfunction expandHome(value: string): string {\n if (value === HOME_PREFIX) return os.homedir();\n return value.startsWith(`${HOME_PREFIX}${path.sep}`) ? path.join(os.homedir(), value.slice(2)) : value;\n}\n\n/**\n * Validates an add-workspace request. A name alone asks for a new default folder,\n * so it must be safe to use as one folder name.\n */\nfunction parseWorkspaceAdmission(body: unknown): HeadlessWorkspaceAdmission | { error: string } {\n if (typeof body !== 'object' || body === null) return { error: 'A workspace root or name is required.' };\n const record = body as Record<string, unknown>;\n if (record.root !== undefined && typeof record.root !== 'string')\n return { error: 'The workspace root must be text.' };\n if (record.name !== undefined && typeof record.name !== 'string')\n return { error: 'The workspace name must be text.' };\n const root =\n typeof record.root === 'string' && record.root.trim() !== '' ? expandHome(record.root.trim()) : undefined;\n const name = typeof record.name === 'string' && record.name.trim() !== '' ? record.name.trim() : undefined;\n if (root === undefined && name === undefined) return { error: 'A workspace root or name is required.' };\n if (\n name !== undefined &&\n (name.length > WORKSPACE_NAME_MAX_LENGTH || !WORKSPACE_NAME_PATTERN.test(name) || name.includes('..'))\n )\n return {\n error: `Workspace names use letters, numbers, spaces, dots, dashes, or underscores (up to ${String(WORKSPACE_NAME_MAX_LENGTH)} characters).`,\n };\n return { ...(root === undefined ? {} : { root }), ...(name === undefined ? {} : { name }) };\n}\n\nasync function directorySuggestions(query: string, sessions: readonly HeadlessHubSession[]): Promise<string[]> {\n const typed = expandHome(query.trim());\n if (typed === '') return [];\n const matches = (value: string): boolean => value.toLowerCase().includes(typed.toLowerCase());\n const known = [...new Set([process.cwd(), ...sessions.map((session) => session.cwd)])].filter(matches);\n const candidates = path.isAbsolute(typed)\n ? [typed]\n : typed.includes(path.sep)\n ? [path.resolve(process.cwd(), typed)]\n : [path.join(path.dirname(process.cwd()), typed), path.join(process.cwd(), typed)];\n const completed: string[] = [];\n for (const candidate of candidates) {\n const drilling = typed.endsWith(path.sep);\n const parent = drilling ? candidate : path.dirname(candidate);\n const partial = drilling ? '' : path.basename(candidate).toLowerCase();\n try {\n const entries = await fs.promises.readdir(parent, { withFileTypes: true });\n completed.push(\n ...entries\n .filter((entry) => entry.isDirectory() && entry.name.toLowerCase().includes(partial))\n .map((entry) => path.join(parent, entry.name)),\n );\n } catch {\n // A missing or unreadable parent simply has no completions.\n }\n }\n return [...new Set([...known, ...completed.sort((left, right) => left.localeCompare(right))])].slice(\n 0,\n DIRECTORY_SUGGESTION_LIMIT,\n );\n}\n\n/**\n * Lists the visible child directories of one folder for the workspace folder browser.\n * Resolves undefined for a relative, missing, or unreadable path.\n */\nasync function directoryChildren(\n requested: string | null,\n): Promise<{ path: string; parent?: string; directories: string[] } | undefined> {\n const directory = requested === null || requested.trim() === '' ? os.homedir() : expandHome(requested.trim());\n if (!path.isAbsolute(directory)) return undefined;\n const resolved = path.resolve(directory);\n let entries: fs.Dirent[];\n try {\n entries = await fs.promises.readdir(resolved, { withFileTypes: true });\n } catch {\n return undefined;\n }\n const directories = entries\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))\n .map((entry) => path.join(resolved, entry.name))\n .sort((left, right) => left.localeCompare(right))\n .slice(0, DIRECTORY_CHILDREN_LIMIT);\n const parent = path.dirname(resolved);\n return { path: resolved, ...(parent === resolved ? {} : { parent }), directories };\n}\n\nclass RequestBodyTooLargeError extends Error {\n constructor() {\n super('Request body is too large.');\n }\n}\n\nasync function readBody(request: IncomingMessage): Promise<Uint8Array> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of request) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n size += buffer.byteLength;\n if (size > MAX_BODY_BYTES) throw new RequestBodyTooLargeError();\n chunks.push(buffer);\n }\n return Buffer.concat(chunks);\n}\n\nfunction parseJson(body: Uint8Array): unknown {\n if (body.byteLength === 0) return {};\n return JSON.parse(Buffer.from(body).toString('utf8')) as unknown;\n}\n\nfunction webRequest(request: IncomingMessage, url: URL, signal?: AbortSignal): Request {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n }\n return new Request(url, {\n method: request.method,\n headers,\n signal,\n ...(request.method === 'GET' || request.method === 'HEAD'\n ? {}\n : {\n body: Readable.toWeb(request) as never,\n duplex: 'half' as const,\n }),\n });\n}\n\nasync function writeResponse(response: ServerResponse, result: Response): Promise<void> {\n response.writeHead(result.status, Object.fromEntries(result.headers.entries()));\n if (result.body === null) {\n response.end();\n return;\n }\n await pipeline(Readable.fromWeb(result.body as import('node:stream/web').ReadableStream), response);\n}\n\nfunction eventFrame(event: HeadlessHubEvent): Record<string, unknown> {\n switch (event.kind) {\n case 'upsert':\n return { type: 'session_upsert', session: sessionView(event.session) };\n case 'removed':\n return { type: 'session_removed', sessionId: event.sessionId };\n case 'workspace_upsert':\n return { type: 'workspace_upsert', workspace: event.workspace };\n case 'workspace_removed':\n return { type: 'workspace_removed', workspaceId: event.workspaceId };\n case 'channel':\n return {\n type: 'channel_frame',\n frameType: event.frameType,\n sessionId: event.sessionId,\n payload: event.payload,\n ...(event.connectionId === undefined ? {} : { connectionId: event.connectionId }),\n };\n case 'frame':\n return { type: 'session_frame', sessionId: event.sessionId, frame: event.frame };\n }\n}\n\nfunction writeSse(response: ServerResponse, event: string, value: unknown): void {\n response.write(`event: ${event}\\ndata: ${JSON.stringify(value)}\\n\\n`);\n}\n\n/**\n * Client-neutral HTTP and WebSocket boundary for the process-local headless hub.\n * It deliberately delegates every session operation to HeadlessHub, so transport\n * clients cannot create a second session backend or bypass its lifecycle.\n */\nexport async function serveHeadlessServer(options: HeadlessServerOptions): Promise<HeadlessServer> {\n const clients = new Set<Client>();\n const scopedProtocols = new Set<Awaited<ReturnType<typeof createHeadlessProtocol>>>();\n const sse = new Map<ServerResponse, (sessionId: string | undefined) => boolean>();\n const desktopAuthorized = (request: IncomingMessage): boolean => {\n const proof = request.headers['x-po-desktop'];\n return (\n typeof proof === 'string' &&\n options.headlessHub.computerUse?.authorize?.(new Headers({ 'x-po-desktop': proof })) === true\n );\n };\n const computerUseAuthorized = (sessionId: string, request: IncomingMessage): boolean => {\n if (desktopAuthorized(request)) return true;\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizeSession?.(sessionId, headers) === true;\n };\n const activationAuthorized = (request: IncomingMessage): boolean => {\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizeActivation?.(headers) === true;\n };\n const pendingAuthorized = (sessionId: string, request: IncomingMessage): boolean => {\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizePending?.(sessionId, headers) === true;\n };\n const recordingAuthorized = (sessionId: string, request: IncomingMessage): boolean => {\n if (!authorized(request, options.token)) return false;\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers))\n if (value !== undefined) headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n return options.headlessHub.computerUse?.authorizeRecording?.(sessionId, headers) === true;\n };\n let closed = false;\n const webSockets = new WebSocketServer({ noServer: true });\n /**\n * A recorded session is dormant exactly while the hub has no session for its\n * id, so reviving one needs no bookkeeping beyond the hub itself.\n */\n const dormant = (): readonly OpenSessionRecord[] =>\n (options.dormantSessions?.() ?? []).filter((record) => options.headlessHub.session(record.sessionId) === undefined);\n const protocol = await createHeadlessProtocol({\n hub: options.headlessHub,\n telemetry: options.telemetry,\n onNotice: options.onNotice,\n dormantSessions: dormant,\n });\n const sessionMcpStateDir = options.sessionMcpStateDir ?? fs.mkdtempSync(path.join(os.tmpdir(), 'po-session-mcp-'));\n const sessionMcp = createSessionMcpRoutes({\n headlessHub: options.headlessHub,\n publicOrigin: options.sessionMcpPublicOrigin ?? (() => undefined),\n publicOriginRevision: options.sessionMcpPublicOriginRevision,\n onNotice: options.onNotice,\n isSessionPersisted: options.isSessionPersisted,\n activityStore: createSessionMcpActivityStore(sessionMcpStateDir),\n conversationStore: createSessionMcpConversationStore(sessionMcpStateDir),\n registrationStore: createSessionMcpRegistrationStore({ stateDir: sessionMcpStateDir, onNotice: options.onNotice }),\n });\n /** Sessions being restarted, keyed by id, settled once the reopen succeeds or fails. */\n const restarting = new Map<string, Promise<void>>();\n const server = createServer((request, response) => {\n void handleRequest(request, response).catch((error: unknown) => {\n if (response.headersSent) {\n response.destroy();\n return;\n }\n options.onNotice?.(`Headless request failed: ${harnessErrorMessage(error)}`);\n // A setup problem the user must fix carries its own instructions; anything else stays generic.\n if (isDoomSessionSetupError(error)) json(response, 422, { error: error.message });\n else json(response, 500, { error: 'Internal server error.' });\n });\n });\n\n const unsubscribe = options.headlessHub.onEvent((event) => {\n const frame = eventFrame(event);\n const sessionId = event.kind === 'upsert' ? event.session.id : 'sessionId' in event ? event.sessionId : undefined;\n for (const [response, native] of sse) {\n if (\n (sessionId !== undefined && options.headlessHub.computerUse?.ownsSession?.(sessionId)) ||\n frame.type === 'computer_use_state'\n ) {\n if (!native(sessionId)) continue;\n }\n writeSse(response, String(frame.type), frame);\n }\n });\n\n async function handleRequest(request: IncomingMessage, response: ServerResponse): Promise<void> {\n const url = requestPath(request);\n if (url.pathname === '/api/health' && request.method === 'GET') {\n json(response, 200, {\n ok: true,\n role: HEALTH_ROLE,\n protocol: PROTOCOL_VERSION,\n sessions: options.headlessHub.snapshot().length,\n });\n return;\n }\n const scopedSession = /^\\/api\\/workspaces\\/[^/]+\\/sessions\\/([^/]+)(?:\\/|$)/u.exec(url.pathname)?.[1];\n if (\n scopedSession &&\n options.headlessHub.computerUse?.ownsSession?.(decodeURIComponent(scopedSession)) &&\n !computerUseAuthorized(decodeURIComponent(scopedSession), request) &&\n !(\n request.method === 'GET' &&\n url.pathname.endsWith('/plugins/computer-use/artifact') &&\n recordingAuthorized(decodeURIComponent(scopedSession), request)\n ) &&\n !(\n request.method === 'POST' &&\n url.pathname.endsWith('/plugins/computer-use/activate') &&\n activationAuthorized(request)\n ) &&\n !(\n url.pathname.endsWith('/plugins/computer-use/activate') &&\n ((request.method === 'GET' &&\n (pendingAuthorized(decodeURIComponent(scopedSession), request) ||\n recordingAuthorized(decodeURIComponent(scopedSession), request))) ||\n (request.method === 'DELETE' && pendingAuthorized(decodeURIComponent(scopedSession), request)))\n )\n ) {\n json(response, 404, { error: 'This session belongs to its Desktop instance.' });\n return;\n }\n if (isPublicSessionMcpRoute(request.method ?? 'GET', url.pathname)) {\n const sessionMcpAbort = new AbortController();\n const abortSessionMcp = (): void => {\n if (!response.writableEnded) sessionMcpAbort.abort();\n };\n response.once('close', abortSessionMcp);\n const publicSessionMcp = await sessionMcp.handlePublic(webRequest(request, url, sessionMcpAbort.signal));\n if (publicSessionMcp !== undefined) {\n try {\n await writeResponse(response, publicSessionMcp);\n } finally {\n response.off('close', abortSessionMcp);\n }\n return;\n }\n response.off('close', abortSessionMcp);\n }\n if (!authorized(request, options.token)) {\n json(response, 401, { error: 'Unauthorized.' });\n return;\n }\n // A restart closes the session before reopening it under the same id. Any session-scoped\n // request that lands in that gap, such as a plugin's poll, waits for the reopened session.\n const reopening = scopedSession === undefined ? undefined : restarting.get(decodeURIComponent(scopedSession));\n if (reopening !== undefined && options.headlessHub.session(decodeURIComponent(scopedSession!)) === undefined)\n await reopening;\n if (isSessionMcpHostRoute(url.pathname)) {\n const hostSessionMcp = await sessionMcp.handleHost(webRequest(request, url));\n if (hostSessionMcp !== undefined) {\n await writeResponse(response, hostSessionMcp);\n return;\n }\n }\n if (url.pathname === '/api/remote' || url.pathname.startsWith('/api/remote/')) {\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value !== undefined && name !== 'authorization' && name !== 'x-po-token')\n headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n }\n const result = await options.headlessHub.requestApi(\n { scope: 'global' },\n 'remote',\n new Request(`http://po.local${url.pathname.slice('/api/remote'.length)}${url.search}`, {\n method: request.method,\n headers,\n ...(request.method === 'GET' || request.method === 'HEAD'\n ? {}\n : { body: Buffer.from(await readBody(request)) }),\n }),\n );\n await writeResponse(response, result);\n return;\n }\n if (url.pathname === '/api/telemetry/browser' && request.method === 'POST') {\n const body = JSON.parse(new TextDecoder().decode(await readBody(request))) as { v?: unknown; events?: unknown };\n if (body.v !== 1 || !Array.isArray(body.events) || body.events.length > 10) {\n json(response, 400, { error: 'Invalid browser telemetry batch.' });\n return;\n }\n for (const event of body.events) {\n if (\n !event ||\n typeof event !== 'object' ||\n typeof event.name !== 'string' ||\n !/^web\\.browser\\.[a-z_]{1,40}$/u.test(event.name)\n )\n continue;\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent(event.name, {\n ...(typeof event.duration_ms === 'number' && Number.isFinite(event.duration_ms) && event.duration_ms >= 0\n ? { duration_ms: event.duration_ms }\n : {}),\n ...(typeof event.count === 'number' && Number.isFinite(event.count) && event.count >= 0\n ? { count: event.count }\n : {}),\n }),\n );\n }\n json(response, 200, { ok: true });\n return;\n }\n if (url.pathname === '/api/compositions' && request.method === 'GET') {\n json(response, 200, options.compositions?.() ?? { workspaces: [] });\n return;\n }\n if (\n (url.pathname.startsWith('/api/web-plugins/') ||\n url.pathname === '/bundle-manifest.json' ||\n url.pathname.startsWith('/bundle-assets/')) &&\n options.requestAsset\n ) {\n const result = await options.requestAsset(new Request(url, { method: request.method }));\n if (result) {\n await writeResponse(response, result);\n return;\n }\n }\n if (url.pathname === '/api/directories/children' && request.method === 'GET') {\n const listing = await directoryChildren(url.searchParams.get('path'));\n if (listing === undefined) json(response, 404, { error: 'That folder cannot be read.' });\n else json(response, 200, listing);\n return;\n }\n if (url.pathname === '/api/directories' && request.method === 'GET') {\n json(response, 200, {\n directories: await directorySuggestions(url.searchParams.get('q') ?? '', options.headlessHub.snapshot()),\n });\n return;\n }\n // Verified browser bundles can remain active across a server upgrade. Keep\n // their former create route working while they refresh to workspace routes.\n if (url.pathname === '/api/sessions' && request.method === 'POST') {\n const body = parseJson(await readBody(request));\n if (\n !body ||\n typeof body !== 'object' ||\n !('cwd' in body) ||\n typeof body.cwd !== 'string' ||\n !body.cwd.trim() ||\n ('name' in body && typeof body.name !== 'string')\n ) {\n json(response, 400, { error: 'A session needs a working directory and an optional name.' });\n return;\n }\n const created = await options.headlessHub.sessionService.create({\n cwd: body.cwd,\n name: 'name' in body ? String(body.name) : path.basename(body.cwd),\n });\n json(response, 201, { sessionId: created.sessionId });\n return;\n }\n const workspaceSessions = /^\\/api\\/workspaces\\/([^/]+)\\/sessions$/u.exec(url.pathname);\n if (workspaceSessions) {\n const workspaceId = decodeURIComponent(workspaceSessions[1]);\n const workspace = options.headlessHub.workspaces().find((entry) => entry.id === workspaceId);\n if (!workspace) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (request.method === 'GET') {\n json(response, 200, {\n sessions: [\n ...options.headlessHub\n .snapshot()\n .filter(\n (session) =>\n session.workspaceId === workspaceId &&\n (!options.headlessHub.computerUse?.ownsSession?.(session.id) ||\n computerUseAuthorized(session.id, request)),\n )\n .map(sessionView),\n ...dormant()\n .filter(\n (record) =>\n record.workspaceId === workspaceId &&\n (!options.headlessHub.computerUse?.ownsSession?.(record.sessionId) ||\n computerUseAuthorized(record.sessionId, request)),\n )\n .map(dormantView),\n ],\n });\n return;\n }\n if (request.method === 'POST') {\n if (workspace.available === false) {\n json(response, 409, { error: 'Workspace is unavailable.' });\n return;\n }\n const body = parseJson(await readBody(request));\n if (!body || typeof body !== 'object' || ('name' in body && typeof body.name !== 'string')) {\n json(response, 400, { error: 'A session accepts an optional name.' });\n return;\n }\n const created = await options.headlessHub.sessionService.create({\n cwd: workspace.root,\n name: 'name' in body ? String(body.name) : path.basename(workspace.root),\n });\n json(response, 201, { sessionId: created.sessionId });\n return;\n }\n }\n if (url.pathname === '/api/events' && request.method === 'GET') {\n response.writeHead(200, {\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n 'content-type': 'text/event-stream; charset=utf-8',\n });\n sse.set(response, (sessionId) =>\n sessionId === undefined ? desktopAuthorized(request) : computerUseAuthorized(sessionId, request),\n );\n response.on('close', () => sse.delete(response));\n writeSse(response, 'sessions_snapshot', {\n type: 'sessions_snapshot',\n sessions: [\n ...options.headlessHub\n .snapshot()\n .filter(\n (session) =>\n !options.headlessHub.computerUse?.ownsSession?.(session.id) ||\n computerUseAuthorized(session.id, request),\n )\n .map(sessionView),\n ...dormant()\n .filter(\n (record) =>\n !options.headlessHub.computerUse?.ownsSession?.(record.sessionId) ||\n computerUseAuthorized(record.sessionId, request),\n )\n .map(dormantView),\n ],\n });\n writeSse(response, 'workspaces_snapshot', {\n type: 'workspaces_snapshot',\n workspaces: options.headlessHub.workspaces(),\n });\n return;\n }\n if (url.pathname === '/api/workspaces') {\n if (request.method === 'GET') {\n json(response, 200, { workspaces: options.headlessHub.workspaces() });\n return;\n }\n if (request.method === 'POST') {\n const admission = parseWorkspaceAdmission(parseJson(await readBody(request)));\n if ('error' in admission) {\n json(response, 400, admission);\n return;\n }\n let workspace: Awaited<ReturnType<HeadlessHub['admitWorkspace']>>;\n try {\n workspace = await options.headlessHub.admitWorkspace(admission);\n } catch (error) {\n json(response, 422, { error: error instanceof Error ? error.message : String(error) });\n return;\n }\n json(response, 201, { workspace });\n return;\n }\n }\n const workspaceHistoryMatch = /^\\/api\\/workspaces\\/([^/]+)\\/history$/u.exec(url.pathname);\n if (workspaceHistoryMatch && request.method === 'GET' && options.workspaceHistory) {\n const workspaceId = decodeURIComponent(workspaceHistoryMatch[1]);\n const workspace = options.headlessHub.workspaces().find((entry) => entry.id === workspaceId);\n if (!workspace) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (workspace.available === false) {\n json(response, 409, { error: 'Workspace is unavailable.' });\n return;\n }\n json(response, 200, { sessions: await options.workspaceHistory(workspaceId) });\n return;\n }\n const workspaceResumeMatch = /^\\/api\\/workspaces\\/([^/]+)\\/resume$/u.exec(url.pathname);\n if (workspaceResumeMatch && request.method === 'POST' && options.resumeWorkspaceSession) {\n const workspaceId = decodeURIComponent(workspaceResumeMatch[1]);\n const workspace = options.headlessHub.workspaces().find((entry) => entry.id === workspaceId);\n if (!workspace) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (workspace.available === false) {\n json(response, 409, { error: 'Workspace is unavailable.' });\n return;\n }\n const body = parseJson(await readBody(request));\n const targetSessionId =\n body && typeof body === 'object' && 'targetSessionId' in body ? body.targetSessionId : undefined;\n if (typeof targetSessionId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(targetSessionId)) {\n json(response, 400, { error: 'Invalid target session id.' });\n return;\n }\n json(response, 200, { sessionId: await options.resumeWorkspaceSession(workspaceId, targetSessionId) });\n return;\n }\n const workspaceMatch = /^\\/api\\/workspaces\\/([^/]+)$/u.exec(url.pathname);\n if (workspaceMatch && request.method === 'GET') {\n const workspace = options.headlessHub\n .workspaces()\n .find((entry) => entry.id === decodeURIComponent(workspaceMatch[1]));\n json(response, workspace ? 200 : 404, workspace ? { workspace } : { error: 'Workspace not found.' });\n return;\n }\n if (workspaceMatch && request.method === 'DELETE') {\n const id = decodeURIComponent(workspaceMatch[1]);\n if (!options.headlessHub.workspaces().some((workspace) => workspace.id === id)) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (\n options.headlessHub.snapshot().some((session) => session.workspaceId === id) ||\n dormant().some((session) => session.workspaceId === id)\n ) {\n json(response, 409, { error: 'Workspace still has sessions.' });\n return;\n }\n await options.headlessHub.removeWorkspace(id);\n json(response, 200, { ok: true });\n return;\n }\n const pluginMatch = DOOM_PACKAGE_API_PATH_PATTERN.exec(url.pathname);\n if (pluginMatch !== null && request.method !== 'CONNECT') {\n const workspaceId = pluginMatch[1] === undefined ? undefined : decodeURIComponent(pluginMatch[1]);\n const sessionId = pluginMatch[2] === undefined ? undefined : decodeURIComponent(pluginMatch[2]);\n if (workspaceId !== undefined && !options.headlessHub.workspaces().some((entry) => entry.id === workspaceId)) {\n json(response, 404, { error: 'Workspace not found.' });\n return;\n }\n if (sessionId !== undefined && options.headlessHub.session(sessionId)?.workspaceId !== workspaceId) {\n // A stopped session still shows the composition it last published, so its context detail\n // is served from the file it wrote. Nothing else answers until it is woken.\n const stopped = dormant().some(\n (record) => record.sessionId === sessionId && record.workspaceId === workspaceId,\n );\n if (stopped && pluginMatch[3] === CONTEXT_API_BASE_PATH && request.method === 'GET') {\n const detail = await createContextApi({ sessionId, environment: process.env }).fetch(\n new Request(`http://po.local/${pluginMatch[4] ?? ''}${url.search}`),\n );\n const body = (await detail.json()) as { error?: string };\n // The detail file is only kept while the session runs, so a stopped session usually has none.\n if (readContextDetail(sessionId, process.env) === undefined)\n json(response, 404, { error: 'This session is stopped. Wake it to read this item.' });\n else json(response, detail.status, body);\n return;\n }\n json(response, 404, { error: 'Session not found.' });\n return;\n }\n const mount: DoomApiMount =\n sessionId !== undefined\n ? { scope: 'session', sessionId }\n : workspaceId !== undefined\n ? { scope: 'workspace', workspaceId }\n : { scope: 'global' };\n const basePath = pluginMatch[3] === undefined ? 'settings' : decodeURIComponent(pluginMatch[3]);\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(basePath)) {\n json(response, 400, { error: 'Invalid package API base path.' });\n return;\n }\n if (pluginMatch[3] === 'settings' || (sessionId !== undefined && basePath === 'settings')) {\n json(response, 404, { error: 'Not found.' });\n return;\n }\n const headers = new Headers();\n // Only the authenticated loopback proxy knows the server token and may\n // forward caller stamps. Browser-supplied stamps remain untrusted.\n const trustedCaller = options.token !== undefined && authorized(request, options.token);\n for (const [name, value] of Object.entries(request.headers)) {\n if (\n value !== undefined &&\n !['host', 'authorization', 'x-po-token'].includes(name) &&\n (trustedCaller || !DOOM_API_CALLER_HEADERS.includes(name as (typeof DOOM_API_CALLER_HEADERS)[number]))\n )\n headers.set(name, Array.isArray(value) ? value.join(', ') : value);\n }\n if (!trustedCaller) {\n headers.set(DOOM_API_CALLER_LOCALITY_HEADER, 'local');\n headers.set(DOOM_API_CALLER_STEP_UP_HEADER, 'not-required');\n }\n const abort = new AbortController();\n const disconnected = (): void => {\n if (!response.writableEnded) abort.abort();\n };\n response.once('close', disconnected);\n try {\n const started = performance.now();\n const attributes = {\n scope: mount.scope,\n 'plugin.name': basePath,\n 'http.operation': request.method,\n ...(mount.scope === 'workspace' ? { 'workspace.id': mount.workspaceId } : {}),\n ...(mount.scope === 'session' ? { 'session.id': mount.sessionId } : {}),\n };\n const dispatch = async () =>\n options.headlessHub.requestApi(\n mount,\n basePath,\n new Request(`http://po.local/${pluginMatch[4] ?? ''}${url.search}`, {\n method: request.method,\n headers,\n signal: abort.signal,\n ...(request.method === 'GET' || request.method === 'HEAD'\n ? {}\n : { body: Buffer.from(await readBody(request)) }),\n }),\n );\n const result = options.telemetry\n ? await options.telemetry.runInSpan('po_server.plugin.request', attributes, dispatch)\n : await dispatch();\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent('po_server.plugin.response', {\n ...attributes,\n status: result.status,\n durationMs: performance.now() - started,\n }),\n options.onNotice,\n );\n await writeResponse(response, result);\n } finally {\n response.off('close', disconnected);\n }\n return;\n }\n const sessionMatch = /^\\/api\\/workspaces\\/([^/]+)\\/sessions\\/([^/]+)(?:\\/(.*))?$/u.exec(url.pathname);\n if (sessionMatch === null) {\n json(response, 404, { error: 'Not found.' });\n return;\n }\n const sessionId = decodeURIComponent(sessionMatch[2]);\n const workspaceId = decodeURIComponent(sessionMatch[1]);\n const session = options.headlessHub.session(sessionId);\n const suffix = sessionMatch[3] === undefined ? '' : `/${sessionMatch[3]}`;\n if (suffix === '/transcript' && request.method === 'GET' && options.readDormantTranscript) {\n const record = dormant().find(\n (candidate) => candidate.sessionId === sessionId && candidate.workspaceId === workspaceId,\n );\n if (record === undefined) {\n json(response, 404, { error: 'Dormant session not found.' });\n return;\n }\n let transcriptRequest: TranscriptPageRequest;\n try {\n transcriptRequest = parseTranscriptRequest(url);\n } catch (error) {\n json(response, 400, { error: error instanceof Error ? error.message : 'Invalid transcript request.' });\n return;\n }\n try {\n const page = await options.readDormantTranscript(record, transcriptRequest, BACKGROUND_CONTEXT);\n json(response, 200, page);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message === 'STALE_TRANSCRIPT_CURSOR' ? 409 : 422;\n json(response, status, {\n error: status === 409 ? 'STALE_TRANSCRIPT_CURSOR' : 'Saved transcript is unavailable.',\n });\n }\n return;\n }\n // Revive is the one session route that answers before a runtime exists: it\n // is what creates one.\n if (sessionMatch[3] === 'revive' && request.method === 'POST' && options.reviveSession) {\n const record = dormant().find(\n (candidate) => candidate.sessionId === sessionId && candidate.workspaceId === workspaceId,\n );\n if (record === undefined) {\n json(response, 404, { error: 'Dormant session not found.' });\n return;\n }\n await options.reviveSession(record);\n json(response, 200, { ok: true });\n return;\n }\n if (session === undefined || session.workspaceId !== workspaceId) {\n const record = dormant().find(\n (candidate) => candidate.sessionId === sessionId && candidate.workspaceId === workspaceId,\n );\n if (request.method === 'DELETE' && record !== undefined && options.removeDormantSession !== undefined) {\n sessionMcp.closeSessionBinding(record.sessionId);\n await options.removeDormantSession(record);\n options.headlessHub.notifySessionRemoved(record.sessionId);\n json(response, 200, { ok: true });\n return;\n }\n json(response, 404, { error: 'Session not found.' });\n return;\n }\n if (suffix === '' && request.method === 'GET') {\n json(response, 200, sessionView(session));\n return;\n }\n if (suffix === '' && request.method === 'DELETE') {\n sessionMcp.closeSessionBinding(sessionId);\n await options.headlessHub.closeSession(sessionId);\n json(response, 200, { ok: true });\n return;\n }\n if (suffix === '/history' && request.method === 'GET' && options.sessionHistory) {\n json(response, 200, { sessions: await options.sessionHistory(session) });\n return;\n }\n if (suffix === '/avatar' && request.method === 'GET') {\n const avatar = options.headlessHub.sessionAvatar(sessionId);\n if (avatar === undefined) {\n json(response, 404, { error: 'This session has no avatar.' });\n return;\n }\n const current = url.searchParams.get('v') === session.profile?.iconVersion;\n response.writeHead(200, {\n 'content-type': avatar.mimeType,\n 'content-length': String(avatar.bytes.byteLength),\n 'cache-control': current ? 'private, max-age=31536000, immutable' : 'no-store',\n 'x-content-type-options': 'nosniff',\n });\n response.end(avatar.bytes);\n return;\n }\n if (suffix === '/file' && request.method === 'GET') {\n await writeResponse(\n response,\n await sessionFile(\n session,\n url.searchParams.get('path'),\n request.headers.range,\n request.headers['if-match'] as string | undefined,\n ),\n );\n return;\n }\n if (suffix === '/attachments' && request.method === 'POST') {\n let bytes: Uint8Array;\n try {\n bytes = await readBody(request);\n } catch (error) {\n if (!(error instanceof RequestBodyTooLargeError)) throw error;\n json(response, 413, { error: 'The attachment exceeds the 8 MB upload limit.' });\n return;\n }\n json(response, 201, await writeSessionAttachment(sessionId, url.searchParams.get('name') ?? 'file', bytes));\n return;\n }\n if (suffix === '/restart' && request.method === 'POST' && options.restartSession) {\n // A restart closes the host, and closing aborts the running turn.\n if ((session.phase ?? 'idle') !== 'idle') {\n json(response, 409, { error: RESTART_WHILE_RUNNING_ERROR });\n return;\n }\n const restart = options.restartSession(session);\n // Settled either way: a failed restart leaves the session dormant, and waiters then see that.\n const settled = restart.then(\n () => undefined,\n () => undefined,\n );\n restarting.set(sessionId, settled);\n try {\n await restart;\n } finally {\n if (restarting.get(sessionId) === settled) restarting.delete(sessionId);\n }\n json(response, 200, { ok: true });\n return;\n }\n if (suffix === '/resume' && request.method === 'POST' && options.resumeSession) {\n const body = parseJson(await readBody(request));\n const targetSessionId =\n body && typeof body === 'object' && 'targetSessionId' in body ? body.targetSessionId : undefined;\n if (typeof targetSessionId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(targetSessionId)) {\n json(response, 400, { error: 'Invalid target session id.' });\n return;\n }\n if (\n options.headlessHub.computerUse?.ownsSession?.(targetSessionId) &&\n !computerUseAuthorized(targetSessionId, request)\n ) {\n json(response, 404, { error: 'This session belongs to its Desktop instance.' });\n return;\n }\n json(response, 200, { sessionId: await options.resumeSession(session, targetSessionId) });\n return;\n }\n if (suffix === '/channels' && request.method === 'GET') {\n json(response, 200, {\n channels: options.headlessHub\n .channelFrames(sessionId)\n .filter((frame) => frame.type !== 'computer_use_state' || computerUseAuthorized(sessionId, request)),\n });\n return;\n }\n const channelMatch = /^\\/channel\\/([^/]+)$/u.exec(suffix);\n if (channelMatch !== null && request.method === 'POST') {\n const frameType = decodeURIComponent(channelMatch[1]);\n const connectionId = request.headers['x-po-connection'];\n options.headlessHub.receiveChannel(\n sessionId,\n frameType,\n parseJson(await readBody(request)),\n typeof connectionId === 'string' ? connectionId : 'http',\n desktopAuthorized(request),\n computerUseAuthorized(sessionId, request),\n );\n json(response, 202, { ok: true });\n return;\n }\n json(response, 404, { error: 'Not found.' });\n }\n\n server.on('upgrade', (request, socket, head) => {\n const url = requestPath(request);\n const mount = parseDoomSocketPath(url.pathname);\n if (!mount) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n if (!authorized(request, options.token)) {\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n if (\n mount.scope !== 'global' &&\n (!options.headlessHub.workspaces().some((entry) => entry.id === mount.workspaceId && entry.available !== false) ||\n (mount.scope === 'session' && options.headlessHub.session(mount.sessionId)?.workspaceId !== mount.workspaceId))\n ) {\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n const prepare =\n mount.scope === 'global' && options.headlessHub.computerUse === undefined\n ? Promise.resolve(protocol)\n : createHeadlessProtocol({\n hub: options.headlessHub,\n mount,\n telemetry: options.telemetry,\n onNotice: options.onNotice,\n dormantSessions: dormant,\n authorizeSession: (id) =>\n !options.headlessHub.computerUse?.ownsSession?.(id) || computerUseAuthorized(id, request),\n authorizeComputerUse: (id) => computerUseAuthorized(id, request),\n authorizeDesktop: () => desktopAuthorized(request),\n });\n void prepare\n .then(async (selected) => {\n if (closed || socket.destroyed) {\n if (selected !== protocol) await selected.close();\n socket.destroy();\n return;\n }\n if (selected !== protocol) {\n scopedProtocols.add(selected);\n socket.once('close', () => {\n void selected.close().finally(() => scopedProtocols.delete(selected));\n });\n }\n webSockets.handleUpgrade(request, socket, head, (client) => {\n webSockets.emit('connection', client, selected);\n });\n })\n .catch(() => {\n socket.destroy();\n });\n });\n webSockets.on('connection', (socket, selected: typeof protocol) => {\n const handler = selected.accept(socket);\n if (!handler) return;\n const client: Client = { socket, handler };\n clients.add(client);\n socket.on('message', (data) => {\n if (Buffer.isBuffer(data)) handler.onData(data);\n else if (Array.isArray(data)) handler.onData(Buffer.concat(data));\n else handler.onData(new Uint8Array(data as ArrayBuffer));\n });\n socket.on('close', () => {\n clients.delete(client);\n handler.onClose();\n });\n socket.on('error', (error) => handler.onError(error));\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(options.port, options.host ?? '127.0.0.1', () => resolve());\n });\n const address = server.address();\n if (address === null || typeof address === 'string') {\n await new Promise<void>((resolve) => server.close(() => resolve()));\n throw new Error('The headless server did not expose a TCP address.');\n }\n const host = options.host ?? '127.0.0.1';\n const url = `http://${host}:${address.port}`;\n return {\n url,\n sessionReservations: sessionMcp.reservations,\n async close() {\n if (closed) return;\n closed = true;\n unsubscribe();\n for (const response of sse.keys()) response.end();\n sse.clear();\n for (const client of clients) client.socket.terminate();\n clients.clear();\n sessionMcp.close();\n if (options.sessionMcpStateDir === undefined)\n await fs.promises.rm(sessionMcpStateDir, { recursive: true, force: true });\n await Promise.all([protocol.close(), ...[...scopedProtocols].map((selected) => selected.close())]);\n webSockets.close();\n server.closeAllConnections();\n await new Promise<void>((resolve, reject) =>\n server.close((error) => (error === undefined ? resolve() : reject(error))),\n );\n },\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"headlessServer.d.mts","names":[],"sources":["../src/server/headlessServer.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;qBAuDa,+BAA6B;;qBAY7B;iBAGI;EACf,aAAa;EACb;EACA;;EAEA;EACA,YAAY;EACZ,YAAY;EACZ;EACA,gBAAgB,SAAS,YAAY,QAAQ;EAC7C,kBAAkB,SAAS,uBAAuB,QAAQ;EAC1D,oBAAoB,wBAAwB,QAAQ;EACpD,0BAA0B,qBAAqB,4BAA4B;EAC3E,yBACE,QAAQ,mBACR,SAAS,uBACT,SAAS,YACN,QAAQ;EACb,kBAAkB,SAAS,uBAAuB;EAClD,iBAAiB,SAAS,oBAAoB,4BAA4B;;EAE1E,iCAAiC;EACjC,wBAAwB,QAAQ,6BAA6B;EAC7D,iBAAiB,QAAQ,sBAAsB;;EAE/C;;EAEA;;EAEA;EACA,sBAAsB,mBAAmB;;iBAG1B;WACN;WACA,qBAAqB;EAC9B,SAAS;;;;;;;wBAsTW,oBAAoB,SAAS,wBAAwB,QAAQ"}
1
+ {"version":3,"file":"headlessServer.d.mts","names":[],"sources":["../src/server/headlessServer.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;qBAuDa,+BAA6B;;qBAY7B;iBAGI;EACf,aAAa;EACb;EACA;;EAEA;EACA,YAAY;EACZ,YAAY;EACZ;EACA,gBAAgB,SAAS,YAAY,QAAQ;EAC7C,kBAAkB,SAAS,uBAAuB,QAAQ;EAC1D,oBAAoB,wBAAwB,QAAQ;EACpD,0BAA0B,qBAAqB,4BAA4B;EAC3E,yBACE,QAAQ,mBACR,SAAS,uBACT,SAAS,YACN,QAAQ;EACb,kBAAkB,SAAS,uBAAuB;EAClD,iBAAiB,SAAS,oBAAoB,4BAA4B;;EAE1E,iCAAiC;EACjC,wBAAwB,QAAQ,6BAA6B;EAC7D,iBAAiB,QAAQ,sBAAsB;;EAE/C;;EAEA;;EAEA;EACA,sBAAsB,mBAAmB;;iBAG1B;WACN;WACA,qBAAqB;EAC9B,SAAS;;;;;;;wBA8VW,oBAAoB,SAAS,wBAAwB,QAAQ"}