noumen 0.1.0 → 0.2.0

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 (118) hide show
  1. package/README.md +767 -51
  2. package/dist/a2a/index.d.ts +148 -0
  3. package/dist/a2a/index.js +579 -0
  4. package/dist/a2a/index.js.map +1 -0
  5. package/dist/acp/index.d.ts +129 -0
  6. package/dist/acp/index.js +498 -0
  7. package/dist/acp/index.js.map +1 -0
  8. package/dist/agent-BrkbZyOT.d.ts +1028 -0
  9. package/dist/cache-DVqaCX8v.d.ts +38 -0
  10. package/dist/chunk-2ZTGQLYK.js +356 -0
  11. package/dist/chunk-2ZTGQLYK.js.map +1 -0
  12. package/dist/chunk-42PHHZUA.js +132 -0
  13. package/dist/chunk-42PHHZUA.js.map +1 -0
  14. package/dist/chunk-4SQA2UCV.js +26 -0
  15. package/dist/chunk-4SQA2UCV.js.map +1 -0
  16. package/dist/chunk-5GEX6ZSB.js +179 -0
  17. package/dist/chunk-5GEX6ZSB.js.map +1 -0
  18. package/dist/chunk-7ZMN7XJE.js +94 -0
  19. package/dist/chunk-7ZMN7XJE.js.map +1 -0
  20. package/dist/chunk-AMYIJSAZ.js +57 -0
  21. package/dist/chunk-AMYIJSAZ.js.map +1 -0
  22. package/dist/chunk-BGG2E6JD.js +10 -0
  23. package/dist/chunk-BGG2E6JD.js.map +1 -0
  24. package/dist/chunk-BZSFUEWM.js +43 -0
  25. package/dist/chunk-BZSFUEWM.js.map +1 -0
  26. package/dist/chunk-CPFHEPW4.js +139 -0
  27. package/dist/chunk-CPFHEPW4.js.map +1 -0
  28. package/dist/chunk-D43BWEZA.js +346 -0
  29. package/dist/chunk-D43BWEZA.js.map +1 -0
  30. package/dist/chunk-DGUM43GV.js +11 -0
  31. package/dist/chunk-DGUM43GV.js.map +1 -0
  32. package/dist/chunk-JACGEMTF.js +43 -0
  33. package/dist/chunk-JACGEMTF.js.map +1 -0
  34. package/dist/chunk-JX7CLUCV.js +21 -0
  35. package/dist/chunk-JX7CLUCV.js.map +1 -0
  36. package/dist/chunk-KXDB56YW.js +39 -0
  37. package/dist/chunk-KXDB56YW.js.map +1 -0
  38. package/dist/chunk-KY6ZPWHO.js +112 -0
  39. package/dist/chunk-KY6ZPWHO.js.map +1 -0
  40. package/dist/chunk-NBDFQYUZ.js +7992 -0
  41. package/dist/chunk-NBDFQYUZ.js.map +1 -0
  42. package/dist/chunk-OGXNFXFA.js +196 -0
  43. package/dist/chunk-OGXNFXFA.js.map +1 -0
  44. package/dist/chunk-QTJ7VTJY.js +1994 -0
  45. package/dist/chunk-QTJ7VTJY.js.map +1 -0
  46. package/dist/chunk-UVSSQBDY.js +192 -0
  47. package/dist/chunk-UVSSQBDY.js.map +1 -0
  48. package/dist/chunk-Y45R3PQL.js +684 -0
  49. package/dist/chunk-Y45R3PQL.js.map +1 -0
  50. package/dist/cli/index.d.ts +1 -0
  51. package/dist/cli/index.js +868 -0
  52. package/dist/cli/index.js.map +1 -0
  53. package/dist/client/index.d.ts +64 -0
  54. package/dist/client/index.js +409 -0
  55. package/dist/client/index.js.map +1 -0
  56. package/dist/client-CRRO2376.js +10 -0
  57. package/dist/client-CRRO2376.js.map +1 -0
  58. package/dist/headless-Q7XHHZIW.js +143 -0
  59. package/dist/headless-Q7XHHZIW.js.map +1 -0
  60. package/dist/history-snip-64GYP4ZL.js +12 -0
  61. package/dist/history-snip-64GYP4ZL.js.map +1 -0
  62. package/dist/index.d.ts +1305 -418
  63. package/dist/index.js +384 -1757
  64. package/dist/index.js.map +1 -1
  65. package/dist/jsonrpc/index.d.ts +54 -0
  66. package/dist/jsonrpc/index.js +34 -0
  67. package/dist/jsonrpc/index.js.map +1 -0
  68. package/dist/lsp/index.d.ts +36 -0
  69. package/dist/lsp/index.js +16 -0
  70. package/dist/lsp/index.js.map +1 -0
  71. package/dist/lsp-PS3BWIHC.js +8 -0
  72. package/dist/lsp-PS3BWIHC.js.map +1 -0
  73. package/dist/manager-DLXK63XC.js +8 -0
  74. package/dist/manager-DLXK63XC.js.map +1 -0
  75. package/dist/mcp/index.d.ts +111 -0
  76. package/dist/mcp/index.js +104 -0
  77. package/dist/mcp/index.js.map +1 -0
  78. package/dist/mcp-auth-AEI2R4ZC.js +9 -0
  79. package/dist/mcp-auth-AEI2R4ZC.js.map +1 -0
  80. package/dist/ollama-YNXAYP3R.js +18 -0
  81. package/dist/ollama-YNXAYP3R.js.map +1 -0
  82. package/dist/provider-factory-34MSWJZ3.js +20 -0
  83. package/dist/provider-factory-34MSWJZ3.js.map +1 -0
  84. package/dist/providers/anthropic.d.ts +19 -0
  85. package/dist/providers/anthropic.js +33 -0
  86. package/dist/providers/anthropic.js.map +1 -0
  87. package/dist/providers/bedrock.d.ts +39 -0
  88. package/dist/providers/bedrock.js +54 -0
  89. package/dist/providers/bedrock.js.map +1 -0
  90. package/dist/providers/gemini.d.ts +16 -0
  91. package/dist/providers/gemini.js +224 -0
  92. package/dist/providers/gemini.js.map +1 -0
  93. package/dist/providers/openai.d.ts +18 -0
  94. package/dist/providers/openai.js +8 -0
  95. package/dist/providers/openai.js.map +1 -0
  96. package/dist/providers/openrouter.d.ts +16 -0
  97. package/dist/providers/openrouter.js +23 -0
  98. package/dist/providers/openrouter.js.map +1 -0
  99. package/dist/providers/vertex.d.ts +40 -0
  100. package/dist/providers/vertex.js +64 -0
  101. package/dist/providers/vertex.js.map +1 -0
  102. package/dist/render-GRN4ZSSW.js +14 -0
  103. package/dist/render-GRN4ZSSW.js.map +1 -0
  104. package/dist/resolve-XM52G7YE.js +14 -0
  105. package/dist/resolve-XM52G7YE.js.map +1 -0
  106. package/dist/server/index.d.ts +128 -0
  107. package/dist/server/index.js +626 -0
  108. package/dist/server/index.js.map +1 -0
  109. package/dist/server-Cg1yWGaV.d.ts +96 -0
  110. package/dist/spinner-OJNR6NFO.js +8 -0
  111. package/dist/spinner-OJNR6NFO.js.map +1 -0
  112. package/dist/types-2kTLUCnD.d.ts +107 -0
  113. package/dist/types-3c88cRKH.d.ts +547 -0
  114. package/dist/types-CwKKucOF.d.ts +620 -0
  115. package/dist/types-DwdzmXfs.d.ts +107 -0
  116. package/dist/types-NIyVwQ4h.d.ts +109 -0
  117. package/dist/types-QwfylltH.d.ts +71 -0
  118. package/package.json +134 -6
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/index.ts"],"sourcesContent":["import type { StreamEvent } from \"../session/types.js\";\nimport type { PermissionResponse } from \"../permissions/types.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst RECONNECT_BASE_DELAY_MS = 1000;\nconst RECONNECT_MAX_DELAY_MS = 30_000;\nconst RECONNECT_GIVE_UP_MS = 600_000; // 10 minutes\nconst LIVENESS_TIMEOUT_MS = 45_000;\nconst PERMANENT_HTTP_CODES = new Set([401, 403, 404]);\n\n// WS_OPEN = WebSocket.OPEN across all environments\nconst WS_OPEN = 1;\nconst WS_CONNECTING = 0;\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ClientOptions {\n /** Base URL of the noumen server, e.g. \"http://localhost:3001\". */\n baseUrl: string;\n /** Bearer token for authentication. */\n token?: string;\n /** Transport preference. \"auto\" tries WebSocket first, falls back to SSE. */\n transport?: \"ws\" | \"sse\" | \"auto\";\n /** Extra headers to send with HTTP requests (SSE transport). */\n headers?: Record<string, string>;\n}\n\nexport interface PermissionRequestEvent {\n toolName: string;\n input: Record<string, unknown>;\n message: string;\n}\n\nexport interface ClientRunOptions {\n /** Provide a session ID to resume an existing session. */\n sessionId?: string;\n signal?: AbortSignal;\n /** Called when the agent requests permission to run a tool. Return approval/denial. */\n onPermissionRequest?: (req: PermissionRequestEvent) => Promise<PermissionResponse>;\n /** Called when the agent asks the user a question. Return the answer. */\n onUserInput?: (question: string) => Promise<string>;\n}\n\ninterface SessionCreatedResponse {\n sessionId: string;\n eventsUrl: string;\n}\n\n// ---------------------------------------------------------------------------\n// NoumenClient\n// ---------------------------------------------------------------------------\n\nexport class NoumenClient {\n private baseUrl: string;\n private token?: string;\n private transport: \"ws\" | \"sse\" | \"auto\";\n private headers: Record<string, string>;\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.token = options.token;\n this.transport = options.transport ?? \"auto\";\n this.headers = options.headers ?? {};\n }\n\n async *run(prompt: string, opts?: ClientRunOptions): AsyncGenerator<StreamEvent> {\n const transport = this.resolveTransport();\n if (transport === \"ws\") {\n yield* this.runWs(prompt, opts);\n } else {\n yield* this.runSse(prompt, opts);\n }\n }\n\n async *sendMessage(\n sessionId: string,\n prompt: string,\n opts?: Omit<ClientRunOptions, \"sessionId\">,\n ): AsyncGenerator<StreamEvent> {\n const transport = this.resolveTransport();\n if (transport === \"ws\") {\n yield* this.sendMessageWs(sessionId, prompt, opts);\n } else {\n yield* this.sendMessageSse(sessionId, prompt, opts);\n }\n }\n\n async abort(sessionId: string): Promise<void> {\n await this.httpFetch(`/sessions/${sessionId}`, { method: \"DELETE\" });\n }\n\n async listSessions(): Promise<Array<{ id: string; lastActivity: number; done: boolean }>> {\n const res = await this.httpFetch(\"/sessions\", { method: \"GET\" });\n return res.json() as Promise<Array<{ id: string; lastActivity: number; done: boolean }>>;\n }\n\n // -------------------------------------------------------------------------\n // Transport resolution\n // -------------------------------------------------------------------------\n\n private resolveTransport(): \"ws\" | \"sse\" {\n if (this.transport === \"ws\") return \"ws\";\n if (this.transport === \"sse\") return \"sse\";\n if (typeof globalThis.WebSocket !== \"undefined\") return \"ws\";\n return \"sse\";\n }\n\n // -------------------------------------------------------------------------\n // WebSocket transport\n // -------------------------------------------------------------------------\n\n private async *runWs(prompt: string, opts?: ClientRunOptions): AsyncGenerator<StreamEvent> {\n const ws = new globalThis.WebSocket(this.buildWsUrl());\n\n yield* this.driveWs(ws, opts, () => {\n ws.send(JSON.stringify({\n type: \"run\",\n prompt,\n sessionId: opts?.sessionId,\n }));\n });\n }\n\n private async *sendMessageWs(\n sessionId: string,\n prompt: string,\n opts?: Omit<ClientRunOptions, \"sessionId\">,\n ): AsyncGenerator<StreamEvent> {\n const ws = new globalThis.WebSocket(this.buildWsUrl());\n\n yield* this.driveWs(ws, opts, () => {\n ws.send(JSON.stringify({\n type: \"message\",\n sessionId,\n prompt,\n }));\n });\n }\n\n private async *driveWs(\n ws: WebSocket,\n opts: ClientRunOptions | Omit<ClientRunOptions, \"sessionId\"> | undefined,\n onOpen: () => void,\n ): AsyncGenerator<StreamEvent> {\n type QueueItem = { event: StreamEvent } | { done: true } | { error: Error };\n const queue: QueueItem[] = [];\n let waiter: ((item: QueueItem) => void) | null = null;\n\n function enqueue(item: QueueItem) {\n if (waiter) {\n const w = waiter;\n waiter = null;\n w(item);\n } else {\n queue.push(item);\n }\n }\n\n function dequeue(): Promise<QueueItem> {\n if (queue.length > 0) return Promise.resolve(queue.shift()!);\n return new Promise<QueueItem>((resolve) => { waiter = resolve; });\n }\n\n ws.addEventListener(\"open\", () => onOpen());\n\n ws.addEventListener(\"message\", async (msg) => {\n try {\n const data = JSON.parse(typeof msg.data === \"string\" ? msg.data : String(msg.data));\n\n if (data.type === \"session_created\") return;\n\n if (data.type === \"permission_request\" && opts && \"onPermissionRequest\" in opts && opts.onPermissionRequest) {\n try {\n const response = await opts.onPermissionRequest({\n toolName: data.toolName,\n input: data.input,\n message: data.message,\n });\n ws.send(JSON.stringify({\n type: \"permission_response\",\n sessionId: data.sessionId,\n ...response,\n }));\n } catch {\n ws.send(JSON.stringify({\n type: \"permission_response\",\n sessionId: data.sessionId,\n allow: false,\n feedback: \"Client error handling permission request\",\n }));\n }\n enqueue({ event: data as StreamEvent });\n return;\n }\n\n if (data.type === \"user_input_request\" && opts?.onUserInput) {\n try {\n const answer = await opts.onUserInput(data.question);\n ws.send(JSON.stringify({\n type: \"input_response\",\n sessionId: data.sessionId,\n answer,\n }));\n } catch {\n ws.send(JSON.stringify({\n type: \"input_response\",\n sessionId: data.sessionId,\n answer: \"\",\n }));\n }\n enqueue({ event: data as StreamEvent });\n return;\n }\n\n if (data.type === \"turn_complete\") {\n enqueue({ event: data as StreamEvent });\n enqueue({ done: true });\n return;\n }\n\n enqueue({ event: data as StreamEvent });\n } catch (err) {\n enqueue({ error: err instanceof Error ? err : new Error(String(err)) });\n }\n });\n\n ws.addEventListener(\"close\", () => enqueue({ done: true }));\n ws.addEventListener(\"error\", (e) => {\n enqueue({ error: new Error(\"WebSocket error: \" + String(e)) });\n });\n\n const handleAbort = () => {\n ws.close();\n enqueue({ done: true });\n };\n opts?.signal?.addEventListener(\"abort\", handleAbort);\n\n try {\n while (true) {\n const item = await dequeue();\n if (\"done\" in item) return;\n if (\"error\" in item) throw item.error;\n yield item.event;\n }\n } finally {\n opts?.signal?.removeEventListener(\"abort\", handleAbort);\n if (ws.readyState === WS_OPEN || ws.readyState === WS_CONNECTING) {\n ws.close();\n }\n }\n }\n\n private buildWsUrl(): string {\n const wsBase = this.baseUrl.replace(/^http/, \"ws\");\n const url = new URL(\"/ws\", wsBase);\n if (this.token) url.searchParams.set(\"token\", this.token);\n return url.toString();\n }\n\n // -------------------------------------------------------------------------\n // SSE transport\n // -------------------------------------------------------------------------\n\n private async *runSse(prompt: string, opts?: ClientRunOptions): AsyncGenerator<StreamEvent> {\n const createRes = await this.httpFetch(\"/sessions\", {\n method: \"POST\",\n body: JSON.stringify({ prompt, sessionId: opts?.sessionId }),\n });\n\n if (!createRes.ok) {\n throw new Error(`Failed to create session: ${createRes.status} ${await createRes.text()}`);\n }\n\n const { sessionId, eventsUrl } = (await createRes.json()) as SessionCreatedResponse;\n yield* this.consumeSseStreamWithReconnect(sessionId, eventsUrl, opts);\n }\n\n private async *sendMessageSse(\n sessionId: string,\n prompt: string,\n opts?: Omit<ClientRunOptions, \"sessionId\">,\n ): AsyncGenerator<StreamEvent> {\n const msgRes = await this.httpFetch(`/sessions/${sessionId}/messages`, {\n method: \"POST\",\n body: JSON.stringify({ prompt }),\n });\n\n if (!msgRes.ok) {\n throw new Error(`Failed to send message: ${msgRes.status} ${await msgRes.text()}`);\n }\n\n yield* this.consumeSseStreamWithReconnect(sessionId, `/sessions/${sessionId}/events`, opts);\n }\n\n /**\n * SSE stream consumer with automatic reconnection, liveness detection,\n * and event deduplication via sequence numbers.\n */\n private async *consumeSseStreamWithReconnect(\n sessionId: string,\n eventsPath: string,\n opts?: ClientRunOptions | Omit<ClientRunOptions, \"sessionId\">,\n ): AsyncGenerator<StreamEvent> {\n const state = { lastSeqNum: 0 };\n let reconnectAttempts = 0;\n let reconnectStartTime: number | null = null;\n let turnComplete = false;\n\n while (!turnComplete) {\n if (opts?.signal?.aborted) return;\n\n try {\n for await (const event of this.consumeSseStream(sessionId, eventsPath, opts, state)) {\n yield event;\n\n if (event.type === \"turn_complete\") {\n turnComplete = true;\n return;\n }\n }\n\n if (turnComplete) return;\n } catch (err) {\n if (opts?.signal?.aborted) return;\n if ((err as Error).name === \"AbortError\") return;\n\n // Permanent HTTP errors — don't reconnect\n const msg = (err as Error).message ?? \"\";\n const statusMatch = msg.match(/SSE connection failed: (\\d+)/);\n if (statusMatch && PERMANENT_HTTP_CODES.has(parseInt(statusMatch[1], 10))) {\n throw err;\n }\n }\n\n // Reconnection logic\n if (opts?.signal?.aborted) return;\n const now = Date.now();\n if (!reconnectStartTime) reconnectStartTime = now;\n\n const elapsed = now - reconnectStartTime;\n if (elapsed >= RECONNECT_GIVE_UP_MS) {\n throw new Error(`SSE reconnection failed after ${Math.round(elapsed / 1000)}s`);\n }\n\n reconnectAttempts++;\n const baseDelay = Math.min(\n RECONNECT_BASE_DELAY_MS * Math.pow(2, reconnectAttempts - 1),\n RECONNECT_MAX_DELAY_MS,\n );\n const delay = Math.max(0, baseDelay + baseDelay * 0.25 * (2 * Math.random() - 1));\n await sleep(delay, opts?.signal);\n if (opts?.signal?.aborted) return;\n }\n }\n\n /**\n * Single SSE connection attempt. Yields events and returns when the stream\n * ends (either gracefully via turn_complete or from a dropped connection).\n * The liveness timer triggers an AbortError if no frames arrive within\n * LIVENESS_TIMEOUT_MS.\n */\n private async *consumeSseStream(\n sessionId: string,\n eventsPath: string,\n opts: ClientRunOptions | Omit<ClientRunOptions, \"sessionId\"> | undefined,\n state: { lastSeqNum: number },\n ): AsyncGenerator<StreamEvent> {\n const url = `${this.baseUrl}${eventsPath}`;\n const headers: Record<string, string> = { ...this.headers };\n if (this.token) headers[\"Authorization\"] = `Bearer ${this.token}`;\n if (state.lastSeqNum > 0) headers[\"Last-Event-ID\"] = String(state.lastSeqNum);\n\n const ac = new AbortController();\n if (opts?.signal) {\n if (opts.signal.aborted) { ac.abort(); return; }\n opts.signal.addEventListener(\"abort\", () => ac.abort(), { once: true });\n }\n\n // Liveness timeout — abort if no data for 45s\n let livenessTimer: ReturnType<typeof setTimeout> | null = null;\n const resetLiveness = () => {\n if (livenessTimer) clearTimeout(livenessTimer);\n livenessTimer = setTimeout(() => ac.abort(), LIVENESS_TIMEOUT_MS);\n };\n const clearLiveness = () => {\n if (livenessTimer) { clearTimeout(livenessTimer); livenessTimer = null; }\n };\n\n const response = await globalThis.fetch(url, { headers, signal: ac.signal });\n\n if (!response.ok) {\n clearLiveness();\n throw new Error(`SSE connection failed: ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) { clearLiveness(); throw new Error(\"No response body\"); }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n resetLiveness();\n\n let currentEventId = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n resetLiveness();\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n // SSE comments (like :keepalive) reset liveness but carry no data\n if (line.startsWith(\":\")) {\n resetLiveness();\n continue;\n }\n\n // Track SSE id: field for sequence-based dedup\n if (line.startsWith(\"id: \")) {\n const seqNum = parseInt(line.slice(4), 10);\n if (!isNaN(seqNum)) currentEventId = seqNum;\n continue;\n }\n\n if (!line.startsWith(\"data: \")) continue;\n\n const json = line.slice(6);\n if (!json) continue;\n\n // Dedup: skip events already seen before reconnect\n if (currentEventId > 0 && currentEventId <= state.lastSeqNum) {\n currentEventId = 0;\n continue;\n }\n if (currentEventId > state.lastSeqNum) {\n state.lastSeqNum = currentEventId;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(json);\n } catch {\n continue;\n }\n\n currentEventId = 0;\n const eventType = parsed.type as string;\n\n if (eventType === \"permission_request\" && opts && \"onPermissionRequest\" in opts && opts.onPermissionRequest) {\n try {\n const permResponse = await opts.onPermissionRequest({\n toolName: parsed.toolName as string,\n input: parsed.input as Record<string, unknown>,\n message: parsed.message as string,\n });\n await this.httpFetch(`/sessions/${sessionId}/permissions`, {\n method: \"POST\",\n body: JSON.stringify(permResponse),\n });\n } catch {\n await this.httpFetch(`/sessions/${sessionId}/permissions`, {\n method: \"POST\",\n body: JSON.stringify({ allow: false }),\n });\n }\n }\n\n if (eventType === \"user_input_request\" && opts?.onUserInput) {\n try {\n const answer = await opts.onUserInput(parsed.question as string);\n await this.httpFetch(`/sessions/${sessionId}/input`, {\n method: \"POST\",\n body: JSON.stringify({ answer }),\n });\n } catch {\n await this.httpFetch(`/sessions/${sessionId}/input`, {\n method: \"POST\",\n body: JSON.stringify({ answer: \"\" }),\n });\n }\n }\n\n yield parsed as unknown as StreamEvent;\n\n if (eventType === \"turn_complete\") {\n ac.abort();\n return;\n }\n }\n }\n } catch (err) {\n if ((err as Error).name !== \"AbortError\") throw err;\n } finally {\n clearLiveness();\n try { reader.releaseLock(); } catch { /* already released */ }\n if (!ac.signal.aborted) ac.abort();\n }\n }\n\n // -------------------------------------------------------------------------\n // HTTP helpers\n // -------------------------------------------------------------------------\n\n private httpFetch(path: string, init?: RequestInit): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n };\n if (this.token) headers[\"Authorization\"] = `Bearer ${this.token}`;\n\n return globalThis.fetch(url, { ...init, headers: { ...headers, ...init?.headers as Record<string, string> } });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve) => {\n if (signal?.aborted) { resolve(); return; }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\"abort\", () => { clearTimeout(timer); resolve(); }, { once: true });\n });\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ McpClientManager
3
+ } from "./chunk-Y45R3PQL.js";
4
+ import "./chunk-5GEX6ZSB.js";
5
+ import "./chunk-4SQA2UCV.js";
6
+ import "./chunk-DGUM43GV.js";
7
+ export {
8
+ McpClientManager
9
+ };
10
+ //# sourceMappingURL=client-CRRO2376.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,143 @@
1
+ import "./chunk-DGUM43GV.js";
2
+
3
+ // src/cli/headless.ts
4
+ import * as readline from "readline";
5
+ import { randomUUID } from "crypto";
6
+ function emit(obj) {
7
+ process.stdout.write(JSON.stringify(obj) + "\n");
8
+ }
9
+ function serializeEvent(event) {
10
+ if (event.type === "error") {
11
+ return { type: "error", error: { message: event.error.message, name: event.error.name } };
12
+ }
13
+ if (event.type === "retry_exhausted") {
14
+ return { ...event, error: { message: event.error.message, name: event.error.name } };
15
+ }
16
+ if (event.type === "retry_attempt") {
17
+ return { ...event, error: { message: event.error.message, name: event.error.name } };
18
+ }
19
+ return event;
20
+ }
21
+ async function runHeadless(code, _config) {
22
+ await code.init();
23
+ const sessions = /* @__PURE__ */ new Map();
24
+ emit({ type: "ready" });
25
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
26
+ for await (const line of rl) {
27
+ if (!line.trim()) continue;
28
+ let cmd;
29
+ try {
30
+ cmd = JSON.parse(line);
31
+ } catch {
32
+ emit({ type: "error", error: { message: "Invalid JSON", name: "ParseError" } });
33
+ continue;
34
+ }
35
+ const cmdType = cmd.type;
36
+ if (cmdType === "prompt") {
37
+ const text = cmd.text;
38
+ if (!text) {
39
+ emit({ type: "error", error: { message: "Missing required field: text", name: "ValidationError" } });
40
+ continue;
41
+ }
42
+ const sessionId = cmd.sessionId ?? randomUUID();
43
+ const existing = sessions.get(sessionId);
44
+ if (existing?.running) {
45
+ emit({ type: "error", error: { message: "Session is still running", name: "ConflictError" }, sessionId });
46
+ continue;
47
+ }
48
+ const abort = new AbortController();
49
+ const permissionHandler = (req) => {
50
+ const entry = sessions.get(sessionId);
51
+ if (!entry) return Promise.reject(new Error("Session not found"));
52
+ return new Promise((resolve, reject) => {
53
+ entry.pendingPermission = { resolve, reject };
54
+ });
55
+ };
56
+ const userInputHandler = (question) => {
57
+ const entry = sessions.get(sessionId);
58
+ if (!entry) return Promise.reject(new Error("Session not found"));
59
+ emit({ ...{}, type: "user_input_request", sessionId, question });
60
+ return new Promise((resolve, reject) => {
61
+ entry.pendingInput = { resolve, reject };
62
+ });
63
+ };
64
+ let thread;
65
+ if (existing) {
66
+ existing.abort = abort;
67
+ existing.running = true;
68
+ thread = existing.thread;
69
+ } else {
70
+ thread = code.createThread({
71
+ sessionId,
72
+ permissionHandler,
73
+ userInputHandler
74
+ });
75
+ sessions.set(sessionId, {
76
+ thread,
77
+ abort,
78
+ pendingPermission: null,
79
+ pendingInput: null,
80
+ running: true
81
+ });
82
+ }
83
+ emit({ type: "session_created", sessionId });
84
+ const maxTurns = cmd.maxTurns;
85
+ (async () => {
86
+ try {
87
+ for await (const event of thread.run(text, { signal: abort.signal, maxTurns })) {
88
+ emit({ ...serializeEvent(event), sessionId });
89
+ }
90
+ } catch (err) {
91
+ if (err.name !== "AbortError") {
92
+ const e = err instanceof Error ? err : new Error(String(err));
93
+ emit({ type: "error", error: { message: e.message, name: e.name }, sessionId });
94
+ }
95
+ } finally {
96
+ const entry = sessions.get(sessionId);
97
+ if (entry) entry.running = false;
98
+ emit({ type: "session_done", sessionId });
99
+ }
100
+ })();
101
+ continue;
102
+ }
103
+ if (cmdType === "permission_response") {
104
+ const sessionId = cmd.sessionId;
105
+ const entry = sessions.get(sessionId);
106
+ if (!entry?.pendingPermission) continue;
107
+ const { sessionId: _sid, type: _type, ...response } = cmd;
108
+ entry.pendingPermission.resolve(response);
109
+ entry.pendingPermission = null;
110
+ continue;
111
+ }
112
+ if (cmdType === "input_response") {
113
+ const sessionId = cmd.sessionId;
114
+ const entry = sessions.get(sessionId);
115
+ if (!entry?.pendingInput) continue;
116
+ entry.pendingInput.resolve(cmd.answer ?? "");
117
+ entry.pendingInput = null;
118
+ continue;
119
+ }
120
+ if (cmdType === "abort") {
121
+ const sessionId = cmd.sessionId;
122
+ const entry = sessions.get(sessionId);
123
+ if (entry) {
124
+ entry.abort.abort();
125
+ if (entry.pendingPermission) {
126
+ entry.pendingPermission.reject(new Error("Session aborted"));
127
+ entry.pendingPermission = null;
128
+ }
129
+ if (entry.pendingInput) {
130
+ entry.pendingInput.reject(new Error("Session aborted"));
131
+ entry.pendingInput = null;
132
+ }
133
+ }
134
+ continue;
135
+ }
136
+ emit({ type: "error", error: { message: `Unknown command type: ${cmdType}`, name: "ValidationError" } });
137
+ }
138
+ await code.close();
139
+ }
140
+ export {
141
+ runHeadless
142
+ };
143
+ //# sourceMappingURL=headless-Q7XHHZIW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/headless.ts"],"sourcesContent":["import * as readline from \"node:readline\";\nimport { randomUUID } from \"node:crypto\";\nimport type { Agent } from \"../agent.js\";\nimport type { Thread } from \"../thread.js\";\nimport type { StreamEvent } from \"../session/types.js\";\nimport type { PermissionResponse } from \"../permissions/types.js\";\nimport type { MergedConfig } from \"./config.js\";\n\ninterface PromiseResolver<T> {\n resolve: (value: T) => void;\n reject: (err: Error) => void;\n}\n\ninterface SessionEntry {\n thread: Thread;\n abort: AbortController;\n pendingPermission: PromiseResolver<PermissionResponse> | null;\n pendingInput: PromiseResolver<string> | null;\n running: boolean;\n}\n\nfunction emit(obj: Record<string, unknown>): void {\n process.stdout.write(JSON.stringify(obj) + \"\\n\");\n}\n\nfunction serializeEvent(event: StreamEvent): Record<string, unknown> {\n if (event.type === \"error\") {\n return { type: \"error\", error: { message: event.error.message, name: event.error.name } };\n }\n if (event.type === \"retry_exhausted\") {\n return { ...event, error: { message: event.error.message, name: event.error.name } };\n }\n if (event.type === \"retry_attempt\") {\n return { ...event, error: { message: event.error.message, name: event.error.name } };\n }\n return event as unknown as Record<string, unknown>;\n}\n\n/**\n * Run the agent in headless mode: bidirectional NDJSON over stdin/stdout.\n *\n * Inbound commands (stdin, one JSON per line):\n * { type: \"prompt\", text, sessionId?, maxTurns? }\n * { type: \"permission_response\", sessionId, allow, updatedInput? }\n * { type: \"input_response\", sessionId, answer }\n * { type: \"abort\", sessionId }\n *\n * Outbound events (stdout, one JSON per line):\n * { type: \"ready\" }\n * { type: \"session_created\", sessionId }\n * { type: \"session_done\", sessionId }\n * All StreamEvent types with an added `sessionId` field\n */\nexport async function runHeadless(code: Agent, _config: MergedConfig): Promise<void> {\n await code.init();\n\n const sessions = new Map<string, SessionEntry>();\n\n emit({ type: \"ready\" });\n\n const rl = readline.createInterface({ input: process.stdin, terminal: false });\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n\n let cmd: Record<string, unknown>;\n try {\n cmd = JSON.parse(line);\n } catch {\n emit({ type: \"error\", error: { message: \"Invalid JSON\", name: \"ParseError\" } });\n continue;\n }\n\n const cmdType = cmd.type as string;\n\n if (cmdType === \"prompt\") {\n const text = cmd.text as string;\n if (!text) {\n emit({ type: \"error\", error: { message: \"Missing required field: text\", name: \"ValidationError\" } });\n continue;\n }\n\n const sessionId = (cmd.sessionId as string) ?? randomUUID();\n const existing = sessions.get(sessionId);\n\n if (existing?.running) {\n emit({ type: \"error\", error: { message: \"Session is still running\", name: \"ConflictError\" }, sessionId });\n continue;\n }\n\n const abort = new AbortController();\n\n const permissionHandler = (req: import(\"../permissions/types.js\").PermissionRequest): Promise<PermissionResponse> => {\n const entry = sessions.get(sessionId);\n if (!entry) return Promise.reject(new Error(\"Session not found\"));\n return new Promise<PermissionResponse>((resolve, reject) => {\n entry.pendingPermission = { resolve, reject };\n });\n };\n\n const userInputHandler = (question: string): Promise<string> => {\n const entry = sessions.get(sessionId);\n if (!entry) return Promise.reject(new Error(\"Session not found\"));\n emit({ ...({} as Record<string, unknown>), type: \"user_input_request\", sessionId, question });\n return new Promise<string>((resolve, reject) => {\n entry.pendingInput = { resolve, reject };\n });\n };\n\n let thread: Thread;\n if (existing) {\n existing.abort = abort;\n existing.running = true;\n thread = existing.thread;\n } else {\n thread = code.createThread({\n sessionId,\n permissionHandler,\n userInputHandler,\n });\n sessions.set(sessionId, {\n thread,\n abort,\n pendingPermission: null,\n pendingInput: null,\n running: true,\n });\n }\n\n emit({ type: \"session_created\", sessionId });\n\n const maxTurns = cmd.maxTurns as number | undefined;\n\n (async () => {\n try {\n for await (const event of thread.run(text, { signal: abort.signal, maxTurns })) {\n emit({ ...serializeEvent(event), sessionId });\n }\n } catch (err) {\n if ((err as Error).name !== \"AbortError\") {\n const e = err instanceof Error ? err : new Error(String(err));\n emit({ type: \"error\", error: { message: e.message, name: e.name }, sessionId });\n }\n } finally {\n const entry = sessions.get(sessionId);\n if (entry) entry.running = false;\n emit({ type: \"session_done\", sessionId });\n }\n })();\n\n continue;\n }\n\n if (cmdType === \"permission_response\") {\n const sessionId = cmd.sessionId as string;\n const entry = sessions.get(sessionId);\n if (!entry?.pendingPermission) continue;\n const { sessionId: _sid, type: _type, ...response } = cmd;\n entry.pendingPermission.resolve(response as unknown as PermissionResponse);\n entry.pendingPermission = null;\n continue;\n }\n\n if (cmdType === \"input_response\") {\n const sessionId = cmd.sessionId as string;\n const entry = sessions.get(sessionId);\n if (!entry?.pendingInput) continue;\n entry.pendingInput.resolve((cmd.answer as string) ?? \"\");\n entry.pendingInput = null;\n continue;\n }\n\n if (cmdType === \"abort\") {\n const sessionId = cmd.sessionId as string;\n const entry = sessions.get(sessionId);\n if (entry) {\n entry.abort.abort();\n if (entry.pendingPermission) {\n entry.pendingPermission.reject(new Error(\"Session aborted\"));\n entry.pendingPermission = null;\n }\n if (entry.pendingInput) {\n entry.pendingInput.reject(new Error(\"Session aborted\"));\n entry.pendingInput = null;\n }\n }\n continue;\n }\n\n emit({ type: \"error\", error: { message: `Unknown command type: ${cmdType}`, name: \"ValidationError\" } });\n }\n\n await code.close();\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,12 @@
1
+ import {
2
+ applySnipRemovals,
3
+ projectSnippedView,
4
+ snipMessagesByUuids
5
+ } from "./chunk-42PHHZUA.js";
6
+ import "./chunk-DGUM43GV.js";
7
+ export {
8
+ applySnipRemovals,
9
+ projectSnippedView,
10
+ snipMessagesByUuids
11
+ };
12
+ //# sourceMappingURL=history-snip-64GYP4ZL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}