hyperbrane 0.1.0 → 0.1.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 (150) hide show
  1. package/README.md +41 -3
  2. package/dist/agent/agentService.d.ts +11 -3
  3. package/dist/agent/agentService.js +63 -19
  4. package/dist/agent/agentStorage.d.ts +2 -0
  5. package/dist/agent/agentStorage.js +4 -2
  6. package/dist/agent/api.d.ts +83 -32
  7. package/dist/agent/api.js +7 -0
  8. package/dist/agent/client.d.ts +3 -0
  9. package/dist/agent/client.js +5 -0
  10. package/dist/agent/hostTranscript.d.ts +13 -0
  11. package/dist/agent/hostTranscript.js +190 -0
  12. package/dist/agent/session/backend.d.ts +82 -0
  13. package/dist/agent/session/backend.js +1 -0
  14. package/dist/agent/session/claude/home.d.ts +2 -0
  15. package/dist/agent/session/claude/home.js +4 -0
  16. package/dist/agent/session/claude/transcript.d.ts +13 -0
  17. package/dist/agent/session/claude/transcript.js +29 -0
  18. package/dist/agent/session/client.d.ts +5 -1
  19. package/dist/agent/session/codex/home.d.ts +2 -0
  20. package/dist/agent/session/codex/home.js +4 -0
  21. package/dist/agent/session/codex/messages.d.ts +30 -0
  22. package/dist/agent/session/codex/messages.js +135 -0
  23. package/dist/agent/session/codex/transcript.d.ts +12 -0
  24. package/dist/agent/session/codex/transcript.js +22 -0
  25. package/dist/agent/session/fileTranscript.d.ts +92 -0
  26. package/dist/agent/session/fileTranscript.js +454 -0
  27. package/dist/agent/session/sdkMessages.d.ts +15 -0
  28. package/dist/agent/session/sdkMessages.js +28 -0
  29. package/dist/agent/session/sessionStorage.d.ts +4 -0
  30. package/dist/agent/session/sessionStorage.js +13 -2
  31. package/dist/agent/session/sharedConnection.d.ts +1 -0
  32. package/dist/agent/session/storedTranscripts.d.ts +13 -0
  33. package/dist/agent/session/storedTranscripts.js +8 -0
  34. package/dist/agent/session/worker/protocol.d.ts +5 -1
  35. package/dist/agent/session/worker/protocol.js +6 -1
  36. package/dist/agent/session/worker/workerParams.d.ts +11 -0
  37. package/dist/agent/session/worker/workerParams.js +163 -0
  38. package/dist/agent/session/workerSseConnection.d.ts +20 -4
  39. package/dist/agent/session/workerSseConnection.js +57 -7
  40. package/dist/agent/vendor-types/codex/app-server/AbsolutePathBuf.d.ts +10 -0
  41. package/dist/agent/vendor-types/codex/app-server/AbsolutePathBuf.js +2 -0
  42. package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputBody.d.ts +2 -0
  43. package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputBody.js +2 -0
  44. package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputContentItem.d.ts +22 -0
  45. package/dist/agent/vendor-types/codex/app-server/FunctionCallOutputContentItem.js +2 -0
  46. package/dist/agent/vendor-types/codex/app-server/ImageDetail.d.ts +1 -0
  47. package/dist/agent/vendor-types/codex/app-server/ImageDetail.js +2 -0
  48. package/dist/agent/vendor-types/codex/app-server/ImageGenerationFailure.d.ts +5 -0
  49. package/dist/agent/vendor-types/codex/app-server/ImageGenerationFailure.js +2 -0
  50. package/dist/agent/vendor-types/codex/app-server/ImageGenerationItem.d.ts +11 -0
  51. package/dist/agent/vendor-types/codex/app-server/ImageGenerationItem.js +2 -0
  52. package/dist/agent/vendor-types/codex/app-server/LegacyAppPathString.d.ts +23 -0
  53. package/dist/agent/vendor-types/codex/app-server/LegacyAppPathString.js +2 -0
  54. package/dist/agent/vendor-types/codex/app-server/MessagePhase.d.ts +7 -0
  55. package/dist/agent/vendor-types/codex/app-server/MessagePhase.js +2 -0
  56. package/dist/agent/vendor-types/codex/app-server/ReasoningEffort.d.ts +4 -0
  57. package/dist/agent/vendor-types/codex/app-server/ReasoningEffort.js +2 -0
  58. package/dist/agent/vendor-types/codex/app-server/SleepItem.d.ts +7 -0
  59. package/dist/agent/vendor-types/codex/app-server/SleepItem.js +2 -0
  60. package/dist/agent/vendor-types/codex/app-server/WebSearchItem.d.ts +14 -0
  61. package/dist/agent/vendor-types/codex/app-server/WebSearchItem.js +2 -0
  62. package/dist/agent/vendor-types/codex/app-server/serde_json/JsonValue.d.ts +3 -0
  63. package/dist/agent/vendor-types/codex/app-server/serde_json/JsonValue.js +2 -0
  64. package/dist/agent/vendor-types/codex/app-server/v2/AgentMessageDelivery.d.ts +1 -0
  65. package/dist/agent/vendor-types/codex/app-server/v2/AgentMessageDelivery.js +2 -0
  66. package/dist/agent/vendor-types/codex/app-server/v2/AsyncUserInputQuestion.d.ts +4 -0
  67. package/dist/agent/vendor-types/codex/app-server/v2/AsyncUserInputQuestion.js +2 -0
  68. package/dist/agent/vendor-types/codex/app-server/v2/ByteRange.d.ts +4 -0
  69. package/dist/agent/vendor-types/codex/app-server/v2/ByteRange.js +2 -0
  70. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentState.d.ts +5 -0
  71. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentState.js +2 -0
  72. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentStatus.d.ts +1 -0
  73. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentStatus.js +2 -0
  74. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentTool.d.ts +1 -0
  75. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentTool.js +2 -0
  76. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentToolCallStatus.d.ts +1 -0
  77. package/dist/agent/vendor-types/codex/app-server/v2/CollabAgentToolCallStatus.js +2 -0
  78. package/dist/agent/vendor-types/codex/app-server/v2/CommandAction.d.ts +19 -0
  79. package/dist/agent/vendor-types/codex/app-server/v2/CommandAction.js +2 -0
  80. package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionSource.d.ts +1 -0
  81. package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionSource.js +2 -0
  82. package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionStatus.d.ts +1 -0
  83. package/dist/agent/vendor-types/codex/app-server/v2/CommandExecutionStatus.js +2 -0
  84. package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallOutputContentItem.d.ts +10 -0
  85. package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallOutputContentItem.js +2 -0
  86. package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallStatus.d.ts +1 -0
  87. package/dist/agent/vendor-types/codex/app-server/v2/DynamicToolCallStatus.js +2 -0
  88. package/dist/agent/vendor-types/codex/app-server/v2/FileUpdateChange.d.ts +6 -0
  89. package/dist/agent/vendor-types/codex/app-server/v2/FileUpdateChange.js +2 -0
  90. package/dist/agent/vendor-types/codex/app-server/v2/HookPromptFragment.d.ts +4 -0
  91. package/dist/agent/vendor-types/codex/app-server/v2/HookPromptFragment.js +2 -0
  92. package/dist/agent/vendor-types/codex/app-server/v2/McpAppDisplayMode.d.ts +1 -0
  93. package/dist/agent/vendor-types/codex/app-server/v2/McpAppDisplayMode.js +2 -0
  94. package/dist/agent/vendor-types/codex/app-server/v2/McpAppUi.d.ts +8 -0
  95. package/dist/agent/vendor-types/codex/app-server/v2/McpAppUi.js +2 -0
  96. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallAppContext.d.ts +7 -0
  97. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallAppContext.js +2 -0
  98. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallError.d.ts +3 -0
  99. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallError.js +2 -0
  100. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallResult.d.ts +6 -0
  101. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallResult.js +2 -0
  102. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallStatus.d.ts +1 -0
  103. package/dist/agent/vendor-types/codex/app-server/v2/McpToolCallStatus.js +2 -0
  104. package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitation.d.ts +5 -0
  105. package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitation.js +2 -0
  106. package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitationEntry.d.ts +6 -0
  107. package/dist/agent/vendor-types/codex/app-server/v2/MemoryCitationEntry.js +2 -0
  108. package/dist/agent/vendor-types/codex/app-server/v2/PatchApplyStatus.d.ts +1 -0
  109. package/dist/agent/vendor-types/codex/app-server/v2/PatchApplyStatus.js +2 -0
  110. package/dist/agent/vendor-types/codex/app-server/v2/PatchChangeKind.d.ts +8 -0
  111. package/dist/agent/vendor-types/codex/app-server/v2/PatchChangeKind.js +2 -0
  112. package/dist/agent/vendor-types/codex/app-server/v2/SubAgentActivityKind.d.ts +1 -0
  113. package/dist/agent/vendor-types/codex/app-server/v2/SubAgentActivityKind.js +2 -0
  114. package/dist/agent/vendor-types/codex/app-server/v2/TextElement.d.ts +11 -0
  115. package/dist/agent/vendor-types/codex/app-server/v2/TextElement.js +2 -0
  116. package/dist/agent/vendor-types/codex/app-server/v2/ThreadItem.d.ts +215 -0
  117. package/dist/agent/vendor-types/codex/app-server/v2/ThreadItem.js +2 -0
  118. package/dist/agent/vendor-types/codex/app-server/v2/UserInput.d.ts +35 -0
  119. package/dist/agent/vendor-types/codex/app-server/v2/UserInput.js +2 -0
  120. package/dist/agent/vendor-types/codex/app-server/v2/WebSearchAction.d.ts +14 -0
  121. package/dist/agent/vendor-types/codex/app-server/v2/WebSearchAction.js +2 -0
  122. package/dist/agent/workerBundle.generated.js +1 -1
  123. package/dist/cli/agent.js +30 -4
  124. package/dist/cli/services.d.ts +6 -5
  125. package/dist/cli/services.js +4 -3
  126. package/dist/dimension/api.d.ts +5 -4
  127. package/dist/dimension/paths.d.ts +4 -0
  128. package/dist/dimension/paths.js +10 -2
  129. package/dist/dimension/service.d.ts +5 -1
  130. package/dist/dimension/service.js +5 -1
  131. package/dist/dimension/storage.js +3 -2
  132. package/dist/index.d.ts +2 -3
  133. package/dist/index.js +7 -5
  134. package/dist/lib/docker.d.ts +1 -0
  135. package/dist/portal-gateway/api.d.ts +6 -5
  136. package/dist/portal-gateway/gatewayService.d.ts +5 -1
  137. package/dist/portal-gateway/gatewayService.js +25 -13
  138. package/dist/portal-gateway/image.d.ts +1 -1
  139. package/dist/portal-gateway/image.js +1 -1
  140. package/dist/portal-gateway/imageFiles.generated.js +1 -1
  141. package/dist/portal-gateway/portalService.d.ts +2 -0
  142. package/dist/portal-gateway/portalService.js +61 -29
  143. package/dist/portal-gateway/upstream.d.ts +22 -11
  144. package/dist/sandbox/api.d.ts +60 -23
  145. package/dist/sandbox/boatService.js +11 -3
  146. package/dist/sandbox/containerService.js +10 -3
  147. package/dist/sandbox/endpointProxy.js +16 -1
  148. package/dist/sandbox/localService.js +20 -2
  149. package/dist/sandbox/sshService.js +37 -4
  150. package/package.json +25 -8
@@ -1,2 +1,2 @@
1
1
  // Generated by scripts/bundle-worker.ts — do not edit; run `bun run bundle:worker`.
2
- export const WORKER_SOURCE = "// @bun\n// agent/session/main.ts\nimport { chown } from \"fs/promises\";\n\n// sandbox/localService.ts\nimport { spawn } from \"child_process\";\nimport { link, mkdir, readFile, readdir, rename, rm, stat, unlink, writeFile } from \"fs/promises\";\nimport { request as httpRequest } from \"http\";\nimport { createConnection } from \"net\";\nimport { homedir } from \"os\";\nimport { Readable } from \"stream\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"path\";\n\n// sandbox/api.ts\nclass SandboxPathError extends Error {\n name = \"SandboxPathError\";\n}\n\nclass SandboxNotFoundError extends Error {\n name = \"SandboxNotFoundError\";\n}\n\nclass SandboxEndpointError extends Error {\n name = \"SandboxEndpointError\";\n}\n\n// sandbox/endpointProxy.ts\nfunction parseAccessibleHost(value) {\n const match = /^\\[(.+)\\]:(\\d+)$/.exec(value) ?? /^([^:]+):(\\d+)$/.exec(value);\n if (!match)\n return { host: value.replace(/^\\[(.+)\\]$/, \"$1\"), port: null };\n const port = Number(match[2]);\n checkPort(port);\n return { host: match[1], port };\n}\nvar BASIC_USER = \"hyperbrane\";\nfunction proxyCredentialsAuth() {\n return {\n bind({ host, port: pinned }) {\n const name = host.includes(\":\") ? `[${host}]` : host;\n return {\n firewall: true,\n plan({ scheme, port }) {\n if (scheme !== \"bearer\" && scheme !== \"basic\") {\n throw new SandboxEndpointError(`the endpoint proxy checks bearer or basic credentials, not \"${scheme}\"`);\n }\n const listen = pinnedPort(pinned, port);\n const secret = Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString(\"base64url\");\n const credentials = scheme === \"bearer\" ? { scheme, token: secret } : { scheme, username: BASIC_USER, password: secret };\n return {\n check: { scheme, credentials: scheme === \"bearer\" ? secret : btoa(`${BASIC_USER}:${secret}`) },\n ports: [listen ?? 0, listen ?? 0],\n publish: async (listening) => ({ url: `https://${name}:${listening}`, credentials })\n };\n }\n };\n }\n };\n}\nfunction pinnedPort(pinned, requested) {\n if (requested !== undefined)\n checkPort(requested);\n if (pinned !== null && requested !== undefined && requested !== pinned) {\n throw new SandboxEndpointError(`endpoints here listen on port ${pinned} (the accessible host's), not ${requested}`);\n }\n return pinned ?? requested ?? null;\n}\nfunction checkPort(port) {\n if (!Number.isInteger(port) || port < 1 || port > 65535)\n throw new SandboxEndpointError(`not a port: ${port}`);\n}\nvar ID_PATTERN = /^hyb-endpoint-(\\d+)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;\nvar ENDPOINT_NAME = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\nfunction parseEndpointId(endpointId) {\n const match = ID_PATTERN.exec(endpointId);\n if (!match)\n throw new SandboxEndpointError(`not an endpoint id: \"${endpointId}\"`);\n return { port: Number(match[1]), name: match[2] };\n}\nvar STATE = 'B=\"${B:-$HOME/.local/state/hyperbrane/endpoints}\"';\nvar RUNNING = `pid=$(cat \"$B/$P/.pid\" 2>/dev/null) && kill -0 \"$pid\" 2>/dev/null && ps -p \"$pid\" -o args= | grep -q hyb-endpoint-proxy`;\nvar START_SCRIPT = `${STATE}\nexec python3 -c \"$1\" hyb-endpoint-proxy \"$B\"`;\nvar READ_SCRIPT = `${STATE}\ncat \"$B/$P/$N.json\" 2>/dev/null || exit 1`;\nvar RUNNING_SCRIPT = `${STATE}\n${RUNNING}`;\nvar WRITE_SCRIPT = `${STATE}\numask 077\n[ -d \"$B/$P\" ] || exit 44\ncat > \"$B/$P/.$N.tmp\" && mv -f \"$B/$P/.$N.tmp\" \"$B/$P/$N.json\"`;\nvar STATUS_SCRIPT = `${STATE}\n[ -e \"$B/$P/$N.json\" ] || exit 1\n${RUNNING} || exit 3`;\nvar REMOVE_SCRIPT = `${STATE}\nrm -f \"$B/$P/$N.json\"\nfor other in \"$B/$P\"/*.json; do [ -e \"$other\" ] && exit 0; done\nif ${RUNNING}; then kill \"$pid\"; fi\nrm -rf \"$B/$P\"\nexit 10`;\nfunction createProxyEndpoints(commands, options, where) {\n const accessible = parseAccessibleHost(options.accessibleHost);\n const auth = (options.auth ?? proxyCredentialsAuth()).bind(accessible);\n const firewall = options.needsFirewall === true && auth.firewall;\n const env = (vars) => ({\n ...options.stateDirectory === undefined ? {} : { B: options.stateDirectory },\n ...Object.fromEntries(Object.entries(vars).map(([name, value]) => [name, String(value)]))\n });\n const sh = (script, vars, stdin) => commands.runCommand([\"sh\", \"-c\", script], { env: env(vars), stdin });\n async function ufw(...args) {\n const result = await commands.runCommand([\"sudo\", \"-n\", \"ufw\", ...args]);\n if (result.exitCode !== 0)\n throw new Error(`ufw ${args.join(\" \")} on ${where} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n async function running(port) {\n return (await sh(RUNNING_SCRIPT, { P: port })).exitCode === 0;\n }\n async function stop(port) {\n const result = await sh(REMOVE_SCRIPT, { P: port, N: \"-\" });\n if (result.exitCode === 10 && firewall)\n await ufw(\"delete\", \"allow\", `${port}/tcp`);\n }\n async function proxyFor(plan) {\n const [low, high] = plan.ports;\n if (low === high && low !== 0 && await running(low))\n return low;\n const port = await start(plan.ports, plan.except ?? []);\n if (port === null)\n throw new Error(`starting the endpoint proxy on ${where} failed: no free port in ${low}-${high}`);\n return port;\n }\n async function start(ports, except) {\n const [low, high] = ports;\n const result = await commands.runCommand([\"sh\", \"-c\", START_SCRIPT, \"sh\", PROXY], {\n env: env({}),\n stdin: `${JSON.stringify({ ports, except })}\n`\n });\n const port = Number(result.stdout.trim());\n if (result.exitCode !== 0 || !Number.isInteger(port) || port <= 0) {\n if (low === high && low !== 0 && await running(low))\n return low;\n if (/no free port/.test(result.stderr))\n return null;\n throw new Error(`starting the endpoint proxy on ${where} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);\n }\n if (firewall) {\n try {\n await ufw(\"allow\", `${port}/tcp`);\n } catch (error) {\n await stop(port).catch(() => {});\n throw error;\n }\n }\n return port;\n }\n function exposeEndpoint(request) {\n return exposeEndpointAs(crypto.randomUUID(), request);\n }\n async function exposeEndpointAs(name, request) {\n if (!ENDPOINT_NAME.test(name))\n throw new SandboxEndpointError(`not an endpoint name: \"${name}\"`);\n const { target, transport = \"http\", allowedOrigins = [] } = request;\n if (transport !== \"http\" && transport !== \"sse\")\n throw new SandboxEndpointError(`unknown transport: ${transport}`);\n const plan = auth.plan(request);\n const port = await proxyFor(plan);\n const id = `hyb-endpoint-${port}-${name}`;\n const published = await plan.publish(port);\n const kept = await sh(READ_SCRIPT, { P: port, N: name });\n if (kept.exitCode === 0) {\n const record2 = JSON.parse(kept.stdout);\n const same = JSON.stringify(record2.target) === JSON.stringify(target) && record2.transport === transport && [...record2.origins].sort().join(`\n`) === [...allowedOrigins].sort().join(`\n`) && (record2.check?.scheme ?? null) === (plan.check?.scheme ?? null);\n if (same)\n return { id, url: `${published.url}/${name}`, credentials: credentialsOf(record2.check, published.credentials), allowedOrigins };\n }\n const record = JSON.stringify({ target, transport, check: plan.check, origins: allowedOrigins });\n const written = await sh(WRITE_SCRIPT, { P: port, N: name }, record);\n if (written.exitCode !== 0) {\n throw new Error(`recording the endpoint for ${describe(target)} on ${where} failed (exit ${written.exitCode}): ${written.stderr.trim()}`);\n }\n return { id, url: `${published.url}/${name}`, credentials: published.credentials, allowedOrigins };\n }\n async function closeEndpoint(endpointId) {\n const { port, name } = parseEndpointId(endpointId);\n const result = await sh(REMOVE_SCRIPT, { P: port, N: name });\n if (result.exitCode !== 0 && result.exitCode !== 10) {\n throw new Error(`closing endpoint ${endpointId} on ${where} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n if (result.exitCode === 10 && firewall)\n await ufw(\"delete\", \"allow\", `${port}/tcp`);\n }\n async function ensureEndpoint(endpointId) {\n const { port, name } = parseEndpointId(endpointId);\n const status = await sh(STATUS_SCRIPT, { P: port, N: name });\n if (status.exitCode === 0)\n return true;\n if (status.exitCode === 1)\n return false;\n if (status.exitCode !== 3) {\n throw new Error(`checking endpoint ${endpointId} on ${where} failed (exit ${status.exitCode}): ${status.stderr.trim()}`);\n }\n if (await start([port, port], []) !== null)\n return true;\n await closeEndpoint(endpointId);\n return false;\n }\n return { accessibleHost: options.accessibleHost, exposeEndpoint, exposeEndpointAs, closeEndpoint, ensureEndpoint };\n}\nfunction credentialsOf(check, none) {\n if (!check)\n return none;\n if (check.scheme === \"bearer\")\n return { scheme: \"bearer\", token: check.credentials };\n const decoded = atob(check.credentials);\n const colon = decoded.indexOf(\":\");\n return { scheme: \"basic\", username: decoded.slice(0, colon), password: decoded.slice(colon + 1) };\n}\nfunction describe(target) {\n return \"port\" in target ? `port ${target.port}` : target.unix;\n}\nvar PROXY = String.raw`\nimport errno, hmac, json, os, random, re, secrets, socket, sys, threading, urllib.parse\n\nconfig = json.loads(sys.stdin.readline())\nMAX_LINE = 16 * 1024 * 1024\nHEARTBEAT = 15\nPREFLIGHT = b\"Access-Control-Allow-Methods: GET, POST, OPTIONS\\r\\nAccess-Control-Allow-Headers: authorization, content-type\\r\\nAccess-Control-Max-Age: 600\\r\\n\"\nMAX_HEAD = 65536\nHEAD_TIMEOUT = 30\nHOP_BY_HOP = {b\"authorization\", b\"connection\", b\"keep-alive\", b\"proxy-connection\", b\"proxy-authorization\"}\nENDPOINT_NAME = re.compile(r\"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$\")\n\n\ndef listen(port):\n if socket.has_dualstack_ipv6():\n return socket.create_server((\"\", port), family=socket.AF_INET6, dualstack_ipv6=True, backlog=128)\n return socket.create_server((\"\", port), backlog=128)\n\n\nlow, high = config[\"ports\"]\ncandidates = [port for port in range(low, high + 1) if port not in config[\"except\"]]\nrandom.shuffle(candidates)\nserver = None\nfor port in candidates:\n try:\n server = listen(port)\n break\n except OSError as e:\n if e.errno != errno.EADDRINUSE:\n raise\nif server is None:\n sys.stderr.write(\"no free port in %d-%d\\n\" % (low, high))\n sys.exit(1)\nPORT = server.getsockname()[1]\n\n# Endpoints recorded by a proxy that's gone (a reboot) are served again, as they were given out;\n# only that proxy's own leftovers (its pid, half-written records) go.\nos.umask(0o077)\nDIR = os.path.join(sys.argv[2], str(PORT))\nos.makedirs(DIR, mode=0o700, exist_ok=True)\nfor stale in os.listdir(DIR):\n if stale.startswith(\".\"):\n os.remove(os.path.join(DIR, stale))\n\n# Detached; the port is printed once the proxy's pid is recorded, so whoever started it can find it.\nready_read, ready_write = os.pipe()\nif os.fork():\n os.close(ready_write)\n if os.read(ready_read, 2) != b\"ok\":\n sys.exit(1)\n sys.stdout.write(\"%d\\n\" % PORT)\n sys.stdout.flush()\n os._exit(0)\nos.setsid()\nif os.fork():\n os._exit(0)\nwith open(os.path.join(DIR, \".pid\"), \"w\") as pid_file:\n pid_file.write(str(os.getpid()))\nos.write(ready_write, b\"ok\")\nos.close(ready_write)\nnull = os.open(os.devnull, os.O_RDWR)\nfor fd in (0, 1, 2):\n os.dup2(null, fd)\n\n\ndef record_path(name):\n return os.path.join(DIR, name + \".json\")\n\n\ndef load(name):\n \"\"\"The endpoint recorded under that name, or None.\"\"\"\n if not ENDPOINT_NAME.match(name):\n return None\n try:\n with open(record_path(name)) as record:\n return json.load(record)\n except (OSError, ValueError):\n return None\n\n\nclass Reply(Exception):\n \"\"\"Answers the request with an empty body and ends the connection: a refusal, a 204, a redirect.\"\"\"\n\n def __init__(self, status, extra=b\"\"):\n self.status = status\n self.extra = extra\n\n\nclass Reader:\n def __init__(self, conn):\n self.conn = conn\n self.buffer = b\"\"\n\n def fill(self):\n data = self.conn.recv(65536)\n if not data:\n raise Reply(b\"400 Bad Request\")\n self.buffer += data\n\n def until(self, marker, limit):\n while marker not in self.buffer:\n if len(self.buffer) > limit:\n raise Reply(b\"431 Request Header Fields Too Large\")\n self.fill()\n found, self.buffer = self.buffer.split(marker, 1)\n return found\n\n def exactly(self, size):\n while len(self.buffer) < size:\n self.fill()\n found, self.buffer = self.buffer[:size], self.buffer[size:]\n return found\n\n\ndef parse(head):\n lines = head.split(b\"\\r\\n\")\n if any(c in line for line in lines for c in (b\"\\r\", b\"\\n\", b\"\\0\")):\n raise Reply(b\"400 Bad Request\")\n method, sep, rest = lines[0].partition(b\" \")\n path, sep2, version = rest.partition(b\" \")\n if not (sep and sep2 and method and path.startswith(b\"/\")) or version not in (b\"HTTP/1.1\", b\"HTTP/1.0\"):\n raise Reply(b\"400 Bad Request\")\n headers = []\n for line in lines[1:]:\n name, sep, value = line.partition(b\":\")\n if not sep or not name or any(c in name for c in b\" \\t\"):\n raise Reply(b\"400 Bad Request\")\n headers.append((name, value.strip()))\n return method, path, version, headers\n\n\ndef header(headers, name):\n for n, v in headers:\n if n.lower() == name:\n return v\n return None\n\n\ndef authorized(headers, check):\n values = [v for n, v in headers if n.lower() == b\"authorization\"]\n if len(values) != 1:\n return False\n scheme, _, credentials = values[0].partition(b\" \")\n return scheme.lower() == check[\"scheme\"].encode() and hmac.compare_digest(credentials.strip(), check[\"credentials\"].encode())\n\n\ndef challenge(check):\n if check[\"scheme\"] == \"basic\":\n return b'WWW-Authenticate: Basic realm=\"hyperbrane\", charset=\"UTF-8\"\\r\\n'\n return b\"WWW-Authenticate: Bearer\\r\\n\"\n\n\ndef cors_headers(origin, endpoint):\n if origin is None or origin.decode(\"latin-1\") not in endpoint[\"origins\"]:\n return b\"\"\n return b\"Access-Control-Allow-Origin: \" + origin + b\"\\r\\nAccess-Control-Allow-Credentials: true\\r\\nVary: Origin\\r\\n\"\n\n\ndef framing(headers):\n lengths = [v for n, v in headers if n.lower() == b\"content-length\"]\n encodings = [v for n, v in headers if n.lower() == b\"transfer-encoding\"]\n if encodings:\n if lengths or len(encodings) != 1 or encodings[0].lower() != b\"chunked\":\n raise Reply(b\"400 Bad Request\")\n return \"chunked\"\n if len(lengths) > 1 or (lengths and not lengths[0].isdigit()):\n raise Reply(b\"400 Bad Request\")\n return int(lengths[0]) if lengths else 0\n\n\ndef forward_body(reader, up, body):\n if body == \"chunked\":\n while True:\n line = reader.until(b\"\\r\\n\", 4096)\n size_text = line.split(b\";\", 1)[0].strip()\n if not size_text or any(c not in b\"0123456789abcdefABCDEF\" for c in size_text):\n raise Reply(b\"400 Bad Request\")\n size = int(size_text, 16)\n if size == 0:\n # Trailers are dropped: read up to the blank line that ends them.\n while reader.until(b\"\\r\\n\", MAX_HEAD):\n pass\n up.sendall(b\"0\\r\\n\\r\\n\")\n return\n data = reader.exactly(size)\n if reader.exactly(2) != b\"\\r\\n\":\n raise Reply(b\"400 Bad Request\")\n up.sendall(b\"%x\\r\\n\" % size + data + b\"\\r\\n\")\n remaining = body\n while remaining:\n data = reader.exactly(min(remaining, 65536))\n up.sendall(data)\n remaining -= len(data)\n\n\ndef tune(sock):\n # Streams (an agent's, as SSE) go out event by event, and a peer that vanished without closing\n # is noticed within a couple of minutes instead of holding its connection forever.\n sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)\n if sock.family == socket.AF_UNIX:\n return\n sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n for name, value in ((\"TCP_KEEPIDLE\", 60), (\"TCP_KEEPINTVL\", 15), (\"TCP_KEEPCNT\", 4)):\n if hasattr(socket, name):\n sock.setsockopt(socket.IPPROTO_TCP, getattr(socket, name), value)\n\n\ndef connect_target(target):\n if \"unix\" in target:\n up = socket.socket(socket.AF_UNIX)\n up.connect(target[\"unix\"])\n else:\n up = socket.create_connection((\"localhost\", target[\"port\"]))\n tune(up)\n return up\n\n\ndef hang_up(sock):\n # shutdown, not just close: it also wakes a thread blocked reading the socket.\n if sock is None:\n return\n try:\n sock.shutdown(socket.SHUT_RDWR)\n except OSError:\n pass\n try:\n sock.close()\n except OSError:\n pass\n\n\ndef pump_response(up, conn, decided, state):\n \"\"\"Copies the target's side to the client until either end goes away, then closes the client's.\"\"\"\n first = b\"\"\n try:\n while True:\n data = up.recv(65536)\n if not data:\n break\n if not decided.is_set():\n first += data\n if b\"\\r\\n\" in first or len(first) > 64:\n state[\"upgraded\"] = first.startswith((b\"HTTP/1.1 101\", b\"HTTP/1.0 101\"))\n decided.set()\n conn.sendall(data)\n except OSError:\n pass\n finally:\n decided.set()\n hang_up(conn)\n\n\nclass Collect:\n \"\"\"forward_body's destination for a body kept here (a POST to an \"sse\" connection).\"\"\"\n\n def __init__(self):\n self.data = b\"\"\n\n def sendall(self, data):\n self.data += data\n if len(self.data) > MAX_LINE:\n raise Reply(b\"413 Content Too Large\")\n\n\nclass Connection:\n \"\"\"An \"sse\" connection to an endpoint's target; POSTs write to it, one at a time.\"\"\"\n\n def __init__(self, endpoint_name, sock):\n self.endpoint_name = endpoint_name\n self.sock = sock\n self.lock = threading.Lock()\n\n def write(self, data):\n with self.lock:\n self.sock.sendall(data)\n\n\nCONNECTIONS = {}\nCONNECTIONS_LOCK = threading.Lock()\n\n\ndef serve_sse(conn, reader, method, rest, body, cors, name, endpoint):\n if rest in (b\"\", b\"/\"):\n if method != b\"GET\":\n raise Reply(b\"405 Method Not Allowed\", b\"Allow: GET\\r\\n\" + cors)\n return stream_target(conn, cors, name, endpoint)\n if method != b\"POST\" or rest.count(b\"/\") != 1:\n raise Reply(b\"404 Not Found\", cors)\n with CONNECTIONS_LOCK:\n target = CONNECTIONS.get(rest[1:].decode(\"ascii\", \"replace\"))\n if target is None or target.endpoint_name != name:\n raise Reply(b\"404 Not Found\", cors)\n collected = Collect()\n forward_body(reader, collected, body)\n try:\n target.write(collected.data)\n except OSError:\n raise Reply(b\"404 Not Found\", cors)\n raise Reply(b\"204 No Content\", cors)\n\n\ndef watch_client(conn, up):\n # Anything the client sends after its request is dropped; its leaving ends the connection.\n try:\n while conn.recv(65536):\n pass\n except OSError:\n pass\n hang_up(up)\n\n\ndef heartbeat(send, stop, name, up):\n while not stop.wait(HEARTBEAT):\n # A closed endpoint takes its streams with it.\n if not os.path.exists(record_path(name)):\n hang_up(up)\n return\n try:\n send(b\": ping\\n\\n\")\n except OSError:\n return\n\n\ndef stream_target(conn, cors, name, endpoint):\n try:\n up = connect_target(endpoint[\"target\"])\n except OSError:\n raise Reply(b\"502 Bad Gateway\", cors)\n connection_id = secrets.token_hex(16)\n lock = threading.Lock()\n\n def send(data):\n with lock:\n conn.sendall(data)\n\n stop = threading.Event()\n with CONNECTIONS_LOCK:\n CONNECTIONS[connection_id] = Connection(name, up)\n try:\n conn.settimeout(None)\n send(b\"HTTP/1.1 200 OK\\r\\nContent-Type: text/event-stream\\r\\nCache-Control: no-cache, no-transform\\r\\nX-Accel-Buffering: no\\r\\nConnection: close\\r\\n\" + cors + b\"\\r\\n\")\n send(b\"event: open\\ndata: \" + json.dumps({\"connection\": connection_id}).encode() + b\"\\n\\n\")\n threading.Thread(target=heartbeat, args=(send, stop, name, up), daemon=True).start()\n threading.Thread(target=watch_client, args=(conn, up), daemon=True).start()\n pending = b\"\"\n while True:\n data = up.recv(65536)\n if not data:\n break\n *lines, pending = (pending + data).split(b\"\\n\")\n for line in lines:\n if line.endswith(b\"\\r\"):\n line = line[:-1]\n # A bare CR would end the event early on the client: the line can't go as SSE.\n if b\"\\r\" in line:\n return\n send(b\"data: \" + line + b\"\\n\\n\")\n if len(pending) > MAX_LINE:\n return\n send(b\"event: close\\ndata: {}\\n\\n\")\n except OSError:\n pass\n finally:\n stop.set()\n with CONNECTIONS_LOCK:\n CONNECTIONS.pop(connection_id, None)\n hang_up(up)\n hang_up(conn)\n\n\ndef return_to(method, query):\n if method != b\"GET\":\n raise Reply(b\"405 Method Not Allowed\", b\"Allow: GET\\r\\n\")\n to = urllib.parse.parse_qs(query.decode(\"latin-1\")).get(\"to\", [\"\"])[0]\n parts = urllib.parse.urlsplit(to)\n if parts.scheme not in (\"http\", \"https\") or not parts.netloc or any(ord(c) < 0x21 or ord(c) > 0x7E for c in to):\n raise Reply(b\"400 Bad Request\")\n origin = parts.scheme + \"://\" + parts.netloc\n for entry in os.listdir(DIR):\n endpoint = load(entry[:-5]) if entry.endswith(\".json\") else None\n if endpoint is not None and endpoint[\"check\"] is None and origin in endpoint[\"origins\"]:\n raise Reply(b\"302 Found\", b\"Location: \" + to.encode() + b\"\\r\\nCache-Control: no-store\\r\\n\")\n raise Reply(b\"400 Bad Request\")\n\n\ndef handle(conn):\n up = None\n try:\n conn.settimeout(HEAD_TIMEOUT)\n reader = Reader(conn)\n method, path, version, headers = parse(reader.until(b\"\\r\\n\\r\\n\", MAX_HEAD))\n route, _, query = path.partition(b\"?\")\n if route == b\"/__hyb/return\":\n return_to(method, query)\n name_bytes, slash, rest = route[1:].partition(b\"/\")\n name = name_bytes.decode(\"ascii\", \"replace\")\n endpoint = load(name)\n if endpoint is None:\n raise Reply(b\"404 Not Found\")\n cors = cors_headers(header(headers, b\"origin\"), endpoint)\n # A browser's preflight carries no credentials; it is answered here and never reaches the target.\n if method == b\"OPTIONS\" and header(headers, b\"access-control-request-method\") is not None:\n raise Reply(b\"204 No Content\", cors + PREFLIGHT) if cors else Reply(b\"403 Forbidden\")\n check = endpoint[\"check\"]\n if check and not authorized(headers, check):\n raise Reply(b\"401 Unauthorized\", challenge(check) + cors)\n body = framing(headers)\n if endpoint[\"transport\"] == \"sse\":\n return serve_sse(conn, reader, method, slash + rest, body, cors, name, endpoint)\n upgrade = any(n.lower() == b\"upgrade\" for n, _ in headers)\n try:\n up = connect_target(endpoint[\"target\"])\n except OSError:\n raise Reply(b\"502 Bad Gateway\", cors)\n target_path = slash + rest if slash else b\"/\"\n if query:\n target_path += b\"?\" + query\n kept = [n + b\": \" + v for n, v in headers if n.lower() not in HOP_BY_HOP]\n kept.append(b\"Connection: Upgrade\" if upgrade else b\"Connection: close\")\n up.sendall(method + b\" \" + target_path + b\" \" + version + b\"\\r\\n\" + b\"\\r\\n\".join(kept) + b\"\\r\\n\\r\\n\")\n decided = threading.Event()\n state = {\"upgraded\": False}\n # The request is done once the response is: the client side closes with it.\n pump = threading.Thread(target=pump_response, args=(up, conn, decided, state), daemon=True)\n pump.start()\n forward_body(reader, up, body)\n conn.settimeout(None)\n if upgrade:\n decided.wait()\n if upgrade and state[\"upgraded\"]:\n if reader.buffer:\n up.sendall(reader.buffer)\n while True:\n data = conn.recv(65536)\n if not data:\n break\n up.sendall(data)\n else:\n # Anything more from the client is dropped: it would reach the target unchecked.\n while conn.recv(65536):\n pass\n # The client is gone (or the response ended and closed it): a stream it was reading stops too.\n hang_up(up)\n pump.join()\n except Reply as reply:\n try:\n conn.sendall(b\"HTTP/1.1 \" + reply.status + b\"\\r\\nContent-Length: 0\\r\\nConnection: close\\r\\n\" + reply.extra + b\"\\r\\n\")\n except OSError:\n pass\n except (OSError, ValueError):\n pass\n finally:\n hang_up(up)\n hang_up(conn)\n\n\nwhile True:\n conn, _ = server.accept()\n tune(conn)\n threading.Thread(target=handle, args=(conn,), daemon=True).start()\n`;\n\n// sandbox/localService.ts\nfunction createLocalSandbox(root, { endpoints } = {}) {\n const base = resolve(root);\n function hostPath(path) {\n const full = resolve(base, isAbsolute(path) ? `.${path}` : path);\n const rel = relative(base, full);\n if (rel.startsWith(\"..\") || isAbsolute(rel))\n throw new SandboxPathError(`Path escapes sandbox: \"${path}\"`);\n return full;\n }\n async function notFoundAs(path, operation) {\n try {\n return await operation;\n } catch (error) {\n if (error.code === \"ENOENT\")\n throw new SandboxNotFoundError(`Not found: \"${path}\"`);\n throw error;\n }\n }\n async function writeTemp(full, data) {\n await mkdir(dirname(full), { recursive: true });\n const tmp = join(dirname(full), `.${basename(full)}.${crypto.randomUUID()}.tmp`);\n await writeFile(tmp, data);\n return tmp;\n }\n async function readFileLocal(path) {\n return new Uint8Array(await notFoundAs(path, readFile(hostPath(path))));\n }\n async function writeFileLocal(path, data) {\n const full = hostPath(path);\n await rename(await writeTemp(full, data), full);\n }\n async function writeFileExclusive(path, data) {\n const full = hostPath(path);\n const tmp = await writeTemp(full, data);\n try {\n await link(tmp, full);\n return true;\n } catch (error) {\n if (error.code === \"EEXIST\")\n return false;\n throw error;\n } finally {\n await unlink(tmp);\n }\n }\n async function removeFile(path) {\n await rm(hostPath(path), { force: true });\n }\n async function createDirectory(path) {\n await mkdir(hostPath(path), { recursive: true });\n }\n async function removeDirectory(path) {\n await rm(hostPath(path), { recursive: true, force: true });\n }\n async function listDirectory(path) {\n return notFoundAs(path, readdir(hostPath(path)));\n }\n async function statLocal(path) {\n const stats = await notFoundAs(path, stat(hostPath(path)));\n const type = stats.isFile() ? \"file\" : stats.isDirectory() ? \"directory\" : \"other\";\n return { type, uid: stats.uid, gid: stats.gid };\n }\n async function homeDirectory() {\n const rel = relative(base, homedir());\n if (rel.startsWith(\"..\") || isAbsolute(rel))\n throw new SandboxPathError(`Home directory is outside the sandbox`);\n return `/${rel}`;\n }\n function runCommand(cmd, { cwd, env = {}, stdin } = {}) {\n return new Promise((resolve2, reject) => {\n const [command, ...args] = cmd;\n if (!command)\n return reject(new Error(\"no command to run\"));\n const child = spawn(command, args, {\n cwd: hostPath(cwd ?? \".\"),\n env: { ...process.env, ...env },\n stdio: [stdin === undefined ? \"ignore\" : \"pipe\", \"pipe\", \"pipe\"]\n });\n const stdout = [];\n const stderr = [];\n child.stdout.on(\"data\", (chunk) => stdout.push(chunk));\n child.stderr.on(\"data\", (chunk) => stderr.push(chunk));\n child.once(\"error\", reject);\n child.once(\"close\", (code) => resolve2({ exitCode: code ?? -1, stdout: Buffer.concat(stdout).toString(), stderr: Buffer.concat(stderr).toString() }));\n if (stdin !== undefined)\n child.stdin.end(stdin);\n });\n }\n async function connect(path) {\n return socketConnection(createConnection({ path: hostPath(path) }), path);\n }\n async function fetchLocal(url, { unix, ...init } = {}) {\n if (unix === undefined || \"Bun\" in globalThis)\n return fetch(url, { ...init, unix: unix === undefined ? undefined : hostPath(unix) });\n return fetchOverSocket(url, hostPath(unix), init);\n }\n const sandbox = {\n readFile: readFileLocal,\n writeFile: writeFileLocal,\n writeFileExclusive,\n removeFile,\n createDirectory,\n removeDirectory,\n listDirectory,\n stat: statLocal,\n homeDirectory,\n runCommand,\n fetch: fetchLocal,\n connect\n };\n if (!endpoints)\n return sandbox;\n return { ...sandbox, ...createProxyEndpoints({ runCommand }, endpoints, \"this machine\") };\n}\nfunction fetchOverSocket(url, socketPath, { method = \"GET\", headers = {}, body, signal, timeout }) {\n return new Promise((resolve2, reject) => {\n const target = new URL(url);\n const request = httpRequest({ socketPath, path: `${target.pathname}${target.search}`, method, headers: { host: target.host, ...headers }, signal }, (response) => {\n const responseHeaders = new Headers;\n for (let i = 0;i + 1 < response.rawHeaders.length; i += 2)\n responseHeaders.append(response.rawHeaders[i], response.rawHeaders[i + 1]);\n const status = response.statusCode ?? 502;\n const nullBody = status === 204 || status === 304 || method === \"HEAD\";\n if (nullBody)\n response.resume();\n resolve2(new Response(nullBody ? null : Readable.toWeb(response), { status, headers: responseHeaders }));\n });\n request.once(\"error\", reject);\n if (typeof timeout === \"number\")\n request.setTimeout(timeout, () => request.destroy(new Error(`fetch ${url}: no data for ${timeout}ms`)));\n request.end(body === undefined ? undefined : typeof body === \"string\" ? body : Buffer.from(body));\n });\n}\nfunction socketConnection(stream, path, { opened = false } = {}) {\n return new Promise((resolve2, reject) => {\n let markClosed;\n const closed = new Promise((done) => markClosed = done);\n const listeners = [];\n stream.on(\"data\", (chunk) => {\n for (const listener of listeners)\n listener(new Uint8Array(chunk));\n });\n stream.once(\"close\", () => markClosed());\n stream.once(\"end\", () => markClosed());\n const connection = {\n write: (data) => void stream.write(data),\n onData: (listener) => void listeners.push(listener),\n closed,\n close: () => stream.end()\n };\n stream.once(\"error\", (error) => {\n markClosed();\n reject(new Error(`connecting to ${path} failed: ${error.message}`));\n });\n if (opened)\n resolve2(connection);\n else\n stream.once(\"connect\", () => resolve2(connection));\n });\n}\n\n// agent/session/login.ts\nfunction plain(text) {\n return text.replace(/\\x1b\\][^\\x07\\x1b]*(\\x07|\\x1b\\\\)/g, \"\").replace(/\\x1b\\[[0-9;?]*[a-zA-Z]/g, \"\");\n}\nfunction spawnLogin(cmd, { env, cwd }, parse) {\n const proc = Bun.spawn(cmd, { env, cwd, stdin: \"pipe\", stdout: \"pipe\", stderr: \"pipe\" });\n let output = \"\";\n let showPrompt;\n let noPrompt;\n const prompt = new Promise((resolve2, reject) => {\n showPrompt = resolve2;\n noPrompt = reject;\n });\n async function read(stream) {\n const decoder = new TextDecoder;\n for await (const chunk of stream) {\n output += plain(decoder.decode(chunk, { stream: true }));\n const found = parse(output);\n if (found)\n showPrompt(found);\n }\n }\n const reading = Promise.all([read(proc.stdout), read(proc.stderr)]);\n const done = reading.then(() => proc.exited).then((code) => {\n const tail = output.trim().split(`\n`).slice(-3).join(\" \").trim();\n noPrompt(new Error(`the login ended before showing where to sign in: ${tail}`));\n if (code !== 0)\n throw new Error(`the login failed (exit ${code}): ${tail}`);\n });\n prompt.catch(() => {});\n done.catch(() => {});\n return {\n prompt,\n done,\n submitCode(code) {\n proc.stdin.write(`${code}\n`);\n proc.stdin.flush();\n },\n cancel() {\n proc.kill();\n }\n };\n}\n\n// agent/session/claude/provision.ts\nimport { existsSync } from \"fs\";\n// agent/vendor-types/manifest.json\nvar manifest_default = {\n claude: {\n docs: \"https://code.claude.com/docs/en/agent-sdk/typescript\",\n sources: [\n {\n source: \"npm:@anthropic-ai/claude-agent-sdk@0.3.283\",\n into: \"agent-sdk\",\n files: 7\n }\n ]\n },\n codex: {\n docs: \"https://developers.openai.com/codex/app-server\",\n sources: [\n {\n source: \"npm:@openai/codex-sdk@0.157.1\",\n into: \"sdk\",\n files: 1\n },\n {\n source: \"github:openai/codex@rust-v0.157.1/codex-rs/app-server-protocol/schema/typescript\",\n into: \"app-server\",\n files: 740\n },\n {\n source: \"github:openai/codex@rust-v0.157.1/codex-rs/app-server-protocol/schema/json\",\n into: \"app-server-json\",\n files: 2\n }\n ]\n },\n pi: {\n docs: \"https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/rpc.md\",\n sources: [\n {\n source: \"npm:@mariozechner/pi-coding-agent@0.73.1\",\n into: \"coding-agent\",\n files: 137\n },\n {\n source: \"npm:@mariozechner/pi-agent-core@0.73.1\",\n into: \"agent-core\",\n files: 5\n },\n {\n source: \"npm:@mariozechner/pi-ai@0.73.1\",\n into: \"ai\",\n files: 44\n }\n ]\n },\n opencode: {\n docs: \"https://opencode.ai/docs/server\",\n sources: [\n {\n source: \"npm:@opencode-ai/sdk@1.18.32\",\n into: \"sdk\",\n files: 39\n },\n {\n source: \"github:anomalyco/opencode@v1.18.32/packages/sdk\",\n into: \"\",\n files: 1\n }\n ]\n },\n openclaw: {\n docs: \"https://docs.openclaw.ai/gateway/protocol\",\n sources: [\n {\n source: \"npm:@openclaw/gateway-protocol@2026.9.6\",\n into: \"gateway-protocol\",\n files: 17\n }\n ]\n },\n hermes: {\n docs: \"https://hermes-agent.nousresearch.com/docs\",\n sources: [\n {\n source: \"github:NousResearch/hermes-agent@v2026.9.24/apps/shared/src\",\n into: \"gateway\",\n files: 3\n }\n ]\n }\n};\n\n// agent/session/install.ts\nfunction pinnedVersion(vendor, pkg, sourcePackage = pkg) {\n const prefix = `npm:${sourcePackage}@`;\n const source = manifest_default[vendor].sources.find((entry) => entry.source.startsWith(prefix));\n if (!source)\n throw new Error(`agent/vendor-types/manifest.json has no ${sourcePackage} for ${vendor} (needed for ${pkg})`);\n return source.source.slice(prefix.length);\n}\nasync function installPackage(installDir, pkg, version) {\n const installed = Bun.file(`${installDir}/node_modules/${pkg}/package.json`);\n if (await installed.exists() && (await installed.json()).version === version)\n return;\n const proc = Bun.spawn([process.execPath, \"add\", \"--exact\", `${pkg}@${version}`], {\n cwd: installDir,\n stdin: \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\"\n });\n const [stdout, stderr, exitCode] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n proc.exited\n ]);\n if (exitCode !== 0)\n throw new Error(`bun add ${pkg}@${version} failed (exit ${exitCode}): ${(stderr || stdout).trim()}`);\n}\n\n// agent/session/claude/provision.ts\nvar CLAUDE_SDK_PACKAGE = \"@anthropic-ai/claude-agent-sdk\";\nfunction installClaude(installDir) {\n return installPackage(installDir, CLAUDE_SDK_PACKAGE, pinnedVersion(\"claude\", CLAUDE_SDK_PACKAGE));\n}\nfunction claudeExecutable(installDir) {\n const base = `${installDir}/node_modules/${CLAUDE_SDK_PACKAGE}-linux-${process.arch}`;\n const glibc = `${base}/claude`;\n return existsSync(glibc) ? glibc : `${base}-musl/claude`;\n}\n\n// agent/session/claude/auth.ts\nvar GATEWAY_CODE = \"x#x\";\nvar claudeAuth = {\n async signedIn({ installDir, env, cwd }) {\n const proc = Bun.spawn([claudeExecutable(installDir), \"auth\", \"status\", \"--json\"], { env, cwd, stdout: \"pipe\", stderr: \"ignore\" });\n const [output, code] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);\n if (code !== 0)\n return false;\n try {\n return JSON.parse(output).loggedIn === true;\n } catch {\n return false;\n }\n },\n login({ installDir, env, cwd }, gatewaySignedIn) {\n const login = spawnLogin([claudeExecutable(installDir), \"auth\", \"login\"], { env, cwd }, (output) => {\n const url = /https:\\/\\/\\S*oauth\\/authorize\\S*/.exec(output)?.[0];\n return url ? { url, needsCode: true } : null;\n });\n if (gatewaySignedIn)\n login.prompt.then(() => login.submitCode(GATEWAY_CODE), () => {});\n return login;\n }\n};\n\n// agent/api.ts\nvar AGENT_BACKENDS = [\"claude\", \"codex\"];\n\nclass AgentInvalidError extends Error {\n name = \"AgentInvalidError\";\n}\n\nclass AgentNotFoundError extends Error {\n name = \"AgentNotFoundError\";\n}\n\nclass AgentConflictError extends Error {\n name = \"AgentConflictError\";\n}\n\n// agent/session/claude/backgroundTasks.ts\nfunction claudeBackgroundTasks() {\n let tasks = [];\n return {\n observe(message) {\n if (message.type !== \"system\")\n return;\n if (message.subtype === \"background_tasks_changed\")\n tasks = message.tasks;\n if (message.subtype === \"task_notification\")\n tasks = tasks.filter((task) => task.task_id !== message.task_id);\n },\n list: async () => tasks\n };\n}\nfunction claudeStopTask(query, tasks) {\n return async (taskId) => {\n if (!(await tasks.list()).some((task) => task.task_id === taskId))\n throw new AgentNotFoundError(`no background task ${taskId}`);\n await query.stopTask(taskId);\n };\n}\n\n// agent/session/claude/input.ts\nfunction createPromptQueue() {\n const queued = [];\n let wake;\n let closed = false;\n function push(message) {\n queued.push(message);\n wake?.();\n }\n function close() {\n closed = true;\n wake?.();\n }\n async function* iterate() {\n for (;; ) {\n while (queued.length > 0)\n yield queued.shift();\n if (closed)\n return;\n await new Promise((resolve2) => wake = resolve2);\n wake = undefined;\n }\n }\n return { push, close, [Symbol.asyncIterator]: iterate };\n}\nfunction claudeInput(prompts, queue) {\n return async (message) => {\n if (!message.uuid)\n throw new Error(\"a message sent to claude needs a uuid to be acknowledged by\");\n const received = queue.sent({ ...message, uuid: message.uuid });\n prompts.push(message);\n await received;\n };\n}\n\n// agent/session/claude/messageQueue.ts\nvar RECEIVE_TIMEOUT_MS = 60000;\nfunction claudeMessageQueue() {\n const commands = new Map;\n let taken = null;\n const receipts = new Map;\n function observe(message) {\n const event = message;\n if (event.type !== \"command_lifecycle\" || !event.command_uuid || !event.state)\n return;\n const command = commands.get(event.command_uuid);\n if (command) {\n command.state = event.state;\n if (event.state === \"started\")\n taken = command.message;\n if (event.state !== \"queued\")\n commands.delete(event.command_uuid);\n }\n const receipt = receipts.get(event.command_uuid);\n if (!receipt)\n return;\n receipts.delete(event.command_uuid);\n if (event.state === \"queued\" || event.state === \"started\")\n receipt.resolve();\n else\n receipt.reject(new Error(`claude ${event.state} the message`));\n }\n function sent(message) {\n commands.set(message.uuid, { message, state: null });\n return new Promise((resolve2, reject) => {\n const timer = setTimeout(() => {\n receipts.delete(message.uuid);\n commands.delete(message.uuid);\n reject(new Error(\"claude didn't confirm it received the message\"));\n }, RECEIVE_TIMEOUT_MS);\n receipts.set(message.uuid, {\n resolve: () => (clearTimeout(timer), resolve2()),\n reject: (error) => (clearTimeout(timer), commands.delete(message.uuid), reject(error))\n });\n });\n }\n async function lastUserMessages() {\n const queued = [...commands.values()].filter((command) => command.state === \"queued\");\n return [...taken ? [{ message: taken, queued: false }] : [], ...queued.map((command) => ({ message: command.message, queued: true }))];\n }\n return { observe, sent, lastUserMessages };\n}\n\n// agent/session/claude/status.ts\nvar SESSION_STATE_EVENTS = { CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: \"1\" };\nfunction claudeStatus() {\n let status = \"idle\";\n return {\n observe(message) {\n if (message.type !== \"system\" || message.subtype !== \"session_state_changed\")\n return;\n status = message.state === \"requires_action\" ? \"waiting\" : message.state;\n },\n status: async () => status\n };\n}\n\n// agent/session/claude/interrupt.ts\nfunction claudeInterrupt(query) {\n return async () => {\n await query.interrupt();\n };\n}\n\n// agent/session/claude/model.ts\nfunction claudeModel(query) {\n return {\n listModels: () => query.supportedModels(),\n setModel: (model) => query.setModel(model ?? undefined)\n };\n}\n\n// agent/session/sdkMessages.ts\nvar ASK_USER_QUESTION = \"AskUserQuestion\";\nfunction resultUsage({ input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } = {}) {\n return {\n input_tokens: input,\n output_tokens: output,\n cache_read_input_tokens: cacheRead,\n cache_creation_input_tokens: cacheWrite,\n cache_creation: { ephemeral_1h_input_tokens: 0, ephemeral_5m_input_tokens: 0 },\n server_tool_use: { web_fetch_requests: 0, web_search_requests: 0 },\n service_tier: \"standard\"\n };\n}\nfunction userMessageText(message) {\n const content = message.message.content;\n if (typeof content === \"string\")\n return content;\n if (!Array.isArray(content))\n return \"\";\n return content.map((block) => block.type === \"text\" && typeof block.text === \"string\" ? block.text : \"\").filter(Boolean).join(`\n`);\n}\n\n// agent/session/claude/permissions.ts\nfunction claudePermissions(context, questions) {\n const canUseTool = (toolName, input, options) => {\n if (toolName === ASK_USER_QUESTION)\n return questions.answer(input, options);\n const { signal, toolUseID, decisionReason } = options;\n return context.requestPermission({ tool_name: toolName, input, tool_use_id: toolUseID, decision_reason: decisionReason }, signal);\n };\n const preToolUse = [\n {\n hooks: [async () => ({ hookSpecificOutput: { hookEventName: \"PreToolUse\", permissionDecision: \"ask\" } })]\n }\n ];\n return { canUseTool, preToolUse };\n}\n\n// agent/session/claude/questions.ts\nvar QUESTION_DIALOG_KINDS = [\"permission_ask_user_question\", \"ask_user_question\", \"user_question\"];\nfunction claudeQuestions(context) {\n async function ask(input, toolUseId, signal) {\n const questions = Array.isArray(input.questions) ? input.questions : [];\n const response = await context.askQuestions({ tool_use_id: toolUseId, questions }, signal);\n if (!response)\n return { behavior: \"deny\", message: \"The user dismissed the questions.\" };\n return { behavior: \"allow\", updatedInput: { ...input, answers: response.answers } };\n }\n const onUserDialog = async (request, { signal }) => {\n if (!QUESTION_DIALOG_KINDS.includes(request.dialogKind))\n return { behavior: \"cancelled\" };\n const result = await ask(request.payload, request.toolUseID ?? crypto.randomUUID(), signal);\n if (result.behavior !== \"allow\")\n return { behavior: \"cancelled\" };\n return { behavior: \"completed\", result };\n };\n return {\n answer: (input, { signal, toolUseID }) => ask(input, toolUseID, signal),\n onUserDialog,\n supportedDialogKinds: QUESTION_DIALOG_KINDS\n };\n}\n\n// agent/session/claude/sdk.ts\nasync function loadClaudeSdk(installDir) {\n return await import(Bun.resolveSync(CLAUDE_SDK_PACKAGE, installDir));\n}\n\n// agent/session/claude/stream.ts\nasync function startClaudeStream(context, prompts, permissions, questions, backgroundTasks, status, queue) {\n const sdk = await loadClaudeSdk(context.installDir);\n const query = sdk.query({\n prompt: prompts,\n options: {\n cwd: context.cwd,\n env: { ...context.env, ...SESSION_STATE_EVENTS },\n model: context.model ?? undefined,\n resume: context.nativeId ?? undefined,\n includePartialMessages: true,\n permissionMode: \"default\",\n settingSources: [],\n canUseTool: permissions.canUseTool,\n hooks: { PreToolUse: permissions.preToolUse },\n onUserDialog: questions.onUserDialog,\n supportedDialogKinds: questions.supportedDialogKinds,\n stderr: (data) => process.stderr.write(`[claude ${context.spec.name}] ${data}`)\n }\n });\n pump(context, query, [backgroundTasks, status, queue]).then(() => context.exited(), (error) => context.exited(error));\n return query;\n}\nasync function pump(context, query, observers) {\n for await (const message of query) {\n for (const observer of observers)\n observer.observe(message);\n if (\"session_id\" in message && typeof message.session_id === \"string\" && message.session_id) {\n context.setNativeId(message.session_id);\n }\n const streamed = toStreamingMessage(message);\n if (streamed)\n context.emit(streamed);\n }\n}\nfunction toStreamingMessage(message) {\n switch (message.type) {\n case \"assistant\":\n case \"stream_event\":\n case \"result\":\n return message;\n case \"user\":\n return { ...message, uuid: message.uuid ?? crypto.randomUUID(), session_id: message.session_id ?? \"\" };\n case \"system\":\n return message.subtype === \"init\" ? message : null;\n default:\n return null;\n }\n}\n\n// agent/session/fileTranscript.ts\nvar CHUNK_BYTES = 64 * 1024;\nvar NEWLINE = 10;\nfunction createFileTranscript(locate, lineMessages) {\n function parse(bytes, start) {\n try {\n return { start, messages: lineMessages(JSON.parse(new TextDecoder().decode(bytes))) };\n } catch {\n return { start, messages: [] };\n }\n }\n async function* backward(path, end) {\n const file = Bun.file(path);\n let position = end;\n let carry = new Uint8Array(0);\n while (position > 0) {\n const from = Math.max(0, position - CHUNK_BYTES);\n const chunk = new Uint8Array(await file.slice(from, position).arrayBuffer());\n const bytes = joined(chunk, carry);\n let lineEnd = bytes.length;\n for (let index = bytes.length - 1;index >= 0; index--) {\n if (bytes[index] !== NEWLINE)\n continue;\n if (lineEnd > index + 1)\n yield parse(bytes.subarray(index + 1, lineEnd), from + index + 1);\n lineEnd = index;\n }\n carry = bytes.slice(0, lineEnd);\n position = from;\n }\n if (carry.length > 0)\n yield parse(carry, 0);\n }\n async function* forward(path, start, end) {\n const file = Bun.file(path);\n let position = start;\n let carry = new Uint8Array(0);\n let carryStart = start;\n while (position < end) {\n const to = Math.min(end, position + CHUNK_BYTES);\n const bytes = joined(carry, new Uint8Array(await file.slice(position, to).arrayBuffer()));\n let lineStart = 0;\n for (let index = 0;index < bytes.length; index++) {\n if (bytes[index] !== NEWLINE)\n continue;\n if (index > lineStart)\n yield parse(bytes.subarray(lineStart, index), carryStart + lineStart);\n lineStart = index + 1;\n }\n carry = bytes.slice(lineStart);\n carryStart += lineStart;\n position = to;\n }\n if (carry.length > 0)\n yield parse(carry, carryStart);\n }\n async function page(cursor, limit) {\n const path = await locate();\n if (!path) {\n if (cursor !== null)\n throw new AgentInvalidError(`no transcript for cursor ${cursor}`);\n return { messages: [], nextCursor: null };\n }\n const size = Bun.file(path).size;\n const end = cursor === null ? size : Number(cursor);\n if (!Number.isInteger(end) || end < 0 || end > size)\n throw new AgentInvalidError(`invalid transcript cursor ${cursor}`);\n const lines = [];\n let count = 0;\n let older = false;\n for await (const line of backward(path, end)) {\n if (line.messages.length === 0)\n continue;\n if (count >= limit) {\n older = true;\n break;\n }\n lines.push(line);\n count += line.messages.length;\n }\n return {\n messages: lines.reverse().flatMap((line) => line.messages),\n nextCursor: older ? String(lines[0].start) : null\n };\n }\n async function replay(afterId, emit) {\n const path = await locate();\n if (!path)\n return afterId === undefined;\n const end = Bun.file(path).size;\n let start = 0;\n if (afterId !== undefined) {\n let found = null;\n for await (const line of backward(path, end)) {\n if (line.messages.some((message) => message.uuid === afterId)) {\n found = line;\n break;\n }\n }\n if (!found)\n return false;\n start = found.start;\n }\n let passed = afterId === undefined;\n for await (const line of forward(path, start, end)) {\n for (const message of line.messages) {\n if (passed)\n emit(message);\n else if (message.uuid === afterId)\n passed = true;\n }\n }\n return true;\n }\n return { page, replay };\n}\nfunction joined(first, second) {\n if (first.length === 0)\n return second;\n if (second.length === 0)\n return first;\n const bytes = new Uint8Array(first.length + second.length);\n bytes.set(first);\n bytes.set(second, first.length);\n return bytes;\n}\n\n// agent/session/claude/transcript.ts\nfunction claudeTranscript({ nativeId, env }) {\n const projects = `${env.CLAUDE_CONFIG_DIR ?? `${env.HOME}/.claude`}/projects`;\n return createFileTranscript(async () => {\n try {\n for await (const path of new Bun.Glob(`*/${nativeId}.jsonl`).scan({ cwd: projects, absolute: true }))\n return path;\n } catch {}\n return null;\n }, claudeLineMessages);\n}\nfunction claudeLineMessages(line) {\n const entry = line;\n if (entry.type !== \"user\" && entry.type !== \"assistant\")\n return [];\n if (entry.isSidechain || entry.isMeta || !entry.uuid || !entry.message)\n return [];\n return [{ type: entry.type, message: entry.message, parent_tool_use_id: null, uuid: entry.uuid, session_id: entry.sessionId ?? \"\" }];\n}\n\n// agent/session/claude/index.ts\nvar claudeBackend = {\n install: installClaude,\n auth: claudeAuth,\n transcript: claudeTranscript,\n homeEnvironment: (home) => ({ CLAUDE_CONFIG_DIR: home }),\n async start(context) {\n const prompts = createPromptQueue();\n const questions = claudeQuestions(context);\n const backgroundTasks = claudeBackgroundTasks();\n const status = claudeStatus();\n const queue = claudeMessageQueue();\n const query = await startClaudeStream(context, prompts, claudePermissions(context, questions), questions, backgroundTasks, status, queue);\n return {\n sendMessage: claudeInput(prompts, queue),\n getSessionStatus: status.status,\n getLastUserMessages: queue.lastUserMessages,\n cancel: claudeInterrupt(query),\n ...claudeModel(query),\n listBackgroundTasks: backgroundTasks.list,\n stopTask: claudeStopTask(query, backgroundTasks),\n async close() {\n prompts.close();\n query.close();\n }\n };\n }\n};\n\n// agent/session/codex/provision.ts\nvar CODEX_PACKAGE = \"@openai/codex\";\nfunction installCodex(installDir) {\n return installPackage(installDir, CODEX_PACKAGE, pinnedVersion(\"codex\", CODEX_PACKAGE, \"@openai/codex-sdk\"));\n}\nvar LINUX_TARGETS = {\n x64: { pkg: \"@openai/codex-linux-x64\", triple: \"x86_64-unknown-linux-musl\" },\n arm64: { pkg: \"@openai/codex-linux-arm64\", triple: \"aarch64-unknown-linux-musl\" }\n};\nfunction codexExecutable(installDir) {\n const target = LINUX_TARGETS[process.arch];\n if (process.platform !== \"linux\" || !target)\n throw new Error(`codex: unsupported platform ${process.platform}/${process.arch}`);\n return {\n path: `${installDir}/node_modules/${target.pkg}/vendor/${target.triple}/bin/codex`,\n env: { CODEX_MANAGED_PACKAGE_ROOT: `${installDir}/node_modules/${CODEX_PACKAGE}`, CODEX_MANAGED_BY_BUN: \"1\" }\n };\n}\n\n// agent/session/codex/auth.ts\nfunction run({ installDir, env, cwd }, args) {\n const executable = codexExecutable(installDir);\n return { cmd: [executable.path, ...args], env: { ...env, ...executable.env }, cwd };\n}\nvar codexAuth = {\n async signedIn(environment) {\n const { cmd, env, cwd } = run(environment, [\"login\", \"status\"]);\n const proc = Bun.spawn(cmd, { env, cwd, stdout: \"ignore\", stderr: \"ignore\" });\n return await proc.exited === 0;\n },\n login(environment) {\n const { cmd, env, cwd } = run(environment, [\"login\", \"--device-auth\"]);\n return spawnLogin(cmd, { env, cwd }, (output) => {\n const url = /https:\\/\\/\\S+\\/device\\S*/.exec(output)?.[0];\n const userCode = /^\\s*([A-Z0-9]{4}-[A-Z0-9]{4,})\\s*$/m.exec(output)?.[1];\n return url && userCode ? { url, userCode, needsCode: false } : null;\n });\n }\n};\n\n// agent/session/codex/backgroundTasks.ts\nimport { readdirSync, readFileSync } from \"fs\";\nvar STOP_GRACE_MS = 1000;\nfunction codexBackgroundTasks() {\n const running = new Map;\n const background = new Map;\n function observe(notification) {\n switch (notification.method) {\n case \"item/started\": {\n const { item } = notification.params;\n if (item.type === \"commandExecution\")\n running.set(item.id, { task_id: item.id, task_type: \"local_bash\", description: item.command });\n return;\n }\n case \"item/completed\": {\n const { item } = notification.params;\n if (item.type !== \"commandExecution\")\n return;\n running.delete(item.id);\n background.delete(item.id);\n return;\n }\n case \"turn/completed\":\n for (const [id, task] of running)\n background.set(id, task);\n running.clear();\n return;\n }\n }\n async function stop(taskId, appServerPid) {\n const task = background.get(taskId);\n if (!task)\n throw new AgentNotFoundError(`no background task ${taskId}`);\n const targets = commandProcesses(appServerPid, task.description);\n signal(targets, \"SIGTERM\");\n const deadline = Date.now() + STOP_GRACE_MS;\n while (targets.some(alive) && Date.now() < deadline)\n await Bun.sleep(50);\n signal(targets.filter(alive), \"SIGKILL\");\n background.delete(taskId);\n }\n return { observe, list: async () => [...background.values()], stop };\n}\nfunction processes() {\n const entries = [];\n for (const name of readdirSync(\"/proc\")) {\n if (!/^\\d+$/.test(name))\n continue;\n try {\n const stat2 = readFileSync(`/proc/${name}/stat`, \"utf8\");\n const ppid = Number(stat2.slice(stat2.lastIndexOf(\")\") + 2).split(\" \")[1]);\n const argv = readFileSync(`/proc/${name}/cmdline`, \"utf8\").split(\"\\x00\").filter(Boolean);\n entries.push({ pid: Number(name), ppid, argv });\n } catch {}\n }\n return entries;\n}\nfunction commandProcesses(root, command) {\n const all = processes();\n const children = new Map;\n for (const entry of all)\n children.set(entry.ppid, [...children.get(entry.ppid) ?? [], entry.pid]);\n const under = (pid) => (children.get(pid) ?? []).flatMap((child) => [child, ...under(child)]);\n const descendants = new Set(under(root));\n const shells = all.filter((entry) => descendants.has(entry.pid) && entry.argv.length >= 3 && [\"-c\", \"-lc\"].includes(entry.argv.at(-2)) && command.includes(entry.argv.at(-1)));\n return [...new Set(shells.flatMap((shell) => [shell.pid, ...under(shell.pid)]))];\n}\nfunction signal(pids, name) {\n for (const pid of pids) {\n try {\n process.kill(pid, name);\n } catch {}\n }\n}\nfunction alive(pid) {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// agent/session/codex/input.ts\nfunction createCodexInput(thread, queue, initialModel) {\n let model = initialModel;\n async function sendMessage(message) {\n if (!message.uuid)\n throw new Error(\"a message sent to codex needs a uuid to be known by\");\n const { rpc, threadId } = thread();\n await rpc.request(\"turn/start\", {\n threadId,\n input: [{ type: \"text\", text: userMessageText(message), text_elements: [] }],\n clientUserMessageId: message.uuid,\n model\n });\n queue.sent(message, message.uuid);\n }\n function setModel(next) {\n model = next;\n }\n return { sendMessage, setModel };\n}\n\n// agent/session/codex/messageQueue.ts\nfunction codexMessageQueue() {\n const queued = new Map;\n let taken = null;\n return {\n observe(notification) {\n if (notification.method !== \"item/started\")\n return;\n const { item } = notification.params;\n if (item.type !== \"userMessage\" || !item.clientId)\n return;\n const message = queued.get(item.clientId);\n if (!message)\n return;\n queued.delete(item.clientId);\n taken = message;\n },\n sent(message, clientId) {\n queued.set(clientId, message);\n },\n async lastUserMessages() {\n return [...taken ? [{ message: taken, queued: false }] : [], ...[...queued.values()].map((message) => ({ message, queued: true }))];\n }\n };\n}\n\n// agent/session/codex/status.ts\nfunction codexStatus() {\n let status = \"idle\";\n return {\n observe(notification) {\n if (notification.method !== \"thread/status/changed\")\n return;\n const reported = notification.params.status;\n if (reported.type === \"active\")\n status = reported.activeFlags.length > 0 ? \"waiting\" : \"running\";\n else if (reported.type === \"systemError\")\n status = \"error\";\n else\n status = \"idle\";\n },\n status: async () => status\n };\n}\n\n// agent/session/codex/interrupt.ts\nfunction codexInterrupt(thread) {\n return async () => {\n const { rpc, threadId, activeTurn } = thread();\n const turnId = activeTurn();\n if (!turnId)\n return;\n await rpc.request(\"turn/interrupt\", { threadId, turnId });\n };\n}\n\n// agent/session/codex/model.ts\nfunction codexModel(thread, input) {\n async function listModels() {\n const { data } = await thread().rpc.request(\"model/list\", {});\n return data.map((model) => ({ value: model.model, displayName: model.displayName, description: model.description }));\n }\n async function setModel(model) {\n input.setModel(model);\n }\n return { listModels, setModel };\n}\n\n// agent/session/codex/permissions.ts\nfunction codexPermissions(context) {\n function ask(request) {\n return context.requestPermission(request);\n }\n async function answer(request, rpc) {\n switch (request.method) {\n case \"item/commandExecution/requestApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"Bash\",\n input: { command: params.command ?? \"\", cwd: params.cwd },\n tool_use_id: params.itemId,\n decision_reason: params.reason ?? undefined\n });\n const response = { decision: decision.behavior === \"allow\" ? \"accept\" : \"decline\" };\n return rpc.respond(request.id, response);\n }\n case \"item/fileChange/requestApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"ApplyPatch\",\n input: { grantRoot: params.grantRoot ?? null },\n tool_use_id: params.itemId,\n decision_reason: params.reason ?? undefined\n });\n const response = { decision: decision.behavior === \"allow\" ? \"accept\" : \"decline\" };\n return rpc.respond(request.id, response);\n }\n case \"execCommandApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"Bash\",\n input: { command: params.command.join(\" \"), cwd: params.cwd },\n tool_use_id: params.callId,\n decision_reason: params.reason ?? undefined\n });\n const response = {\n decision: decision.behavior === \"allow\" ? \"approved\" : { denied: { rejection: decision.message } }\n };\n return rpc.respond(request.id, response);\n }\n case \"applyPatchApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"ApplyPatch\",\n input: { changes: params.fileChanges, grantRoot: params.grantRoot },\n tool_use_id: params.callId,\n decision_reason: params.reason ?? undefined\n });\n const response = {\n decision: decision.behavior === \"allow\" ? \"approved\" : { denied: { rejection: decision.message } }\n };\n return rpc.respond(request.id, response);\n }\n default:\n return rpc.respondError(request.id, `${request.method} is not supported by hyperbrane`);\n }\n }\n return (request, rpc) => {\n answer(request, rpc).catch((error) => {\n console.error(`answering codex's ${request.method} failed:`, error);\n rpc.respondError(request.id, error.message);\n });\n };\n}\n\n// agent/session/codex/questions.ts\nfunction codexQuestions(context, thread) {\n return async (params) => {\n const questions = params.questions.map((question) => ({\n question: question.question,\n header: question.header,\n options: question.options ?? [],\n multiSelect: false\n }));\n thread().emitToolUse(params.itemId, ASK_USER_QUESTION, { questions });\n const response = await context.askQuestions({ tool_use_id: params.itemId, questions });\n if (!response)\n thread().emitToolResult(params.itemId, \"The user dismissed the questions.\", true);\n else\n thread().emitToolResult(params.itemId, answersText(response.answers), false);\n const answers = {};\n for (const question of params.questions) {\n const answer = response?.answers[question.question];\n answers[question.id] = { answers: answer === undefined ? [] : [answer] };\n }\n return { answers };\n };\n}\nfunction answersText(answers) {\n const pairs = Object.entries(answers).map(([question, answer]) => `\"${question}\"=\"${answer}\"`);\n return `User has answered your questions: ${pairs.join(\", \")}.`;\n}\n\n// agent/session/codex/messages.ts\nfunction backendId(id) {\n return id;\n}\nfunction toolResultId(itemId) {\n return `${itemId}:result`;\n}\nfunction assistantMessage(uuid, content, threadId, model) {\n const usage = { ...resultUsage(), cache_creation: null, server_tool_use: null, service_tier: null };\n return {\n type: \"assistant\",\n message: {\n id: uuid,\n type: \"message\",\n role: \"assistant\",\n model,\n content,\n container: null,\n context_management: null,\n stop_reason: null,\n stop_sequence: null,\n usage\n },\n parent_tool_use_id: null,\n uuid: backendId(uuid),\n session_id: threadId\n };\n}\nfunction toolResultMessage(itemId, content, isError, threadId) {\n return {\n type: \"user\",\n message: { role: \"user\", content: [{ type: \"tool_result\", tool_use_id: itemId, content, is_error: isError }] },\n parent_tool_use_id: null,\n uuid: backendId(toolResultId(itemId)),\n session_id: threadId\n };\n}\nfunction itemMessages(item, threadId, model) {\n if (item.type === \"userMessage\") {\n const text = item.content.map((input) => input.type === \"text\" ? input.text : \"\").join(\"\");\n return [{ type: \"user\", message: { role: \"user\", content: text }, parent_tool_use_id: null, uuid: backendId(item.clientId ?? item.id), session_id: threadId }];\n }\n if (item.type === \"agentMessage\")\n return [assistantMessage(item.id, [{ type: \"text\", text: item.text, citations: null }], threadId, model)];\n const toolUse = toolUseOf(item);\n const toolResult = toolResultOf(item);\n if (!toolUse)\n return [];\n const messages = [assistantMessage(item.id, [toolUse], threadId, model)];\n if (toolResult)\n messages.push(toolResultMessage(item.id, toolResult.content, toolResult.is_error, threadId));\n return messages;\n}\nfunction shownCommand(argv) {\n return argv.map((arg) => /^[\\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll(\"'\", \"'\\\\''\")}'`).join(\" \");\n}\nfunction rolloutItemMessages(stored, threadId) {\n const item = stored;\n const text = (content) => (content ?? []).map((part) => part.text ?? \"\").join(\"\");\n if (item.type === \"UserMessage\" && \"content\" in item) {\n const user = item;\n return [{ type: \"user\", message: { role: \"user\", content: text(user.content) }, parent_tool_use_id: null, uuid: backendId(user.client_id ?? user.id), session_id: threadId }];\n }\n if (item.type === \"AgentMessage\" && item.id) {\n const agent = item;\n return [assistantMessage(agent.id, [{ type: \"text\", text: text(agent.content), citations: null }], threadId, \"\")];\n }\n if (item.type === \"CommandExecution\" && item.id) {\n const command = item;\n const input = { command: shownCommand(command.command ?? []), cwd: (command.cwd ?? \"\").replace(/^file:\\/\\//, \"\") };\n return [\n assistantMessage(command.id, [{ type: \"tool_use\", id: command.id, name: \"Bash\", input }], threadId, \"\"),\n toolResultMessage(command.id, command.aggregated_output ?? \"\", command.status !== \"completed\" || (command.exit_code ?? 0) !== 0, threadId)\n ];\n }\n return [];\n}\nfunction toolUseOf(item) {\n switch (item.type) {\n case \"commandExecution\":\n return { type: \"tool_use\", id: item.id, name: \"Bash\", input: { command: item.command, cwd: item.cwd } };\n case \"fileChange\":\n return { type: \"tool_use\", id: item.id, name: \"ApplyPatch\", input: { changes: item.changes } };\n case \"mcpToolCall\":\n return { type: \"tool_use\", id: item.id, name: `mcp__${item.server}__${item.tool}`, input: item.arguments };\n case \"dynamicToolCall\":\n return { type: \"tool_use\", id: item.id, name: item.tool, input: item.arguments };\n default:\n return null;\n }\n}\nfunction toolResultOf(item) {\n switch (item.type) {\n case \"commandExecution\":\n return {\n type: \"tool_result\",\n tool_use_id: item.id,\n content: item.aggregatedOutput ?? \"\",\n is_error: item.status !== \"completed\" || (item.exitCode ?? 0) !== 0\n };\n case \"fileChange\":\n return { type: \"tool_result\", tool_use_id: item.id, content: item.status, is_error: item.status !== \"completed\" };\n case \"mcpToolCall\":\n return {\n type: \"tool_result\",\n tool_use_id: item.id,\n content: JSON.stringify(item.error ?? item.result?.content ?? null),\n is_error: item.status !== \"completed\"\n };\n case \"dynamicToolCall\":\n return {\n type: \"tool_result\",\n tool_use_id: item.id,\n content: JSON.stringify(item.contentItems ?? null),\n is_error: item.success === false\n };\n default:\n return null;\n }\n}\n\n// agent/session/codex/transcript.ts\nfunction codexTranscript({ nativeId, env }) {\n const sessions = `${env.CODEX_HOME ?? `${env.HOME}/.codex`}/sessions`;\n return createFileTranscript(async () => {\n try {\n for await (const path of new Bun.Glob(`**/rollout-*-${nativeId}.jsonl`).scan({ cwd: sessions, absolute: true }))\n return path;\n } catch {}\n return null;\n }, (line) => {\n const { type, payload } = line;\n if (type !== \"event_msg\" || payload?.type !== \"item_completed\" || !payload.item)\n return [];\n return rolloutItemMessages(payload.item, nativeId);\n });\n}\n\n// lib/version.ts\nvar HYPERBRANE_VERSION = \"v1\";\n\n// agent/session/codex/rpc.ts\nvar METHOD_NOT_FOUND = -32601;\nfunction spawnCodexAppServer(executable, { cwd, env }, handlers) {\n const args = [\"app-server\", \"-c\", \"tools.experimental_request_user_input.enabled=true\", \"--enable\", \"default_mode_request_user_input\"];\n const proc = Bun.spawn([executable.path, ...args], {\n cwd,\n env: { ...env, ...executable.env },\n stdin: \"pipe\",\n stdout: \"pipe\",\n stderr: \"pipe\"\n });\n const pending = new Map;\n let nextId = 1;\n function send(message) {\n proc.stdin.write(JSON.stringify(message) + `\n`);\n proc.stdin.flush();\n }\n function dispatch(message) {\n if (message.id !== undefined && message.method === undefined) {\n const waiting = pending.get(message.id);\n pending.delete(message.id);\n if (message.error)\n waiting?.reject(new Error(`codex: ${message.error.message ?? JSON.stringify(message.error)}`));\n else\n waiting?.resolve(message.result);\n return;\n }\n if (message.id !== undefined)\n handlers.onRequest(message);\n else\n handlers.onNotification(message);\n }\n async function readLines() {\n const decoder = new TextDecoder;\n let buffered = \"\";\n for await (const chunk of proc.stdout) {\n buffered += decoder.decode(chunk, { stream: true });\n let newline;\n while ((newline = buffered.indexOf(`\n`)) >= 0) {\n const line = buffered.slice(0, newline).trim();\n buffered = buffered.slice(newline + 1);\n if (line)\n dispatch(JSON.parse(line));\n }\n }\n }\n async function forwardStderr() {\n for await (const chunk of proc.stderr)\n process.stderr.write(chunk);\n }\n forwardStderr().catch(() => {});\n readLines().then(() => proc.exited).then((code) => finish(code === 0 ? undefined : new Error(`codex app-server exited with code ${code}`)), (error) => finish(error));\n function finish(error) {\n for (const waiting of pending.values())\n waiting.reject(error ?? new Error(\"codex app-server exited\"));\n pending.clear();\n handlers.onExit(error);\n }\n function request(method, params) {\n const id = nextId++;\n return new Promise((resolve2, reject) => {\n pending.set(id, { resolve: (result) => resolve2(result), reject });\n send({ id, method, params });\n });\n }\n function notify(method) {\n send({ method });\n }\n function respond(id, result) {\n send({ id, result });\n }\n function respondError(id, message) {\n send({ id, error: { code: METHOD_NOT_FOUND, message } });\n }\n function close() {\n proc.stdin.end();\n proc.kill();\n }\n return { pid: proc.pid, request, notify, respond, respondError, close };\n}\n\n// agent/session/codex/stream.ts\nasync function startCodexStream(context, hooks) {\n let threadId = context.nativeId ?? \"\";\n let model = context.model ?? \"\";\n let turn = null;\n const rpc = spawnCodexAppServer(codexExecutable(context.installDir), { cwd: context.cwd, env: context.env }, {\n onNotification,\n onRequest: (request) => hooks.onServerRequest(request, rpc),\n onExit: (error) => context.exited(error)\n });\n function base() {\n return { parent_tool_use_id: null, uuid: crypto.randomUUID(), session_id: threadId };\n }\n function currentTurn(id) {\n turn ??= { id, startedAt: Date.now(), lastText: \"\", usage: null, errors: [] };\n turn.id ??= id;\n return turn;\n }\n function onNotification(notification) {\n for (const observer of hooks.observers)\n observer.observe(notification);\n switch (notification.method) {\n case \"turn/started\":\n currentTurn(notification.params.turn.id);\n return;\n case \"item/agentMessage/delta\":\n context.emit({\n type: \"stream_event\",\n event: { type: \"content_block_delta\", index: 0, delta: { type: \"text_delta\", text: notification.params.delta } },\n ...base()\n });\n return;\n case \"item/reasoning/summaryTextDelta\":\n case \"item/reasoning/textDelta\":\n context.emit({\n type: \"stream_event\",\n event: { type: \"content_block_delta\", index: 0, delta: { type: \"thinking_delta\", thinking: notification.params.delta } },\n ...base()\n });\n return;\n case \"item/started\": {\n const { item } = notification.params;\n const toolUse = toolUseOf(item);\n if (toolUse)\n context.emit(assistantMessage(item.id, [toolUse], threadId, model));\n return;\n }\n case \"item/completed\": {\n const { item } = notification.params;\n if (item.type === \"agentMessage\")\n currentTurn(notification.params.turnId).lastText = item.text;\n if (item.type === \"userMessage\")\n return;\n const messages = itemMessages(item, threadId, model);\n for (const message of toolUseOf(item) ? messages.slice(1) : messages)\n context.emit(message);\n return;\n }\n case \"thread/tokenUsage/updated\":\n currentTurn(notification.params.turnId).usage = notification.params.tokenUsage.last;\n return;\n case \"error\":\n if (!notification.params.willRetry)\n currentTurn(notification.params.turnId).errors.push(notification.params.error.message);\n return;\n case \"turn/completed\":\n context.emit(resultOf(currentTurn(notification.params.turn.id), notification.params.turn));\n turn = null;\n return;\n }\n }\n function resultOf(state, finished) {\n const duration = finished.durationMs ?? Date.now() - state.startedAt;\n const usage = resultUsage({\n input: state.usage?.inputTokens,\n output: state.usage?.outputTokens,\n cacheRead: state.usage?.cachedInputTokens,\n cacheWrite: state.usage?.cacheWriteInputTokens\n });\n const common = {\n duration_ms: duration,\n duration_api_ms: duration,\n num_turns: 1,\n total_cost_usd: 0,\n usage,\n modelUsage: {},\n permission_denials: [],\n uuid: crypto.randomUUID(),\n session_id: threadId\n };\n if (finished.status === \"completed\") {\n return { type: \"result\", subtype: \"success\", is_error: false, result: state.lastText, stop_reason: \"end_turn\", ...common };\n }\n const errors = [...state.errors];\n if (finished.error)\n errors.push(finished.error.message);\n if (errors.length === 0)\n errors.push(`turn ${finished.status}`);\n return { type: \"result\", subtype: \"error_during_execution\", is_error: true, stop_reason: null, errors, ...common };\n }\n await rpc.request(\"initialize\", {\n clientInfo: { name: \"hyperbrane\", title: \"hyperbrane\", version: HYPERBRANE_VERSION },\n capabilities: { experimentalApi: true, requestAttestation: false }\n });\n rpc.notify(\"initialized\");\n const settings = {\n cwd: context.spec.cwd ?? null,\n model: context.model,\n approvalPolicy: \"untrusted\",\n sandbox: \"danger-full-access\"\n };\n const started = threadId ? await rpc.request(\"thread/resume\", { threadId, ...settings }) : await rpc.request(\"thread/start\", settings);\n threadId = started.thread.id;\n model = started.model;\n context.setNativeId(threadId);\n return {\n rpc,\n threadId,\n model,\n activeTurn: () => turn?.id ?? null,\n emitToolUse: (id, name, input) => context.emit(assistantMessage(id, [{ type: \"tool_use\", id, name, input }], threadId, model)),\n emitToolResult: (id, content, isError) => context.emit(toolResultMessage(id, content, isError, threadId))\n };\n}\n\n// agent/session/codex/index.ts\nvar codexBackend = {\n install: installCodex,\n auth: codexAuth,\n transcript: codexTranscript,\n homeEnvironment: (home) => ({ CODEX_HOME: home }),\n async start(context) {\n let thread;\n const current = () => thread;\n const queue = codexMessageQueue();\n const status = codexStatus();\n const input = createCodexInput(current, queue, context.model);\n const permissions = codexPermissions(context);\n const questions = codexQuestions(context, current);\n function onServerRequest(request, rpc) {\n if (request.method !== \"item/tool/requestUserInput\")\n return permissions(request, rpc);\n questions(request.params).then((response) => rpc.respond(request.id, response), (error) => rpc.respondError(request.id, error.message));\n }\n const backgroundTasks = codexBackgroundTasks();\n thread = await startCodexStream(context, { onServerRequest, observers: [backgroundTasks, status, queue] });\n return {\n sendMessage: input.sendMessage,\n getSessionStatus: status.status,\n getLastUserMessages: queue.lastUserMessages,\n cancel: codexInterrupt(current),\n ...codexModel(current, input),\n listBackgroundTasks: backgroundTasks.list,\n stopTask: (taskId) => backgroundTasks.stop(taskId, current().rpc.pid),\n async close() {\n current().rpc.close();\n }\n };\n }\n};\n\n// agent/session/backends.ts\nvar SESSION_BACKENDS = {\n claude: claudeBackend,\n codex: codexBackend\n};\n\n// dimension/paths.ts\nvar WORKSPACE_PATH = \"/workspace\";\nvar RUN_PATH = \"/run/hyperbrane\";\nvar STATE_PATH = \"/var/lib/hyperbrane\";\n\n// lib/jsonDirectory.ts\nvar EXTENSION = \".json\";\nvar NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,62}$/;\n\nclass InvalidNameError extends Error {\n name = \"InvalidNameError\";\n}\nfunction checkName(name) {\n if (!NAME_PATTERN.test(name)) {\n throw new InvalidNameError(`Invalid name \"${name}\": use letters, digits, \"_\", \".\" and \"-\", up to 63 characters`);\n }\n return name;\n}\nfunction createJsonDirectory(sandbox, dir) {\n async function pathFor(name) {\n return `${await dir()}/${checkName(name)}${EXTENSION}`;\n }\n function serialize(record) {\n return JSON.stringify(record, null, 2) + `\n`;\n }\n async function readPath(path) {\n try {\n return JSON.parse(new TextDecoder().decode(await sandbox.readFile(path)));\n } catch (error) {\n if (error instanceof SandboxNotFoundError)\n return null;\n throw error;\n }\n }\n async function read(name) {\n return readPath(await pathFor(name));\n }\n async function insert(name, record) {\n const path = await pathFor(name);\n if (await sandbox.writeFileExclusive(path, serialize(record)))\n return record;\n return await readPath(path) ?? insert(name, record);\n }\n async function save(name, record) {\n await sandbox.writeFile(await pathFor(name), serialize(record));\n }\n async function remove(name) {\n await sandbox.removeFile(await pathFor(name));\n }\n async function entries() {\n const path = await dir();\n const all = await sandbox.runCommand([\"sh\", \"-c\", LIST_SCRIPT, \"sh\", path]).catch(() => null);\n if (all?.exitCode === MISSING)\n return [];\n if (all?.exitCode === 0) {\n return all.stdout.split(RECORD_END).filter((text) => text.trim()).flatMap((text) => {\n const newline = text.indexOf(`\n`);\n try {\n return [[text.slice(0, newline).slice(0, -EXTENSION.length), JSON.parse(text.slice(newline + 1))]];\n } catch {\n return [];\n }\n });\n }\n let files;\n try {\n files = await sandbox.listDirectory(path);\n } catch (error) {\n if (error instanceof SandboxNotFoundError)\n return [];\n throw error;\n }\n const records = await Promise.all(files.filter((file) => file.endsWith(EXTENSION)).map(async (file) => [file.slice(0, -EXTENSION.length), await readPath(`${path}/${file}`)]));\n return records.filter((entry) => entry[1] !== null);\n }\n async function list() {\n return (await entries()).map(([, record]) => record);\n }\n return { read, insert, save, remove, list, entries };\n}\nvar MISSING = 44;\nvar RECORD_END = `\n\\x1E\n`;\nvar LIST_SCRIPT = `cd \"$1\" 2>/dev/null || exit ${MISSING}\nfor file in *${EXTENSION}; do\n [ -f \"$file\" ] || continue\n printf '%s\\\\n' \"$file\" && cat \"$file\" && printf '\\\\n\\\\036\\\\n'\ndone`;\n\n// agent/session/sessionStorage.ts\nfunction workerSocketPath(runDirectory, agentName) {\n return `${runDirectory}/${agentName}.sock`;\n}\nfunction createSessionStorage(sandbox, agentName, { stateDirectory = STATE_PATH, runDirectory = RUN_PATH } = {}) {\n const sessionsDir = `${stateDirectory}/agents/${agentName}/sessions`;\n const sessions = createJsonDirectory(sandbox, async () => sessionsDir);\n const sessionDir = (sessionName) => `${sessionsDir}/${checkName(sessionName)}`;\n const permissionRequests = (sessionName) => createJsonDirectory(sandbox, async () => `${sessionDir(sessionName)}/permission-requests`);\n const questionRequests = (sessionName) => createJsonDirectory(sandbox, async () => `${sessionDir(sessionName)}/question-requests`);\n const sessionFiles = (sessionName) => createJsonDirectory(sandbox, async () => sessionDir(sessionName));\n async function oldestFirst(stored) {\n return (await stored).sort((a, b) => a.at - b.at).map((entry) => entry.request);\n }\n async function getSessions() {\n return sessions.list();\n }\n async function insertSession(record) {\n return sessions.insert(record.spec.name, record);\n }\n async function saveSession(record) {\n await sessions.save(record.spec.name, record);\n }\n async function removeSession(sessionName) {\n await sandbox.removeDirectory(sessionDir(sessionName));\n await sessions.remove(sessionName);\n }\n async function getPermissionRequests(sessionName) {\n return oldestFirst(permissionRequests(sessionName).list());\n }\n async function savePermissionRequest(sessionName, request) {\n await permissionRequests(sessionName).save(request.id, { request, at: Date.now() });\n }\n async function removePermissionRequest(sessionName, requestId) {\n await permissionRequests(sessionName).remove(requestId);\n }\n async function getQuestionRequests(sessionName) {\n return oldestFirst(questionRequests(sessionName).list());\n }\n async function saveQuestionRequest(sessionName, request) {\n await questionRequests(sessionName).save(request.id, { request, at: Date.now() });\n }\n async function removeQuestionRequest(sessionName, requestId) {\n await questionRequests(sessionName).remove(requestId);\n }\n async function readAuth(sessionName) {\n return sessionFiles(sessionName).read(\"auth\");\n }\n async function saveAuth(sessionName, record) {\n await sessionFiles(sessionName).save(\"auth\", record);\n }\n async function socketPath() {\n return workerSocketPath(runDirectory, agentName);\n }\n async function backendHome(backend) {\n const path = `${stateDirectory}/backends/${backend}`;\n await sandbox.createDirectory(path);\n return path;\n }\n return {\n getSessions,\n insertSession,\n saveSession,\n removeSession,\n getPermissionRequests,\n savePermissionRequest,\n removePermissionRequest,\n getQuestionRequests,\n saveQuestionRequest,\n removeQuestionRequest,\n readAuth,\n saveAuth,\n socketPath,\n backendHome\n };\n}\n\n// agent/session/worker/workerServer.ts\nimport { rm as rm2 } from \"fs/promises\";\n\n// agent/session/worker/jsonRpc.ts\nvar PARSE_ERROR = -32700;\nfunction createJsonRpcPeer(write, options) {\n const pending = new Map;\n let nextId = 1;\n let buffered = \"\";\n let closedWith;\n function send(message) {\n if (closedWith)\n return;\n write(JSON.stringify({ jsonrpc: \"2.0\", ...message }) + `\n`);\n }\n function handle(message) {\n if (message.method === undefined) {\n if (message.id === undefined || message.id === null)\n return;\n const waiting = pending.get(message.id);\n pending.delete(message.id);\n if (message.error)\n waiting?.reject(options.decodeError(message.error));\n else\n waiting?.resolve(message.result);\n return;\n }\n if (message.id === undefined || message.id === null) {\n options.onNotification?.(message.method, message.params);\n return;\n }\n const id = message.id;\n options.onRequest(message.method, message.params).then((result) => send({ id, result: result ?? null }), (error) => send({ id, error: options.encodeError(error) }));\n }\n function receive(text) {\n buffered += text;\n let newline;\n while ((newline = buffered.indexOf(`\n`)) >= 0) {\n const line = buffered.slice(0, newline).trim();\n buffered = buffered.slice(newline + 1);\n if (!line)\n continue;\n let message;\n try {\n message = JSON.parse(line);\n } catch {\n send({ id: null, error: { code: PARSE_ERROR, message: \"not JSON\" } });\n continue;\n }\n handle(message);\n }\n }\n function request(method, params) {\n if (closedWith)\n return Promise.reject(closedWith);\n const id = nextId++;\n return new Promise((resolve2, reject) => {\n pending.set(id, { resolve: resolve2, reject });\n send({ id, method, params });\n });\n }\n function notify(method, params) {\n send({ method, params });\n }\n function close(error) {\n closedWith ??= error;\n for (const waiting of pending.values())\n waiting.reject(error);\n pending.clear();\n }\n return { receive, request, notify, close };\n}\nfunction createSocketWriter(socket) {\n const encoder = new TextEncoder;\n let backlog = null;\n function write(text) {\n const bytes = encoder.encode(text);\n if (backlog) {\n const joined2 = new Uint8Array(backlog.length + bytes.length);\n joined2.set(backlog);\n joined2.set(bytes, backlog.length);\n backlog = joined2;\n return;\n }\n const written = Math.max(socket.write(bytes), 0);\n if (written < bytes.length)\n backlog = bytes.subarray(written);\n }\n function drain() {\n if (!backlog)\n return;\n const written = Math.max(socket.write(backlog), 0);\n backlog = written < backlog.length ? backlog.subarray(written) : null;\n }\n return { write, drain };\n}\n\n// agent/session/worker/protocol.ts\nvar METHOD_NOT_FOUND2 = -32601;\nvar INVALID_PARAMS = -32602;\nvar INTERNAL_ERROR = -32603;\nvar NOT_FOUND = -32004;\nvar CONFLICT = -32009;\n\nclass WorkerMethodNotFoundError extends Error {\n name = \"WorkerMethodNotFoundError\";\n}\nfunction encodeWorkerError(error) {\n const message = error instanceof Error ? error.message : String(error);\n if (error instanceof AgentInvalidError)\n return { code: INVALID_PARAMS, message };\n if (error instanceof AgentNotFoundError)\n return { code: NOT_FOUND, message };\n if (error instanceof AgentConflictError)\n return { code: CONFLICT, message };\n if (error instanceof WorkerMethodNotFoundError)\n return { code: METHOD_NOT_FOUND2, message };\n return { code: INTERNAL_ERROR, message };\n}\nfunction decodeWorkerError({ code, message }) {\n if (code === INVALID_PARAMS)\n return new AgentInvalidError(message);\n if (code === NOT_FOUND)\n return new AgentNotFoundError(message);\n if (code === CONFLICT)\n return new AgentConflictError(message);\n return new Error(`worker: ${message}`);\n}\n\n// agent/session/worker/workerParams.ts\nvar WORKER_PARAMS = {\n \"worker/health\": () => ({}),\n \"worker/shutdown\": () => ({}),\n \"backend/install\": (params) => ({ backend: backend(params.backend) }),\n \"session/create\": (params) => ({ session: session(object(params.session, \"session\")) }),\n \"session/list\": () => ({}),\n \"session/update\": (params) => ({ session: name(params), limits: limits(object(params.limits, \"limits\")) }),\n \"session/stop\": (params) => ({ session: name(params) }),\n \"session/send\": (params) => ({ session: name(params), message: userMessage(params.message) }),\n \"session/interrupt\": (params) => ({ session: name(params) }),\n \"session/status\": (params) => ({ session: name(params) }),\n \"session/lastUserMessages\": (params) => ({ session: name(params) }),\n \"session/subscribe\": (params) => ({\n session: name(params),\n subscription: text(params.subscription, \"subscription\"),\n after_id: optional(params.after_id, (value) => text(value, \"after_id\"))\n }),\n \"session/unsubscribe\": (params) => ({ subscription: text(params.subscription, \"subscription\") }),\n \"session/transcript\": (params) => ({\n session: name(params),\n limit: optional(params.limit, (value) => number(value, \"limit\")),\n cursor: optional(params.cursor, (value) => text(value, \"cursor\"))\n }),\n \"permission/list\": (params) => ({ session: name(params) }),\n \"permission/respond\": (params) => ({\n session: name(params),\n request: text(params.request, \"request\"),\n result: permissionResult(params.result)\n }),\n \"question/list\": (params) => ({ session: name(params) }),\n \"question/respond\": (params) => ({\n session: name(params),\n request: text(params.request, \"request\"),\n response: questionResponse(params.response)\n }),\n \"model/list\": (params) => ({ session: name(params) }),\n \"model/set\": (params) => ({\n session: name(params),\n model: params.model === null ? null : text(params.model, \"the model (a model name, or null for the backend's default)\")\n }),\n \"task/list\": (params) => ({ session: name(params) }),\n \"task/stop\": (params) => ({ session: name(params), task: text(params.task, \"task\") }),\n \"auth/status\": (params) => ({ session: name(params) }),\n \"auth/login\": (params) => ({\n session: name(params),\n gatewaySignedIn: optional(params.gatewaySignedIn, (value) => boolean(value, \"gatewaySignedIn\")) ?? false\n }),\n \"auth/code\": (params) => ({ session: name(params), code: text(params.code, \"the code (the one the sign-in page showed)\").trim() })\n};\nfunction invalid(message) {\n throw new AgentInvalidError(message);\n}\nfunction name(params) {\n return text(params.session, \"session\");\n}\nfunction object(value, what) {\n if (value === null || typeof value !== \"object\" || Array.isArray(value))\n invalid(`${what} must be an object`);\n return value;\n}\nfunction text(value, what) {\n if (typeof value !== \"string\" || value.trim() === \"\")\n invalid(`${what} must be a non-empty string`);\n return value;\n}\nfunction number(value, what) {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n invalid(`${what} must be a number`);\n return value;\n}\nfunction boolean(value, what) {\n if (typeof value !== \"boolean\")\n invalid(`${what} must be true or false`);\n return value;\n}\nfunction optional(value, parse) {\n return value === undefined ? undefined : parse(value);\n}\nfunction backend(value) {\n const known = AGENT_BACKENDS.find((name2) => name2 === value);\n if (!known)\n invalid(`unknown backend \"${String(value)}\"; known: ${AGENT_BACKENDS.join(\", \")}`);\n return known;\n}\nfunction memoryLimit(value) {\n const bytes = number(value, \"memoryLimit\");\n if (!(bytes > 0))\n invalid(\"memoryLimit must be positive\");\n return bytes;\n}\nfunction cpuLimit(value) {\n const cores = number(value, \"cpuLimit\");\n if (!(cores > 0))\n invalid(\"cpuLimit must be positive\");\n return cores;\n}\nfunction environment(value) {\n const fields = object(value, \"env\");\n for (const [key, entry] of Object.entries(fields))\n if (typeof entry !== \"string\")\n invalid(`env.${key} must be a string`);\n return fields;\n}\nfunction session(fields) {\n return {\n name: text(fields.name, \"the session's name\"),\n backend: backend(fields.backend),\n memoryLimit: memoryLimit(fields.memoryLimit),\n cpuLimit: cpuLimit(fields.cpuLimit),\n cwd: optional(fields.cwd, (value) => text(value, \"cwd\")),\n env: optional(fields.env, environment)\n };\n}\nfunction limits(fields) {\n return { memoryLimit: optional(fields.memoryLimit, memoryLimit), cpuLimit: optional(fields.cpuLimit, cpuLimit) };\n}\nfunction userMessage(value) {\n const fields = object(value, 'a message (an SDK user message: {type: \"user\", message})');\n if (fields.type !== \"user\")\n invalid('a message is an SDK user message: {type: \"user\", message}');\n const message = object(fields.message, \"message.message\");\n if (message.role !== \"user\")\n invalid('message.message.role must be \"user\"');\n if (typeof message.content !== \"string\" && !Array.isArray(message.content))\n invalid(\"message.message.content must be a string or an array of content blocks\");\n return value;\n}\nfunction permissionResult(value) {\n const fields = object(value, \"result\");\n if (fields.behavior === \"allow\") {\n return { behavior: \"allow\", updatedInput: optional(fields.updatedInput, (input) => object(input, \"updatedInput\")) };\n }\n if (fields.behavior === \"deny\") {\n return {\n behavior: \"deny\",\n message: typeof fields.message === \"string\" ? fields.message : invalid(\"a denial needs a message\"),\n interrupt: optional(fields.interrupt, (interrupt) => boolean(interrupt, \"interrupt\"))\n };\n }\n return invalid('a permission result is {behavior: \"allow\"} or {behavior: \"deny\", message}');\n}\nfunction questionResponse(value) {\n const answers = object(object(value, \"response\").answers, \"a question response's answers ({<question>: <answer>})\");\n for (const [question, answer] of Object.entries(answers))\n if (typeof answer !== \"string\")\n invalid(`the answer to \"${question}\" must be a string`);\n return { answers };\n}\n\n// agent/session/worker/workerServer.ts\nvar INTERNAL_ERROR_LOGGED = -32603;\nfunction createWorkerServer(service, options) {\n let listener;\n function ref(session2) {\n return { agentName: options.health.agentName, sessionName: session2 };\n }\n const handlers = {\n \"worker/health\": async () => options.health,\n \"worker/shutdown\": async () => {\n setTimeout(options.onShutdown, 0);\n return null;\n },\n \"backend/install\": async ({ backend: backend2 }) => nothing(await service.install(options.health.agentName, backend2)),\n \"session/create\": ({ session: session2 }) => service.createSession(options.health.agentName, session2),\n \"session/list\": () => service.listSessions(),\n \"session/update\": ({ session: session2, limits: limits2 }) => service.updateSession(ref(session2), limits2),\n \"session/stop\": async ({ session: session2 }) => nothing(await service.stopSession(ref(session2))),\n \"session/send\": async ({ session: session2, message }) => nothing(await service.sendMessage(ref(session2), message)),\n \"session/interrupt\": async ({ session: session2 }) => nothing(await service.cancel(ref(session2))),\n \"session/status\": ({ session: session2 }) => service.getSessionStatus(ref(session2)),\n \"session/lastUserMessages\": ({ session: session2 }) => service.getLastUserMessages(ref(session2)),\n \"session/subscribe\": async ({ session: session2, subscription, after_id }, connection) => {\n if (connection.subscriptions.has(subscription))\n throw new AgentConflictError(`subscription ${subscription} already exists`);\n let unsubscribe = null;\n let cancelled = false;\n connection.subscriptions.set(subscription, () => {\n cancelled = true;\n unsubscribe?.();\n });\n try {\n unsubscribe = await service.subscribe(ref(session2), after_id, (message) => {\n const notification = { subscription, message };\n connection.peer.notify(\"session/message\", notification);\n });\n } catch (error) {\n connection.subscriptions.delete(subscription);\n throw error;\n }\n if (cancelled)\n unsubscribe();\n return null;\n },\n \"session/unsubscribe\": async ({ subscription }, connection) => {\n connection.subscriptions.get(subscription)?.();\n connection.subscriptions.delete(subscription);\n return null;\n },\n \"session/transcript\": ({ session: session2, limit, cursor }) => service.getTranscript(ref(session2), { limit, cursor }),\n \"permission/list\": ({ session: session2 }) => service.listPermissionRequests(ref(session2)),\n \"permission/respond\": async ({ session: session2, request, result }) => nothing(await service.respondPermissionRequest(ref(session2), request, result)),\n \"question/list\": ({ session: session2 }) => service.listQuestionRequests(ref(session2)),\n \"question/respond\": async ({ session: session2, request, response }) => nothing(await service.respondQuestionRequest(ref(session2), request, response)),\n \"model/list\": ({ session: session2 }) => service.listModels(ref(session2)),\n \"model/set\": async ({ session: session2, model }) => nothing(await service.setModel(ref(session2), model)),\n \"task/list\": ({ session: session2 }) => service.listBackgroundTasks(ref(session2)),\n \"task/stop\": async ({ session: session2, task }) => nothing(await service.stopTask(ref(session2), task)),\n \"auth/status\": ({ session: session2 }) => service.getAuthStatus(ref(session2)),\n \"auth/login\": ({ session: session2, gatewaySignedIn }) => service.login(ref(session2), gatewaySignedIn),\n \"auth/code\": ({ session: session2, code }) => service.submitAuthCode(ref(session2), code)\n };\n function handle(method, params, connection) {\n return handlers[method](WORKER_PARAMS[method](params), connection);\n }\n async function dispatch(method, params, connection) {\n if (!isWorkerMethod(method))\n throw new WorkerMethodNotFoundError(`no method ${method}`);\n const fields = params ?? {};\n if (typeof fields !== \"object\" || Array.isArray(fields))\n throw new AgentInvalidError(`${method} takes an object of params`);\n return handle(method, fields, connection);\n }\n function openConnection(socket) {\n const writer = createSocketWriter(socket);\n const peer = createJsonRpcPeer(writer.write, {\n onRequest: (method, params) => dispatch(method, params, connection),\n encodeError: (error) => {\n const encoded = encodeWorkerError(error);\n if (encoded.code === INTERNAL_ERROR_LOGGED)\n console.error(error);\n return encoded;\n },\n decodeError: decodeWorkerError\n });\n const connection = { peer, writer, subscriptions: new Map, decoder: new TextDecoder };\n return connection;\n }\n async function start() {\n await rm2(options.socketPath, { force: true });\n listener = Bun.listen({\n unix: options.socketPath,\n socket: {\n open(socket) {\n socket.data = openConnection(socket);\n },\n data(socket, data) {\n socket.data.peer.receive(socket.data.decoder.decode(data, { stream: true }));\n },\n drain(socket) {\n socket.data.writer.drain();\n },\n close(socket) {\n for (const unsubscribe of socket.data.subscriptions.values())\n unsubscribe();\n socket.data.subscriptions.clear();\n socket.data.peer.close(new Error(\"the connection closed\"));\n },\n error(_socket, error) {\n console.error(\"worker connection failed:\", error);\n }\n }\n });\n }\n function stop() {\n listener?.stop(true);\n listener = undefined;\n }\n return { start, stop };\n}\nfunction isWorkerMethod(method) {\n return Object.hasOwn(WORKER_PARAMS, method);\n}\nfunction nothing(_done) {\n return null;\n}\n\n// agent/session/workerService.ts\nimport { statSync } from \"fs\";\n\n// agent/session/pending.ts\nfunction createPendingRequests(store, fallback) {\n const waiting = new Map;\n function add(request, signal2) {\n const id = crypto.randomUUID();\n return new Promise((resolve2) => {\n let settled = false;\n const settle = (response) => {\n if (settled)\n return;\n settled = true;\n waiting.delete(id);\n signal2?.removeEventListener(\"abort\", aborted);\n store.remove(id).catch((error) => console.error(`removing request ${id} failed:`, error));\n resolve2(response);\n };\n const aborted = () => settle(fallback(\"the request was cancelled\"));\n if (signal2?.aborted)\n return aborted();\n signal2?.addEventListener(\"abort\", aborted);\n waiting.set(id, settle);\n store.save({ ...request, id }).catch((error) => {\n console.error(`keeping request ${id} failed:`, error);\n settle(fallback(\"the request couldn't be kept\"));\n });\n });\n }\n async function list() {\n return (await store.list()).filter((request) => waiting.has(request.id));\n }\n async function answer(id, response) {\n const settle = waiting.get(id);\n if (!settle)\n return false;\n settle(response);\n return true;\n }\n async function dropAll(reason) {\n for (const settle of [...waiting.values()])\n settle(fallback(reason));\n for (const request of await store.list())\n if (!waiting.has(request.id))\n await store.remove(request.id);\n }\n return { add, list, answer, dropAll };\n}\n\n// agent/session/workerService.ts\nfunction createWorkerService(config) {\n const sessions = new Map;\n let installing = Promise.resolve();\n async function loadSessions() {\n for (const record of await config.storage.getSessions()) {\n const state = await newState(record);\n sessions.set(record.spec.name, state);\n await dropRequests(state, \"the worker restarted\");\n const auth = await config.storage.readAuth(record.spec.name);\n if (auth?.login)\n await config.storage.saveAuth(record.spec.name, { login: null, error: auth.error });\n }\n }\n async function newState(record) {\n return {\n ...record,\n listeners: new Set,\n running: null,\n startedAt: 0,\n generation: 0,\n session: null,\n login: null,\n permissionRequests: createPendingRequests({\n list: () => config.storage.getPermissionRequests(record.spec.name),\n save: (request) => config.storage.savePermissionRequest(record.spec.name, request),\n remove: (id) => config.storage.removePermissionRequest(record.spec.name, id)\n }, (message) => ({ behavior: \"deny\", message })),\n questionRequests: createPendingRequests({\n list: () => config.storage.getQuestionRequests(record.spec.name),\n save: (request) => config.storage.saveQuestionRequest(record.spec.name, request),\n remove: (id) => config.storage.removeQuestionRequest(record.spec.name, id)\n }, () => null)\n };\n }\n async function saveRecord(state) {\n await config.storage.saveSession({ spec: state.spec, nativeId: state.nativeId, model: state.model });\n }\n async function info(state) {\n return { ...state.spec, agentName: config.agentName, status: await statusOf(state), nativeId: state.nativeId, model: state.model };\n }\n async function statusOf(state) {\n if (!state.running)\n return \"stopped\";\n if (!state.session)\n return \"starting\";\n return state.session.getSessionStatus();\n }\n async function lastStoredPrompt(state) {\n const transcript = await transcriptOf(state);\n let cursor = null;\n while (transcript) {\n const page = await transcript.page(cursor, LAST_PROMPT_PAGE_SIZE);\n const prompt = page.messages.findLast((message) => message.type === \"user\" && isPrompt(message.message.content));\n if (prompt?.type === \"user\")\n return { message: prompt, queued: false };\n if (!page.nextCursor)\n return null;\n cursor = page.nextCursor;\n }\n return null;\n }\n function trustChangedSince(time) {\n if (!config.trustBundle)\n return false;\n try {\n return statSync(config.trustBundle).mtimeMs > time;\n } catch {\n return false;\n }\n }\n function requireAgent(agentName) {\n if (agentName !== config.agentName)\n throw new AgentNotFoundError(`this worker runs agent ${config.agentName}, not ${agentName}`);\n }\n function requireSession({ agentName, sessionName }) {\n requireAgent(agentName);\n const state = sessions.get(sessionName);\n if (!state)\n throw new AgentNotFoundError(`session ${sessionName} does not exist`);\n return state;\n }\n async function dropRequests(state, reason) {\n await Promise.all([state.permissionRequests.dropAll(reason), state.questionRequests.dropAll(reason)]);\n }\n function broadcast(state, message) {\n for (const listener of state.listeners)\n listener(message);\n }\n async function transcriptOf(state) {\n if (!state.nativeId)\n return null;\n return config.backends[state.spec.backend].transcript({ nativeId: state.nativeId, env: await environmentOf(state) });\n }\n async function environmentOf(state) {\n const env = {};\n for (const [key, value] of Object.entries(process.env))\n if (value !== undefined)\n env[key] = value;\n const backend2 = config.backends[state.spec.backend];\n return { ...env, ...backend2.homeEnvironment(await config.storage.backendHome(state.spec.backend)), ...state.spec.env };\n }\n async function authEnvironment(state) {\n return { installDir: config.installDir, env: await environmentOf(state), cwd: state.spec.cwd ?? process.cwd() };\n }\n async function authStatus(state) {\n const auth = await config.storage.readAuth(state.spec.name);\n if (state.login && auth?.login)\n return auth.login;\n if (await config.backends[state.spec.backend].auth.signedIn(await authEnvironment(state)))\n return { state: \"signedIn\" };\n return auth?.error ? { state: \"signedOut\", error: auth.error } : { state: \"signedOut\" };\n }\n function saveAuth(state, record) {\n return config.storage.saveAuth(state.spec.name, record);\n }\n function watchLogin(state, login2) {\n return login2.done.then(async () => {\n if (state.login?.process !== login2)\n return;\n state.login = null;\n await saveAuth(state, { login: null, error: null });\n if (await statusOf(state) === \"idle\")\n await closeSession(state);\n }, async (error) => {\n if (state.login?.process !== login2)\n return;\n state.login = null;\n await saveAuth(state, { login: null, error: error.message });\n });\n }\n async function settleLogin(state, settled, timeoutMs) {\n await Promise.race([settled, Bun.sleep(timeoutMs)]);\n return authStatus(state);\n }\n function contextFor(state, generation, env) {\n const current = () => state.generation === generation;\n return {\n spec: state.spec,\n nativeId: state.nativeId,\n cwd: state.spec.cwd ?? process.cwd(),\n model: state.model,\n installDir: config.installDir,\n env,\n emit(message) {\n if (!current())\n return;\n broadcast(state, message);\n },\n setNativeId(id) {\n if (!current() || state.nativeId === id)\n return;\n state.nativeId = id;\n saveRecord(state).catch((error) => console.error(`saving session ${state.spec.name} failed:`, error));\n },\n async requestPermission(request, signal2) {\n if (!current())\n return { behavior: \"deny\", message: \"the session stopped\" };\n return state.permissionRequests.add(request, signal2);\n },\n async askQuestions(request, signal2) {\n if (!current())\n return null;\n return state.questionRequests.add(request, signal2);\n },\n exited(error) {\n if (!current())\n return;\n const session2 = state.session;\n state.running = null;\n state.session = null;\n dropRequests(state, \"the agent exited\").catch((error2) => console.error(`dropping ${state.spec.name}'s requests failed:`, error2));\n if (error)\n console.error(`session ${state.spec.name} exited:`, error);\n session2?.getSessionStatus().then((last) => {\n if (last !== \"running\" && last !== \"waiting\")\n return;\n broadcast(state, {\n type: \"result\",\n subtype: \"error_during_execution\",\n duration_ms: 0,\n duration_api_ms: 0,\n is_error: true,\n num_turns: 0,\n stop_reason: null,\n total_cost_usd: 0,\n usage: resultUsage(),\n modelUsage: {},\n permission_denials: [],\n errors: [`the agent exited${error ? `: ${error.message}` : \"\"}`],\n uuid: crypto.randomUUID(),\n session_id: state.nativeId ?? \"\"\n });\n });\n }\n };\n }\n function ensureRunning(state) {\n if (state.running)\n return state.running;\n const generation = ++state.generation;\n state.startedAt = Date.now();\n const starting = environmentOf(state).then((env) => config.backends[state.spec.backend].start(contextFor(state, generation, env)));\n state.running = starting;\n starting.then((session2) => {\n if (state.generation === generation)\n state.session = session2;\n }, () => {\n if (state.generation === generation)\n state.running = null;\n });\n return starting;\n }\n async function closeSession(state) {\n const running = state.running;\n state.generation++;\n state.running = null;\n state.session = null;\n await dropRequests(state, \"the session stopped\");\n if (running)\n await (await running.catch(() => null))?.close();\n }\n async function cancelLogin(state) {\n if (!state.login)\n return;\n state.login.process.cancel();\n state.login = null;\n const auth = await config.storage.readAuth(state.spec.name);\n await saveAuth(state, { login: null, error: auth?.error ?? null });\n }\n async function install(agentName, backend2) {\n requireAgent(agentName);\n const run2 = installing.then(() => config.backends[backend2].install(config.installDir));\n installing = run2.catch(() => {});\n await run2;\n }\n async function createSession(agentName, session2) {\n requireAgent(agentName);\n const spec = validSession(session2);\n const existing = sessions.get(spec.name);\n if (existing) {\n if (!sameSpec(existing.spec, spec))\n throw new AgentConflictError(`session ${spec.name} already exists with a different spec`);\n return info(existing);\n }\n const record = await config.storage.insertSession({ spec, nativeId: null, model: null });\n const state = await newState(record);\n sessions.set(spec.name, state);\n return info(state);\n }\n async function listSessions() {\n return Promise.all([...sessions.values()].map(info));\n }\n async function updateSession(ref, limits2) {\n const state = requireSession(ref);\n const { memoryLimit: memoryLimit2, cpuLimit: cpuLimit2 } = limits2;\n state.spec = { ...state.spec, memoryLimit: memoryLimit2 ?? state.spec.memoryLimit, cpuLimit: cpuLimit2 ?? state.spec.cpuLimit };\n await saveRecord(state);\n return info(state);\n }\n async function stopSession(ref) {\n requireAgent(ref.agentName);\n const state = sessions.get(ref.sessionName);\n if (!state)\n return;\n sessions.delete(ref.sessionName);\n await closeSession(state);\n state.login?.process.cancel();\n state.login = null;\n state.listeners.clear();\n await config.storage.removeSession(state.spec.name);\n }\n async function sendMessage(ref, sent) {\n const state = requireSession(ref);\n if (await statusOf(state) === \"idle\" && trustChangedSince(state.startedAt))\n await closeSession(state);\n const uuid = sent.uuid ?? crypto.randomUUID();\n const message = { ...sent, uuid, session_id: state.nativeId ?? \"\" };\n await (await ensureRunning(state)).sendMessage(message);\n broadcast(state, { ...message, uuid, session_id: message.session_id });\n }\n async function cancel(ref) {\n const state = requireSession(ref);\n await dropRequests(state, \"the turn was interrupted\");\n if (state.running)\n await (await state.running).cancel();\n }\n async function getSessionStatus(ref) {\n return statusOf(requireSession(ref));\n }\n async function getLastUserMessages(ref) {\n const state = requireSession(ref);\n if (state.session)\n return state.session.getLastUserMessages();\n const stored = await lastStoredPrompt(state);\n return stored ? [stored] : [];\n }\n async function subscribe(ref, afterId, emit) {\n const state = requireSession(ref);\n let held = [];\n const listener = (message) => held ? held.push(message) : emit(message);\n state.listeners.add(listener);\n const unsubscribe = () => void state.listeners.delete(listener);\n try {\n const replayed = new Set;\n const transcript = await transcriptOf(state);\n const found = transcript ? await transcript.replay(afterId, (message) => {\n replayed.add(message.uuid);\n emit(message);\n }) : afterId === undefined;\n if (!found) {\n throw new AgentInvalidError(`no message ${afterId} in session ${ref.sessionName}: after_id is the uuid of a user or assistant message (partial output and results aren't stored)`);\n }\n for (const message of held)\n if (!replayed.has(message.uuid))\n emit(message);\n held = null;\n } catch (error) {\n unsubscribe();\n throw error;\n }\n return unsubscribe;\n }\n async function getTranscript(ref, { limit, cursor } = {}) {\n const transcript = await transcriptOf(requireSession(ref));\n if (!transcript) {\n if (cursor !== undefined)\n throw new AgentInvalidError(`no transcript for cursor ${cursor}`);\n return { messages: [], nextCursor: null };\n }\n const size = Math.min(Math.max(Math.floor(limit ?? DEFAULT_PAGE_SIZE), 1), MAX_PAGE_SIZE);\n const page = await transcript.page(cursor ?? null, size);\n return page;\n }\n async function listPermissionRequests(ref) {\n return requireSession(ref).permissionRequests.list();\n }\n async function respondPermissionRequest(ref, requestId, result) {\n const state = requireSession(ref);\n if (!await state.permissionRequests.answer(requestId, result))\n throw new AgentNotFoundError(`no pending permission request ${requestId}`);\n }\n async function listQuestionRequests(ref) {\n return requireSession(ref).questionRequests.list();\n }\n async function respondQuestionRequest(ref, requestId, response) {\n const state = requireSession(ref);\n if (!await state.questionRequests.answer(requestId, response)) {\n throw new AgentNotFoundError(`no pending question request ${requestId}`);\n }\n }\n async function listModels(ref) {\n return (await ensureRunning(requireSession(ref))).listModels();\n }\n async function setModel(ref, model) {\n const state = requireSession(ref);\n state.model = model;\n await saveRecord(state);\n if (state.running)\n await (await state.running).setModel(model);\n }\n async function listBackgroundTasks(ref) {\n const state = requireSession(ref);\n return state.running ? (await state.running).listBackgroundTasks() : [];\n }\n async function stopTask(ref, taskId) {\n const state = requireSession(ref);\n if (!state.running)\n throw new AgentNotFoundError(`no background task ${taskId}: session ${ref.sessionName}'s CLI isn't running`);\n await (await state.running).stopTask(taskId);\n }\n async function login(ref, gatewaySignedIn) {\n const state = requireSession(ref);\n if (state.login)\n return authStatus(state);\n if (await config.backends[state.spec.backend].auth.signedIn(await authEnvironment(state)))\n return { state: \"signedIn\" };\n const login2 = config.backends[state.spec.backend].auth.login(await authEnvironment(state), gatewaySignedIn);\n const entry = { process: login2, settled: Promise.resolve() };\n state.login = entry;\n await saveAuth(state, { login: null, error: null });\n entry.settled = watchLogin(state, login2);\n try {\n const prompt = await Promise.race([\n login2.prompt,\n Bun.sleep(LOGIN_PROMPT_TIMEOUT_MS).then(() => Promise.reject(new Error(\"the login didn't show where to sign in\")))\n ]);\n if (state.login === entry)\n await saveAuth(state, { login: { state: \"pending\", ...prompt }, error: null });\n } catch (error) {\n if (state.login === entry)\n await cancelLogin(state);\n await saveAuth(state, { login: null, error: error.message });\n return authStatus(state);\n }\n return settleLogin(state, entry.settled, gatewaySignedIn ? LOGIN_COMPLETION_TIMEOUT_MS : 0);\n }\n async function submitAuthCode(ref, code) {\n const state = requireSession(ref);\n const login2 = state.login;\n const prompt = (await config.storage.readAuth(ref.sessionName))?.login;\n if (!login2 || !prompt)\n throw new AgentInvalidError(`session ${ref.sessionName} has no sign-in waiting`);\n if (!prompt.needsCode)\n throw new AgentInvalidError(`session ${ref.sessionName}'s sign-in takes no code: finish it at ${prompt.url}`);\n login2.process.submitCode(code);\n return settleLogin(state, login2.settled, LOGIN_COMPLETION_TIMEOUT_MS);\n }\n async function close() {\n await Promise.all([...sessions.values()].map(closeSession));\n }\n return {\n load: loadSessions,\n close,\n install,\n createSession,\n listSessions,\n updateSession,\n stopSession,\n sendMessage,\n cancel,\n getSessionStatus,\n getLastUserMessages,\n subscribe,\n getTranscript,\n listPermissionRequests,\n respondPermissionRequest,\n listQuestionRequests,\n respondQuestionRequest,\n listModels,\n setModel,\n listBackgroundTasks,\n stopTask,\n getAuthStatus: async (ref) => authStatus(requireSession(ref)),\n login,\n submitAuthCode\n };\n}\nvar DEFAULT_PAGE_SIZE = 50;\nvar LAST_PROMPT_PAGE_SIZE = 50;\nfunction isPrompt(content) {\n if (typeof content === \"string\")\n return true;\n return Array.isArray(content) && content.some((block) => block.type === \"text\");\n}\nvar MAX_PAGE_SIZE = 500;\nvar LOGIN_PROMPT_TIMEOUT_MS = 30000;\nvar LOGIN_COMPLETION_TIMEOUT_MS = 60000;\nfunction validSession(spec) {\n try {\n checkName(spec.name);\n } catch (error) {\n if (error instanceof InvalidNameError)\n throw new AgentInvalidError(`invalid session name: ${error.message}`);\n throw error;\n }\n return { ...spec, cwd: spec.cwd ?? WORKSPACE_PATH };\n}\nfunction sameSpec(a, b) {\n return a.backend === b.backend && a.memoryLimit === b.memoryLimit && a.cpuLimit === b.cpuLimit && a.cwd === b.cwd && JSON.stringify(a.env ?? {}) === JSON.stringify(b.env ?? {});\n}\n\n// agent/session/main.ts\nfunction required(name2) {\n const value = process.env[name2];\n if (!value)\n throw new Error(`${name2} is not set`);\n return value;\n}\nvar agentName = required(\"HYB_AGENT\");\nvar build = required(\"HYB_WORKER_BUILD\");\nvar storage = createSessionStorage(createLocalSandbox(\"/\"), agentName);\nvar service = createWorkerService({\n agentName,\n storage,\n installDir: required(\"HYB_INSTALL_DIR\"),\n trustBundle: process.env.NODE_EXTRA_CA_CERTS,\n backends: SESSION_BACKENDS\n});\nvar socketPath = await storage.socketPath();\nvar server = createWorkerServer(service, { socketPath, health: { agentName, build }, onShutdown: shutdown });\nfunction shutdown() {\n server.stop();\n service.close().catch((error) => console.error(\"stopping the sessions failed:\", error)).finally(() => process.exit(0));\n}\nfor (const signal2 of [\"SIGTERM\", \"SIGINT\"])\n process.once(signal2, shutdown);\nawait service.load();\nawait server.start();\nvar socketOwner = process.env.HYB_SOCKET_OWNER;\nif (socketOwner) {\n const [uid, gid] = socketOwner.split(\":\").map(Number);\n await chown(socketPath, uid, gid);\n}\nconsole.log(`session worker for agent ${agentName} (build ${build}) listening on ${socketPath}`);\n";
2
+ export const WORKER_SOURCE = "// @bun\n// agent/session/main.ts\nimport { chown } from \"fs/promises\";\n\n// sandbox/localService.ts\nimport { spawn } from \"child_process\";\nimport { link, mkdir, open, readFile, readdir, rename, rm, stat, unlink, writeFile } from \"fs/promises\";\nimport { request as httpRequest } from \"http\";\nimport { createConnection } from \"net\";\nimport { homedir } from \"os\";\nimport { Readable } from \"stream\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"path\";\n\n// sandbox/api.ts\nclass SandboxPathError extends Error {\n name = \"SandboxPathError\";\n}\n\nclass SandboxNotFoundError extends Error {\n name = \"SandboxNotFoundError\";\n}\n\nclass SandboxEndpointError extends Error {\n name = \"SandboxEndpointError\";\n}\n\n// sandbox/endpointProxy.ts\nfunction parseAccessibleHost(value) {\n const match = /^\\[(.+)\\]:(\\d+)$/.exec(value) ?? /^([^:]+):(\\d+)$/.exec(value);\n if (!match)\n return { host: value.replace(/^\\[(.+)\\]$/, \"$1\"), port: null };\n const port = Number(match[2]);\n checkPort(port);\n return { host: match[1], port };\n}\nvar BASIC_USER = \"hyperbrane\";\nfunction proxyCredentialsAuth() {\n return {\n bind({ host, port: pinned }) {\n const name = host.includes(\":\") ? `[${host}]` : host;\n return {\n firewall: true,\n plan({ scheme, port }) {\n if (scheme !== \"bearer\" && scheme !== \"basic\") {\n throw new SandboxEndpointError(`the endpoint proxy checks bearer or basic credentials, not \"${scheme}\"`);\n }\n const listen = pinnedPort(pinned, port);\n const secret = Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString(\"base64url\");\n const credentials = scheme === \"bearer\" ? { scheme, token: secret } : { scheme, username: BASIC_USER, password: secret };\n return {\n check: { scheme, credentials: scheme === \"bearer\" ? secret : btoa(`${BASIC_USER}:${secret}`) },\n ports: [listen ?? 0, listen ?? 0],\n publish: async (listening) => ({ url: `https://${name}:${listening}`, credentials })\n };\n }\n };\n }\n };\n}\nfunction pinnedPort(pinned, requested) {\n if (requested !== undefined)\n checkPort(requested);\n if (pinned !== null && requested !== undefined && requested !== pinned) {\n throw new SandboxEndpointError(`endpoints here listen on port ${pinned} (the accessible host's), not ${requested}`);\n }\n return pinned ?? requested ?? null;\n}\nfunction checkPort(port) {\n if (!Number.isInteger(port) || port < 1 || port > 65535)\n throw new SandboxEndpointError(`not a port: ${port}`);\n}\nvar ID_PATTERN = /^hyb-endpoint-(\\d+)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;\nvar ENDPOINT_NAME = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\nfunction parseEndpointId(endpointId) {\n const match = ID_PATTERN.exec(endpointId);\n if (!match)\n throw new SandboxEndpointError(`not an endpoint id: \"${endpointId}\"`);\n return { port: Number(match[1]), name: match[2] };\n}\nvar STATE = 'B=\"${B:-$HOME/.local/state/hyperbrane/endpoints}\"';\nvar RUNNING = `pid=$(cat \"$B/$P/.pid\" 2>/dev/null) && kill -0 \"$pid\" 2>/dev/null && ps -p \"$pid\" -o args= | grep -q hyb-endpoint-proxy`;\nvar START_SCRIPT = `${STATE}\nexec python3 -c \"$1\" hyb-endpoint-proxy \"$B\"`;\nvar READ_SCRIPT = `${STATE}\ncat \"$B/$P/$N.json\" 2>/dev/null || exit 1`;\nvar RUNNING_SCRIPT = `${STATE}\n${RUNNING}`;\nvar WRITE_SCRIPT = `${STATE}\numask 077\n[ -d \"$B/$P\" ] || exit 44\ncat > \"$B/$P/.$N.tmp\" && mv -f \"$B/$P/.$N.tmp\" \"$B/$P/$N.json\"`;\nvar STATUS_SCRIPT = `${STATE}\n[ -e \"$B/$P/$N.json\" ] || exit 1\n${RUNNING} || exit 3`;\nvar REMOVE_SCRIPT = `${STATE}\nrm -f \"$B/$P/$N.json\"\nfor other in \"$B/$P\"/*.json; do [ -e \"$other\" ] && exit 0; done\nif ${RUNNING}; then kill \"$pid\"; fi\nrm -rf \"$B/$P\"\nexit 10`;\nfunction createProxyEndpoints(commands, options, where) {\n const accessible = parseAccessibleHost(options.accessibleHost);\n const auth = (options.auth ?? proxyCredentialsAuth()).bind(accessible);\n const firewall = options.needsFirewall === true && auth.firewall;\n const env = (vars) => ({\n ...options.stateDirectory === undefined ? {} : { B: options.stateDirectory },\n ...Object.fromEntries(Object.entries(vars).map(([name, value]) => [name, String(value)]))\n });\n const sh = (script, vars, stdin) => commands.runCommand([\"sh\", \"-c\", script], { env: env(vars), stdin });\n async function ufw(...args) {\n const result = await commands.runCommand([\"sudo\", \"-n\", \"ufw\", ...args]);\n if (result.exitCode !== 0)\n throw new Error(`ufw ${args.join(\" \")} on ${where} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n async function running(port) {\n return (await sh(RUNNING_SCRIPT, { P: port })).exitCode === 0;\n }\n async function stop(port) {\n const result = await sh(REMOVE_SCRIPT, { P: port, N: \"-\" });\n if (result.exitCode === 10 && firewall)\n await ufw(\"delete\", \"allow\", `${port}/tcp`);\n }\n async function proxyFor(plan) {\n const [low, high] = plan.ports;\n if (low === high && low !== 0 && await running(low))\n return low;\n const port = await start(plan.ports, plan.except ?? []);\n if (port === null)\n throw new Error(`starting the endpoint proxy on ${where} failed: no free port in ${low}-${high}`);\n return port;\n }\n async function start(ports, except) {\n const [low, high] = ports;\n const result = await commands.runCommand([\"sh\", \"-c\", START_SCRIPT, \"sh\", PROXY], {\n env: env({}),\n stdin: `${JSON.stringify({ ports, except })}\n`\n });\n const port = Number(result.stdout.trim());\n if (result.exitCode !== 0 || !Number.isInteger(port) || port <= 0) {\n if (low === high && low !== 0 && await running(low))\n return low;\n if (/no free port/.test(result.stderr))\n return null;\n throw new Error(`starting the endpoint proxy on ${where} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);\n }\n if (firewall) {\n try {\n await ufw(\"allow\", `${port}/tcp`);\n } catch (error) {\n await stop(port).catch(() => {});\n throw error;\n }\n }\n return port;\n }\n function exposeEndpoint(request) {\n return exposeEndpointAs(crypto.randomUUID(), request);\n }\n async function exposeEndpointAs(name, request) {\n if (!ENDPOINT_NAME.test(name))\n throw new SandboxEndpointError(`not an endpoint name: \"${name}\"`);\n const { target, transport = \"http\", allowedOrigins = [] } = request;\n if (transport !== \"http\" && transport !== \"sse\")\n throw new SandboxEndpointError(`unknown transport: ${transport}`);\n const plan = auth.plan(request);\n const port = await proxyFor(plan);\n const id = `hyb-endpoint-${port}-${name}`;\n const published = await plan.publish(port);\n const kept = await sh(READ_SCRIPT, { P: port, N: name });\n if (kept.exitCode === 0) {\n const record2 = JSON.parse(kept.stdout);\n const same = JSON.stringify(record2.target) === JSON.stringify(target) && record2.transport === transport && [...record2.origins].sort().join(`\n`) === [...allowedOrigins].sort().join(`\n`) && (record2.check?.scheme ?? null) === (plan.check?.scheme ?? null);\n if (same)\n return { id, url: `${published.url}/${name}`, credentials: credentialsOf(record2.check, published.credentials), allowedOrigins };\n }\n const record = JSON.stringify({ target, transport, check: plan.check, origins: allowedOrigins });\n const written = await sh(WRITE_SCRIPT, { P: port, N: name }, record);\n if (written.exitCode !== 0) {\n throw new Error(`recording the endpoint for ${describe(target)} on ${where} failed (exit ${written.exitCode}): ${written.stderr.trim()}`);\n }\n return { id, url: `${published.url}/${name}`, credentials: published.credentials, allowedOrigins };\n }\n async function closeEndpoint(endpointId) {\n const { port, name } = parseEndpointId(endpointId);\n const result = await sh(REMOVE_SCRIPT, { P: port, N: name });\n if (result.exitCode !== 0 && result.exitCode !== 10) {\n throw new Error(`closing endpoint ${endpointId} on ${where} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n if (result.exitCode === 10 && firewall)\n await ufw(\"delete\", \"allow\", `${port}/tcp`);\n }\n async function updateEndpoint(endpointId, { allowedOrigins }) {\n const { port, name } = parseEndpointId(endpointId);\n const read = await sh(READ_SCRIPT, { P: port, N: name });\n if (read.exitCode !== 0)\n return false;\n const record = { ...JSON.parse(read.stdout), origins: allowedOrigins };\n const written = await sh(WRITE_SCRIPT, { P: port, N: name }, JSON.stringify(record));\n if (written.exitCode === 44)\n return false;\n if (written.exitCode !== 0) {\n throw new Error(`updating endpoint ${endpointId} on ${where} failed (exit ${written.exitCode}): ${written.stderr.trim()}`);\n }\n return true;\n }\n async function ensureEndpoint(endpointId) {\n const { port, name } = parseEndpointId(endpointId);\n const status = await sh(STATUS_SCRIPT, { P: port, N: name });\n if (status.exitCode === 0)\n return true;\n if (status.exitCode === 1)\n return false;\n if (status.exitCode !== 3) {\n throw new Error(`checking endpoint ${endpointId} on ${where} failed (exit ${status.exitCode}): ${status.stderr.trim()}`);\n }\n if (await start([port, port], []) !== null)\n return true;\n await closeEndpoint(endpointId);\n return false;\n }\n return { accessibleHost: options.accessibleHost, exposeEndpoint, exposeEndpointAs, closeEndpoint, ensureEndpoint, updateEndpoint };\n}\nfunction credentialsOf(check, none) {\n if (!check)\n return none;\n if (check.scheme === \"bearer\")\n return { scheme: \"bearer\", token: check.credentials };\n const decoded = atob(check.credentials);\n const colon = decoded.indexOf(\":\");\n return { scheme: \"basic\", username: decoded.slice(0, colon), password: decoded.slice(colon + 1) };\n}\nfunction describe(target) {\n return \"port\" in target ? `port ${target.port}` : target.unix;\n}\nvar PROXY = String.raw`\nimport errno, hmac, json, os, random, re, secrets, socket, sys, threading, urllib.parse\n\nconfig = json.loads(sys.stdin.readline())\nMAX_LINE = 16 * 1024 * 1024\nHEARTBEAT = 15\nPREFLIGHT = b\"Access-Control-Allow-Methods: GET, POST, OPTIONS\\r\\nAccess-Control-Allow-Headers: authorization, content-type\\r\\nAccess-Control-Max-Age: 600\\r\\n\"\nMAX_HEAD = 65536\nHEAD_TIMEOUT = 30\nHOP_BY_HOP = {b\"authorization\", b\"connection\", b\"keep-alive\", b\"proxy-connection\", b\"proxy-authorization\"}\nENDPOINT_NAME = re.compile(r\"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$\")\n\n\ndef listen(port):\n if socket.has_dualstack_ipv6():\n return socket.create_server((\"\", port), family=socket.AF_INET6, dualstack_ipv6=True, backlog=128)\n return socket.create_server((\"\", port), backlog=128)\n\n\nlow, high = config[\"ports\"]\ncandidates = [port for port in range(low, high + 1) if port not in config[\"except\"]]\nrandom.shuffle(candidates)\nserver = None\nfor port in candidates:\n try:\n server = listen(port)\n break\n except OSError as e:\n if e.errno != errno.EADDRINUSE:\n raise\nif server is None:\n sys.stderr.write(\"no free port in %d-%d\\n\" % (low, high))\n sys.exit(1)\nPORT = server.getsockname()[1]\n\n# Endpoints recorded by a proxy that's gone (a reboot) are served again, as they were given out;\n# only that proxy's own leftovers (its pid, half-written records) go.\nos.umask(0o077)\nDIR = os.path.join(sys.argv[2], str(PORT))\nos.makedirs(DIR, mode=0o700, exist_ok=True)\nfor stale in os.listdir(DIR):\n if stale.startswith(\".\"):\n os.remove(os.path.join(DIR, stale))\n\n# Detached; the port is printed once the proxy's pid is recorded, so whoever started it can find it.\nready_read, ready_write = os.pipe()\nif os.fork():\n os.close(ready_write)\n if os.read(ready_read, 2) != b\"ok\":\n sys.exit(1)\n sys.stdout.write(\"%d\\n\" % PORT)\n sys.stdout.flush()\n os._exit(0)\nos.setsid()\nif os.fork():\n os._exit(0)\nwith open(os.path.join(DIR, \".pid\"), \"w\") as pid_file:\n pid_file.write(str(os.getpid()))\nos.write(ready_write, b\"ok\")\nos.close(ready_write)\nnull = os.open(os.devnull, os.O_RDWR)\nfor fd in (0, 1, 2):\n os.dup2(null, fd)\n\n\ndef record_path(name):\n return os.path.join(DIR, name + \".json\")\n\n\ndef load(name):\n \"\"\"The endpoint recorded under that name, or None.\"\"\"\n if not ENDPOINT_NAME.match(name):\n return None\n try:\n with open(record_path(name)) as record:\n return json.load(record)\n except (OSError, ValueError):\n return None\n\n\nclass Reply(Exception):\n \"\"\"Answers the request with an empty body and ends the connection: a refusal, a 204, a redirect.\"\"\"\n\n def __init__(self, status, extra=b\"\"):\n self.status = status\n self.extra = extra\n\n\nclass Reader:\n def __init__(self, conn):\n self.conn = conn\n self.buffer = b\"\"\n\n def fill(self):\n data = self.conn.recv(65536)\n if not data:\n raise Reply(b\"400 Bad Request\")\n self.buffer += data\n\n def until(self, marker, limit):\n while marker not in self.buffer:\n if len(self.buffer) > limit:\n raise Reply(b\"431 Request Header Fields Too Large\")\n self.fill()\n found, self.buffer = self.buffer.split(marker, 1)\n return found\n\n def exactly(self, size):\n while len(self.buffer) < size:\n self.fill()\n found, self.buffer = self.buffer[:size], self.buffer[size:]\n return found\n\n\ndef parse(head):\n lines = head.split(b\"\\r\\n\")\n if any(c in line for line in lines for c in (b\"\\r\", b\"\\n\", b\"\\0\")):\n raise Reply(b\"400 Bad Request\")\n method, sep, rest = lines[0].partition(b\" \")\n path, sep2, version = rest.partition(b\" \")\n if not (sep and sep2 and method and path.startswith(b\"/\")) or version not in (b\"HTTP/1.1\", b\"HTTP/1.0\"):\n raise Reply(b\"400 Bad Request\")\n headers = []\n for line in lines[1:]:\n name, sep, value = line.partition(b\":\")\n if not sep or not name or any(c in name for c in b\" \\t\"):\n raise Reply(b\"400 Bad Request\")\n headers.append((name, value.strip()))\n return method, path, version, headers\n\n\ndef header(headers, name):\n for n, v in headers:\n if n.lower() == name:\n return v\n return None\n\n\ndef authorized(headers, check):\n values = [v for n, v in headers if n.lower() == b\"authorization\"]\n if len(values) != 1:\n return False\n scheme, _, credentials = values[0].partition(b\" \")\n return scheme.lower() == check[\"scheme\"].encode() and hmac.compare_digest(credentials.strip(), check[\"credentials\"].encode())\n\n\ndef challenge(check):\n if check[\"scheme\"] == \"basic\":\n return b'WWW-Authenticate: Basic realm=\"hyperbrane\", charset=\"UTF-8\"\\r\\n'\n return b\"WWW-Authenticate: Bearer\\r\\n\"\n\n\ndef cors_headers(origin, endpoint):\n if origin is None or origin.decode(\"latin-1\") not in endpoint[\"origins\"]:\n return b\"\"\n return b\"Access-Control-Allow-Origin: \" + origin + b\"\\r\\nAccess-Control-Allow-Credentials: true\\r\\nVary: Origin\\r\\n\"\n\n\ndef framing(headers):\n lengths = [v for n, v in headers if n.lower() == b\"content-length\"]\n encodings = [v for n, v in headers if n.lower() == b\"transfer-encoding\"]\n if encodings:\n if lengths or len(encodings) != 1 or encodings[0].lower() != b\"chunked\":\n raise Reply(b\"400 Bad Request\")\n return \"chunked\"\n if len(lengths) > 1 or (lengths and not lengths[0].isdigit()):\n raise Reply(b\"400 Bad Request\")\n return int(lengths[0]) if lengths else 0\n\n\ndef forward_body(reader, up, body):\n if body == \"chunked\":\n while True:\n line = reader.until(b\"\\r\\n\", 4096)\n size_text = line.split(b\";\", 1)[0].strip()\n if not size_text or any(c not in b\"0123456789abcdefABCDEF\" for c in size_text):\n raise Reply(b\"400 Bad Request\")\n size = int(size_text, 16)\n if size == 0:\n # Trailers are dropped: read up to the blank line that ends them.\n while reader.until(b\"\\r\\n\", MAX_HEAD):\n pass\n up.sendall(b\"0\\r\\n\\r\\n\")\n return\n data = reader.exactly(size)\n if reader.exactly(2) != b\"\\r\\n\":\n raise Reply(b\"400 Bad Request\")\n up.sendall(b\"%x\\r\\n\" % size + data + b\"\\r\\n\")\n remaining = body\n while remaining:\n data = reader.exactly(min(remaining, 65536))\n up.sendall(data)\n remaining -= len(data)\n\n\ndef tune(sock):\n # Streams (an agent's, as SSE) go out event by event, and a peer that vanished without closing\n # is noticed within a couple of minutes instead of holding its connection forever.\n sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)\n if sock.family == socket.AF_UNIX:\n return\n sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n for name, value in ((\"TCP_KEEPIDLE\", 60), (\"TCP_KEEPINTVL\", 15), (\"TCP_KEEPCNT\", 4)):\n if hasattr(socket, name):\n sock.setsockopt(socket.IPPROTO_TCP, getattr(socket, name), value)\n\n\ndef connect_target(target):\n if \"unix\" in target:\n up = socket.socket(socket.AF_UNIX)\n up.connect(target[\"unix\"])\n else:\n up = socket.create_connection((\"localhost\", target[\"port\"]))\n tune(up)\n return up\n\n\ndef hang_up(sock):\n # shutdown, not just close: it also wakes a thread blocked reading the socket.\n if sock is None:\n return\n try:\n sock.shutdown(socket.SHUT_RDWR)\n except OSError:\n pass\n try:\n sock.close()\n except OSError:\n pass\n\n\ndef pump_response(up, conn, decided, state):\n \"\"\"Copies the target's side to the client until either end goes away, then closes the client's.\"\"\"\n first = b\"\"\n try:\n while True:\n data = up.recv(65536)\n if not data:\n break\n if not decided.is_set():\n first += data\n if b\"\\r\\n\" in first or len(first) > 64:\n state[\"upgraded\"] = first.startswith((b\"HTTP/1.1 101\", b\"HTTP/1.0 101\"))\n decided.set()\n conn.sendall(data)\n except OSError:\n pass\n finally:\n decided.set()\n hang_up(conn)\n\n\nclass Collect:\n \"\"\"forward_body's destination for a body kept here (a POST to an \"sse\" connection).\"\"\"\n\n def __init__(self):\n self.data = b\"\"\n\n def sendall(self, data):\n self.data += data\n if len(self.data) > MAX_LINE:\n raise Reply(b\"413 Content Too Large\")\n\n\nclass Connection:\n \"\"\"An \"sse\" connection to an endpoint's target; POSTs write to it, one at a time.\"\"\"\n\n def __init__(self, endpoint_name, sock):\n self.endpoint_name = endpoint_name\n self.sock = sock\n self.lock = threading.Lock()\n\n def write(self, data):\n with self.lock:\n self.sock.sendall(data)\n\n\nCONNECTIONS = {}\nCONNECTIONS_LOCK = threading.Lock()\n\n\ndef serve_sse(conn, reader, method, rest, body, cors, name, endpoint):\n if rest in (b\"\", b\"/\"):\n if method != b\"GET\":\n raise Reply(b\"405 Method Not Allowed\", b\"Allow: GET\\r\\n\" + cors)\n return stream_target(conn, cors, name, endpoint)\n if method != b\"POST\" or rest.count(b\"/\") != 1:\n raise Reply(b\"404 Not Found\", cors)\n with CONNECTIONS_LOCK:\n target = CONNECTIONS.get(rest[1:].decode(\"ascii\", \"replace\"))\n if target is None or target.endpoint_name != name:\n raise Reply(b\"404 Not Found\", cors)\n collected = Collect()\n forward_body(reader, collected, body)\n try:\n target.write(collected.data)\n except OSError:\n raise Reply(b\"404 Not Found\", cors)\n raise Reply(b\"204 No Content\", cors)\n\n\ndef watch_client(conn, up):\n # Anything the client sends after its request is dropped; its leaving ends the connection.\n try:\n while conn.recv(65536):\n pass\n except OSError:\n pass\n hang_up(up)\n\n\ndef heartbeat(send, stop, name, up):\n while not stop.wait(HEARTBEAT):\n # A closed endpoint takes its streams with it.\n if not os.path.exists(record_path(name)):\n hang_up(up)\n return\n try:\n send(b\": ping\\n\\n\")\n except OSError:\n return\n\n\ndef stream_target(conn, cors, name, endpoint):\n try:\n up = connect_target(endpoint[\"target\"])\n except OSError:\n raise Reply(b\"502 Bad Gateway\", cors)\n connection_id = secrets.token_hex(16)\n lock = threading.Lock()\n\n def send(data):\n with lock:\n conn.sendall(data)\n\n stop = threading.Event()\n with CONNECTIONS_LOCK:\n CONNECTIONS[connection_id] = Connection(name, up)\n try:\n conn.settimeout(None)\n send(b\"HTTP/1.1 200 OK\\r\\nContent-Type: text/event-stream\\r\\nCache-Control: no-cache, no-transform\\r\\nX-Accel-Buffering: no\\r\\nConnection: close\\r\\n\" + cors + b\"\\r\\n\")\n send(b\"event: open\\ndata: \" + json.dumps({\"connection\": connection_id}).encode() + b\"\\n\\n\")\n threading.Thread(target=heartbeat, args=(send, stop, name, up), daemon=True).start()\n threading.Thread(target=watch_client, args=(conn, up), daemon=True).start()\n pending = b\"\"\n while True:\n data = up.recv(65536)\n if not data:\n break\n *lines, pending = (pending + data).split(b\"\\n\")\n for line in lines:\n if line.endswith(b\"\\r\"):\n line = line[:-1]\n # A bare CR would end the event early on the client: the line can't go as SSE.\n if b\"\\r\" in line:\n return\n send(b\"data: \" + line + b\"\\n\\n\")\n if len(pending) > MAX_LINE:\n return\n send(b\"event: close\\ndata: {}\\n\\n\")\n except OSError:\n pass\n finally:\n stop.set()\n with CONNECTIONS_LOCK:\n CONNECTIONS.pop(connection_id, None)\n hang_up(up)\n hang_up(conn)\n\n\ndef return_to(method, query):\n if method != b\"GET\":\n raise Reply(b\"405 Method Not Allowed\", b\"Allow: GET\\r\\n\")\n to = urllib.parse.parse_qs(query.decode(\"latin-1\")).get(\"to\", [\"\"])[0]\n parts = urllib.parse.urlsplit(to)\n if parts.scheme not in (\"http\", \"https\") or not parts.netloc or any(ord(c) < 0x21 or ord(c) > 0x7E for c in to):\n raise Reply(b\"400 Bad Request\")\n origin = parts.scheme + \"://\" + parts.netloc\n for entry in os.listdir(DIR):\n endpoint = load(entry[:-5]) if entry.endswith(\".json\") else None\n if endpoint is not None and endpoint[\"check\"] is None and origin in endpoint[\"origins\"]:\n raise Reply(b\"302 Found\", b\"Location: \" + to.encode() + b\"\\r\\nCache-Control: no-store\\r\\n\")\n raise Reply(b\"400 Bad Request\")\n\n\ndef handle(conn):\n up = None\n try:\n conn.settimeout(HEAD_TIMEOUT)\n reader = Reader(conn)\n method, path, version, headers = parse(reader.until(b\"\\r\\n\\r\\n\", MAX_HEAD))\n route, _, query = path.partition(b\"?\")\n if route == b\"/__hyb/return\":\n return_to(method, query)\n name_bytes, slash, rest = route[1:].partition(b\"/\")\n name = name_bytes.decode(\"ascii\", \"replace\")\n endpoint = load(name)\n if endpoint is None:\n raise Reply(b\"404 Not Found\")\n cors = cors_headers(header(headers, b\"origin\"), endpoint)\n # A browser's preflight carries no credentials; it is answered here and never reaches the target.\n if method == b\"OPTIONS\" and header(headers, b\"access-control-request-method\") is not None:\n raise Reply(b\"204 No Content\", cors + PREFLIGHT) if cors else Reply(b\"403 Forbidden\")\n check = endpoint[\"check\"]\n if check and not authorized(headers, check):\n raise Reply(b\"401 Unauthorized\", challenge(check) + cors)\n body = framing(headers)\n if endpoint[\"transport\"] == \"sse\":\n return serve_sse(conn, reader, method, slash + rest, body, cors, name, endpoint)\n upgrade = any(n.lower() == b\"upgrade\" for n, _ in headers)\n try:\n up = connect_target(endpoint[\"target\"])\n except OSError:\n raise Reply(b\"502 Bad Gateway\", cors)\n target_path = slash + rest if slash else b\"/\"\n if query:\n target_path += b\"?\" + query\n kept = [n + b\": \" + v for n, v in headers if n.lower() not in HOP_BY_HOP]\n kept.append(b\"Connection: Upgrade\" if upgrade else b\"Connection: close\")\n up.sendall(method + b\" \" + target_path + b\" \" + version + b\"\\r\\n\" + b\"\\r\\n\".join(kept) + b\"\\r\\n\\r\\n\")\n decided = threading.Event()\n state = {\"upgraded\": False}\n # The request is done once the response is: the client side closes with it.\n pump = threading.Thread(target=pump_response, args=(up, conn, decided, state), daemon=True)\n pump.start()\n forward_body(reader, up, body)\n conn.settimeout(None)\n if upgrade:\n decided.wait()\n if upgrade and state[\"upgraded\"]:\n if reader.buffer:\n up.sendall(reader.buffer)\n while True:\n data = conn.recv(65536)\n if not data:\n break\n up.sendall(data)\n else:\n # Anything more from the client is dropped: it would reach the target unchecked.\n while conn.recv(65536):\n pass\n # The client is gone (or the response ended and closed it): a stream it was reading stops too.\n hang_up(up)\n pump.join()\n except Reply as reply:\n try:\n conn.sendall(b\"HTTP/1.1 \" + reply.status + b\"\\r\\nContent-Length: 0\\r\\nConnection: close\\r\\n\" + reply.extra + b\"\\r\\n\")\n except OSError:\n pass\n except (OSError, ValueError):\n pass\n finally:\n hang_up(up)\n hang_up(conn)\n\n\nwhile True:\n conn, _ = server.accept()\n tune(conn)\n threading.Thread(target=handle, args=(conn,), daemon=True).start()\n`;\n\n// sandbox/localService.ts\nfunction createLocalSandbox(root, { endpoints } = {}) {\n const base = resolve(root);\n function hostPath(path) {\n const full = resolve(base, isAbsolute(path) ? `.${path}` : path);\n const rel = relative(base, full);\n if (rel.startsWith(\"..\") || isAbsolute(rel))\n throw new SandboxPathError(`Path escapes sandbox: \"${path}\"`);\n return full;\n }\n async function notFoundAs(path, operation) {\n try {\n return await operation;\n } catch (error) {\n if (error.code === \"ENOENT\")\n throw new SandboxNotFoundError(`Not found: \"${path}\"`);\n throw error;\n }\n }\n async function writeTemp(full, data) {\n await mkdir(dirname(full), { recursive: true });\n const tmp = join(dirname(full), `.${basename(full)}.${crypto.randomUUID()}.tmp`);\n await writeFile(tmp, data);\n return tmp;\n }\n async function readFileLocal(path) {\n return new Uint8Array(await notFoundAs(path, readFile(hostPath(path))));\n }\n async function readFileRangeLocal(path, start, end) {\n const file = await notFoundAs(path, open(hostPath(path), \"r\"));\n try {\n const buffer = new Uint8Array(Math.max(0, end - start));\n let filled = 0;\n while (filled < buffer.length) {\n const { bytesRead } = await file.read(buffer, filled, buffer.length - filled, start + filled);\n if (bytesRead === 0)\n break;\n filled += bytesRead;\n }\n return buffer.subarray(0, filled);\n } finally {\n await file.close();\n }\n }\n async function writeFileLocal(path, data) {\n const full = hostPath(path);\n await rename(await writeTemp(full, data), full);\n }\n async function writeFileExclusive(path, data) {\n const full = hostPath(path);\n const tmp = await writeTemp(full, data);\n try {\n await link(tmp, full);\n return true;\n } catch (error) {\n if (error.code === \"EEXIST\")\n return false;\n throw error;\n } finally {\n await unlink(tmp);\n }\n }\n async function removeFile(path) {\n await rm(hostPath(path), { force: true });\n }\n async function createDirectory(path) {\n await mkdir(hostPath(path), { recursive: true });\n }\n async function removeDirectory(path) {\n await rm(hostPath(path), { recursive: true, force: true });\n }\n async function listDirectory(path) {\n return notFoundAs(path, readdir(hostPath(path)));\n }\n async function statLocal(path) {\n const stats = await notFoundAs(path, stat(hostPath(path)));\n const type = stats.isFile() ? \"file\" : stats.isDirectory() ? \"directory\" : \"other\";\n return { type, uid: stats.uid, gid: stats.gid, size: stats.size };\n }\n async function homeDirectory() {\n const rel = relative(base, homedir());\n if (rel.startsWith(\"..\") || isAbsolute(rel))\n throw new SandboxPathError(`Home directory is outside the sandbox`);\n return `/${rel}`;\n }\n function runCommand(cmd, { cwd, env = {}, stdin } = {}) {\n return new Promise((resolve2, reject) => {\n const [command, ...args] = cmd;\n if (!command)\n return reject(new Error(\"no command to run\"));\n const child = spawn(command, args, {\n cwd: hostPath(cwd ?? \".\"),\n env: { ...process.env, ...env },\n stdio: [stdin === undefined ? \"ignore\" : \"pipe\", \"pipe\", \"pipe\"]\n });\n const stdout = [];\n const stderr = [];\n child.stdout.on(\"data\", (chunk) => stdout.push(chunk));\n child.stderr.on(\"data\", (chunk) => stderr.push(chunk));\n child.once(\"error\", reject);\n child.once(\"close\", (code) => resolve2({ exitCode: code ?? -1, stdout: Buffer.concat(stdout).toString(), stderr: Buffer.concat(stderr).toString() }));\n if (stdin !== undefined)\n child.stdin.end(stdin);\n });\n }\n async function connect(path) {\n return socketConnection(createConnection({ path: hostPath(path) }), path);\n }\n async function fetchLocal(url, { unix, ...init } = {}) {\n if (unix === undefined || \"Bun\" in globalThis)\n return fetch(url, { ...init, unix: unix === undefined ? undefined : hostPath(unix) });\n return fetchOverSocket(url, hostPath(unix), init);\n }\n const sandbox = {\n readFile: readFileLocal,\n readFileRange: readFileRangeLocal,\n writeFile: writeFileLocal,\n writeFileExclusive,\n removeFile,\n createDirectory,\n removeDirectory,\n listDirectory,\n stat: statLocal,\n homeDirectory,\n runCommand,\n fetch: fetchLocal,\n connect\n };\n if (!endpoints)\n return sandbox;\n return { ...sandbox, ...createProxyEndpoints({ runCommand }, endpoints, \"this machine\") };\n}\nfunction fetchOverSocket(url, socketPath, { method = \"GET\", headers = {}, body, signal, timeout }) {\n return new Promise((resolve2, reject) => {\n const target = new URL(url);\n const request = httpRequest({ socketPath, path: `${target.pathname}${target.search}`, method, headers: { host: target.host, ...headers }, signal }, (response) => {\n const responseHeaders = new Headers;\n for (let i = 0;i + 1 < response.rawHeaders.length; i += 2)\n responseHeaders.append(response.rawHeaders[i], response.rawHeaders[i + 1]);\n const status = response.statusCode ?? 502;\n const nullBody = status === 204 || status === 304 || method === \"HEAD\";\n if (nullBody)\n response.resume();\n resolve2(new Response(nullBody ? null : Readable.toWeb(response), { status, headers: responseHeaders }));\n });\n request.once(\"error\", reject);\n if (typeof timeout === \"number\")\n request.setTimeout(timeout, () => request.destroy(new Error(`fetch ${url}: no data for ${timeout}ms`)));\n request.end(body === undefined ? undefined : typeof body === \"string\" ? body : Buffer.from(body));\n });\n}\nfunction socketConnection(stream, path, { opened = false } = {}) {\n return new Promise((resolve2, reject) => {\n let markClosed;\n const closed = new Promise((done) => markClosed = done);\n const listeners = [];\n stream.on(\"data\", (chunk) => {\n for (const listener of listeners)\n listener(new Uint8Array(chunk));\n });\n stream.once(\"close\", () => markClosed());\n stream.once(\"end\", () => markClosed());\n const connection = {\n write: (data) => void stream.write(data),\n onData: (listener) => void listeners.push(listener),\n closed,\n close: () => stream.end()\n };\n stream.once(\"error\", (error) => {\n markClosed();\n reject(new Error(`connecting to ${path} failed: ${error.message}`));\n });\n if (opened)\n resolve2(connection);\n else\n stream.once(\"connect\", () => resolve2(connection));\n });\n}\n\n// agent/session/login.ts\nfunction plain(text) {\n return text.replace(/\\x1b\\][^\\x07\\x1b]*(\\x07|\\x1b\\\\)/g, \"\").replace(/\\x1b\\[[0-9;?]*[a-zA-Z]/g, \"\");\n}\nfunction spawnLogin(cmd, { env, cwd }, parse) {\n const proc = Bun.spawn(cmd, { env, cwd, stdin: \"pipe\", stdout: \"pipe\", stderr: \"pipe\" });\n let output = \"\";\n let showPrompt;\n let noPrompt;\n const prompt = new Promise((resolve2, reject) => {\n showPrompt = resolve2;\n noPrompt = reject;\n });\n async function read(stream) {\n const decoder = new TextDecoder;\n for await (const chunk of stream) {\n output += plain(decoder.decode(chunk, { stream: true }));\n const found = parse(output);\n if (found)\n showPrompt(found);\n }\n }\n const reading = Promise.all([read(proc.stdout), read(proc.stderr)]);\n const done = reading.then(() => proc.exited).then((code) => {\n const tail = output.trim().split(`\n`).slice(-3).join(\" \").trim();\n noPrompt(new Error(`the login ended before showing where to sign in: ${tail}`));\n if (code !== 0)\n throw new Error(`the login failed (exit ${code}): ${tail}`);\n });\n prompt.catch(() => {});\n done.catch(() => {});\n return {\n prompt,\n done,\n submitCode(code) {\n proc.stdin.write(`${code}\n`);\n proc.stdin.flush();\n },\n cancel() {\n proc.kill();\n }\n };\n}\n\n// agent/session/claude/provision.ts\nimport { existsSync as existsSync2 } from \"fs\";\n\n// agent/session/install.ts\nimport { existsSync } from \"fs\";\n// agent/vendor-types/manifest.json\nvar manifest_default = {\n claude: {\n docs: \"https://code.claude.com/docs/en/agent-sdk/typescript\",\n sources: [\n {\n source: \"npm:@anthropic-ai/claude-agent-sdk@0.3.283\",\n into: \"agent-sdk\",\n files: 7\n }\n ]\n },\n codex: {\n docs: \"https://developers.openai.com/codex/app-server\",\n sources: [\n {\n source: \"npm:@openai/codex-sdk@0.157.1\",\n into: \"sdk\",\n files: 1\n },\n {\n source: \"github:openai/codex@rust-v0.157.1/codex-rs/app-server-protocol/schema/typescript\",\n into: \"app-server\",\n files: 740\n },\n {\n source: \"github:openai/codex@rust-v0.157.1/codex-rs/app-server-protocol/schema/json\",\n into: \"app-server-json\",\n files: 2\n }\n ]\n },\n pi: {\n docs: \"https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/rpc.md\",\n sources: [\n {\n source: \"npm:@mariozechner/pi-coding-agent@0.73.1\",\n into: \"coding-agent\",\n files: 137\n },\n {\n source: \"npm:@mariozechner/pi-agent-core@0.73.1\",\n into: \"agent-core\",\n files: 5\n },\n {\n source: \"npm:@mariozechner/pi-ai@0.73.1\",\n into: \"ai\",\n files: 44\n }\n ]\n },\n opencode: {\n docs: \"https://opencode.ai/docs/server\",\n sources: [\n {\n source: \"npm:@opencode-ai/sdk@1.18.32\",\n into: \"sdk\",\n files: 39\n },\n {\n source: \"github:anomalyco/opencode@v1.18.32/packages/sdk\",\n into: \"\",\n files: 1\n }\n ]\n },\n openclaw: {\n docs: \"https://docs.openclaw.ai/gateway/protocol\",\n sources: [\n {\n source: \"npm:@openclaw/gateway-protocol@2026.9.6\",\n into: \"gateway-protocol\",\n files: 17\n }\n ]\n },\n hermes: {\n docs: \"https://hermes-agent.nousresearch.com/docs\",\n sources: [\n {\n source: \"github:NousResearch/hermes-agent@v2026.9.24/apps/shared/src\",\n into: \"gateway\",\n files: 3\n }\n ]\n }\n};\n\n// agent/session/install.ts\nfunction pinnedVersion(vendor, pkg, sourcePackage = pkg) {\n const prefix = `npm:${sourcePackage}@`;\n const source = manifest_default[vendor].sources.find((entry) => entry.source.startsWith(prefix));\n if (!source)\n throw new Error(`agent/vendor-types/manifest.json has no ${sourcePackage} for ${vendor} (needed for ${pkg})`);\n return source.source.slice(prefix.length);\n}\nasync function installedPackage(installDir, pkg, version, executable) {\n const manifest = Bun.file(`${installDir}/node_modules/${pkg}/package.json`);\n const found = await manifest.exists() ? (await manifest.json()).version ?? null : null;\n return { version: found, ready: found === version && existsSync(executable()) };\n}\nasync function installPackage(installDir, pkg, version, executable) {\n const installed = await installedPackage(installDir, pkg, version, executable);\n if (installed.ready)\n return;\n const force = installed.version === version ? [\"--force\"] : [];\n const proc = Bun.spawn([process.execPath, \"add\", \"--exact\", ...force, `${pkg}@${version}`], {\n cwd: installDir,\n stdin: \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\"\n });\n const [stdout, stderr, exitCode] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n proc.exited\n ]);\n if (exitCode !== 0)\n throw new Error(`bun add ${pkg}@${version} failed (exit ${exitCode}): ${(stderr || stdout).trim()}`);\n if (!existsSync(executable()))\n throw new Error(`bun add ${pkg}@${version} left no ${executable()}: its platform package didn't install`);\n}\n\n// agent/session/claude/provision.ts\nvar CLAUDE_SDK_PACKAGE = \"@anthropic-ai/claude-agent-sdk\";\nfunction installClaude(installDir) {\n return installPackage(installDir, CLAUDE_SDK_PACKAGE, pinnedVersion(\"claude\", CLAUDE_SDK_PACKAGE), () => claudeExecutable(installDir));\n}\nfunction installedClaude(installDir) {\n return installedPackage(installDir, CLAUDE_SDK_PACKAGE, pinnedVersion(\"claude\", CLAUDE_SDK_PACKAGE), () => claudeExecutable(installDir));\n}\nfunction claudeExecutable(installDir) {\n const base = `${installDir}/node_modules/${CLAUDE_SDK_PACKAGE}-linux-${process.arch}`;\n const glibc = `${base}/claude`;\n return existsSync2(glibc) ? glibc : `${base}-musl/claude`;\n}\n\n// agent/session/claude/auth.ts\nvar GATEWAY_CODE = \"x#x\";\nvar claudeAuth = {\n async signedIn({ installDir, env, cwd }) {\n const proc = Bun.spawn([claudeExecutable(installDir), \"auth\", \"status\", \"--json\"], { env, cwd, stdout: \"pipe\", stderr: \"ignore\" });\n const [output, code] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);\n if (code !== 0)\n return false;\n try {\n return JSON.parse(output).loggedIn === true;\n } catch {\n return false;\n }\n },\n login({ installDir, env, cwd }, gatewaySignedIn) {\n const login = spawnLogin([claudeExecutable(installDir), \"auth\", \"login\"], { env, cwd }, (output) => {\n const url = /https:\\/\\/\\S*oauth\\/authorize\\S*/.exec(output)?.[0];\n return url ? { url, needsCode: true } : null;\n });\n if (gatewaySignedIn)\n login.prompt.then(() => login.submitCode(GATEWAY_CODE), () => {});\n return login;\n }\n};\n\n// agent/api.ts\nvar AGENT_BACKENDS = [\"claude\", \"codex\"];\n\nclass AgentInvalidError extends Error {\n name = \"AgentInvalidError\";\n}\n\nclass AgentNotFoundError extends Error {\n name = \"AgentNotFoundError\";\n}\n\nclass AgentConflictError extends Error {\n name = \"AgentConflictError\";\n}\n\nclass AgentBackendNotInstalledError extends AgentConflictError {\n name = \"AgentBackendNotInstalledError\";\n}\n\n// agent/session/claude/backgroundTasks.ts\nfunction claudeBackgroundTasks() {\n let tasks = [];\n return {\n observe(message) {\n if (message.type !== \"system\")\n return;\n if (message.subtype === \"background_tasks_changed\")\n tasks = message.tasks;\n if (message.subtype === \"task_notification\")\n tasks = tasks.filter((task) => task.task_id !== message.task_id);\n },\n list: async () => tasks\n };\n}\nfunction claudeStopTask(query, tasks) {\n return async (taskId) => {\n if (!(await tasks.list()).some((task) => task.task_id === taskId))\n throw new AgentNotFoundError(`no background task ${taskId}`);\n await query.stopTask(taskId);\n };\n}\n\n// agent/session/claude/home.ts\nfunction claudeHomeEnvironment(home) {\n return { CLAUDE_CONFIG_DIR: home };\n}\n\n// agent/session/claude/input.ts\nfunction createPromptQueue() {\n const queued = [];\n let wake;\n let closed = false;\n function push(message) {\n queued.push(message);\n wake?.();\n }\n function close() {\n closed = true;\n wake?.();\n }\n async function* iterate() {\n for (;; ) {\n while (queued.length > 0)\n yield queued.shift();\n if (closed)\n return;\n await new Promise((resolve2) => wake = resolve2);\n wake = undefined;\n }\n }\n return { push, close, [Symbol.asyncIterator]: iterate };\n}\nfunction claudeInput(prompts, queue) {\n return async (message) => {\n if (!message.uuid)\n throw new Error(\"a message sent to claude needs a uuid to be acknowledged by\");\n const received = queue.sent({ ...message, uuid: message.uuid });\n prompts.push(message);\n await received;\n };\n}\n\n// agent/session/claude/messageQueue.ts\nvar RECEIVE_TIMEOUT_MS = 60000;\nfunction claudeMessageQueue() {\n const commands = new Map;\n let taken = null;\n const receipts = new Map;\n function observe(message) {\n const event = message;\n if (event.type !== \"command_lifecycle\" || !event.command_uuid || !event.state)\n return;\n const command = commands.get(event.command_uuid);\n if (command) {\n command.state = event.state;\n if (event.state === \"started\")\n taken = command.message;\n if (event.state !== \"queued\")\n commands.delete(event.command_uuid);\n }\n const receipt = receipts.get(event.command_uuid);\n if (!receipt)\n return;\n receipts.delete(event.command_uuid);\n if (event.state === \"queued\" || event.state === \"started\")\n receipt.resolve();\n else\n receipt.reject(new Error(`claude ${event.state} the message`));\n }\n function sent(message) {\n commands.set(message.uuid, { message, state: null });\n return new Promise((resolve2, reject) => {\n const timer = setTimeout(() => {\n receipts.delete(message.uuid);\n commands.delete(message.uuid);\n reject(new Error(\"claude didn't confirm it received the message\"));\n }, RECEIVE_TIMEOUT_MS);\n receipts.set(message.uuid, {\n resolve: () => (clearTimeout(timer), resolve2()),\n reject: (error) => (clearTimeout(timer), commands.delete(message.uuid), reject(error))\n });\n });\n }\n async function lastUserMessages() {\n const queued = [...commands.values()].filter((command) => command.state === \"queued\");\n return [...taken ? [{ message: taken, queued: false }] : [], ...queued.map((command) => ({ message: command.message, queued: true }))];\n }\n return { observe, sent, lastUserMessages };\n}\n\n// agent/session/claude/status.ts\nvar SESSION_STATE_EVENTS = { CLAUDE_CODE_EMIT_SESSION_STATE_EVENTS: \"1\" };\nfunction claudeStatus() {\n let status = \"idle\";\n return {\n observe(message) {\n if (message.type !== \"system\" || message.subtype !== \"session_state_changed\")\n return;\n status = message.state === \"requires_action\" ? \"waiting\" : message.state;\n },\n status: async () => status\n };\n}\n\n// agent/session/claude/interrupt.ts\nfunction claudeInterrupt(query) {\n return async () => {\n await query.interrupt();\n };\n}\n\n// agent/session/claude/model.ts\nfunction claudeModel(query) {\n return {\n listModels: () => query.supportedModels(),\n setModel: (model) => query.setModel(model ?? undefined)\n };\n}\n\n// agent/session/sdkMessages.ts\nvar ASK_USER_QUESTION = \"AskUserQuestion\";\nfunction resultUsage({ input = 0, output = 0, cacheRead = 0, cacheWrite = 0 } = {}) {\n return {\n input_tokens: input,\n output_tokens: output,\n cache_read_input_tokens: cacheRead,\n cache_creation_input_tokens: cacheWrite,\n cache_creation: { ephemeral_1h_input_tokens: 0, ephemeral_5m_input_tokens: 0 },\n server_tool_use: { web_fetch_requests: 0, web_search_requests: 0 },\n service_tier: \"standard\"\n };\n}\nfunction userMessageText(message) {\n const content = message.message.content;\n if (typeof content === \"string\")\n return content;\n if (!Array.isArray(content))\n return \"\";\n return content.map((block) => block.type === \"text\" && typeof block.text === \"string\" ? block.text : \"\").filter(Boolean).join(`\n`);\n}\n\n// agent/session/claude/permissions.ts\nfunction claudePermissions(context, questions) {\n const canUseTool = (toolName, input, options) => {\n if (toolName === ASK_USER_QUESTION)\n return questions.answer(input, options);\n const { signal, toolUseID, decisionReason } = options;\n return context.requestPermission({ tool_name: toolName, input, tool_use_id: toolUseID, decision_reason: decisionReason }, signal);\n };\n const preToolUse = [\n {\n hooks: [async () => ({ hookSpecificOutput: { hookEventName: \"PreToolUse\", permissionDecision: \"ask\" } })]\n }\n ];\n return { canUseTool, preToolUse };\n}\n\n// agent/session/claude/questions.ts\nvar QUESTION_DIALOG_KINDS = [\"permission_ask_user_question\", \"ask_user_question\", \"user_question\"];\nfunction claudeQuestions(context) {\n async function ask(input, toolUseId, signal) {\n const questions = Array.isArray(input.questions) ? input.questions : [];\n const response = await context.askQuestions({ tool_use_id: toolUseId, questions }, signal);\n if (!response)\n return { behavior: \"deny\", message: \"The user dismissed the questions.\" };\n return { behavior: \"allow\", updatedInput: { ...input, answers: response.answers } };\n }\n const onUserDialog = async (request, { signal }) => {\n if (!QUESTION_DIALOG_KINDS.includes(request.dialogKind))\n return { behavior: \"cancelled\" };\n const result = await ask(request.payload, request.toolUseID ?? crypto.randomUUID(), signal);\n if (result.behavior !== \"allow\")\n return { behavior: \"cancelled\" };\n return { behavior: \"completed\", result };\n };\n return {\n answer: (input, { signal, toolUseID }) => ask(input, toolUseID, signal),\n onUserDialog,\n supportedDialogKinds: QUESTION_DIALOG_KINDS\n };\n}\n\n// agent/session/claude/sdk.ts\nasync function loadClaudeSdk(installDir) {\n return await import(Bun.resolveSync(CLAUDE_SDK_PACKAGE, installDir));\n}\n\n// agent/session/claude/stream.ts\nasync function startClaudeStream(context, prompts, permissions, questions, backgroundTasks, status, queue) {\n const sdk = await loadClaudeSdk(context.installDir);\n const query = sdk.query({\n prompt: prompts,\n options: {\n cwd: context.cwd,\n env: { ...context.env, ...SESSION_STATE_EVENTS },\n model: context.model ?? undefined,\n resume: context.nativeId ?? undefined,\n includePartialMessages: true,\n permissionMode: \"default\",\n settingSources: [],\n canUseTool: permissions.canUseTool,\n hooks: { PreToolUse: permissions.preToolUse },\n onUserDialog: questions.onUserDialog,\n supportedDialogKinds: questions.supportedDialogKinds,\n stderr: (data) => process.stderr.write(`[claude ${context.spec.name}] ${data}`)\n }\n });\n pump(context, query, [backgroundTasks, status, queue]).then(() => context.exited(), (error) => context.exited(error));\n return query;\n}\nasync function pump(context, query, observers) {\n for await (const message of query) {\n for (const observer of observers)\n observer.observe(message);\n if (\"session_id\" in message && typeof message.session_id === \"string\" && message.session_id) {\n context.setNativeId(message.session_id);\n }\n const streamed = toStreamingMessage(message);\n if (streamed)\n context.emit(streamed);\n }\n}\nfunction toStreamingMessage(message) {\n switch (message.type) {\n case \"assistant\":\n case \"stream_event\":\n case \"result\":\n return message;\n case \"user\":\n return { ...message, uuid: message.uuid ?? crypto.randomUUID(), session_id: message.session_id ?? \"\" };\n case \"system\":\n return message.subtype === \"init\" ? message : null;\n default:\n return null;\n }\n}\n\n// agent/session/fileTranscript.ts\nfunction sandboxFiles(sandbox) {\n return {\n size: async (path) => (await sandbox.stat(path)).size,\n readFileRange: (path, start, end) => sandbox.readFileRange(path, start, end),\n listDirectory: (path) => sandbox.listDirectory(path)\n };\n}\nfunction locateTranscript(files, home, layout, nativeId) {\n const escape = (text) => text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const [before = \"\", after = \"\"] = layout.name.split(\"{id}\").map((part) => part.split(\"*\").map(escape).join(\".*\"));\n const name = new RegExp(`^${before}${escape(nativeId)}${after}$`);\n return findFile(files, `${home}/${layout.dir}`, layout.depth, (entry) => name.test(entry));\n}\nvar CHUNK_BYTES = 64 * 1024;\nvar TIME_SLACK_MS = 60000;\nvar PROBE_LINES = 3;\nvar PROBE_BYTES = 4 * CHUNK_BYTES;\nvar NEWLINE = 10;\nfunction lineTime(entry, field) {\n const value = entry?.[field];\n const time = typeof value === \"string\" ? Date.parse(value) : NaN;\n return Number.isNaN(time) ? null : time;\n}\nvar SCAN_BYTES = 1024 * 1024;\nvar searchedCopies = new Map;\nvar SEARCHED_FILES = 16;\nfunction createFileTranscript(files, locate, lineMessages, layout) {\n function parse(bytes, start) {\n try {\n const entry = JSON.parse(new TextDecoder().decode(bytes));\n return { start, time: lineTime(entry, layout.time), messages: lineMessages(entry) };\n } catch {\n return { start, time: null, messages: [] };\n }\n }\n function kept(from, to, skip) {\n const parts = [];\n let start = from;\n for (const stretch of [...skip].sort((a, b) => a.start - b.start)) {\n if (stretch.end <= start || stretch.start >= to)\n continue;\n if (stretch.start > start)\n parts.push({ start, end: stretch.start });\n start = Math.max(start, stretch.end);\n }\n if (start < to)\n parts.push({ start, end: to });\n return parts;\n }\n async function* backward(path, end, skip = []) {\n for (const part of kept(0, end, skip).reverse())\n yield* backwardIn(path, part.start, part.end);\n }\n async function* backwardIn(path, floor, end) {\n let position = end;\n let carry = new Uint8Array(0);\n while (position > floor) {\n const from = Math.max(floor, position - CHUNK_BYTES);\n const chunk = await files.readFileRange(path, from, position);\n const bytes = joined(chunk, carry);\n let lineEnd = bytes.length;\n for (let index = bytes.length - 1;index >= 0; index--) {\n if (bytes[index] !== NEWLINE)\n continue;\n if (lineEnd > index + 1)\n yield parse(bytes.subarray(index + 1, lineEnd), from + index + 1);\n lineEnd = index;\n }\n carry = bytes.slice(0, lineEnd);\n position = from;\n }\n if (carry.length > 0)\n yield parse(carry, floor);\n }\n async function* forward(path, start, end, skip = []) {\n for (const part of kept(start, end, skip))\n yield* forwardIn(path, part.start, part.end);\n }\n async function* forwardIn(path, start, end) {\n let position = start;\n let carry = new Uint8Array(0);\n let carryStart = start;\n while (position < end) {\n const to = Math.min(end, position + CHUNK_BYTES);\n const bytes = joined(carry, await files.readFileRange(path, position, to));\n let lineStart2 = 0;\n for (let index = 0;index < bytes.length; index++) {\n if (bytes[index] !== NEWLINE)\n continue;\n if (index > lineStart2)\n yield parse(bytes.subarray(lineStart2, index), carryStart + lineStart2);\n lineStart2 = index + 1;\n }\n carry = bytes.slice(lineStart2);\n carryStart += lineStart2;\n position = to;\n }\n if (carry.length > 0)\n yield parse(carry, carryStart);\n }\n async function seek(path, low, high, target, skip) {\n return (await narrow(path, low, high, target, skip)).high;\n }\n async function narrow(path, low, high, target, skip) {\n while (high - low > CHUNK_BYTES) {\n let middle = Math.floor((low + high) / 2);\n const inside = skip.find((stretch) => stretch.start <= middle && middle < stretch.end);\n if (inside) {\n if (inside.end >= high) {\n high = Math.max(low, inside.start);\n continue;\n }\n middle = inside.end;\n }\n const probe = await probeTime(path, middle, high, skip);\n if (!probe)\n break;\n if (probe.time >= target)\n high = probe.start;\n else\n low = probe.start;\n }\n return { low, high };\n }\n async function probeTime(path, from, limit, skip) {\n let start = -1;\n let time = Infinity;\n let timed = 0;\n for await (const line of forward(path, from, Math.min(limit, from + PROBE_BYTES), skip)) {\n if (line.start === from && from > 0)\n continue;\n if (line.start >= limit)\n break;\n if (start < 0)\n start = line.start;\n if (line.time === null)\n continue;\n time = Math.min(time, line.time);\n if (++timed === PROBE_LINES)\n break;\n }\n return start < 0 || timed === 0 ? null : { start, time };\n }\n async function timeAt(path, from, size, skip) {\n for await (const line of forward(path, from, Math.min(size, from + PROBE_BYTES), skip))\n if (line.time !== null)\n return line.time;\n return null;\n }\n async function lineStart(path, at) {\n for await (const line of backward(path, at + 1))\n return line.start;\n return 0;\n }\n function copiesOf(path, size) {\n if (!layout.copies)\n return Promise.resolve([]);\n const key = `${path}\\x00${size}`;\n let copies = searchedCopies.get(key);\n if (!copies) {\n copies = findCopies(path, size, layout.copies);\n copies.catch(() => searchedCopies.delete(key));\n searchedCopies.set(key, copies);\n if (searchedCopies.size > SEARCHED_FILES)\n searchedCopies.delete(searchedCopies.keys().next().value);\n }\n return copies;\n }\n async function findCopies(path, size, marker) {\n const needle = Buffer.from(marker);\n const found = [];\n for (let position = 0;position < size; position += SCAN_BYTES) {\n const from = Math.max(0, position - needle.length + 1);\n const bytes = Buffer.from(await files.readFileRange(path, from, Math.min(size, position + SCAN_BYTES)));\n for (let index = bytes.indexOf(needle);index >= 0; index = bytes.indexOf(needle, index + 1)) {\n if (from + index >= position || position === 0)\n found.push(from + index);\n }\n }\n const copies = [];\n for (const [index, at] of found.entries()) {\n const start = await lineStart(path, at);\n let earlier = null;\n for await (const before of backward(path, start)) {\n if (before.time === null)\n continue;\n earlier = before.time;\n break;\n }\n if (earlier === null || copies.some((copy) => copy.start <= start && start < copy.end))\n continue;\n let time = null;\n for await (const line of forward(path, start, size)) {\n time = line.time;\n break;\n }\n if (time === null || time >= earlier)\n continue;\n const next = found[index + 1];\n const near = await narrow(path, start + 1, next === undefined ? size : await lineStart(path, next), earlier + 1, []);\n let end = near.high;\n for await (const line of forward(path, near.low, near.high)) {\n if (line.start <= start || line.time === null || line.time <= earlier)\n continue;\n end = line.start;\n break;\n }\n copies.push({ start, end });\n }\n return copies;\n }\n async function* pagedBackward(path, end, after, skip) {\n let next = after;\n let waiting = [];\n const settle = function* (before) {\n const [timed, ...untimed] = waiting;\n if (!timed)\n return;\n const own = timed.time;\n const late = before !== null && own < before - TIME_SLACK_MS && (next === null || own < next - TIME_SLACK_MS);\n const ahead = before !== null && own > before + TIME_SLACK_MS && (next === null || own > next + TIME_SLACK_MS);\n const time = late || ahead ? before : own;\n yield { ...timed, time };\n for (const line of untimed)\n yield { ...line, time };\n next = own;\n waiting = [];\n };\n for await (const line of backward(path, end, skip)) {\n if (line.time === null) {\n if (waiting.length === 0)\n yield { ...line, time: next ?? Infinity };\n else\n waiting.push(line);\n continue;\n }\n yield* settle(line.time);\n waiting = [line];\n }\n yield* settle(null);\n }\n async function page(before, limit, found) {\n const path = await locate();\n if (!path)\n return { messages: [], nextBefore: null };\n const size = await files.size(path);\n const copies = found?.copies ?? await copiesOf(path, size);\n const from = Math.min(found?.end ?? (before === null ? size : await seek(path, 0, size, before + TIME_SLACK_MS, copies)), size);\n const after = found ? found.after : from < size ? await timeAt(path, from, size, copies) : null;\n const taken = [];\n let count = 0;\n let oldest = Infinity;\n let older = false;\n for await (const line of pagedBackward(path, from, after, copies)) {\n if (count >= limit && line.time < oldest - TIME_SLACK_MS) {\n older = true;\n break;\n }\n if (line.messages.length === 0 || before !== null && !(line.time < before))\n continue;\n taken.push(line);\n count += line.messages.length;\n if (count >= limit)\n oldest = oldestOnPage(taken, limit);\n }\n const kept2 = count >= limit ? taken.filter((line) => line.time >= oldest) : taken;\n if (kept2.length < taken.length)\n older = true;\n return {\n messages: kept2.sort((a, b) => a.start - b.start).flatMap((line) => line.messages),\n nextBefore: older && Number.isFinite(oldest) ? new Date(oldest).toISOString() : null\n };\n }\n async function replay(afterId, emit) {\n const path = await locate();\n if (!path)\n return afterId === undefined;\n const end = await files.size(path);\n const copies = await copiesOf(path, end);\n let start = 0;\n if (afterId !== undefined) {\n let found = null;\n for await (const line of backward(path, end, copies)) {\n if (line.messages.some((message) => message.uuid === afterId)) {\n found = line;\n break;\n }\n }\n if (!found)\n return false;\n start = found.start;\n }\n let passed = afterId === undefined;\n for await (const line of forward(path, start, end, copies)) {\n for (const message of line.messages) {\n if (passed)\n emit(message);\n else if (message.uuid === afterId)\n passed = true;\n }\n }\n return true;\n }\n return { page, replay };\n}\nfunction oldestOnPage(lines, limit) {\n const newestFirst = [...lines].sort((a, b) => b.time - a.time);\n let count = 0;\n for (const line of newestFirst) {\n count += line.messages.length;\n if (count >= limit)\n return line.time;\n }\n return newestFirst[newestFirst.length - 1]?.time ?? Infinity;\n}\nfunction joined(first, second) {\n if (first.length === 0)\n return second;\n if (second.length === 0)\n return first;\n const bytes = new Uint8Array(first.length + second.length);\n bytes.set(first);\n bytes.set(second, first.length);\n return bytes;\n}\nvar DEFAULT_PAGE_SIZE = 50;\nvar MAX_PAGE_SIZE = 500;\nasync function transcriptPage(transcript, { limit, before, cursor } = {}, found) {\n const time = transcriptTime(before ?? cursor);\n if (!transcript)\n return { messages: [], nextBefore: null, nextCursor: null };\n const size = Math.min(Math.max(Math.floor(limit ?? DEFAULT_PAGE_SIZE), 1), MAX_PAGE_SIZE);\n const page = await transcript.page(time, size, found);\n return { ...page, nextCursor: page.nextBefore };\n}\nfunction transcriptTime(before) {\n if (before === undefined)\n return null;\n const time = Date.parse(before);\n if (Number.isNaN(time))\n throw new AgentInvalidError(`invalid time ${before}: give an ISO 8601 time`);\n return time;\n}\nasync function findFile(files, dir, depth, matches) {\n let names;\n try {\n names = await files.listDirectory(dir);\n } catch (error) {\n if (error instanceof SandboxNotFoundError)\n return null;\n throw error;\n }\n if (depth <= 1) {\n const name = names.find(matches);\n return name === undefined ? null : `${dir}/${name}`;\n }\n const found = await Promise.all(names.sort().reverse().map((name) => findFile(files, `${dir}/${name}`, depth - 1, matches).catch(() => null)));\n return found.find((path) => path !== null) ?? null;\n}\n\n// agent/session/claude/transcript.ts\nfunction claudeTranscript({ nativeId, env, files }) {\n const home = env.CLAUDE_CONFIG_DIR ?? `${env.HOME}/.claude`;\n return createFileTranscript(files, () => locateTranscript(files, home, CLAUDE_TRANSCRIPT_LAYOUT, nativeId), claudeLineMessages, CLAUDE_TRANSCRIPT_LAYOUT);\n}\nvar CLAUDE_TRANSCRIPT_LAYOUT = {\n dir: \"projects\",\n depth: 2,\n name: \"{id}.jsonl\",\n time: \"timestamp\",\n copies: '\"subtype\":\"compact_boundary\"'\n};\nfunction claudeLineMessages(line) {\n const entry = line;\n if (entry.type !== \"user\" && entry.type !== \"assistant\")\n return [];\n if (entry.isSidechain || entry.isMeta || !entry.uuid || !entry.message)\n return [];\n return [{ type: entry.type, message: entry.message, parent_tool_use_id: null, uuid: entry.uuid, session_id: entry.sessionId ?? \"\" }];\n}\n\n// agent/session/claude/index.ts\nvar claudeBackend = {\n install: installClaude,\n installed: installedClaude,\n auth: claudeAuth,\n transcript: claudeTranscript,\n homeEnvironment: claudeHomeEnvironment,\n async start(context) {\n const prompts = createPromptQueue();\n const questions = claudeQuestions(context);\n const backgroundTasks = claudeBackgroundTasks();\n const status = claudeStatus();\n const queue = claudeMessageQueue();\n const query = await startClaudeStream(context, prompts, claudePermissions(context, questions), questions, backgroundTasks, status, queue);\n return {\n sendMessage: claudeInput(prompts, queue),\n getSessionStatus: status.status,\n getLastUserMessages: queue.lastUserMessages,\n cancel: claudeInterrupt(query),\n ...claudeModel(query),\n listBackgroundTasks: backgroundTasks.list,\n stopTask: claudeStopTask(query, backgroundTasks),\n async close() {\n prompts.close();\n query.close();\n }\n };\n }\n};\n\n// agent/session/codex/provision.ts\nvar CODEX_PACKAGE = \"@openai/codex\";\nvar CODEX_VERSION = () => pinnedVersion(\"codex\", CODEX_PACKAGE, \"@openai/codex-sdk\");\nfunction installCodex(installDir) {\n return installPackage(installDir, CODEX_PACKAGE, CODEX_VERSION(), () => codexExecutable(installDir).path);\n}\nfunction installedCodex(installDir) {\n return installedPackage(installDir, CODEX_PACKAGE, CODEX_VERSION(), () => codexExecutable(installDir).path);\n}\nvar LINUX_TARGETS = {\n x64: { pkg: \"@openai/codex-linux-x64\", triple: \"x86_64-unknown-linux-musl\" },\n arm64: { pkg: \"@openai/codex-linux-arm64\", triple: \"aarch64-unknown-linux-musl\" }\n};\nfunction codexExecutable(installDir) {\n const target = LINUX_TARGETS[process.arch];\n if (process.platform !== \"linux\" || !target)\n throw new Error(`codex: unsupported platform ${process.platform}/${process.arch}`);\n return {\n path: `${installDir}/node_modules/${target.pkg}/vendor/${target.triple}/bin/codex`,\n env: { CODEX_MANAGED_PACKAGE_ROOT: `${installDir}/node_modules/${CODEX_PACKAGE}`, CODEX_MANAGED_BY_BUN: \"1\" }\n };\n}\n\n// agent/session/codex/auth.ts\nfunction run({ installDir, env, cwd }, args) {\n const executable = codexExecutable(installDir);\n return { cmd: [executable.path, ...args], env: { ...env, ...executable.env }, cwd };\n}\nvar codexAuth = {\n async signedIn(environment) {\n const { cmd, env, cwd } = run(environment, [\"login\", \"status\"]);\n const proc = Bun.spawn(cmd, { env, cwd, stdout: \"ignore\", stderr: \"ignore\" });\n return await proc.exited === 0;\n },\n login(environment) {\n const { cmd, env, cwd } = run(environment, [\"login\", \"--device-auth\"]);\n return spawnLogin(cmd, { env, cwd }, (output) => {\n const url = /https:\\/\\/\\S+\\/device\\S*/.exec(output)?.[0];\n const userCode = /^\\s*([A-Z0-9]{4}-[A-Z0-9]{4,})\\s*$/m.exec(output)?.[1];\n return url && userCode ? { url, userCode, needsCode: false } : null;\n });\n }\n};\n\n// agent/session/codex/backgroundTasks.ts\nimport { readdirSync, readFileSync } from \"fs\";\nvar STOP_GRACE_MS = 1000;\nfunction codexBackgroundTasks() {\n const running = new Map;\n const background = new Map;\n function observe(notification) {\n switch (notification.method) {\n case \"item/started\": {\n const { item } = notification.params;\n if (item.type === \"commandExecution\")\n running.set(item.id, { task_id: item.id, task_type: \"local_bash\", description: item.command });\n return;\n }\n case \"item/completed\": {\n const { item } = notification.params;\n if (item.type !== \"commandExecution\")\n return;\n running.delete(item.id);\n background.delete(item.id);\n return;\n }\n case \"turn/completed\":\n for (const [id, task] of running)\n background.set(id, task);\n running.clear();\n return;\n }\n }\n async function stop(taskId, appServerPid) {\n const task = background.get(taskId);\n if (!task)\n throw new AgentNotFoundError(`no background task ${taskId}`);\n const targets = commandProcesses(appServerPid, task.description);\n signal(targets, \"SIGTERM\");\n const deadline = Date.now() + STOP_GRACE_MS;\n while (targets.some(alive) && Date.now() < deadline)\n await Bun.sleep(50);\n signal(targets.filter(alive), \"SIGKILL\");\n background.delete(taskId);\n }\n return { observe, list: async () => [...background.values()], stop };\n}\nfunction processes() {\n const entries = [];\n for (const name of readdirSync(\"/proc\")) {\n if (!/^\\d+$/.test(name))\n continue;\n try {\n const stat2 = readFileSync(`/proc/${name}/stat`, \"utf8\");\n const ppid = Number(stat2.slice(stat2.lastIndexOf(\")\") + 2).split(\" \")[1]);\n const argv = readFileSync(`/proc/${name}/cmdline`, \"utf8\").split(\"\\x00\").filter(Boolean);\n entries.push({ pid: Number(name), ppid, argv });\n } catch {}\n }\n return entries;\n}\nfunction commandProcesses(root, command) {\n const all = processes();\n const children = new Map;\n for (const entry of all)\n children.set(entry.ppid, [...children.get(entry.ppid) ?? [], entry.pid]);\n const under = (pid) => (children.get(pid) ?? []).flatMap((child) => [child, ...under(child)]);\n const descendants = new Set(under(root));\n const shells = all.filter((entry) => descendants.has(entry.pid) && entry.argv.length >= 3 && [\"-c\", \"-lc\"].includes(entry.argv.at(-2)) && command.includes(entry.argv.at(-1)));\n return [...new Set(shells.flatMap((shell) => [shell.pid, ...under(shell.pid)]))];\n}\nfunction signal(pids, name) {\n for (const pid of pids) {\n try {\n process.kill(pid, name);\n } catch {}\n }\n}\nfunction alive(pid) {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// agent/session/codex/input.ts\nfunction createCodexInput(thread, queue, initialModel) {\n let model = initialModel;\n async function sendMessage(message) {\n if (!message.uuid)\n throw new Error(\"a message sent to codex needs a uuid to be known by\");\n const { rpc, threadId } = thread();\n await rpc.request(\"turn/start\", {\n threadId,\n input: [{ type: \"text\", text: userMessageText(message), text_elements: [] }],\n clientUserMessageId: message.uuid,\n model\n });\n queue.sent(message, message.uuid);\n }\n function setModel(next) {\n model = next;\n }\n return { sendMessage, setModel };\n}\n\n// agent/session/codex/messageQueue.ts\nfunction codexMessageQueue() {\n const queued = new Map;\n let taken = null;\n return {\n observe(notification) {\n if (notification.method !== \"item/started\")\n return;\n const { item } = notification.params;\n if (item.type !== \"userMessage\" || !item.clientId)\n return;\n const message = queued.get(item.clientId);\n if (!message)\n return;\n queued.delete(item.clientId);\n taken = message;\n },\n sent(message, clientId) {\n queued.set(clientId, message);\n },\n async lastUserMessages() {\n return [...taken ? [{ message: taken, queued: false }] : [], ...[...queued.values()].map((message) => ({ message, queued: true }))];\n }\n };\n}\n\n// agent/session/codex/status.ts\nfunction codexStatus() {\n let status = \"idle\";\n return {\n observe(notification) {\n if (notification.method !== \"thread/status/changed\")\n return;\n const reported = notification.params.status;\n if (reported.type === \"active\")\n status = reported.activeFlags.length > 0 ? \"waiting\" : \"running\";\n else if (reported.type === \"systemError\")\n status = \"error\";\n else\n status = \"idle\";\n },\n status: async () => status\n };\n}\n\n// agent/session/codex/interrupt.ts\nfunction codexInterrupt(thread) {\n return async () => {\n const { rpc, threadId, activeTurn } = thread();\n const turnId = activeTurn();\n if (!turnId)\n return;\n await rpc.request(\"turn/interrupt\", { threadId, turnId });\n };\n}\n\n// agent/session/codex/model.ts\nfunction codexModel(thread, input) {\n async function listModels() {\n const { data } = await thread().rpc.request(\"model/list\", {});\n return data.map((model) => ({ value: model.model, displayName: model.displayName, description: model.description }));\n }\n async function setModel(model) {\n input.setModel(model);\n }\n return { listModels, setModel };\n}\n\n// agent/session/codex/permissions.ts\nfunction codexPermissions(context) {\n function ask(request) {\n return context.requestPermission(request);\n }\n async function answer(request, rpc) {\n switch (request.method) {\n case \"item/commandExecution/requestApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"Bash\",\n input: { command: params.command ?? \"\", cwd: params.cwd },\n tool_use_id: params.itemId,\n decision_reason: params.reason ?? undefined\n });\n const response = { decision: decision.behavior === \"allow\" ? \"accept\" : \"decline\" };\n return rpc.respond(request.id, response);\n }\n case \"item/fileChange/requestApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"ApplyPatch\",\n input: { grantRoot: params.grantRoot ?? null },\n tool_use_id: params.itemId,\n decision_reason: params.reason ?? undefined\n });\n const response = { decision: decision.behavior === \"allow\" ? \"accept\" : \"decline\" };\n return rpc.respond(request.id, response);\n }\n case \"execCommandApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"Bash\",\n input: { command: params.command.join(\" \"), cwd: params.cwd },\n tool_use_id: params.callId,\n decision_reason: params.reason ?? undefined\n });\n const response = {\n decision: decision.behavior === \"allow\" ? \"approved\" : { denied: { rejection: decision.message } }\n };\n return rpc.respond(request.id, response);\n }\n case \"applyPatchApproval\": {\n const { params } = request;\n const decision = await ask({\n tool_name: \"ApplyPatch\",\n input: { changes: params.fileChanges, grantRoot: params.grantRoot },\n tool_use_id: params.callId,\n decision_reason: params.reason ?? undefined\n });\n const response = {\n decision: decision.behavior === \"allow\" ? \"approved\" : { denied: { rejection: decision.message } }\n };\n return rpc.respond(request.id, response);\n }\n default:\n return rpc.respondError(request.id, `${request.method} is not supported by hyperbrane`);\n }\n }\n return (request, rpc) => {\n answer(request, rpc).catch((error) => {\n console.error(`answering codex's ${request.method} failed:`, error);\n rpc.respondError(request.id, error.message);\n });\n };\n}\n\n// agent/session/codex/questions.ts\nfunction codexQuestions(context, thread) {\n return async (params) => {\n const questions = params.questions.map((question) => ({\n question: question.question,\n header: question.header,\n options: question.options ?? [],\n multiSelect: false\n }));\n thread().emitToolUse(params.itemId, ASK_USER_QUESTION, { questions });\n const response = await context.askQuestions({ tool_use_id: params.itemId, questions });\n if (!response)\n thread().emitToolResult(params.itemId, \"The user dismissed the questions.\", true);\n else\n thread().emitToolResult(params.itemId, answersText(response.answers), false);\n const answers = {};\n for (const question of params.questions) {\n const answer = response?.answers[question.question];\n answers[question.id] = { answers: answer === undefined ? [] : [answer] };\n }\n return { answers };\n };\n}\nfunction answersText(answers) {\n const pairs = Object.entries(answers).map(([question, answer]) => `\"${question}\"=\"${answer}\"`);\n return `User has answered your questions: ${pairs.join(\", \")}.`;\n}\n\n// agent/session/codex/home.ts\nfunction codexHomeEnvironment(home) {\n return { CODEX_HOME: home };\n}\n\n// agent/session/codex/messages.ts\nfunction backendId(id) {\n return id;\n}\nfunction toolResultId(itemId) {\n return `${itemId}:result`;\n}\nfunction assistantMessage(uuid, content, threadId, model) {\n const usage = { ...resultUsage(), cache_creation: null, server_tool_use: null, service_tier: null };\n return {\n type: \"assistant\",\n message: {\n id: uuid,\n type: \"message\",\n role: \"assistant\",\n model,\n content,\n container: null,\n context_management: null,\n stop_reason: null,\n stop_sequence: null,\n usage\n },\n parent_tool_use_id: null,\n uuid: backendId(uuid),\n session_id: threadId\n };\n}\nfunction toolResultMessage(itemId, content, isError, threadId) {\n return {\n type: \"user\",\n message: { role: \"user\", content: [{ type: \"tool_result\", tool_use_id: itemId, content, is_error: isError }] },\n parent_tool_use_id: null,\n uuid: backendId(toolResultId(itemId)),\n session_id: threadId\n };\n}\nfunction itemMessages(item, threadId, model) {\n if (item.type === \"userMessage\") {\n const text = item.content.map((input) => input.type === \"text\" ? input.text : \"\").join(\"\");\n return [{ type: \"user\", message: { role: \"user\", content: text }, parent_tool_use_id: null, uuid: backendId(item.clientId ?? item.id), session_id: threadId }];\n }\n if (item.type === \"agentMessage\")\n return [assistantMessage(item.id, [{ type: \"text\", text: item.text, citations: null }], threadId, model)];\n const toolUse = toolUseOf(item);\n const toolResult = toolResultOf(item);\n if (!toolUse)\n return [];\n const messages = [assistantMessage(item.id, [toolUse], threadId, model)];\n if (toolResult)\n messages.push(toolResultMessage(item.id, toolResult.content, toolResult.is_error, threadId));\n return messages;\n}\nfunction shownCommand(argv) {\n return argv.map((arg) => /^[\\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll(\"'\", \"'\\\\''\")}'`).join(\" \");\n}\nfunction rolloutItemMessages(stored, threadId) {\n const item = stored;\n const text = (content) => (content ?? []).map((part) => part.text ?? \"\").join(\"\");\n if (item.type === \"UserMessage\" && \"content\" in item) {\n const user = item;\n return [{ type: \"user\", message: { role: \"user\", content: text(user.content) }, parent_tool_use_id: null, uuid: backendId(user.client_id ?? user.id), session_id: threadId }];\n }\n if (item.type === \"AgentMessage\" && item.id) {\n const agent = item;\n return [assistantMessage(agent.id, [{ type: \"text\", text: text(agent.content), citations: null }], threadId, \"\")];\n }\n if (item.type === \"CommandExecution\" && item.id) {\n const command = item;\n const input = { command: shownCommand(command.command ?? []), cwd: (command.cwd ?? \"\").replace(/^file:\\/\\//, \"\") };\n return [\n assistantMessage(command.id, [{ type: \"tool_use\", id: command.id, name: \"Bash\", input }], threadId, \"\"),\n toolResultMessage(command.id, command.aggregated_output ?? \"\", command.status !== \"completed\" || (command.exit_code ?? 0) !== 0, threadId)\n ];\n }\n return [];\n}\nfunction toolUseOf(item) {\n switch (item.type) {\n case \"commandExecution\":\n return { type: \"tool_use\", id: item.id, name: \"Bash\", input: { command: item.command, cwd: item.cwd } };\n case \"fileChange\":\n return { type: \"tool_use\", id: item.id, name: \"ApplyPatch\", input: { changes: item.changes } };\n case \"mcpToolCall\":\n return { type: \"tool_use\", id: item.id, name: `mcp__${item.server}__${item.tool}`, input: item.arguments };\n case \"dynamicToolCall\":\n return { type: \"tool_use\", id: item.id, name: item.tool, input: item.arguments };\n default:\n return null;\n }\n}\nfunction toolResultOf(item) {\n switch (item.type) {\n case \"commandExecution\":\n return {\n type: \"tool_result\",\n tool_use_id: item.id,\n content: item.aggregatedOutput ?? \"\",\n is_error: item.status !== \"completed\" || (item.exitCode ?? 0) !== 0\n };\n case \"fileChange\":\n return { type: \"tool_result\", tool_use_id: item.id, content: item.status, is_error: item.status !== \"completed\" };\n case \"mcpToolCall\":\n return {\n type: \"tool_result\",\n tool_use_id: item.id,\n content: JSON.stringify(item.error ?? item.result?.content ?? null),\n is_error: item.status !== \"completed\"\n };\n case \"dynamicToolCall\":\n return {\n type: \"tool_result\",\n tool_use_id: item.id,\n content: JSON.stringify(item.contentItems ?? null),\n is_error: item.success === false\n };\n default:\n return null;\n }\n}\n\n// agent/session/codex/transcript.ts\nfunction codexTranscript({ nativeId, env, files }) {\n const home = env.CODEX_HOME ?? `${env.HOME}/.codex`;\n return createFileTranscript(files, () => locateTranscript(files, home, CODEX_TRANSCRIPT_LAYOUT, nativeId), codexLineMessages(nativeId), CODEX_TRANSCRIPT_LAYOUT);\n}\nvar CODEX_TRANSCRIPT_LAYOUT = { dir: \"sessions\", depth: 4, name: \"rollout-*-{id}.jsonl\", time: \"timestamp\" };\nfunction codexLineMessages(threadId) {\n return (line) => {\n const { type, payload } = line;\n if (type !== \"event_msg\" || payload?.type !== \"item_completed\" || !payload.item)\n return [];\n return rolloutItemMessages(payload.item, threadId);\n };\n}\n\n// lib/version.ts\nvar HYPERBRANE_VERSION = \"v1\";\n\n// agent/session/codex/rpc.ts\nvar METHOD_NOT_FOUND = -32601;\nfunction spawnCodexAppServer(executable, { cwd, env }, handlers) {\n const args = [\"app-server\", \"-c\", \"tools.experimental_request_user_input.enabled=true\", \"--enable\", \"default_mode_request_user_input\"];\n const proc = Bun.spawn([executable.path, ...args], {\n cwd,\n env: { ...env, ...executable.env },\n stdin: \"pipe\",\n stdout: \"pipe\",\n stderr: \"pipe\"\n });\n const pending = new Map;\n let nextId = 1;\n function send(message) {\n proc.stdin.write(JSON.stringify(message) + `\n`);\n proc.stdin.flush();\n }\n function dispatch(message) {\n if (message.id !== undefined && message.method === undefined) {\n const waiting = pending.get(message.id);\n pending.delete(message.id);\n if (message.error)\n waiting?.reject(new Error(`codex: ${message.error.message ?? JSON.stringify(message.error)}`));\n else\n waiting?.resolve(message.result);\n return;\n }\n if (message.id !== undefined)\n handlers.onRequest(message);\n else\n handlers.onNotification(message);\n }\n async function readLines() {\n const decoder = new TextDecoder;\n let buffered = \"\";\n for await (const chunk of proc.stdout) {\n buffered += decoder.decode(chunk, { stream: true });\n let newline;\n while ((newline = buffered.indexOf(`\n`)) >= 0) {\n const line = buffered.slice(0, newline).trim();\n buffered = buffered.slice(newline + 1);\n if (line)\n dispatch(JSON.parse(line));\n }\n }\n }\n async function forwardStderr() {\n for await (const chunk of proc.stderr)\n process.stderr.write(chunk);\n }\n forwardStderr().catch(() => {});\n readLines().then(() => proc.exited).then((code) => finish(code === 0 ? undefined : new Error(`codex app-server exited with code ${code}`)), (error) => finish(error));\n function finish(error) {\n for (const waiting of pending.values())\n waiting.reject(error ?? new Error(\"codex app-server exited\"));\n pending.clear();\n handlers.onExit(error);\n }\n function request(method, params) {\n const id = nextId++;\n return new Promise((resolve2, reject) => {\n pending.set(id, { resolve: (result) => resolve2(result), reject });\n send({ id, method, params });\n });\n }\n function notify(method) {\n send({ method });\n }\n function respond(id, result) {\n send({ id, result });\n }\n function respondError(id, message) {\n send({ id, error: { code: METHOD_NOT_FOUND, message } });\n }\n function close() {\n proc.stdin.end();\n proc.kill();\n }\n return { pid: proc.pid, request, notify, respond, respondError, close };\n}\n\n// agent/session/codex/stream.ts\nasync function startCodexStream(context, hooks) {\n let threadId = context.nativeId ?? \"\";\n let model = context.model ?? \"\";\n let turn = null;\n const rpc = spawnCodexAppServer(codexExecutable(context.installDir), { cwd: context.cwd, env: context.env }, {\n onNotification,\n onRequest: (request) => hooks.onServerRequest(request, rpc),\n onExit: (error) => context.exited(error)\n });\n function base() {\n return { parent_tool_use_id: null, uuid: crypto.randomUUID(), session_id: threadId };\n }\n function currentTurn(id) {\n turn ??= { id, startedAt: Date.now(), lastText: \"\", usage: null, errors: [] };\n turn.id ??= id;\n return turn;\n }\n function onNotification(notification) {\n for (const observer of hooks.observers)\n observer.observe(notification);\n switch (notification.method) {\n case \"turn/started\":\n currentTurn(notification.params.turn.id);\n return;\n case \"item/agentMessage/delta\":\n context.emit({\n type: \"stream_event\",\n event: { type: \"content_block_delta\", index: 0, delta: { type: \"text_delta\", text: notification.params.delta } },\n ...base()\n });\n return;\n case \"item/reasoning/summaryTextDelta\":\n case \"item/reasoning/textDelta\":\n context.emit({\n type: \"stream_event\",\n event: { type: \"content_block_delta\", index: 0, delta: { type: \"thinking_delta\", thinking: notification.params.delta } },\n ...base()\n });\n return;\n case \"item/started\": {\n const { item } = notification.params;\n const toolUse = toolUseOf(item);\n if (toolUse)\n context.emit(assistantMessage(item.id, [toolUse], threadId, model));\n return;\n }\n case \"item/completed\": {\n const { item } = notification.params;\n if (item.type === \"agentMessage\")\n currentTurn(notification.params.turnId).lastText = item.text;\n if (item.type === \"userMessage\")\n return;\n const messages = itemMessages(item, threadId, model);\n for (const message of toolUseOf(item) ? messages.slice(1) : messages)\n context.emit(message);\n return;\n }\n case \"thread/tokenUsage/updated\":\n currentTurn(notification.params.turnId).usage = notification.params.tokenUsage.last;\n return;\n case \"error\":\n if (!notification.params.willRetry)\n currentTurn(notification.params.turnId).errors.push(notification.params.error.message);\n return;\n case \"turn/completed\":\n context.emit(resultOf(currentTurn(notification.params.turn.id), notification.params.turn));\n turn = null;\n return;\n }\n }\n function resultOf(state, finished) {\n const duration = finished.durationMs ?? Date.now() - state.startedAt;\n const usage = resultUsage({\n input: state.usage?.inputTokens,\n output: state.usage?.outputTokens,\n cacheRead: state.usage?.cachedInputTokens,\n cacheWrite: state.usage?.cacheWriteInputTokens\n });\n const common = {\n duration_ms: duration,\n duration_api_ms: duration,\n num_turns: 1,\n total_cost_usd: 0,\n usage,\n modelUsage: {},\n permission_denials: [],\n uuid: crypto.randomUUID(),\n session_id: threadId\n };\n if (finished.status === \"completed\") {\n return { type: \"result\", subtype: \"success\", is_error: false, result: state.lastText, stop_reason: \"end_turn\", ...common };\n }\n const errors = [...state.errors];\n if (finished.error)\n errors.push(finished.error.message);\n if (errors.length === 0)\n errors.push(`turn ${finished.status}`);\n return { type: \"result\", subtype: \"error_during_execution\", is_error: true, stop_reason: null, errors, ...common };\n }\n await rpc.request(\"initialize\", {\n clientInfo: { name: \"hyperbrane\", title: \"hyperbrane\", version: HYPERBRANE_VERSION },\n capabilities: { experimentalApi: true, requestAttestation: false }\n });\n rpc.notify(\"initialized\");\n const settings = {\n cwd: context.spec.cwd ?? null,\n model: context.model,\n approvalPolicy: \"untrusted\",\n sandbox: \"danger-full-access\"\n };\n const started = threadId ? await rpc.request(\"thread/resume\", { threadId, ...settings }) : await rpc.request(\"thread/start\", settings);\n threadId = started.thread.id;\n model = started.model;\n context.setNativeId(threadId);\n return {\n rpc,\n threadId,\n model,\n activeTurn: () => turn?.id ?? null,\n emitToolUse: (id, name, input) => context.emit(assistantMessage(id, [{ type: \"tool_use\", id, name, input }], threadId, model)),\n emitToolResult: (id, content, isError) => context.emit(toolResultMessage(id, content, isError, threadId))\n };\n}\n\n// agent/session/codex/index.ts\nvar codexBackend = {\n install: installCodex,\n installed: installedCodex,\n auth: codexAuth,\n transcript: codexTranscript,\n homeEnvironment: codexHomeEnvironment,\n async start(context) {\n let thread;\n const current = () => thread;\n const queue = codexMessageQueue();\n const status = codexStatus();\n const input = createCodexInput(current, queue, context.model);\n const permissions = codexPermissions(context);\n const questions = codexQuestions(context, current);\n function onServerRequest(request, rpc) {\n if (request.method !== \"item/tool/requestUserInput\")\n return permissions(request, rpc);\n questions(request.params).then((response) => rpc.respond(request.id, response), (error) => rpc.respondError(request.id, error.message));\n }\n const backgroundTasks = codexBackgroundTasks();\n thread = await startCodexStream(context, { onServerRequest, observers: [backgroundTasks, status, queue] });\n return {\n sendMessage: input.sendMessage,\n getSessionStatus: status.status,\n getLastUserMessages: queue.lastUserMessages,\n cancel: codexInterrupt(current),\n ...codexModel(current, input),\n listBackgroundTasks: backgroundTasks.list,\n stopTask: (taskId) => backgroundTasks.stop(taskId, current().rpc.pid),\n async close() {\n current().rpc.close();\n }\n };\n }\n};\n\n// agent/session/backends.ts\nvar SESSION_BACKENDS = {\n claude: claudeBackend,\n codex: codexBackend\n};\n\n// dimension/paths.ts\nvar WORKSPACE_PATH = \"/workspace\";\nvar RUN_PATH = \"/run/hyperbrane\";\nvar STATE_PATH = \"/var/lib/hyperbrane\";\n\n// lib/jsonDirectory.ts\nvar EXTENSION = \".json\";\nvar NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,62}$/;\n\nclass InvalidNameError extends Error {\n name = \"InvalidNameError\";\n}\nfunction checkName(name) {\n if (!NAME_PATTERN.test(name)) {\n throw new InvalidNameError(`Invalid name \"${name}\": use letters, digits, \"_\", \".\" and \"-\", up to 63 characters`);\n }\n return name;\n}\nfunction createJsonDirectory(sandbox, dir) {\n async function pathFor(name) {\n return `${await dir()}/${checkName(name)}${EXTENSION}`;\n }\n function serialize(record) {\n return JSON.stringify(record, null, 2) + `\n`;\n }\n async function readPath(path) {\n try {\n return JSON.parse(new TextDecoder().decode(await sandbox.readFile(path)));\n } catch (error) {\n if (error instanceof SandboxNotFoundError)\n return null;\n throw error;\n }\n }\n async function read(name) {\n return readPath(await pathFor(name));\n }\n async function insert(name, record) {\n const path = await pathFor(name);\n if (await sandbox.writeFileExclusive(path, serialize(record)))\n return record;\n return await readPath(path) ?? insert(name, record);\n }\n async function save(name, record) {\n await sandbox.writeFile(await pathFor(name), serialize(record));\n }\n async function remove(name) {\n await sandbox.removeFile(await pathFor(name));\n }\n async function entries() {\n const path = await dir();\n const all = await sandbox.runCommand([\"sh\", \"-c\", LIST_SCRIPT, \"sh\", path]).catch(() => null);\n if (all?.exitCode === MISSING)\n return [];\n if (all?.exitCode === 0) {\n return all.stdout.split(RECORD_END).filter((text) => text.trim()).flatMap((text) => {\n const newline = text.indexOf(`\n`);\n try {\n return [[text.slice(0, newline).slice(0, -EXTENSION.length), JSON.parse(text.slice(newline + 1))]];\n } catch {\n return [];\n }\n });\n }\n let files;\n try {\n files = await sandbox.listDirectory(path);\n } catch (error) {\n if (error instanceof SandboxNotFoundError)\n return [];\n throw error;\n }\n const records = await Promise.all(files.filter((file) => file.endsWith(EXTENSION)).map(async (file) => [file.slice(0, -EXTENSION.length), await readPath(`${path}/${file}`)]));\n return records.filter((entry) => entry[1] !== null);\n }\n async function list() {\n return (await entries()).map(([, record]) => record);\n }\n return { read, insert, save, remove, list, entries };\n}\nvar MISSING = 44;\nvar RECORD_END = `\n\\x1E\n`;\nvar LIST_SCRIPT = `cd \"$1\" 2>/dev/null || exit ${MISSING}\nfor file in *${EXTENSION}; do\n [ -f \"$file\" ] || continue\n printf '%s\\\\n' \"$file\" && cat \"$file\" && printf '\\\\n\\\\036\\\\n'\ndone`;\n\n// agent/session/sessionStorage.ts\nfunction workerSocketPath(runDirectory, agentName) {\n return `${runDirectory}/${agentName}.sock`;\n}\nfunction sessionsDirectory(stateDirectory, agentName) {\n return `${stateDirectory}/agents/${agentName}/sessions`;\n}\nfunction backendHomePath(stateDirectory, backend) {\n return `${stateDirectory}/backends/${backend}`;\n}\nfunction createSessionStorage(sandbox, agentName, { stateDirectory = STATE_PATH, runDirectory = RUN_PATH } = {}) {\n const sessionsDir = sessionsDirectory(stateDirectory, agentName);\n const sessions = createJsonDirectory(sandbox, async () => sessionsDir);\n const sessionDir = (sessionName) => `${sessionsDir}/${checkName(sessionName)}`;\n const permissionRequests = (sessionName) => createJsonDirectory(sandbox, async () => `${sessionDir(sessionName)}/permission-requests`);\n const questionRequests = (sessionName) => createJsonDirectory(sandbox, async () => `${sessionDir(sessionName)}/question-requests`);\n const sessionFiles = (sessionName) => createJsonDirectory(sandbox, async () => sessionDir(sessionName));\n async function oldestFirst(stored) {\n return (await stored).sort((a, b) => a.at - b.at).map((entry) => entry.request);\n }\n async function getSessions() {\n return sessions.list();\n }\n async function insertSession(record) {\n return sessions.insert(record.spec.name, record);\n }\n async function saveSession(record) {\n await sessions.save(record.spec.name, record);\n }\n async function removeSession(sessionName) {\n await sandbox.removeDirectory(sessionDir(sessionName));\n await sessions.remove(sessionName);\n }\n async function getPermissionRequests(sessionName) {\n return oldestFirst(permissionRequests(sessionName).list());\n }\n async function savePermissionRequest(sessionName, request) {\n await permissionRequests(sessionName).save(request.id, { request, at: Date.now() });\n }\n async function removePermissionRequest(sessionName, requestId) {\n await permissionRequests(sessionName).remove(requestId);\n }\n async function getQuestionRequests(sessionName) {\n return oldestFirst(questionRequests(sessionName).list());\n }\n async function saveQuestionRequest(sessionName, request) {\n await questionRequests(sessionName).save(request.id, { request, at: Date.now() });\n }\n async function removeQuestionRequest(sessionName, requestId) {\n await questionRequests(sessionName).remove(requestId);\n }\n async function readAuth(sessionName) {\n return sessionFiles(sessionName).read(\"auth\");\n }\n async function saveAuth(sessionName, record) {\n await sessionFiles(sessionName).save(\"auth\", record);\n }\n async function socketPath() {\n return workerSocketPath(runDirectory, agentName);\n }\n async function backendHome(backend) {\n const path = backendHomePath(stateDirectory, backend);\n await sandbox.createDirectory(path);\n return path;\n }\n return {\n getSessions,\n insertSession,\n saveSession,\n removeSession,\n getPermissionRequests,\n savePermissionRequest,\n removePermissionRequest,\n getQuestionRequests,\n saveQuestionRequest,\n removeQuestionRequest,\n readAuth,\n saveAuth,\n socketPath,\n backendHome\n };\n}\n\n// agent/session/worker/workerServer.ts\nimport { rm as rm2 } from \"fs/promises\";\n\n// agent/session/worker/jsonRpc.ts\nvar PARSE_ERROR = -32700;\nfunction createJsonRpcPeer(write, options) {\n const pending = new Map;\n let nextId = 1;\n let buffered = \"\";\n let closedWith;\n function send(message) {\n if (closedWith)\n return;\n write(JSON.stringify({ jsonrpc: \"2.0\", ...message }) + `\n`);\n }\n function handle(message) {\n if (message.method === undefined) {\n if (message.id === undefined || message.id === null)\n return;\n const waiting = pending.get(message.id);\n pending.delete(message.id);\n if (message.error)\n waiting?.reject(options.decodeError(message.error));\n else\n waiting?.resolve(message.result);\n return;\n }\n if (message.id === undefined || message.id === null) {\n options.onNotification?.(message.method, message.params);\n return;\n }\n const id = message.id;\n options.onRequest(message.method, message.params).then((result) => send({ id, result: result ?? null }), (error) => send({ id, error: options.encodeError(error) }));\n }\n function receive(text) {\n buffered += text;\n let newline;\n while ((newline = buffered.indexOf(`\n`)) >= 0) {\n const line = buffered.slice(0, newline).trim();\n buffered = buffered.slice(newline + 1);\n if (!line)\n continue;\n let message;\n try {\n message = JSON.parse(line);\n } catch {\n send({ id: null, error: { code: PARSE_ERROR, message: \"not JSON\" } });\n continue;\n }\n handle(message);\n }\n }\n function request(method, params) {\n if (closedWith)\n return Promise.reject(closedWith);\n const id = nextId++;\n return new Promise((resolve2, reject) => {\n pending.set(id, { resolve: resolve2, reject });\n send({ id, method, params });\n });\n }\n function notify(method, params) {\n send({ method, params });\n }\n function close(error) {\n closedWith ??= error;\n for (const waiting of pending.values())\n waiting.reject(error);\n pending.clear();\n }\n return { receive, request, notify, close };\n}\nfunction createSocketWriter(socket) {\n const encoder = new TextEncoder;\n let backlog = null;\n function write(text) {\n const bytes = encoder.encode(text);\n if (backlog) {\n const joined2 = new Uint8Array(backlog.length + bytes.length);\n joined2.set(backlog);\n joined2.set(bytes, backlog.length);\n backlog = joined2;\n return;\n }\n const written = Math.max(socket.write(bytes), 0);\n if (written < bytes.length)\n backlog = bytes.subarray(written);\n }\n function drain() {\n if (!backlog)\n return;\n const written = Math.max(socket.write(backlog), 0);\n backlog = written < backlog.length ? backlog.subarray(written) : null;\n }\n return { write, drain };\n}\n\n// agent/session/worker/protocol.ts\nvar METHOD_NOT_FOUND2 = -32601;\nvar INVALID_PARAMS = -32602;\nvar INTERNAL_ERROR = -32603;\nvar NOT_FOUND = -32004;\nvar CONFLICT = -32009;\nvar BACKEND_NOT_INSTALLED = -32010;\n\nclass WorkerMethodNotFoundError extends Error {\n name = \"WorkerMethodNotFoundError\";\n}\nfunction encodeWorkerError(error) {\n const message = error instanceof Error ? error.message : String(error);\n if (error instanceof AgentInvalidError)\n return { code: INVALID_PARAMS, message };\n if (error instanceof AgentNotFoundError)\n return { code: NOT_FOUND, message };\n if (error instanceof AgentBackendNotInstalledError)\n return { code: BACKEND_NOT_INSTALLED, message };\n if (error instanceof AgentConflictError)\n return { code: CONFLICT, message };\n if (error instanceof WorkerMethodNotFoundError)\n return { code: METHOD_NOT_FOUND2, message };\n return { code: INTERNAL_ERROR, message };\n}\nfunction decodeWorkerError({ code, message }) {\n if (code === INVALID_PARAMS)\n return new AgentInvalidError(message);\n if (code === NOT_FOUND)\n return new AgentNotFoundError(message);\n if (code === CONFLICT)\n return new AgentConflictError(message);\n if (code === BACKEND_NOT_INSTALLED)\n return new AgentBackendNotInstalledError(message);\n return new Error(`worker: ${message}`);\n}\n\n// agent/session/worker/workerParams.ts\nvar WORKER_PARAMS = {\n \"worker/health\": () => ({}),\n \"worker/shutdown\": () => ({}),\n \"backend/install\": (params) => ({ backend: backend(params.backend) }),\n \"backend/list\": () => ({}),\n \"session/create\": (params) => ({ session: session(object(params.session, \"session\")) }),\n \"session/list\": () => ({}),\n \"session/update\": (params) => ({ session: name(params), limits: limits(object(params.limits, \"limits\")) }),\n \"session/stop\": (params) => ({ session: name(params) }),\n \"session/send\": (params) => ({ session: name(params), message: userMessage(params.message) }),\n \"session/interrupt\": (params) => ({ session: name(params) }),\n \"session/status\": (params) => ({ session: name(params) }),\n \"session/lastUserMessages\": (params) => ({ session: name(params) }),\n \"session/subscribe\": (params) => ({\n session: name(params),\n subscription: text(params.subscription, \"subscription\"),\n after_id: optional(params.after_id, (value) => text(value, \"after_id\"))\n }),\n \"session/unsubscribe\": (params) => ({ subscription: text(params.subscription, \"subscription\") }),\n \"session/transcript\": (params) => ({\n session: name(params),\n limit: optional(params.limit, (value) => number(value, \"limit\")),\n before: params.before === undefined ? optional(params.cursor, (value) => text(value, \"cursor\")) : text(params.before, \"before\")\n }),\n \"permission/list\": (params) => ({ session: name(params) }),\n \"permission/respond\": (params) => ({\n session: name(params),\n request: text(params.request, \"request\"),\n result: permissionResult(params.result)\n }),\n \"question/list\": (params) => ({ session: name(params) }),\n \"question/respond\": (params) => ({\n session: name(params),\n request: text(params.request, \"request\"),\n response: questionResponse(params.response)\n }),\n \"model/list\": (params) => ({ session: name(params) }),\n \"model/set\": (params) => ({\n session: name(params),\n model: params.model === null ? null : text(params.model, \"the model (a model name, or null for the backend's default)\")\n }),\n \"task/list\": (params) => ({ session: name(params) }),\n \"task/stop\": (params) => ({ session: name(params), task: text(params.task, \"task\") }),\n \"auth/status\": (params) => ({ session: name(params) }),\n \"auth/login\": (params) => ({\n session: name(params),\n gatewaySignedIn: optional(params.gatewaySignedIn, (value) => boolean(value, \"gatewaySignedIn\")) ?? false\n }),\n \"auth/code\": (params) => ({ session: name(params), code: text(params.code, \"the code (the one the sign-in page showed)\").trim() })\n};\nfunction invalid(message) {\n throw new AgentInvalidError(message);\n}\nfunction name(params) {\n return text(params.session, \"session\");\n}\nfunction object(value, what) {\n if (value === null || typeof value !== \"object\" || Array.isArray(value))\n invalid(`${what} must be an object`);\n return value;\n}\nfunction text(value, what) {\n if (typeof value !== \"string\" || value.trim() === \"\")\n invalid(`${what} must be a non-empty string`);\n return value;\n}\nfunction number(value, what) {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n invalid(`${what} must be a number`);\n return value;\n}\nfunction boolean(value, what) {\n if (typeof value !== \"boolean\")\n invalid(`${what} must be true or false`);\n return value;\n}\nfunction optional(value, parse) {\n return value === undefined ? undefined : parse(value);\n}\nfunction backend(value) {\n const known = AGENT_BACKENDS.find((name2) => name2 === value);\n if (!known)\n invalid(`unknown backend \"${String(value)}\"; known: ${AGENT_BACKENDS.join(\", \")}`);\n return known;\n}\nfunction memoryLimit(value) {\n const bytes = number(value, \"memoryLimit\");\n if (!(bytes > 0))\n invalid(\"memoryLimit must be positive\");\n return bytes;\n}\nfunction cpuLimit(value) {\n const cores = number(value, \"cpuLimit\");\n if (!(cores > 0))\n invalid(\"cpuLimit must be positive\");\n return cores;\n}\nfunction environment(value) {\n const fields = object(value, \"env\");\n for (const [key, entry] of Object.entries(fields))\n if (typeof entry !== \"string\")\n invalid(`env.${key} must be a string`);\n return fields;\n}\nfunction session(fields) {\n return {\n name: text(fields.name, \"the session's name\"),\n backend: backend(fields.backend),\n memoryLimit: memoryLimit(fields.memoryLimit),\n cpuLimit: cpuLimit(fields.cpuLimit),\n cwd: optional(fields.cwd, (value) => text(value, \"cwd\")),\n env: optional(fields.env, environment)\n };\n}\nfunction limits(fields) {\n return { memoryLimit: optional(fields.memoryLimit, memoryLimit), cpuLimit: optional(fields.cpuLimit, cpuLimit) };\n}\nfunction userMessage(value) {\n const fields = object(value, 'a message (an SDK user message: {type: \"user\", message})');\n if (fields.type !== \"user\")\n invalid('a message is an SDK user message: {type: \"user\", message}');\n const message = object(fields.message, \"message.message\");\n if (message.role !== \"user\")\n invalid('message.message.role must be \"user\"');\n if (typeof message.content !== \"string\" && !Array.isArray(message.content))\n invalid(\"message.message.content must be a string or an array of content blocks\");\n return value;\n}\nfunction permissionResult(value) {\n const fields = object(value, \"result\");\n if (fields.behavior === \"allow\") {\n return { behavior: \"allow\", updatedInput: optional(fields.updatedInput, (input) => object(input, \"updatedInput\")) };\n }\n if (fields.behavior === \"deny\") {\n return {\n behavior: \"deny\",\n message: typeof fields.message === \"string\" ? fields.message : invalid(\"a denial needs a message\"),\n interrupt: optional(fields.interrupt, (interrupt) => boolean(interrupt, \"interrupt\"))\n };\n }\n return invalid('a permission result is {behavior: \"allow\"} or {behavior: \"deny\", message}');\n}\nfunction questionResponse(value) {\n const answers = object(object(value, \"response\").answers, \"a question response's answers ({<question>: <answer>})\");\n for (const [question, answer] of Object.entries(answers))\n if (typeof answer !== \"string\")\n invalid(`the answer to \"${question}\" must be a string`);\n return { answers };\n}\n\n// agent/session/worker/workerServer.ts\nvar INTERNAL_ERROR_LOGGED = -32603;\nfunction createWorkerServer(service, options) {\n let listener;\n function ref(session2) {\n return { agentName: options.health.agentName, sessionName: session2 };\n }\n const handlers = {\n \"worker/health\": async () => options.health,\n \"worker/shutdown\": async () => {\n setTimeout(options.onShutdown, 0);\n return null;\n },\n \"backend/install\": async ({ backend: backend2 }) => nothing(await service.install(options.health.agentName, backend2)),\n \"backend/list\": () => service.listBackends(options.health.agentName),\n \"session/create\": ({ session: session2 }) => service.createSession(options.health.agentName, session2),\n \"session/list\": () => service.listSessions(),\n \"session/update\": ({ session: session2, limits: limits2 }) => service.updateSession(ref(session2), limits2),\n \"session/stop\": async ({ session: session2 }) => nothing(await service.stopSession(ref(session2))),\n \"session/send\": async ({ session: session2, message }) => nothing(await service.sendMessage(ref(session2), message)),\n \"session/interrupt\": async ({ session: session2 }) => nothing(await service.cancel(ref(session2))),\n \"session/status\": ({ session: session2 }) => service.getSessionStatus(ref(session2)),\n \"session/lastUserMessages\": ({ session: session2 }) => service.getLastUserMessages(ref(session2)),\n \"session/subscribe\": async ({ session: session2, subscription, after_id }, connection) => {\n if (connection.subscriptions.has(subscription))\n throw new AgentConflictError(`subscription ${subscription} already exists`);\n let unsubscribe = null;\n let cancelled = false;\n connection.subscriptions.set(subscription, () => {\n cancelled = true;\n unsubscribe?.();\n });\n try {\n unsubscribe = await service.subscribe(ref(session2), after_id, (message) => {\n const notification = { subscription, message };\n connection.peer.notify(\"session/message\", notification);\n });\n } catch (error) {\n connection.subscriptions.delete(subscription);\n throw error;\n }\n if (cancelled)\n unsubscribe();\n return null;\n },\n \"session/unsubscribe\": async ({ subscription }, connection) => {\n connection.subscriptions.get(subscription)?.();\n connection.subscriptions.delete(subscription);\n return null;\n },\n \"session/transcript\": ({ session: session2, limit, before }) => service.getTranscript(ref(session2), { limit, before }),\n \"permission/list\": ({ session: session2 }) => service.listPermissionRequests(ref(session2)),\n \"permission/respond\": async ({ session: session2, request, result }) => nothing(await service.respondPermissionRequest(ref(session2), request, result)),\n \"question/list\": ({ session: session2 }) => service.listQuestionRequests(ref(session2)),\n \"question/respond\": async ({ session: session2, request, response }) => nothing(await service.respondQuestionRequest(ref(session2), request, response)),\n \"model/list\": ({ session: session2 }) => service.listModels(ref(session2)),\n \"model/set\": async ({ session: session2, model }) => nothing(await service.setModel(ref(session2), model)),\n \"task/list\": ({ session: session2 }) => service.listBackgroundTasks(ref(session2)),\n \"task/stop\": async ({ session: session2, task }) => nothing(await service.stopTask(ref(session2), task)),\n \"auth/status\": ({ session: session2 }) => service.getAuthStatus(ref(session2)),\n \"auth/login\": ({ session: session2, gatewaySignedIn }) => service.login(ref(session2), gatewaySignedIn),\n \"auth/code\": ({ session: session2, code }) => service.submitAuthCode(ref(session2), code)\n };\n function handle(method, params, connection) {\n return handlers[method](WORKER_PARAMS[method](params), connection);\n }\n async function dispatch(method, params, connection) {\n if (!isWorkerMethod(method))\n throw new WorkerMethodNotFoundError(`no method ${method}`);\n const fields = params ?? {};\n if (typeof fields !== \"object\" || Array.isArray(fields))\n throw new AgentInvalidError(`${method} takes an object of params`);\n return handle(method, fields, connection);\n }\n function openConnection(socket) {\n const writer = createSocketWriter(socket);\n const peer = createJsonRpcPeer(writer.write, {\n onRequest: (method, params) => dispatch(method, params, connection),\n encodeError: (error) => {\n const encoded = encodeWorkerError(error);\n if (encoded.code === INTERNAL_ERROR_LOGGED)\n console.error(error);\n return encoded;\n },\n decodeError: decodeWorkerError\n });\n const connection = { peer, writer, subscriptions: new Map, decoder: new TextDecoder };\n return connection;\n }\n async function start() {\n await rm2(options.socketPath, { force: true });\n listener = Bun.listen({\n unix: options.socketPath,\n socket: {\n open(socket) {\n socket.data = openConnection(socket);\n },\n data(socket, data) {\n socket.data.peer.receive(socket.data.decoder.decode(data, { stream: true }));\n },\n drain(socket) {\n socket.data.writer.drain();\n },\n close(socket) {\n for (const unsubscribe of socket.data.subscriptions.values())\n unsubscribe();\n socket.data.subscriptions.clear();\n socket.data.peer.close(new Error(\"the connection closed\"));\n },\n error(_socket, error) {\n console.error(\"worker connection failed:\", error);\n }\n }\n });\n }\n function stop() {\n listener?.stop(true);\n listener = undefined;\n }\n return { start, stop };\n}\nfunction isWorkerMethod(method) {\n return Object.hasOwn(WORKER_PARAMS, method);\n}\nfunction nothing(_done) {\n return null;\n}\n\n// agent/session/workerService.ts\nimport { statSync } from \"fs\";\n\n// agent/session/pending.ts\nfunction createPendingRequests(store, fallback) {\n const waiting = new Map;\n function add(request, signal2) {\n const id = crypto.randomUUID();\n return new Promise((resolve2) => {\n let settled = false;\n const settle = (response) => {\n if (settled)\n return;\n settled = true;\n waiting.delete(id);\n signal2?.removeEventListener(\"abort\", aborted);\n store.remove(id).catch((error) => console.error(`removing request ${id} failed:`, error));\n resolve2(response);\n };\n const aborted = () => settle(fallback(\"the request was cancelled\"));\n if (signal2?.aborted)\n return aborted();\n signal2?.addEventListener(\"abort\", aborted);\n waiting.set(id, settle);\n store.save({ ...request, id }).catch((error) => {\n console.error(`keeping request ${id} failed:`, error);\n settle(fallback(\"the request couldn't be kept\"));\n });\n });\n }\n async function list() {\n return (await store.list()).filter((request) => waiting.has(request.id));\n }\n async function answer(id, response) {\n const settle = waiting.get(id);\n if (!settle)\n return false;\n settle(response);\n return true;\n }\n async function dropAll(reason) {\n for (const settle of [...waiting.values()])\n settle(fallback(reason));\n for (const request of await store.list())\n if (!waiting.has(request.id))\n await store.remove(request.id);\n }\n return { add, list, answer, dropAll };\n}\n\n// agent/session/workerService.ts\nfunction createWorkerService(config) {\n const sessions = new Map;\n let installing = Promise.resolve();\n async function loadSessions() {\n for (const record of await config.storage.getSessions()) {\n const state = await newState(record);\n sessions.set(record.spec.name, state);\n await dropRequests(state, \"the worker restarted\");\n const auth = await config.storage.readAuth(record.spec.name);\n if (auth?.login)\n await config.storage.saveAuth(record.spec.name, { login: null, error: auth.error });\n }\n }\n async function newState(record) {\n return {\n ...record,\n listeners: new Set,\n running: null,\n startedAt: 0,\n generation: 0,\n session: null,\n login: null,\n permissionRequests: createPendingRequests({\n list: () => config.storage.getPermissionRequests(record.spec.name),\n save: (request) => config.storage.savePermissionRequest(record.spec.name, request),\n remove: (id) => config.storage.removePermissionRequest(record.spec.name, id)\n }, (message) => ({ behavior: \"deny\", message })),\n questionRequests: createPendingRequests({\n list: () => config.storage.getQuestionRequests(record.spec.name),\n save: (request) => config.storage.saveQuestionRequest(record.spec.name, request),\n remove: (id) => config.storage.removeQuestionRequest(record.spec.name, id)\n }, () => null)\n };\n }\n async function saveRecord(state) {\n await config.storage.saveSession({ spec: state.spec, nativeId: state.nativeId, model: state.model });\n }\n async function info(state) {\n return { ...state.spec, agentName: config.agentName, status: await statusOf(state), nativeId: state.nativeId, model: state.model };\n }\n async function statusOf(state) {\n if (!state.running)\n return \"stopped\";\n if (!state.session)\n return \"starting\";\n return state.session.getSessionStatus();\n }\n async function lastStoredPrompt(state) {\n const transcript = await transcriptOf(state);\n let before = null;\n while (transcript) {\n const page = await transcript.page(before, LAST_PROMPT_PAGE_SIZE);\n const prompt = page.messages.findLast((message) => message.type === \"user\" && isPrompt(message.message.content));\n if (prompt?.type === \"user\")\n return { message: prompt, queued: false };\n if (!page.nextBefore)\n return null;\n before = Date.parse(page.nextBefore);\n }\n return null;\n }\n function trustChangedSince(time) {\n if (!config.trustBundle)\n return false;\n try {\n return statSync(config.trustBundle).mtimeMs > time;\n } catch {\n return false;\n }\n }\n function requireAgent(agentName) {\n if (agentName !== config.agentName)\n throw new AgentNotFoundError(`this worker runs agent ${config.agentName}, not ${agentName}`);\n }\n function requireSession({ agentName, sessionName }) {\n requireAgent(agentName);\n const state = sessions.get(sessionName);\n if (!state)\n throw new AgentNotFoundError(`session ${sessionName} does not exist`);\n return state;\n }\n async function dropRequests(state, reason) {\n await Promise.all([state.permissionRequests.dropAll(reason), state.questionRequests.dropAll(reason)]);\n }\n function broadcast(state, message) {\n for (const listener of state.listeners)\n listener(message);\n }\n async function transcriptOf(state) {\n if (!state.nativeId)\n return null;\n return config.backends[state.spec.backend].transcript({ nativeId: state.nativeId, env: await environmentOf(state), files: config.files });\n }\n async function environmentOf(state) {\n const env = {};\n for (const [key, value] of Object.entries(process.env))\n if (value !== undefined)\n env[key] = value;\n const backend2 = config.backends[state.spec.backend];\n return { ...env, ...backend2.homeEnvironment(await config.storage.backendHome(state.spec.backend)), ...state.spec.env };\n }\n async function authEnvironment(state) {\n return { installDir: config.installDir, env: await environmentOf(state), cwd: state.spec.cwd ?? process.cwd() };\n }\n async function requireInstalled(backend2) {\n if ((await config.backends[backend2].installed(config.installDir)).ready)\n return;\n throw new AgentBackendNotInstalledError(`${backend2} isn't installed in agent ${config.agentName}'s dimension, or not completely: install it`);\n }\n async function authStatus(state) {\n const auth = await config.storage.readAuth(state.spec.name);\n if (state.login && auth?.login)\n return auth.login;\n await requireInstalled(state.spec.backend);\n if (await config.backends[state.spec.backend].auth.signedIn(await authEnvironment(state)))\n return { state: \"signedIn\" };\n return auth?.error ? { state: \"signedOut\", error: auth.error } : { state: \"signedOut\" };\n }\n function saveAuth(state, record) {\n return config.storage.saveAuth(state.spec.name, record);\n }\n function watchLogin(state, login2) {\n return login2.done.then(async () => {\n if (state.login?.process !== login2)\n return;\n state.login = null;\n await saveAuth(state, { login: null, error: null });\n if (await statusOf(state) === \"idle\")\n await closeSession(state);\n }, async (error) => {\n if (state.login?.process !== login2)\n return;\n state.login = null;\n await saveAuth(state, { login: null, error: error.message });\n });\n }\n async function settleLogin(state, settled, timeoutMs) {\n await Promise.race([settled, Bun.sleep(timeoutMs)]);\n return authStatus(state);\n }\n function contextFor(state, generation, env) {\n const current = () => state.generation === generation;\n return {\n spec: state.spec,\n nativeId: state.nativeId,\n cwd: state.spec.cwd ?? process.cwd(),\n model: state.model,\n installDir: config.installDir,\n env,\n emit(message) {\n if (!current())\n return;\n broadcast(state, message);\n },\n setNativeId(id) {\n if (!current() || state.nativeId === id)\n return;\n state.nativeId = id;\n saveRecord(state).catch((error) => console.error(`saving session ${state.spec.name} failed:`, error));\n },\n async requestPermission(request, signal2) {\n if (!current())\n return { behavior: \"deny\", message: \"the session stopped\" };\n return state.permissionRequests.add(request, signal2);\n },\n async askQuestions(request, signal2) {\n if (!current())\n return null;\n return state.questionRequests.add(request, signal2);\n },\n exited(error) {\n if (!current())\n return;\n const session2 = state.session;\n state.running = null;\n state.session = null;\n dropRequests(state, \"the agent exited\").catch((error2) => console.error(`dropping ${state.spec.name}'s requests failed:`, error2));\n if (error)\n console.error(`session ${state.spec.name} exited:`, error);\n session2?.getSessionStatus().then((last) => {\n if (last !== \"running\" && last !== \"waiting\")\n return;\n broadcast(state, {\n type: \"result\",\n subtype: \"error_during_execution\",\n duration_ms: 0,\n duration_api_ms: 0,\n is_error: true,\n num_turns: 0,\n stop_reason: null,\n total_cost_usd: 0,\n usage: resultUsage(),\n modelUsage: {},\n permission_denials: [],\n errors: [`the agent exited${error ? `: ${error.message}` : \"\"}`],\n uuid: crypto.randomUUID(),\n session_id: state.nativeId ?? \"\"\n });\n });\n }\n };\n }\n function ensureRunning(state) {\n if (state.running)\n return state.running;\n const generation = ++state.generation;\n state.startedAt = Date.now();\n const starting = requireInstalled(state.spec.backend).then(() => environmentOf(state)).then((env) => config.backends[state.spec.backend].start(contextFor(state, generation, env)));\n state.running = starting;\n starting.then((session2) => {\n if (state.generation === generation)\n state.session = session2;\n }, () => {\n if (state.generation === generation)\n state.running = null;\n });\n return starting;\n }\n async function closeSession(state) {\n const running = state.running;\n state.generation++;\n state.running = null;\n state.session = null;\n await dropRequests(state, \"the session stopped\");\n if (running)\n await (await running.catch(() => null))?.close();\n }\n async function cancelLogin(state) {\n if (!state.login)\n return;\n state.login.process.cancel();\n state.login = null;\n const auth = await config.storage.readAuth(state.spec.name);\n await saveAuth(state, { login: null, error: auth?.error ?? null });\n }\n async function listBackends(agentName) {\n requireAgent(agentName);\n return Promise.all(AGENT_BACKENDS.map(async (backend2) => ({ backend: backend2, ...await config.backends[backend2].installed(config.installDir) })));\n }\n async function install(agentName, backend2) {\n requireAgent(agentName);\n const run2 = installing.then(() => config.backends[backend2].install(config.installDir));\n installing = run2.catch(() => {});\n await run2;\n }\n async function createSession(agentName, session2) {\n requireAgent(agentName);\n const spec = validSession(session2);\n const existing = sessions.get(spec.name);\n if (existing) {\n if (!sameSpec(existing.spec, spec))\n throw new AgentConflictError(`session ${spec.name} already exists with a different spec`);\n return info(existing);\n }\n const record = await config.storage.insertSession({ spec, nativeId: null, model: null });\n const state = await newState(record);\n sessions.set(spec.name, state);\n return info(state);\n }\n async function listSessions() {\n return Promise.all([...sessions.values()].map(info));\n }\n async function updateSession(ref, limits2) {\n const state = requireSession(ref);\n const { memoryLimit: memoryLimit2, cpuLimit: cpuLimit2 } = limits2;\n state.spec = { ...state.spec, memoryLimit: memoryLimit2 ?? state.spec.memoryLimit, cpuLimit: cpuLimit2 ?? state.spec.cpuLimit };\n await saveRecord(state);\n return info(state);\n }\n async function stopSession(ref) {\n requireAgent(ref.agentName);\n const state = sessions.get(ref.sessionName);\n if (!state)\n return;\n sessions.delete(ref.sessionName);\n await closeSession(state);\n state.login?.process.cancel();\n state.login = null;\n state.listeners.clear();\n await config.storage.removeSession(state.spec.name);\n }\n async function sendMessage(ref, sent) {\n const state = requireSession(ref);\n if (await statusOf(state) === \"idle\" && trustChangedSince(state.startedAt))\n await closeSession(state);\n const uuid = sent.uuid ?? crypto.randomUUID();\n const message = { ...sent, uuid, session_id: state.nativeId ?? \"\" };\n await (await ensureRunning(state)).sendMessage(message);\n broadcast(state, { ...message, uuid, session_id: message.session_id });\n }\n async function cancel(ref) {\n const state = requireSession(ref);\n await dropRequests(state, \"the turn was interrupted\");\n if (state.running)\n await (await state.running).cancel();\n }\n async function getSessionStatus(ref) {\n return statusOf(requireSession(ref));\n }\n async function getLastUserMessages(ref) {\n const state = requireSession(ref);\n if (state.session)\n return state.session.getLastUserMessages();\n const stored = await lastStoredPrompt(state);\n return stored ? [stored] : [];\n }\n async function subscribe(ref, afterId, emit) {\n const state = requireSession(ref);\n let held = [];\n const listener = (message) => held ? held.push(message) : emit(message);\n state.listeners.add(listener);\n const unsubscribe = () => void state.listeners.delete(listener);\n try {\n const replayed = new Set;\n const transcript = await transcriptOf(state);\n const found = transcript ? await transcript.replay(afterId, (message) => {\n replayed.add(message.uuid);\n emit(message);\n }) : afterId === undefined;\n if (!found) {\n throw new AgentInvalidError(`no message ${afterId} in session ${ref.sessionName}: after_id is the uuid of a user or assistant message (partial output and results aren't stored)`);\n }\n for (const message of held)\n if (!replayed.has(message.uuid))\n emit(message);\n held = null;\n } catch (error) {\n unsubscribe();\n throw error;\n }\n return unsubscribe;\n }\n async function getTranscript(ref, request = {}) {\n return transcriptPage(await transcriptOf(requireSession(ref)), request);\n }\n async function listPermissionRequests(ref) {\n return requireSession(ref).permissionRequests.list();\n }\n async function respondPermissionRequest(ref, requestId, result) {\n const state = requireSession(ref);\n if (!await state.permissionRequests.answer(requestId, result))\n throw new AgentNotFoundError(`no pending permission request ${requestId}`);\n }\n async function listQuestionRequests(ref) {\n return requireSession(ref).questionRequests.list();\n }\n async function respondQuestionRequest(ref, requestId, response) {\n const state = requireSession(ref);\n if (!await state.questionRequests.answer(requestId, response)) {\n throw new AgentNotFoundError(`no pending question request ${requestId}`);\n }\n }\n async function listModels(ref) {\n return (await ensureRunning(requireSession(ref))).listModels();\n }\n async function setModel(ref, model) {\n const state = requireSession(ref);\n state.model = model;\n await saveRecord(state);\n if (state.running)\n await (await state.running).setModel(model);\n }\n async function listBackgroundTasks(ref) {\n const state = requireSession(ref);\n return state.running ? (await state.running).listBackgroundTasks() : [];\n }\n async function stopTask(ref, taskId) {\n const state = requireSession(ref);\n if (!state.running)\n throw new AgentNotFoundError(`no background task ${taskId}: session ${ref.sessionName}'s CLI isn't running`);\n await (await state.running).stopTask(taskId);\n }\n async function login(ref, gatewaySignedIn) {\n const state = requireSession(ref);\n if (state.login)\n return authStatus(state);\n await requireInstalled(state.spec.backend);\n if (await config.backends[state.spec.backend].auth.signedIn(await authEnvironment(state)))\n return { state: \"signedIn\" };\n const login2 = config.backends[state.spec.backend].auth.login(await authEnvironment(state), gatewaySignedIn);\n const entry = { process: login2, settled: Promise.resolve() };\n state.login = entry;\n await saveAuth(state, { login: null, error: null });\n entry.settled = watchLogin(state, login2);\n try {\n const prompt = await Promise.race([\n login2.prompt,\n Bun.sleep(LOGIN_PROMPT_TIMEOUT_MS).then(() => Promise.reject(new Error(\"the login didn't show where to sign in\")))\n ]);\n if (state.login === entry)\n await saveAuth(state, { login: { state: \"pending\", ...prompt }, error: null });\n } catch (error) {\n if (state.login === entry)\n await cancelLogin(state);\n await saveAuth(state, { login: null, error: error.message });\n return authStatus(state);\n }\n return settleLogin(state, entry.settled, gatewaySignedIn ? LOGIN_COMPLETION_TIMEOUT_MS : 0);\n }\n async function submitAuthCode(ref, code) {\n const state = requireSession(ref);\n const login2 = state.login;\n const prompt = (await config.storage.readAuth(ref.sessionName))?.login;\n if (!login2 || !prompt)\n throw new AgentInvalidError(`session ${ref.sessionName} has no sign-in waiting`);\n if (!prompt.needsCode)\n throw new AgentInvalidError(`session ${ref.sessionName}'s sign-in takes no code: finish it at ${prompt.url}`);\n login2.process.submitCode(code);\n return settleLogin(state, login2.settled, LOGIN_COMPLETION_TIMEOUT_MS);\n }\n async function close() {\n await Promise.all([...sessions.values()].map(closeSession));\n }\n return {\n load: loadSessions,\n close,\n install,\n listBackends,\n createSession,\n listSessions,\n updateSession,\n stopSession,\n sendMessage,\n cancel,\n getSessionStatus,\n getLastUserMessages,\n subscribe,\n getTranscript,\n listPermissionRequests,\n respondPermissionRequest,\n listQuestionRequests,\n respondQuestionRequest,\n listModels,\n setModel,\n listBackgroundTasks,\n stopTask,\n getAuthStatus: async (ref) => authStatus(requireSession(ref)),\n login,\n submitAuthCode\n };\n}\nvar LAST_PROMPT_PAGE_SIZE = 50;\nfunction isPrompt(content) {\n if (typeof content === \"string\")\n return true;\n return Array.isArray(content) && content.some((block) => block.type === \"text\");\n}\nvar LOGIN_PROMPT_TIMEOUT_MS = 30000;\nvar LOGIN_COMPLETION_TIMEOUT_MS = 60000;\nfunction validSession(spec) {\n try {\n checkName(spec.name);\n } catch (error) {\n if (error instanceof InvalidNameError)\n throw new AgentInvalidError(`invalid session name: ${error.message}`);\n throw error;\n }\n return { ...spec, cwd: spec.cwd ?? WORKSPACE_PATH };\n}\nfunction sameSpec(a, b) {\n return a.backend === b.backend && a.memoryLimit === b.memoryLimit && a.cpuLimit === b.cpuLimit && a.cwd === b.cwd && JSON.stringify(a.env ?? {}) === JSON.stringify(b.env ?? {});\n}\n\n// agent/session/main.ts\nfunction required(name2) {\n const value = process.env[name2];\n if (!value)\n throw new Error(`${name2} is not set`);\n return value;\n}\nvar agentName = required(\"HYB_AGENT\");\nvar build = required(\"HYB_WORKER_BUILD\");\nvar files = createLocalSandbox(\"/\");\nvar storage = createSessionStorage(files, agentName);\nvar service = createWorkerService({\n agentName,\n storage,\n installDir: required(\"HYB_INSTALL_DIR\"),\n files: sandboxFiles(files),\n trustBundle: process.env.NODE_EXTRA_CA_CERTS,\n backends: SESSION_BACKENDS\n});\nvar socketPath = await storage.socketPath();\nvar server = createWorkerServer(service, { socketPath, health: { agentName, build }, onShutdown: shutdown });\nfunction shutdown() {\n server.stop();\n service.close().catch((error) => console.error(\"stopping the sessions failed:\", error)).finally(() => process.exit(0));\n}\nfor (const signal2 of [\"SIGTERM\", \"SIGINT\"])\n process.once(signal2, shutdown);\nawait service.load();\nawait server.start();\nvar socketOwner = process.env.HYB_SOCKET_OWNER;\nif (socketOwner) {\n const [uid, gid] = socketOwner.split(\":\").map(Number);\n await chown(socketPath, uid, gid);\n}\nconsole.log(`session worker for agent ${agentName} (build ${build}) listening on ${socketPath}`);\n";