noumen 0.6.0 → 0.8.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 (137) hide show
  1. package/README.md +237 -93
  2. package/dist/a2a/index.d.ts +5 -7
  3. package/dist/a2a/index.js +3 -4
  4. package/dist/a2a/index.js.map +1 -1
  5. package/dist/acp/index.d.ts +5 -7
  6. package/dist/acp/index.js +0 -1
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/{agent-DWE4_P5X.d.ts → agent-D0gl-qYi.d.ts} +89 -34
  9. package/dist/{chunk-6MMYCGJQ.js → chunk-5HY4IYNT.js} +1529 -2321
  10. package/dist/chunk-5HY4IYNT.js.map +1 -0
  11. package/dist/chunk-BC5BLWBC.js +21 -0
  12. package/dist/chunk-BC5BLWBC.js.map +1 -0
  13. package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
  14. package/dist/chunk-CX4BL6PC.js.map +1 -0
  15. package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
  16. package/dist/chunk-HQISH4D7.js.map +1 -0
  17. package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
  18. package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
  19. package/dist/chunk-OPFFLQZL.js +40 -0
  20. package/dist/chunk-OPFFLQZL.js.map +1 -0
  21. package/dist/chunk-PDEAJ272.js +660 -0
  22. package/dist/chunk-PDEAJ272.js.map +1 -0
  23. package/dist/chunk-PKHLGGEC.js +115 -0
  24. package/dist/chunk-PKHLGGEC.js.map +1 -0
  25. package/dist/chunk-XQTNXRE7.js +176 -0
  26. package/dist/chunk-XQTNXRE7.js.map +1 -0
  27. package/dist/chunk-XZPAA5TO.js +817 -0
  28. package/dist/chunk-XZPAA5TO.js.map +1 -0
  29. package/dist/cli/index.js +77 -42
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/client/index.d.ts +1 -2
  32. package/dist/client/index.js +0 -2
  33. package/dist/client/index.js.map +1 -1
  34. package/dist/client-JJFLE6RT.js +9 -0
  35. package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
  36. package/dist/docker.d.ts +2 -2
  37. package/dist/docker.js +0 -1
  38. package/dist/docker.js.map +1 -1
  39. package/dist/e2b.d.ts +2 -2
  40. package/dist/e2b.js +0 -1
  41. package/dist/e2b.js.map +1 -1
  42. package/dist/freestyle.d.ts +2 -2
  43. package/dist/freestyle.js +0 -1
  44. package/dist/freestyle.js.map +1 -1
  45. package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
  46. package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
  47. package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
  48. package/dist/index.d.ts +351 -72
  49. package/dist/index.js +54 -55
  50. package/dist/jsonrpc/index.js +0 -1
  51. package/dist/local.d.ts +168 -0
  52. package/dist/local.js +40 -0
  53. package/dist/local.js.map +1 -0
  54. package/dist/lsp/index.d.ts +4 -5
  55. package/dist/lsp/index.js +0 -1
  56. package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
  57. package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
  58. package/dist/mcp/index.d.ts +16 -8
  59. package/dist/mcp/index.js +5 -6
  60. package/dist/mcp/index.js.map +1 -1
  61. package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
  62. package/dist/{provider-factory-TUHU3DIG.js → provider-factory-KNBSHXJ6.js} +3 -3
  63. package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
  64. package/dist/{resolve-6KUZNEYW.js → resolve-AGQZFMKD.js} +3 -3
  65. package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
  66. package/dist/sandbox-index-ODNREIFA.js +32 -0
  67. package/dist/sandbox-index-ODNREIFA.js.map +1 -0
  68. package/dist/server/index.d.ts +18 -7
  69. package/dist/server/index.js +9 -5
  70. package/dist/server/index.js.map +1 -1
  71. package/dist/{server-BzNGKTP6.d.ts → server-DFXdlqyX.d.ts} +1 -1
  72. package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
  73. package/dist/sprites.d.ts +2 -2
  74. package/dist/sprites.js +0 -1
  75. package/dist/sprites.js.map +1 -1
  76. package/dist/ssh.d.ts +2 -2
  77. package/dist/ssh.js +0 -1
  78. package/dist/ssh.js.map +1 -1
  79. package/dist/{types-DhXwOQwD.d.ts → types-BX4ALqoN.d.ts} +76 -4
  80. package/dist/{types-kiGBF35b.d.ts → types-DLZNyF5t.d.ts} +125 -1
  81. package/dist/unsandboxed.d.ts +59 -0
  82. package/dist/unsandboxed.js +32 -0
  83. package/dist/unsandboxed.js.map +1 -0
  84. package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
  85. package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
  86. package/package.json +35 -50
  87. package/dist/cache-BlBwXXPS.d.ts +0 -38
  88. package/dist/chunk-5GEX6ZSB.js.map +0 -1
  89. package/dist/chunk-6MMYCGJQ.js.map +0 -1
  90. package/dist/chunk-7IQCQI2G.js +0 -94
  91. package/dist/chunk-7IQCQI2G.js.map +0 -1
  92. package/dist/chunk-CCM2AXZG.js +0 -16
  93. package/dist/chunk-CCM2AXZG.js.map +0 -1
  94. package/dist/chunk-DGUM43GV.js +0 -11
  95. package/dist/chunk-HEQQQGK5.js +0 -131
  96. package/dist/chunk-HEQQQGK5.js.map +0 -1
  97. package/dist/chunk-I3JTUFPK.js +0 -171
  98. package/dist/chunk-I3JTUFPK.js.map +0 -1
  99. package/dist/chunk-XZN4QZLK.js.map +0 -1
  100. package/dist/chunk-ZXSDKBYB.js +0 -474
  101. package/dist/chunk-ZXSDKBYB.js.map +0 -1
  102. package/dist/client-CRRO2376.js +0 -10
  103. package/dist/providers/anthropic.d.ts +0 -19
  104. package/dist/providers/anthropic.js +0 -36
  105. package/dist/providers/anthropic.js.map +0 -1
  106. package/dist/providers/bedrock.d.ts +0 -39
  107. package/dist/providers/bedrock.js +0 -56
  108. package/dist/providers/bedrock.js.map +0 -1
  109. package/dist/providers/gemini.d.ts +0 -17
  110. package/dist/providers/gemini.js +0 -262
  111. package/dist/providers/gemini.js.map +0 -1
  112. package/dist/providers/ollama.d.ts +0 -13
  113. package/dist/providers/ollama.js +0 -20
  114. package/dist/providers/ollama.js.map +0 -1
  115. package/dist/providers/openai.d.ts +0 -21
  116. package/dist/providers/openai.js +0 -9
  117. package/dist/providers/openrouter.d.ts +0 -16
  118. package/dist/providers/openrouter.js +0 -24
  119. package/dist/providers/openrouter.js.map +0 -1
  120. package/dist/providers/vertex.d.ts +0 -42
  121. package/dist/providers/vertex.js +0 -68
  122. package/dist/providers/vertex.js.map +0 -1
  123. package/dist/sandbox-9qeMTNrD.d.ts +0 -126
  124. package/dist/types-CD0rUKKT.d.ts +0 -109
  125. package/dist/uuid-RVN2T26F.js.map +0 -1
  126. package/dist/zod-7YXKWYMC.js.map +0 -1
  127. /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
  128. /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
  129. /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
  130. /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
  131. /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
  132. /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
  133. /package/dist/{provider-factory-TUHU3DIG.js.map → render-4VEODRK7.js.map} +0 -0
  134. /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
  135. /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
  136. /package/dist/{resolve-6KUZNEYW.js.map → uuid-CVTNAPEB.js.map} +0 -0
  137. /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/config.ts","../../src/cli/repl.ts","../../src/cli/init.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadCliConfig, mergeConfig, type MergedConfig } from \"./config.js\";\nimport { createProvider, detectProvider, type ProviderName } from \"./provider-factory.js\";\nimport { startRepl } from \"./repl.js\";\nimport { renderEvent, createRenderState, promptPermission } from \"./render.js\";\nimport { runInit } from \"./init.js\";\nimport * as os from \"node:os\";\nimport { Agent, LocalSandbox, UnsandboxedLocal, type Sandbox, type DiagnoseResult, type DiagnoseCheckResult } from \"../index.js\";\nimport type { ThinkingConfig } from \"../thinking/types.js\";\nimport type { PermissionMode } from \"../permissions/types.js\";\n\nconst VERSION = \"0.2.0\";\n\nasync function listLocalOllamaModels(baseURL: string): Promise<string[]> {\n try {\n const res = await fetch(`${baseURL}/api/tags`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) return [];\n const data = (await res.json()) as { models?: Array<{ name: string }> };\n return (data.models ?? []).map((m) => m.name);\n } catch {\n return [];\n }\n}\n\nfunction parseThinking(level: string | undefined): ThinkingConfig | undefined {\n if (!level || level === \"off\") return { type: \"disabled\" };\n const budgets: Record<string, number> = {\n low: 1024,\n medium: 10240,\n high: 32768,\n };\n const budget = budgets[level];\n if (budget) return { type: \"enabled\", budgetTokens: budget };\n return undefined;\n}\n\n/**\n * Create the CLI sandbox. Defaults to OS-level sandboxed `LocalSandbox`.\n * Use `--no-sandbox` to explicitly opt out.\n */\nfunction createCliSandbox(config: MergedConfig): Sandbox {\n if (config.noSandbox) {\n return UnsandboxedLocal({ cwd: config.cwd });\n }\n\n const sandboxOpts: import(\"../index.js\").LocalSandboxOptions = {\n cwd: config.cwd,\n };\n\n const allowWrite = config.sandboxAllowWrite\n ? (config.sandboxAllowWrite as string).split(\",\").map((s: string) => s.trim())\n : undefined;\n const allowDomains = config.sandboxAllowDomain\n ? (config.sandboxAllowDomain as string).split(\",\").map((s: string) => s.trim())\n : undefined;\n\n if (allowWrite || allowDomains) {\n sandboxOpts.sandbox = {\n filesystem: allowWrite ? { allowWrite: [config.cwd, ...allowWrite] } : undefined,\n network: allowDomains ? { allowedDomains: allowDomains } : undefined,\n };\n }\n\n return LocalSandbox(sandboxOpts);\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n}\n\nasync function main(): Promise<void> {\n const program = new Command(\"noumen\")\n .version(VERSION)\n .description(\"AI coding agent — bring your own provider\")\n .option(\"-p, --provider <name>\", \"openai | anthropic | gemini | openrouter | bedrock | vertex | ollama\")\n .option(\"-m, --model <model>\", \"model name\")\n .option(\"--api-key <key>\", \"API key (overrides env vars)\")\n .option(\"--base-url <url>\", \"override provider base URL\")\n .option(\"--cwd <dir>\", \"working directory\")\n .option(\"--permission <mode>\", \"permission mode (default, plan, acceptEdits, auto, bypassPermissions, dontAsk)\")\n .option(\"--thinking <level>\", \"thinking level: off, low, medium, high\")\n .option(\"--max-turns <n>\", \"max agent turns\", parseInt)\n .option(\"--json\", \"emit JSONL stream events to stdout\")\n .option(\"--quiet\", \"only output final text\")\n .option(\"--verbose\", \"show tool calls and thinking\")\n .option(\"--headless\", \"NDJSON stdin/stdout protocol for programmatic control\")\n .option(\"--no-sandbox\", \"disable OS-level sandboxing (use UnsandboxedLocal)\")\n .option(\"--sandbox-allow-write <paths>\", \"comma-separated paths to allow writing in sandbox\")\n .option(\"--sandbox-allow-domain <domains>\", \"comma-separated domains to allow in sandbox\")\n .option(\"-c, --prompt <text>\", \"one-shot prompt (non-interactive)\")\n .argument(\"[prompt...]\", \"inline prompt\")\n .allowExcessArguments(true)\n .action(async (args: string[]) => {\n const opts = program.opts();\n\n if (args.length > 0 && !opts.prompt) {\n opts.prompt = args.join(\" \");\n }\n\n if (!process.stdin.isTTY && !opts.prompt) {\n opts.prompt = await readStdin();\n if (!opts.prompt) {\n process.stderr.write(chalk.red(\"No input provided.\\n\"));\n process.exit(1);\n }\n }\n\n const cwd = opts.cwd ?? process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, opts);\n\n await runAgent(merged);\n });\n\n program\n .command(\"init\")\n .description(\"create .noumen/config.json in the current directory\")\n .action(async () => {\n await runInit();\n process.exit(0);\n });\n\n program\n .command(\"sessions\")\n .description(\"list past sessions\")\n .action(async () => {\n await listSessions();\n process.exit(0);\n });\n\n program\n .command(\"resume <session-id>\")\n .description(\"resume a previous session\")\n .action(async (sessionId: string) => {\n await resumeSession(sessionId);\n });\n\n program\n .command(\"doctor\")\n .description(\"run health checks on provider, sandbox, MCP, and LSP\")\n .action(async () => {\n await runDoctor();\n });\n\n await program.parseAsync(process.argv);\n}\n\nasync function runAgent(config: MergedConfig): Promise<void> {\n const providerName: ProviderName | undefined =\n (config.provider as ProviderName | undefined) ?? await detectProvider();\n\n if (!providerName) {\n if (!process.stdin.isTTY) {\n process.stderr.write(chalk.red(\"No provider specified.\\n\"));\n process.exit(1);\n }\n process.stderr.write(\n chalk.bold(\"Welcome to noumen!\\n\\n\") +\n chalk.dim(\"No provider detected. Let's set one up.\\n\\n\"),\n );\n\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr, terminal: true });\n\n try {\n const { SUPPORTED_PROVIDERS, isOllamaRunning, ollamaBaseURL } = await import(\"./provider-factory.js\");\n const providerAnswer = await rl.question(\n ` Provider (${SUPPORTED_PROVIDERS.join(\", \")}) [${chalk.bold(\"ollama\")}]: `,\n );\n const picked = providerAnswer.trim() || \"ollama\";\n if (!(SUPPORTED_PROVIDERS as readonly string[]).includes(picked)) {\n process.stderr.write(chalk.red(`Unknown provider: ${picked}\\n`));\n process.exit(1);\n }\n\n if (picked === \"ollama\") {\n if (!(await isOllamaRunning())) {\n process.stderr.write(\n chalk.yellow(`\\n Ollama doesn't appear to be running at ${ollamaBaseURL()}.\\n`) +\n chalk.yellow(` Install it from https://ollama.com, then run:\\n\\n`) +\n ` ${chalk.cyan(\"ollama pull qwen2.5-coder:32b\")}\\n` +\n ` ${chalk.cyan(\"ollama serve\")}\\n\\n` +\n chalk.yellow(` Then re-run noumen.\\n`),\n );\n rl.close();\n process.exit(1);\n }\n\n const models = await listLocalOllamaModels(ollamaBaseURL());\n if (models.length > 0) {\n process.stderr.write(chalk.dim(` Available models: ${models.join(\", \")}\\n`));\n const defaultModel = models.includes(\"qwen2.5-coder:32b\") ? \"qwen2.5-coder:32b\" : models[0];\n const modelAnswer = await rl.question(\n ` Model [${chalk.bold(defaultModel)}]: `,\n );\n config.model = modelAnswer.trim() || defaultModel;\n }\n }\n\n const needsKey = ![\"bedrock\", \"vertex\", \"ollama\"].includes(picked);\n let apiKey: string | undefined;\n if (needsKey) {\n const keyAnswer = await rl.question(` API key: `);\n apiKey = keyAnswer.trim();\n if (!apiKey) {\n process.stderr.write(chalk.red(\"API key is required.\\n\"));\n process.exit(1);\n }\n }\n\n rl.close();\n config.provider = picked;\n if (apiKey) config.apiKey = apiKey;\n } catch {\n rl.close();\n process.exit(1);\n }\n\n return runAgent(config);\n }\n\n if (!config.model) {\n const { DEFAULT_MODELS } = await import(\"./provider-factory.js\");\n if (providerName === \"ollama\") {\n const { ollamaBaseURL } = await import(\"./provider-factory.js\");\n const models = await listLocalOllamaModels(ollamaBaseURL());\n const preferred = DEFAULT_MODELS[providerName];\n config.model = models.includes(preferred) ? preferred : models[0] ?? preferred;\n } else {\n config.model = DEFAULT_MODELS[providerName];\n }\n }\n\n const provider = await createProvider(providerName, {\n apiKey: config.apiKey,\n model: config.model,\n baseURL: config.baseURL,\n });\n\n const thinking = parseThinking(config.thinking);\n const permissionMode = (config.permissions ?? \"default\") as PermissionMode;\n\n const agent = new Agent({\n provider: provider,\n sandbox: createCliSandbox(config),\n options: {\n cwd: config.cwd,\n model: config.model,\n systemPrompt: config.systemPrompt,\n permissions: {\n mode: permissionMode,\n },\n thinking,\n autoCompact: config.autoCompact ?? true,\n enableSubagents: config.enableSubagents ?? true,\n enableTasks: config.enableTasks ?? false,\n enablePlanMode: config.enablePlanMode ?? true,\n enableWorktrees: config.enableWorktrees ?? false,\n mcpServers: config.mcpServers,\n lsp: config.lsp,\n hooks: config.hooks,\n webSearch: config.webSearch,\n sessionDir: config.sessionDir ?? \".noumen/sessions\",\n projectContext: { cwd: config.cwd, homeDir: os.homedir() },\n costTracking: { enabled: true },\n retry: true,\n },\n });\n\n if (config.headless) {\n const { runHeadless } = await import(\"./headless.js\");\n await runHeadless(agent, config);\n return;\n }\n\n await agent.init();\n\n try {\n if (config.prompt) {\n await runOneShot(agent, config);\n } else {\n if (!process.stdin.isTTY) {\n process.stderr.write(\n chalk.red(\"Interactive mode requires a TTY. Use -c or pipe input.\\n\"),\n );\n process.exit(1);\n }\n await startRepl(agent, config, () => agent.close());\n }\n } finally {\n await agent.close();\n }\n}\n\nasync function runOneShot(agent: Agent, config: MergedConfig): Promise<void> {\n const { startSpinner } = await import(\"./spinner.js\");\n const { isVisibleEvent } = await import(\"./render.js\");\n const thread = await agent.createThread();\n const state = createRenderState();\n const runOpts = config.maxTurns ? { maxTurns: config.maxTurns } : undefined;\n\n const spinner =\n !config.json && !config.quiet ? startSpinner(\"Thinking\") : null;\n\n try {\n for await (const event of thread.run(config.prompt!, runOpts)) {\n if (!state.showedActivity && spinner && isVisibleEvent(event, config)) {\n spinner.stop();\n state.showedActivity = true;\n }\n renderEvent(event, config, state);\n }\n } finally {\n spinner?.stop();\n }\n\n if (config.quiet && state.accumulatedText) {\n process.stdout.write(state.accumulatedText);\n if (!state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n } else if (state.accumulatedText && !state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n}\n\nasync function listSessions(): Promise<void> {\n const cwd = process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, { cwd });\n\n const providerName: ProviderName | undefined = (merged.provider as ProviderName | undefined) ?? await detectProvider();\n if (!providerName) {\n process.stderr.write(chalk.red(\"No provider configured. Run `noumen init` first.\\n\"));\n process.exit(1);\n }\n\n const provider = await createProvider(providerName, {\n apiKey: merged.apiKey,\n model: merged.model,\n baseURL: merged.baseURL,\n });\n\n const agent = new Agent({\n provider: provider,\n sandbox: UnsandboxedLocal({ cwd }),\n options: { cwd, sessionDir: merged.sessionDir ?? \".noumen/sessions\" },\n });\n\n const sessions = await agent.listSessions();\n if (sessions.length === 0) {\n process.stdout.write(chalk.dim(\"No saved sessions.\\n\"));\n return;\n }\n\n process.stdout.write(chalk.bold(\"Sessions:\\n\"));\n for (const s of sessions) {\n const title = s.title ? chalk.white(` ${s.title}`) : \"\";\n process.stdout.write(\n ` ${chalk.cyan(s.sessionId.slice(0, 8))} ${chalk.dim(s.createdAt)} ${chalk.dim(`${s.messageCount} msgs`)}${title}\\n`,\n );\n }\n}\n\nasync function resumeSession(sessionId: string): Promise<void> {\n const cwd = process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, { cwd });\n\n const providerName: ProviderName | undefined = (merged.provider as ProviderName | undefined) ?? await detectProvider();\n if (!providerName) {\n process.stderr.write(chalk.red(\"No provider configured. Run `noumen init` first.\\n\"));\n process.exit(1);\n }\n\n const provider = await createProvider(providerName, {\n apiKey: merged.apiKey,\n model: merged.model,\n baseURL: merged.baseURL,\n });\n\n const thinking = parseThinking(merged.thinking);\n const permissionMode = (merged.permissions ?? \"default\") as PermissionMode;\n\n const agent = new Agent({\n provider: provider,\n sandbox: createCliSandbox(merged),\n options: {\n cwd,\n model: merged.model,\n permissions: { mode: permissionMode },\n thinking,\n autoCompact: merged.autoCompact ?? true,\n enableSubagents: merged.enableSubagents ?? true,\n enablePlanMode: merged.enablePlanMode ?? true,\n mcpServers: merged.mcpServers,\n lsp: merged.lsp,\n hooks: merged.hooks,\n sessionDir: merged.sessionDir ?? \".noumen/sessions\",\n projectContext: { cwd, homeDir: os.homedir() },\n costTracking: { enabled: true },\n retry: true,\n },\n });\n\n await agent.init();\n\n // Match full session ID from partial prefix\n const sessions = await agent.listSessions();\n const match = sessions.find(\n (s) => s.sessionId === sessionId || s.sessionId.startsWith(sessionId),\n );\n\n if (!match) {\n process.stderr.write(chalk.red(`Session not found: ${sessionId}\\n`));\n process.exit(1);\n }\n\n process.stderr.write(\n chalk.dim(`Resuming session ${match.sessionId.slice(0, 8)}...\\n\\n`),\n );\n\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr, terminal: true });\n\n const thread = await agent.resumeThread(match.sessionId);\n\n // Enter REPL with the resumed thread\n const { renderEvent: render, createRenderState: makeState } = await import(\"./render.js\");\n\n process.stderr.write(chalk.dim(\"Session resumed. Type a message to continue.\\n\\n\"));\n\n try {\n while (true) {\n let input: string;\n try {\n input = await rl.question(chalk.blue(\"> \"));\n } catch {\n break;\n }\n if (!input.trim()) continue;\n if (input.trim() === \"/quit\" || input.trim() === \"/exit\") break;\n\n const state = makeState();\n for await (const event of thread.run(input)) {\n render(event, merged, state);\n }\n if (state.accumulatedText && !state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n }\n } finally {\n rl.close();\n await agent.close();\n }\n}\n\nasync function runDoctor(): Promise<void> {\n const cwd = process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, { cwd });\n\n const providerName: ProviderName | undefined = (merged.provider as ProviderName | undefined) ?? await detectProvider();\n if (!providerName) {\n process.stderr.write(chalk.red(\"No provider configured. Run `noumen init` first.\\n\"));\n process.exit(1);\n }\n\n const provider = await createProvider(providerName, {\n apiKey: merged.apiKey,\n model: merged.model,\n baseURL: merged.baseURL,\n });\n\n const agent = new Agent({\n provider: provider,\n sandbox: createCliSandbox(merged),\n options: {\n cwd,\n model: merged.model,\n mcpServers: merged.mcpServers,\n lsp: merged.lsp,\n sessionDir: merged.sessionDir ?? \".noumen/sessions\",\n },\n });\n\n await agent.init();\n\n process.stderr.write(chalk.bold(\"\\nnoumen doctor\\n\\n\"));\n const result = await agent.diagnose();\n printDiagnoseResult(result);\n await agent.close();\n process.exit(result.overall ? 0 : 1);\n}\n\nfunction formatCheckLine(label: string, check: DiagnoseCheckResult, extra?: string): string {\n const icon = check.ok ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const timing = check.latencyMs > 0 ? chalk.dim(` (${check.latencyMs}ms)`) : \"\";\n const suffix = extra ? chalk.dim(` ${extra}`) : \"\";\n const errMsg = check.error ? chalk.red(` ${check.error}`) : \"\";\n const warnMsg = !check.error && check.warning ? chalk.yellow(` ${check.warning}`) : \"\";\n return ` ${icon} ${label}${timing}${suffix}${errMsg}${warnMsg}\\n`;\n}\n\nfunction printDiagnoseResult(r: DiagnoseResult): void {\n const modelLabel = r.provider.model ? ` (${r.provider.model})` : \"\";\n process.stderr.write(formatCheckLine(`Provider${modelLabel}`, r.provider));\n process.stderr.write(formatCheckLine(\"Sandbox: filesystem\", r.sandbox.fs));\n process.stderr.write(formatCheckLine(\"Sandbox: shell\", r.sandbox.computer));\n process.stderr.write(formatCheckLine(\n \"Sandbox: OS-level (sandbox-runtime)\",\n r.sandboxRuntime,\n r.sandboxRuntime.platform,\n ));\n\n for (const [name, check] of Object.entries(r.mcp)) {\n const parts: string[] = [];\n if (check.status) parts.push(check.status);\n if (check.toolCount != null) parts.push(`${check.toolCount} tools`);\n const extra = parts.length ? parts.join(\", \") : undefined;\n process.stderr.write(formatCheckLine(`MCP: ${name}`, check, extra));\n }\n\n for (const [name, check] of Object.entries(r.lsp)) {\n const extra = check.state ?? undefined;\n process.stderr.write(formatCheckLine(`LSP: ${name}`, check, extra));\n }\n\n process.stderr.write(\"\\n\");\n if (r.overall) {\n process.stderr.write(` ${chalk.green(\"Overall: healthy\")}\\n\\n`);\n } else {\n process.stderr.write(` ${chalk.red(\"Overall: unhealthy\")}\\n\\n`);\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(chalk.red(`Fatal: ${err.message}\\n`));\n process.exit(1);\n});\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport type { McpServerConfig } from \"../mcp/types.js\";\nimport type { LspServerConfig } from \"../lsp/types.js\";\nimport type { HookDefinition } from \"../hooks/types.js\";\nimport type { WebSearchConfig } from \"../tools/web-search.js\";\n\nexport interface CliConfig {\n provider?: string;\n model?: string;\n apiKey?: string;\n baseURL?: string;\n permissions?: string;\n thinking?: string;\n sandbox?: string;\n mcpServers?: Record<string, McpServerConfig>;\n lsp?: Record<string, LspServerConfig>;\n hooks?: HookDefinition[];\n autoCompact?: boolean;\n enableSubagents?: boolean;\n enableTasks?: boolean;\n enablePlanMode?: boolean;\n enableWorktrees?: boolean;\n webSearch?: WebSearchConfig;\n costLimit?: number;\n maxTurns?: number;\n systemPrompt?: string;\n sessionDir?: string;\n}\n\n/**\n * Load global config from ~/.noumen/config.json.\n * Returns empty object if not found or invalid.\n */\nexport function loadGlobalConfig(): CliConfig {\n const globalPath = path.join(os.homedir(), \".noumen\", \"config.json\");\n try {\n const raw = fs.readFileSync(globalPath, \"utf-8\");\n return JSON.parse(raw) as CliConfig;\n } catch {\n return {};\n }\n}\n\n/**\n * Walk up from `cwd` looking for `.noumen/config.json`.\n * Returns parsed config or empty object if none found.\n */\nfunction loadProjectConfig(cwd: string): CliConfig {\n let dir = path.resolve(cwd);\n const root = path.parse(dir).root;\n\n while (true) {\n const candidate = path.join(dir, \".noumen\", \"config.json\");\n try {\n const raw = fs.readFileSync(candidate, \"utf-8\");\n return JSON.parse(raw) as CliConfig;\n } catch {\n // not found or invalid — keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir || dir === root) break;\n dir = parent;\n }\n\n return {};\n}\n\n/**\n * Load config with layering: global (~/.noumen/config.json) < project < flags.\n * Project-level values override global values.\n */\nexport function loadCliConfig(cwd: string): CliConfig {\n const global = loadGlobalConfig();\n const project = loadProjectConfig(cwd);\n return { ...global, ...project };\n}\n\nexport interface MergedConfig extends CliConfig {\n cwd: string;\n json?: boolean;\n quiet?: boolean;\n verbose?: boolean;\n headless?: boolean;\n prompt?: string;\n noSandbox?: boolean;\n sandboxAllowWrite?: string;\n sandboxAllowDomain?: string;\n}\n\n/**\n * Merge CLI flags over the config file values. Flags take precedence.\n */\nexport function mergeConfig(\n config: CliConfig,\n flags: Record<string, unknown>,\n): MergedConfig {\n const cwd = (flags.cwd as string) ?? process.cwd();\n return {\n ...config,\n ...(flags.provider !== undefined && { provider: flags.provider as string }),\n ...(flags.model !== undefined && { model: flags.model as string }),\n ...(flags.apiKey !== undefined && { apiKey: flags.apiKey as string }),\n ...(flags.baseUrl !== undefined && { baseURL: flags.baseUrl as string }),\n ...(flags.permission !== undefined && { permissions: flags.permission as string }),\n ...(flags.thinking !== undefined && { thinking: flags.thinking as string }),\n ...(flags.maxTurns !== undefined && { maxTurns: flags.maxTurns as number }),\n ...(flags.systemPrompt !== undefined && { systemPrompt: flags.systemPrompt as string }),\n cwd,\n json: flags.json as boolean | undefined,\n quiet: flags.quiet as boolean | undefined,\n verbose: flags.verbose as boolean | undefined,\n headless: flags.headless as boolean | undefined,\n prompt: flags.prompt as string | undefined,\n noSandbox: flags.sandbox === false ? true : undefined,\n sandboxAllowWrite: flags.sandboxAllowWrite as string | undefined,\n sandboxAllowDomain: flags.sandboxAllowDomain as string | undefined,\n };\n}\n","import * as readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport type { Agent } from \"../agent.js\";\nimport type { Thread } from \"../thread.js\";\nimport type { MergedConfig } from \"./config.js\";\nimport { renderEvent, createRenderState, promptPermission, isVisibleEvent } from \"./render.js\";\nimport { DEFAULT_MODELS, createProvider, SUPPORTED_PROVIDERS, type ProviderName } from \"./provider-factory.js\";\nimport { startSpinner } from \"./spinner.js\";\n\nexport async function startRepl(\n code: Agent,\n config: MergedConfig,\n cleanup?: () => Promise<void>,\n): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n terminal: true,\n });\n\n let thread = await code.createThread({\n userInputHandler: (q) => promptPermission(rl, \"agent\", q).then((ok) => ok ? \"yes\" : \"no\"),\n });\n\n let runningTurn = false;\n let currentThread: Thread = thread;\n\n const sigintHandler = () => {\n if (runningTurn) {\n currentThread.abort();\n runningTurn = false;\n process.stderr.write(chalk.yellow(\"\\n Cancelled.\\n\\n\"));\n } else {\n process.stderr.write(chalk.dim(\"\\nGoodbye.\\n\"));\n rl.close();\n cleanup?.().catch(() => {}).finally(() => process.exit(0));\n }\n };\n process.on(\"SIGINT\", sigintHandler);\n\n printWelcome(config);\n\n try {\n while (true) {\n let input: string;\n try {\n input = await rl.question(chalk.blue(\"> \"));\n } catch {\n break;\n }\n\n if (!input.trim()) continue;\n\n if (input.startsWith(\"/\")) {\n const result = await handleSlashCommand(\n input,\n thread,\n code,\n config,\n rl,\n );\n if (result === \"quit\") break;\n if (result === \"new\") {\n thread = await code.createThread({\n userInputHandler: (q) => promptPermission(rl, \"agent\", q).then((ok) => ok ? \"yes\" : \"no\"),\n });\n currentThread = thread;\n }\n continue;\n }\n\n const state = createRenderState();\n const runOpts = config.maxTurns ? { maxTurns: config.maxTurns } : undefined;\n\n const spinner =\n !config.json && !config.quiet ? startSpinner(\"Thinking\") : null;\n\n runningTurn = true;\n try {\n for await (const event of thread.run(input, runOpts)) {\n if (!state.showedActivity && spinner && isVisibleEvent(event, config)) {\n spinner.stop();\n state.showedActivity = true;\n }\n renderEvent(event, config, state);\n }\n } catch (err) {\n if ((err as Error)?.name === \"AbortError\") {\n // already handled by SIGINT handler\n } else {\n throw err;\n }\n } finally {\n spinner?.stop();\n runningTurn = false;\n }\n\n if (state.accumulatedText && !state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n }\n } finally {\n process.removeListener(\"SIGINT\", sigintHandler);\n rl.close();\n }\n}\n\nfunction printWelcome(config: MergedConfig): void {\n const provider = config.provider ?? \"auto\";\n const model = config.model ?? DEFAULT_MODELS[provider] ?? \"default\";\n process.stderr.write(\n chalk.bold(\"noumen\") +\n chalk.dim(` — ${provider}/${model}`) +\n \"\\n\" +\n chalk.dim(\"Type a message to begin. /help for commands, Ctrl+C to cancel.\") +\n \"\\n\\n\",\n );\n}\n\ntype SlashResult = \"continue\" | \"quit\" | \"new\";\n\nasync function handleSlashCommand(\n input: string,\n thread: Thread,\n code: Agent,\n config: MergedConfig,\n _rl: readline.Interface,\n): Promise<SlashResult> {\n const [cmd] = input.trim().split(/\\s+/);\n\n switch (cmd) {\n case \"/quit\":\n case \"/exit\":\n case \"/q\":\n process.stderr.write(chalk.dim(\"Goodbye.\\n\"));\n return \"quit\";\n\n case \"/new\":\n process.stderr.write(chalk.dim(\"Starting new conversation.\\n\\n\"));\n return \"new\";\n\n case \"/session\":\n process.stderr.write(chalk.dim(`Session: ${thread.sessionId}\\n`));\n return \"continue\";\n\n case \"/cost\": {\n const summary = code.getCostSummary();\n if (summary) {\n process.stderr.write(\n chalk.dim(\n `Cost: $${summary.totalCostUSD.toFixed(4)} | ` +\n `Input: ${summary.totalInputTokens} tokens | ` +\n `Output: ${summary.totalOutputTokens} tokens\\n`,\n ),\n );\n } else {\n process.stderr.write(chalk.dim(\"Cost tracking not enabled.\\n\"));\n }\n return \"continue\";\n }\n\n case \"/sessions\": {\n const sessions = await code.listSessions();\n if (sessions.length === 0) {\n process.stderr.write(chalk.dim(\"No saved sessions.\\n\"));\n } else {\n for (const s of sessions.slice(0, 20)) {\n process.stderr.write(\n chalk.dim(\n ` ${s.sessionId.slice(0, 8)} ${s.createdAt ?? \"\"} ${s.messageCount ?? 0} messages\\n`,\n ),\n );\n }\n }\n return \"continue\";\n }\n\n case \"/model\": {\n const arg = input.trim().split(/\\s+/).slice(1).join(\" \");\n if (!arg) {\n process.stderr.write(chalk.dim(`Current model: ${thread.getModel()}\\n`));\n } else {\n thread.setModel(arg);\n process.stderr.write(chalk.dim(`Model set to ${arg}\\n`));\n }\n return \"continue\";\n }\n\n case \"/provider\": {\n const parts = input.trim().split(/\\s+/).slice(1);\n const providerName = parts[0];\n const modelArg = parts[1];\n if (!providerName) {\n process.stderr.write(\n chalk.dim(`Current: ${config.provider ?? \"auto\"}/${thread.getModel()}\\n`) +\n chalk.dim(`Available: ${SUPPORTED_PROVIDERS.join(\", \")}\\n`),\n );\n return \"continue\";\n }\n if (!(SUPPORTED_PROVIDERS as readonly string[]).includes(providerName)) {\n process.stderr.write(chalk.red(`Unknown provider: ${providerName}. Available: ${SUPPORTED_PROVIDERS.join(\", \")}\\n`));\n return \"continue\";\n }\n try {\n const model = modelArg ?? DEFAULT_MODELS[providerName];\n const provider = await createProvider(providerName as ProviderName, {\n apiKey: config.apiKey,\n model,\n baseURL: config.baseURL,\n });\n thread.setProvider(provider, model);\n config.provider = providerName;\n config.model = model;\n process.stderr.write(chalk.dim(`Switched to ${providerName}/${model}\\n`));\n } catch (err) {\n process.stderr.write(chalk.red(`Failed to switch: ${(err as Error).message}\\n`));\n }\n return \"continue\";\n }\n\n case \"/verbose\":\n config.verbose = !config.verbose;\n process.stderr.write(\n chalk.dim(`Verbose mode: ${config.verbose ? \"on\" : \"off\"}\\n`),\n );\n return \"continue\";\n\n case \"/help\":\n process.stderr.write(\n chalk.dim(\n [\n \"Commands:\",\n \" /quit, /exit Exit the REPL\",\n \" /new Start a new conversation\",\n \" /model [name] Show or change the model\",\n \" /provider [name] Show or switch provider (and model)\",\n \" /session Show current session ID\",\n \" /sessions List saved sessions\",\n \" /cost Show token usage and cost\",\n \" /verbose Toggle verbose output\",\n \" /help Show this help\",\n \"\",\n \"Shortcuts:\",\n \" Ctrl+C Cancel current turn / exit when idle\",\n \"\",\n ].join(\"\\n\"),\n ),\n );\n return \"continue\";\n\n default:\n process.stderr.write(\n chalk.yellow(`Unknown command: ${cmd}. Try /help\\n`),\n );\n return \"continue\";\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { SUPPORTED_PROVIDERS, DEFAULT_MODELS, isOllamaRunning, ollamaBaseURL } from \"./provider-factory.js\";\n\nconst PERMISSION_MODES = [\"default\", \"plan\", \"acceptEdits\", \"auto\", \"bypassPermissions\"];\n\nexport async function runInit(): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n try {\n process.stdout.write(chalk.bold(\"noumen init\") + \"\\n\\n\");\n\n const provider = await askChoice(\n rl,\n \"Provider\",\n SUPPORTED_PROVIDERS,\n \"anthropic\",\n );\n\n let defaultModel = DEFAULT_MODELS[provider] ?? \"\";\n\n if (provider === \"ollama\") {\n const ollamaModels = await listOllamaModels();\n if (ollamaModels.length > 0) {\n process.stdout.write(chalk.dim(` Available models: ${ollamaModels.join(\", \")}\\n`));\n if (ollamaModels.includes(defaultModel)) {\n // keep the default\n } else {\n defaultModel = ollamaModels[0];\n }\n } else {\n process.stdout.write(\n chalk.yellow(\n `\\n Ollama doesn't appear to be running at ${ollamaBaseURL()}.\\n` +\n ` Install it from https://ollama.com, then run:\\n` +\n ` ollama pull ${defaultModel}\\n` +\n ` ollama serve\\n\\n`,\n ),\n );\n }\n }\n\n const model = await askDefault(rl, \"Model\", defaultModel);\n\n const permissions = await askChoice(\n rl,\n \"Permission mode\",\n PERMISSION_MODES,\n \"default\",\n );\n\n const config: Record<string, unknown> = { provider };\n if (model !== defaultModel) config.model = model;\n if (permissions !== \"default\") config.permissions = permissions;\n\n const dir = path.join(process.cwd(), \".noumen\");\n fs.mkdirSync(dir, { recursive: true });\n\n const configPath = path.join(dir, \"config.json\");\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\");\n process.stdout.write(chalk.green(` Created ${configPath}\\n`));\n\n const noumenMdPath = path.join(process.cwd(), \"NOUMEN.md\");\n if (!fs.existsSync(noumenMdPath)) {\n const create = await askDefault(rl, \"Create NOUMEN.md?\", \"Y\");\n if (create.toLowerCase() === \"y\" || create.toLowerCase() === \"yes\") {\n fs.writeFileSync(noumenMdPath, NOUMEN_MD_TEMPLATE);\n process.stdout.write(chalk.green(` Created ${noumenMdPath}\\n`));\n }\n }\n\n process.stdout.write(\n \"\\n\" + chalk.dim(\"Run `noumen` to start a session.\") + \"\\n\",\n );\n } finally {\n rl.close();\n }\n}\n\nasync function listOllamaModels(): Promise<string[]> {\n if (!(await isOllamaRunning())) return [];\n try {\n const res = await fetch(`${ollamaBaseURL()}/api/tags`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) return [];\n const data = (await res.json()) as { models?: Array<{ name: string }> };\n return (data.models ?? []).map((m) => m.name);\n } catch {\n return [];\n }\n}\n\nasync function askChoice(\n rl: readline.Interface,\n label: string,\n choices: string[],\n defaultValue: string,\n): Promise<string> {\n const hint = choices.join(\", \");\n const answer = await rl.question(\n ` ${label} (${hint}) [${chalk.bold(defaultValue)}]: `,\n );\n const trimmed = answer.trim();\n if (!trimmed) return defaultValue;\n if (choices.includes(trimmed)) return trimmed;\n process.stdout.write(chalk.yellow(` Invalid choice, using ${defaultValue}\\n`));\n return defaultValue;\n}\n\nasync function askDefault(\n rl: readline.Interface,\n label: string,\n defaultValue: string,\n): Promise<string> {\n const answer = await rl.question(\n ` ${label} [${chalk.bold(defaultValue)}]: `,\n );\n return answer.trim() || defaultValue;\n}\n\nconst NOUMEN_MD_TEMPLATE = `# Project Instructions\n\nAdd project-specific instructions for the AI agent here.\nThese instructions are loaded automatically when running noumen in this directory.\n\n## Guidelines\n\n- Describe your project's coding conventions\n- Note important architectural decisions\n- List files or patterns the agent should be aware of\n`;\n"],"mappings":"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","names":["chalk","fs","path","readline","chalk","chalk","os","chalk","createInterface","SUPPORTED_PROVIDERS","isOllamaRunning","ollamaBaseURL","DEFAULT_MODELS","startSpinner","isVisibleEvent"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/config.ts","../../src/cli/repl.ts","../../src/cli/init.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { loadCliConfig, mergeConfig, type MergedConfig } from \"./config.js\";\nimport { createProvider, detectProvider, type ProviderName } from \"./provider-factory.js\";\nimport { startRepl } from \"./repl.js\";\nimport { renderEvent, createRenderState, promptPermission } from \"./render.js\";\nimport { runInit } from \"./init.js\";\nimport * as os from \"node:os\";\nimport { Agent, type Sandbox, type DiagnoseResult, type DiagnoseCheckResult } from \"../index.js\";\nimport { LocalSandbox, type LocalSandboxOptions } from \"../virtual/local-sandbox.js\";\nimport { UnsandboxedLocal } from \"../virtual/unsandboxed.js\";\nimport type { ThinkingConfig } from \"../thinking/types.js\";\nimport type { PermissionMode } from \"../permissions/types.js\";\n\nconst VERSION = \"0.2.0\";\n\nasync function listLocalOllamaModels(baseURL: string): Promise<string[]> {\n try {\n const res = await fetch(`${baseURL}/api/tags`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) return [];\n const data = (await res.json()) as { models?: Array<{ name: string }> };\n return (data.models ?? []).map((m) => m.name);\n } catch {\n return [];\n }\n}\n\nfunction parseThinking(level: string | undefined): ThinkingConfig | undefined {\n if (!level || level === \"off\") return { type: \"disabled\" };\n const budgets: Record<string, number> = {\n low: 1024,\n medium: 10240,\n high: 32768,\n };\n const budget = budgets[level];\n if (budget) return { type: \"enabled\", budgetTokens: budget };\n return undefined;\n}\n\n/**\n * Create the CLI sandbox. Defaults to OS-level sandboxed `LocalSandbox`.\n * Use `--no-sandbox` to explicitly opt out.\n */\nfunction createCliSandbox(config: MergedConfig): Sandbox {\n if (config.noSandbox) {\n return UnsandboxedLocal({ cwd: config.cwd });\n }\n\n const sandboxOpts: LocalSandboxOptions = {\n cwd: config.cwd,\n };\n\n const allowWrite = config.sandboxAllowWrite\n ? (config.sandboxAllowWrite as string).split(\",\").map((s: string) => s.trim())\n : undefined;\n const allowDomains = config.sandboxAllowDomain\n ? (config.sandboxAllowDomain as string).split(\",\").map((s: string) => s.trim())\n : undefined;\n\n if (allowWrite || allowDomains) {\n sandboxOpts.sandbox = {\n filesystem: allowWrite ? { allowWrite: [config.cwd, ...allowWrite] } : undefined,\n network: allowDomains ? { allowedDomains: allowDomains } : undefined,\n };\n }\n\n return LocalSandbox(sandboxOpts);\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n}\n\nasync function main(): Promise<void> {\n const program = new Command(\"noumen\")\n .version(VERSION)\n .description(\"AI coding agent — bring your own provider\")\n .option(\"-p, --provider <name>\", \"openai | anthropic | gemini | openrouter | bedrock | vertex | ollama\")\n .option(\"-m, --model <model>\", \"model name\")\n .option(\"--api-key <key>\", \"API key (overrides env vars)\")\n .option(\"--base-url <url>\", \"override provider base URL\")\n .option(\"--cwd <dir>\", \"working directory\")\n .option(\"--permission <mode>\", \"permission mode (default, plan, acceptEdits, auto, bypassPermissions, dontAsk)\")\n .option(\"--thinking <level>\", \"thinking level: off, low, medium, high\")\n .option(\"--max-turns <n>\", \"max agent turns\", parseInt)\n .option(\"--json\", \"emit JSONL stream events to stdout\")\n .option(\"--quiet\", \"only output final text\")\n .option(\"--verbose\", \"show tool calls and thinking\")\n .option(\"--headless\", \"NDJSON stdin/stdout protocol for programmatic control\")\n .option(\"--no-sandbox\", \"disable OS-level sandboxing (use UnsandboxedLocal)\")\n .option(\"--sandbox-allow-write <paths>\", \"comma-separated paths to allow writing in sandbox\")\n .option(\"--sandbox-allow-domain <domains>\", \"comma-separated domains to allow in sandbox\")\n .option(\"-c, --prompt <text>\", \"one-shot prompt (non-interactive)\")\n .argument(\"[prompt...]\", \"inline prompt\")\n .allowExcessArguments(true)\n .action(async (args: string[]) => {\n const opts = program.opts();\n\n if (args.length > 0 && !opts.prompt) {\n opts.prompt = args.join(\" \");\n }\n\n if (!process.stdin.isTTY && !opts.prompt) {\n opts.prompt = await readStdin();\n if (!opts.prompt) {\n process.stderr.write(chalk.red(\"No input provided.\\n\"));\n process.exit(1);\n }\n }\n\n const cwd = opts.cwd ?? process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, opts);\n\n await runAgent(merged);\n });\n\n program\n .command(\"init\")\n .description(\"create .noumen/config.json in the current directory\")\n .action(async () => {\n await runInit();\n process.exit(0);\n });\n\n program\n .command(\"sessions\")\n .description(\"list past sessions\")\n .action(async () => {\n await listSessions();\n process.exit(0);\n });\n\n program\n .command(\"resume <session-id>\")\n .description(\"resume a previous session\")\n .action(async (sessionId: string) => {\n await resumeSession(sessionId);\n });\n\n program\n .command(\"doctor\")\n .description(\"run health checks on provider, sandbox, MCP, and LSP\")\n .action(async () => {\n await runDoctor();\n });\n\n await program.parseAsync(process.argv);\n}\n\nasync function runAgent(config: MergedConfig): Promise<void> {\n const providerName: ProviderName | undefined =\n (config.provider as ProviderName | undefined) ?? await detectProvider();\n\n if (!providerName) {\n if (!process.stdin.isTTY) {\n process.stderr.write(chalk.red(\"No provider specified.\\n\"));\n process.exit(1);\n }\n process.stderr.write(\n chalk.bold(\"Welcome to noumen!\\n\\n\") +\n chalk.dim(\"No provider detected. Let's set one up.\\n\\n\"),\n );\n\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr, terminal: true });\n\n try {\n const { SUPPORTED_PROVIDERS, isOllamaRunning, ollamaBaseURL } = await import(\"./provider-factory.js\");\n const providerAnswer = await rl.question(\n ` Provider (${SUPPORTED_PROVIDERS.join(\", \")}) [${chalk.bold(\"ollama\")}]: `,\n );\n const picked = providerAnswer.trim() || \"ollama\";\n if (!(SUPPORTED_PROVIDERS as readonly string[]).includes(picked)) {\n process.stderr.write(chalk.red(`Unknown provider: ${picked}\\n`));\n process.exit(1);\n }\n\n if (picked === \"ollama\") {\n if (!(await isOllamaRunning())) {\n process.stderr.write(\n chalk.yellow(`\\n Ollama doesn't appear to be running at ${ollamaBaseURL()}.\\n`) +\n chalk.yellow(` Install it from https://ollama.com, then run:\\n\\n`) +\n ` ${chalk.cyan(\"ollama pull qwen2.5-coder:32b\")}\\n` +\n ` ${chalk.cyan(\"ollama serve\")}\\n\\n` +\n chalk.yellow(` Then re-run noumen.\\n`),\n );\n rl.close();\n process.exit(1);\n }\n\n const models = await listLocalOllamaModels(ollamaBaseURL());\n if (models.length > 0) {\n process.stderr.write(chalk.dim(` Available models: ${models.join(\", \")}\\n`));\n const defaultModel = models.includes(\"qwen2.5-coder:32b\") ? \"qwen2.5-coder:32b\" : models[0];\n const modelAnswer = await rl.question(\n ` Model [${chalk.bold(defaultModel)}]: `,\n );\n config.model = modelAnswer.trim() || defaultModel;\n }\n }\n\n const needsKey = ![\"bedrock\", \"vertex\", \"ollama\"].includes(picked);\n let apiKey: string | undefined;\n if (needsKey) {\n const keyAnswer = await rl.question(` API key: `);\n apiKey = keyAnswer.trim();\n if (!apiKey) {\n process.stderr.write(chalk.red(\"API key is required.\\n\"));\n process.exit(1);\n }\n }\n\n rl.close();\n config.provider = picked;\n if (apiKey) config.apiKey = apiKey;\n } catch {\n rl.close();\n process.exit(1);\n }\n\n return runAgent(config);\n }\n\n if (!config.model) {\n const { DEFAULT_MODELS } = await import(\"./provider-factory.js\");\n if (providerName === \"ollama\") {\n const { ollamaBaseURL } = await import(\"./provider-factory.js\");\n const models = await listLocalOllamaModels(ollamaBaseURL());\n const preferred = DEFAULT_MODELS[providerName];\n config.model = models.includes(preferred) ? preferred : models[0] ?? preferred;\n } else {\n config.model = DEFAULT_MODELS[providerName];\n }\n }\n\n const provider = await createProvider(providerName, {\n apiKey: config.apiKey,\n model: config.model,\n baseURL: config.baseURL,\n });\n\n const thinking = parseThinking(config.thinking);\n const permissionMode = (config.permissions ?? \"default\") as PermissionMode;\n\n const agent = new Agent({\n provider: provider,\n sandbox: createCliSandbox(config),\n options: {\n cwd: config.cwd,\n model: config.model,\n systemPrompt: config.systemPrompt,\n permissions: {\n mode: permissionMode,\n },\n thinking,\n autoCompact: config.autoCompact ?? true,\n enableSubagents: config.enableSubagents ?? true,\n enableTasks: config.enableTasks ?? false,\n enablePlanMode: config.enablePlanMode ?? true,\n enableWorktrees: config.enableWorktrees ?? false,\n mcpServers: config.mcpServers,\n lsp: config.lsp,\n hooks: config.hooks,\n webSearch: config.webSearch,\n ...(config.sessionDir ? { sessionDir: config.sessionDir } : {}),\n ...(config.dotDirs ? { dotDirs: config.dotDirs } : {}),\n projectContext: { cwd: config.cwd, homeDir: os.homedir() },\n costTracking: { enabled: true },\n retry: true,\n },\n });\n\n if (config.headless) {\n const { runHeadless } = await import(\"./headless.js\");\n await runHeadless(agent, config);\n return;\n }\n\n await agent.init();\n\n try {\n if (config.prompt) {\n await runOneShot(agent, config);\n } else {\n if (!process.stdin.isTTY) {\n process.stderr.write(\n chalk.red(\"Interactive mode requires a TTY. Use -c or pipe input.\\n\"),\n );\n process.exit(1);\n }\n await startRepl(agent, config, () => agent.close());\n }\n } finally {\n await agent.close();\n }\n}\n\nasync function runOneShot(agent: Agent, config: MergedConfig): Promise<void> {\n const { startSpinner } = await import(\"./spinner.js\");\n const { isVisibleEvent } = await import(\"./render.js\");\n const thread = await agent.createThread();\n const state = createRenderState();\n const runOpts = config.maxTurns ? { maxTurns: config.maxTurns } : undefined;\n\n const spinner =\n !config.json && !config.quiet ? startSpinner(\"Thinking\") : null;\n\n try {\n for await (const event of thread.run(config.prompt!, runOpts)) {\n if (!state.showedActivity && spinner && isVisibleEvent(event, config)) {\n spinner.stop();\n state.showedActivity = true;\n }\n renderEvent(event, config, state);\n }\n } finally {\n spinner?.stop();\n }\n\n if (config.quiet && state.accumulatedText) {\n process.stdout.write(state.accumulatedText);\n if (!state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n } else if (state.accumulatedText && !state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n}\n\nasync function listSessions(): Promise<void> {\n const cwd = process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, { cwd });\n\n const providerName: ProviderName | undefined = (merged.provider as ProviderName | undefined) ?? await detectProvider();\n if (!providerName) {\n process.stderr.write(chalk.red(\"No provider configured. Run `noumen init` first.\\n\"));\n process.exit(1);\n }\n\n const provider = await createProvider(providerName, {\n apiKey: merged.apiKey,\n model: merged.model,\n baseURL: merged.baseURL,\n });\n\n const agent = new Agent({\n provider: provider,\n sandbox: UnsandboxedLocal({ cwd }),\n options: {\n cwd,\n ...(merged.sessionDir ? { sessionDir: merged.sessionDir } : {}),\n ...(merged.dotDirs ? { dotDirs: merged.dotDirs } : {}),\n },\n });\n\n const sessions = await agent.listSessions();\n if (sessions.length === 0) {\n process.stdout.write(chalk.dim(\"No saved sessions.\\n\"));\n return;\n }\n\n process.stdout.write(chalk.bold(\"Sessions:\\n\"));\n for (const s of sessions) {\n const title = s.title ? chalk.white(` ${s.title}`) : \"\";\n process.stdout.write(\n ` ${chalk.cyan(s.sessionId.slice(0, 8))} ${chalk.dim(s.createdAt)} ${chalk.dim(`${s.messageCount} msgs`)}${title}\\n`,\n );\n }\n}\n\nasync function resumeSession(sessionId: string): Promise<void> {\n const cwd = process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, { cwd });\n\n const providerName: ProviderName | undefined = (merged.provider as ProviderName | undefined) ?? await detectProvider();\n if (!providerName) {\n process.stderr.write(chalk.red(\"No provider configured. Run `noumen init` first.\\n\"));\n process.exit(1);\n }\n\n const provider = await createProvider(providerName, {\n apiKey: merged.apiKey,\n model: merged.model,\n baseURL: merged.baseURL,\n });\n\n const thinking = parseThinking(merged.thinking);\n const permissionMode = (merged.permissions ?? \"default\") as PermissionMode;\n\n const agent = new Agent({\n provider: provider,\n sandbox: createCliSandbox(merged),\n options: {\n cwd,\n model: merged.model,\n permissions: { mode: permissionMode },\n thinking,\n autoCompact: merged.autoCompact ?? true,\n enableSubagents: merged.enableSubagents ?? true,\n enablePlanMode: merged.enablePlanMode ?? true,\n mcpServers: merged.mcpServers,\n lsp: merged.lsp,\n hooks: merged.hooks,\n ...(merged.sessionDir ? { sessionDir: merged.sessionDir } : {}),\n ...(merged.dotDirs ? { dotDirs: merged.dotDirs } : {}),\n projectContext: { cwd, homeDir: os.homedir() },\n costTracking: { enabled: true },\n retry: true,\n },\n });\n\n await agent.init();\n\n // Match full session ID from partial prefix\n const sessions = await agent.listSessions();\n const match = sessions.find(\n (s) => s.sessionId === sessionId || s.sessionId.startsWith(sessionId),\n );\n\n if (!match) {\n process.stderr.write(chalk.red(`Session not found: ${sessionId}\\n`));\n process.exit(1);\n }\n\n process.stderr.write(\n chalk.dim(`Resuming session ${match.sessionId.slice(0, 8)}...\\n\\n`),\n );\n\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr, terminal: true });\n\n const thread = await agent.resumeThread(match.sessionId);\n\n // Enter REPL with the resumed thread\n const { renderEvent: render, createRenderState: makeState } = await import(\"./render.js\");\n\n process.stderr.write(chalk.dim(\"Session resumed. Type a message to continue.\\n\\n\"));\n\n try {\n while (true) {\n let input: string;\n try {\n input = await rl.question(chalk.blue(\"> \"));\n } catch {\n break;\n }\n if (!input.trim()) continue;\n if (input.trim() === \"/quit\" || input.trim() === \"/exit\") break;\n\n const state = makeState();\n for await (const event of thread.run(input)) {\n render(event, merged, state);\n }\n if (state.accumulatedText && !state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n }\n } finally {\n rl.close();\n await agent.close();\n }\n}\n\nasync function runDoctor(): Promise<void> {\n const cwd = process.cwd();\n const config = loadCliConfig(cwd);\n const merged = mergeConfig(config, { cwd });\n\n const providerName: ProviderName | undefined = (merged.provider as ProviderName | undefined) ?? await detectProvider();\n if (!providerName) {\n process.stderr.write(chalk.red(\"No provider configured. Run `noumen init` first.\\n\"));\n process.exit(1);\n }\n\n const provider = await createProvider(providerName, {\n apiKey: merged.apiKey,\n model: merged.model,\n baseURL: merged.baseURL,\n });\n\n const agent = new Agent({\n provider: provider,\n sandbox: createCliSandbox(merged),\n options: {\n cwd,\n model: merged.model,\n mcpServers: merged.mcpServers,\n lsp: merged.lsp,\n ...(merged.sessionDir ? { sessionDir: merged.sessionDir } : {}),\n ...(merged.dotDirs ? { dotDirs: merged.dotDirs } : {}),\n },\n });\n\n await agent.init();\n\n process.stderr.write(chalk.bold(\"\\nnoumen doctor\\n\\n\"));\n const result = await agent.diagnose();\n printDiagnoseResult(result);\n await agent.close();\n process.exit(result.overall ? 0 : 1);\n}\n\nfunction formatCheckLine(label: string, check: DiagnoseCheckResult, extra?: string): string {\n const icon = check.ok ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const timing = check.latencyMs > 0 ? chalk.dim(` (${check.latencyMs}ms)`) : \"\";\n const suffix = extra ? chalk.dim(` ${extra}`) : \"\";\n const errMsg = check.error ? chalk.red(` ${check.error}`) : \"\";\n const warnMsg = !check.error && check.warning ? chalk.yellow(` ${check.warning}`) : \"\";\n return ` ${icon} ${label}${timing}${suffix}${errMsg}${warnMsg}\\n`;\n}\n\nfunction printDiagnoseResult(r: DiagnoseResult): void {\n const modelLabel = r.provider.model ? ` (${r.provider.model})` : \"\";\n process.stderr.write(formatCheckLine(`Provider${modelLabel}`, r.provider));\n process.stderr.write(formatCheckLine(\"Sandbox: filesystem\", r.sandbox.fs));\n process.stderr.write(formatCheckLine(\"Sandbox: shell\", r.sandbox.computer));\n process.stderr.write(formatCheckLine(\n \"Sandbox: OS-level (sandbox-runtime)\",\n r.sandboxRuntime,\n r.sandboxRuntime.platform,\n ));\n\n for (const [name, check] of Object.entries(r.mcp)) {\n const parts: string[] = [];\n if (check.status) parts.push(check.status);\n if (check.toolCount != null) parts.push(`${check.toolCount} tools`);\n const extra = parts.length ? parts.join(\", \") : undefined;\n process.stderr.write(formatCheckLine(`MCP: ${name}`, check, extra));\n }\n\n for (const [name, check] of Object.entries(r.lsp)) {\n const extra = check.state ?? undefined;\n process.stderr.write(formatCheckLine(`LSP: ${name}`, check, extra));\n }\n\n process.stderr.write(\"\\n\");\n if (r.overall) {\n process.stderr.write(` ${chalk.green(\"Overall: healthy\")}\\n\\n`);\n } else {\n process.stderr.write(` ${chalk.red(\"Overall: unhealthy\")}\\n\\n`);\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(chalk.red(`Fatal: ${err.message}\\n`));\n process.exit(1);\n});\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport type { McpServerConfig } from \"../mcp/types.js\";\nimport type { LspServerConfig } from \"../lsp/types.js\";\nimport type { HookDefinition } from \"../hooks/types.js\";\nimport type { WebSearchConfig } from \"../tools/web-search.js\";\nimport {\n DEFAULT_DOT_DIRS,\n createDotDirResolver,\n type DotDirConfig,\n type DotDirResolver,\n} from \"../config/dot-dirs.js\";\n\nexport interface CliConfig {\n provider?: string;\n model?: string;\n apiKey?: string;\n baseURL?: string;\n permissions?: string;\n thinking?: string;\n sandbox?: string;\n mcpServers?: Record<string, McpServerConfig>;\n lsp?: Record<string, LspServerConfig>;\n hooks?: HookDefinition[];\n autoCompact?: boolean;\n enableSubagents?: boolean;\n enableTasks?: boolean;\n enablePlanMode?: boolean;\n enableWorktrees?: boolean;\n webSearch?: WebSearchConfig;\n costLimit?: number;\n maxTurns?: number;\n systemPrompt?: string;\n sessionDir?: string;\n /**\n * Dot-directory configuration for the CLI. Controls which hidden\n * directories are read for config and written to on init.\n */\n dotDirs?: DotDirConfig;\n}\n\n/**\n * First-hit-wins read of `<base>/<dotdir>/<rel>` across the resolver's\n * candidate dirs. Returns parsed JSON or `null` if none found.\n */\nfunction readFirstJson(resolver: DotDirResolver, base: string, rel: string): CliConfig | null {\n for (const candidate of resolver.joinRead(base, rel)) {\n try {\n const raw = fs.readFileSync(candidate, \"utf-8\");\n return JSON.parse(raw) as CliConfig;\n } catch {\n // keep walking\n }\n }\n return null;\n}\n\n/**\n * Bootstrap resolver for the initial config load. We read global config\n * first to discover any `dotDirs` override, then rebuild the resolver and\n * reload. This lets users put `{ \"dotDirs\": { \"names\": [\".custom\"] } }`\n * in a default location (`.noumen/config.json`) to reroute everything.\n */\nfunction resolverFromConfigs(...configs: CliConfig[]): DotDirResolver {\n for (const cfg of configs) {\n if (cfg.dotDirs) return createDotDirResolver(cfg.dotDirs);\n }\n return createDotDirResolver(DEFAULT_DOT_DIRS);\n}\n\n/**\n * Load global config from the first hit across `~/<dotdir>/config.json`\n * candidates. Returns empty object if not found or invalid.\n */\nexport function loadGlobalConfig(resolver?: DotDirResolver): CliConfig {\n const r = resolver ?? createDotDirResolver(DEFAULT_DOT_DIRS);\n return readFirstJson(r, os.homedir(), \"config.json\") ?? {};\n}\n\n/**\n * Walk up from `cwd` looking for `<ancestor>/<dotdir>/config.json`. At\n * each ancestor, all candidate dot-dirs are probed in preference order\n * before moving up. Returns parsed config or empty object if none found.\n */\nfunction loadProjectConfig(cwd: string, resolver?: DotDirResolver): CliConfig {\n const r = resolver ?? createDotDirResolver(DEFAULT_DOT_DIRS);\n let dir = path.resolve(cwd);\n const root = path.parse(dir).root;\n\n while (true) {\n const hit = readFirstJson(r, dir, \"config.json\");\n if (hit) return hit;\n const parent = path.dirname(dir);\n if (parent === dir || dir === root) break;\n dir = parent;\n }\n\n return {};\n}\n\n/**\n * Load config with layering: global (home scope) < project < flags. If\n * either layer specifies a `dotDirs` override, that override is used for\n * any subsequent reads. Project-level values override global values.\n */\nexport function loadCliConfig(cwd: string): CliConfig {\n // Phase 1: probe with default resolver so we can discover dotDirs overrides.\n const bootstrapResolver = createDotDirResolver(DEFAULT_DOT_DIRS);\n const globalBootstrap = loadGlobalConfig(bootstrapResolver);\n const projectBootstrap = loadProjectConfig(cwd, bootstrapResolver);\n\n // Phase 2: if any layer declared dotDirs, rebuild the resolver and reload.\n const override = projectBootstrap.dotDirs ?? globalBootstrap.dotDirs;\n if (override) {\n const resolver = createDotDirResolver(override);\n const global = loadGlobalConfig(resolver);\n const project = loadProjectConfig(cwd, resolver);\n return { ...global, ...project };\n }\n\n return { ...globalBootstrap, ...projectBootstrap };\n}\n\n/**\n * Resolve the CLI dot-dir resolver after layering. Used by code paths\n * that need to write (e.g. init) or locate auxiliary dirs.\n */\nexport function resolveCliDotDirs(config: CliConfig): DotDirResolver {\n return resolverFromConfigs(config);\n}\n\nexport interface MergedConfig extends CliConfig {\n cwd: string;\n json?: boolean;\n quiet?: boolean;\n verbose?: boolean;\n headless?: boolean;\n prompt?: string;\n noSandbox?: boolean;\n sandboxAllowWrite?: string;\n sandboxAllowDomain?: string;\n}\n\n/**\n * Merge CLI flags over the config file values. Flags take precedence.\n */\nexport function mergeConfig(\n config: CliConfig,\n flags: Record<string, unknown>,\n): MergedConfig {\n const cwd = (flags.cwd as string) ?? process.cwd();\n return {\n ...config,\n ...(flags.provider !== undefined && { provider: flags.provider as string }),\n ...(flags.model !== undefined && { model: flags.model as string }),\n ...(flags.apiKey !== undefined && { apiKey: flags.apiKey as string }),\n ...(flags.baseUrl !== undefined && { baseURL: flags.baseUrl as string }),\n ...(flags.permission !== undefined && { permissions: flags.permission as string }),\n ...(flags.thinking !== undefined && { thinking: flags.thinking as string }),\n ...(flags.maxTurns !== undefined && { maxTurns: flags.maxTurns as number }),\n ...(flags.systemPrompt !== undefined && { systemPrompt: flags.systemPrompt as string }),\n cwd,\n json: flags.json as boolean | undefined,\n quiet: flags.quiet as boolean | undefined,\n verbose: flags.verbose as boolean | undefined,\n headless: flags.headless as boolean | undefined,\n prompt: flags.prompt as string | undefined,\n noSandbox: flags.sandbox === false ? true : undefined,\n sandboxAllowWrite: flags.sandboxAllowWrite as string | undefined,\n sandboxAllowDomain: flags.sandboxAllowDomain as string | undefined,\n };\n}\n","import * as readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport type { Agent } from \"../agent.js\";\nimport type { Thread } from \"../thread.js\";\nimport type { MergedConfig } from \"./config.js\";\nimport { renderEvent, createRenderState, promptPermission, isVisibleEvent } from \"./render.js\";\nimport { DEFAULT_MODELS, createProvider, SUPPORTED_PROVIDERS, type ProviderName } from \"./provider-factory.js\";\nimport { startSpinner } from \"./spinner.js\";\n\nexport async function startRepl(\n code: Agent,\n config: MergedConfig,\n cleanup?: () => Promise<void>,\n): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n terminal: true,\n });\n\n let thread = await code.createThread({\n userInputHandler: (q) => promptPermission(rl, \"agent\", q).then((ok) => ok ? \"yes\" : \"no\"),\n });\n\n let runningTurn = false;\n let currentThread: Thread = thread;\n\n const sigintHandler = () => {\n if (runningTurn) {\n currentThread.abort();\n runningTurn = false;\n process.stderr.write(chalk.yellow(\"\\n Cancelled.\\n\\n\"));\n } else {\n process.stderr.write(chalk.dim(\"\\nGoodbye.\\n\"));\n rl.close();\n cleanup?.().catch(() => {}).finally(() => process.exit(0));\n }\n };\n process.on(\"SIGINT\", sigintHandler);\n\n printWelcome(config);\n\n try {\n while (true) {\n let input: string;\n try {\n input = await rl.question(chalk.blue(\"> \"));\n } catch {\n break;\n }\n\n if (!input.trim()) continue;\n\n if (input.startsWith(\"/\")) {\n const result = await handleSlashCommand(\n input,\n thread,\n code,\n config,\n rl,\n );\n if (result === \"quit\") break;\n if (result === \"new\") {\n thread = await code.createThread({\n userInputHandler: (q) => promptPermission(rl, \"agent\", q).then((ok) => ok ? \"yes\" : \"no\"),\n });\n currentThread = thread;\n }\n continue;\n }\n\n const state = createRenderState();\n const runOpts = config.maxTurns ? { maxTurns: config.maxTurns } : undefined;\n\n const spinner =\n !config.json && !config.quiet ? startSpinner(\"Thinking\") : null;\n\n runningTurn = true;\n try {\n for await (const event of thread.run(input, runOpts)) {\n if (!state.showedActivity && spinner && isVisibleEvent(event, config)) {\n spinner.stop();\n state.showedActivity = true;\n }\n renderEvent(event, config, state);\n }\n } catch (err) {\n if ((err as Error)?.name === \"AbortError\") {\n // already handled by SIGINT handler\n } else {\n throw err;\n }\n } finally {\n spinner?.stop();\n runningTurn = false;\n }\n\n if (state.accumulatedText && !state.accumulatedText.endsWith(\"\\n\")) {\n process.stdout.write(\"\\n\");\n }\n }\n } finally {\n process.removeListener(\"SIGINT\", sigintHandler);\n rl.close();\n }\n}\n\nfunction printWelcome(config: MergedConfig): void {\n const provider = config.provider ?? \"auto\";\n const model = config.model ?? DEFAULT_MODELS[provider] ?? \"default\";\n process.stderr.write(\n chalk.bold(\"noumen\") +\n chalk.dim(` — ${provider}/${model}`) +\n \"\\n\" +\n chalk.dim(\"Type a message to begin. /help for commands, Ctrl+C to cancel.\") +\n \"\\n\\n\",\n );\n}\n\ntype SlashResult = \"continue\" | \"quit\" | \"new\";\n\nasync function handleSlashCommand(\n input: string,\n thread: Thread,\n code: Agent,\n config: MergedConfig,\n _rl: readline.Interface,\n): Promise<SlashResult> {\n const [cmd] = input.trim().split(/\\s+/);\n\n switch (cmd) {\n case \"/quit\":\n case \"/exit\":\n case \"/q\":\n process.stderr.write(chalk.dim(\"Goodbye.\\n\"));\n return \"quit\";\n\n case \"/new\":\n process.stderr.write(chalk.dim(\"Starting new conversation.\\n\\n\"));\n return \"new\";\n\n case \"/session\":\n process.stderr.write(chalk.dim(`Session: ${thread.sessionId}\\n`));\n return \"continue\";\n\n case \"/cost\": {\n const summary = code.getCostSummary();\n if (summary) {\n process.stderr.write(\n chalk.dim(\n `Cost: $${summary.totalCostUSD.toFixed(4)} | ` +\n `Input: ${summary.totalInputTokens} tokens | ` +\n `Output: ${summary.totalOutputTokens} tokens\\n`,\n ),\n );\n } else {\n process.stderr.write(chalk.dim(\"Cost tracking not enabled.\\n\"));\n }\n return \"continue\";\n }\n\n case \"/sessions\": {\n const sessions = await code.listSessions();\n if (sessions.length === 0) {\n process.stderr.write(chalk.dim(\"No saved sessions.\\n\"));\n } else {\n for (const s of sessions.slice(0, 20)) {\n process.stderr.write(\n chalk.dim(\n ` ${s.sessionId.slice(0, 8)} ${s.createdAt ?? \"\"} ${s.messageCount ?? 0} messages\\n`,\n ),\n );\n }\n }\n return \"continue\";\n }\n\n case \"/model\": {\n const arg = input.trim().split(/\\s+/).slice(1).join(\" \");\n if (!arg) {\n process.stderr.write(chalk.dim(`Current model: ${thread.getModel()}\\n`));\n } else {\n thread.setModel(arg);\n process.stderr.write(chalk.dim(`Model set to ${arg}\\n`));\n }\n return \"continue\";\n }\n\n case \"/provider\": {\n const parts = input.trim().split(/\\s+/).slice(1);\n const providerName = parts[0];\n const modelArg = parts[1];\n if (!providerName) {\n process.stderr.write(\n chalk.dim(`Current: ${config.provider ?? \"auto\"}/${thread.getModel()}\\n`) +\n chalk.dim(`Available: ${SUPPORTED_PROVIDERS.join(\", \")}\\n`),\n );\n return \"continue\";\n }\n if (!(SUPPORTED_PROVIDERS as readonly string[]).includes(providerName)) {\n process.stderr.write(chalk.red(`Unknown provider: ${providerName}. Available: ${SUPPORTED_PROVIDERS.join(\", \")}\\n`));\n return \"continue\";\n }\n try {\n const model = modelArg ?? DEFAULT_MODELS[providerName];\n const provider = await createProvider(providerName as ProviderName, {\n apiKey: config.apiKey,\n model,\n baseURL: config.baseURL,\n });\n thread.setProvider(provider, model);\n config.provider = providerName;\n config.model = model;\n process.stderr.write(chalk.dim(`Switched to ${providerName}/${model}\\n`));\n } catch (err) {\n process.stderr.write(chalk.red(`Failed to switch: ${(err as Error).message}\\n`));\n }\n return \"continue\";\n }\n\n case \"/verbose\":\n config.verbose = !config.verbose;\n process.stderr.write(\n chalk.dim(`Verbose mode: ${config.verbose ? \"on\" : \"off\"}\\n`),\n );\n return \"continue\";\n\n case \"/help\":\n process.stderr.write(\n chalk.dim(\n [\n \"Commands:\",\n \" /quit, /exit Exit the REPL\",\n \" /new Start a new conversation\",\n \" /model [name] Show or change the model\",\n \" /provider [name] Show or switch provider (and model)\",\n \" /session Show current session ID\",\n \" /sessions List saved sessions\",\n \" /cost Show token usage and cost\",\n \" /verbose Toggle verbose output\",\n \" /help Show this help\",\n \"\",\n \"Shortcuts:\",\n \" Ctrl+C Cancel current turn / exit when idle\",\n \"\",\n ].join(\"\\n\"),\n ),\n );\n return \"continue\";\n\n default:\n process.stderr.write(\n chalk.yellow(`Unknown command: ${cmd}. Try /help\\n`),\n );\n return \"continue\";\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { SUPPORTED_PROVIDERS, DEFAULT_MODELS, isOllamaRunning, ollamaBaseURL } from \"./provider-factory.js\";\nimport { loadCliConfig, resolveCliDotDirs } from \"./config.js\";\n\nconst PERMISSION_MODES = [\"default\", \"plan\", \"acceptEdits\", \"auto\", \"bypassPermissions\"];\n\nexport async function runInit(): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n try {\n process.stdout.write(chalk.bold(\"noumen init\") + \"\\n\\n\");\n\n const provider = await askChoice(\n rl,\n \"Provider\",\n SUPPORTED_PROVIDERS,\n \"anthropic\",\n );\n\n let defaultModel = DEFAULT_MODELS[provider] ?? \"\";\n\n if (provider === \"ollama\") {\n const ollamaModels = await listOllamaModels();\n if (ollamaModels.length > 0) {\n process.stdout.write(chalk.dim(` Available models: ${ollamaModels.join(\", \")}\\n`));\n if (ollamaModels.includes(defaultModel)) {\n // keep the default\n } else {\n defaultModel = ollamaModels[0];\n }\n } else {\n process.stdout.write(\n chalk.yellow(\n `\\n Ollama doesn't appear to be running at ${ollamaBaseURL()}.\\n` +\n ` Install it from https://ollama.com, then run:\\n` +\n ` ollama pull ${defaultModel}\\n` +\n ` ollama serve\\n\\n`,\n ),\n );\n }\n }\n\n const model = await askDefault(rl, \"Model\", defaultModel);\n\n const permissions = await askChoice(\n rl,\n \"Permission mode\",\n PERMISSION_MODES,\n \"default\",\n );\n\n const config: Record<string, unknown> = { provider };\n if (model !== defaultModel) config.model = model;\n if (permissions !== \"default\") config.permissions = permissions;\n\n const existing = loadCliConfig(process.cwd());\n const resolver = resolveCliDotDirs(existing);\n const dir = resolver.writePath(process.cwd());\n fs.mkdirSync(dir, { recursive: true });\n\n const configPath = path.join(dir, \"config.json\");\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\");\n process.stdout.write(chalk.green(` Created ${configPath}\\n`));\n\n const noumenMdPath = path.join(process.cwd(), \"NOUMEN.md\");\n if (!fs.existsSync(noumenMdPath)) {\n const create = await askDefault(rl, \"Create NOUMEN.md?\", \"Y\");\n if (create.toLowerCase() === \"y\" || create.toLowerCase() === \"yes\") {\n fs.writeFileSync(noumenMdPath, NOUMEN_MD_TEMPLATE);\n process.stdout.write(chalk.green(` Created ${noumenMdPath}\\n`));\n }\n }\n\n process.stdout.write(\n \"\\n\" + chalk.dim(\"Run `noumen` to start a session.\") + \"\\n\",\n );\n } finally {\n rl.close();\n }\n}\n\nasync function listOllamaModels(): Promise<string[]> {\n if (!(await isOllamaRunning())) return [];\n try {\n const res = await fetch(`${ollamaBaseURL()}/api/tags`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) return [];\n const data = (await res.json()) as { models?: Array<{ name: string }> };\n return (data.models ?? []).map((m) => m.name);\n } catch {\n return [];\n }\n}\n\nasync function askChoice(\n rl: readline.Interface,\n label: string,\n choices: string[],\n defaultValue: string,\n): Promise<string> {\n const hint = choices.join(\", \");\n const answer = await rl.question(\n ` ${label} (${hint}) [${chalk.bold(defaultValue)}]: `,\n );\n const trimmed = answer.trim();\n if (!trimmed) return defaultValue;\n if (choices.includes(trimmed)) return trimmed;\n process.stdout.write(chalk.yellow(` Invalid choice, using ${defaultValue}\\n`));\n return defaultValue;\n}\n\nasync function askDefault(\n rl: readline.Interface,\n label: string,\n defaultValue: string,\n): Promise<string> {\n const answer = await rl.question(\n ` ${label} [${chalk.bold(defaultValue)}]: `,\n );\n return answer.trim() || defaultValue;\n}\n\nconst NOUMEN_MD_TEMPLATE = `# Project Instructions\n\nAdd project-specific instructions for the AI agent here.\nThese instructions are loaded automatically when running noumen in this directory.\n\n## Guidelines\n\n- Describe your project's coding conventions\n- Note important architectural decisions\n- List files or patterns the agent should be aware of\n`;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAS,eAAe;AACxB,OAAOA,YAAW;;;ACHlB,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AA4CpB,SAAS,cAAc,UAA0B,MAAc,KAA+B;AAC5F,aAAW,aAAa,SAAS,SAAS,MAAM,GAAG,GAAG;AACpD,QAAI;AACF,YAAM,MAAS,gBAAa,WAAW,OAAO;AAC9C,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,uBAAuB,SAAsC;AACpE,aAAW,OAAO,SAAS;AACzB,QAAI,IAAI,QAAS,QAAO,qBAAqB,IAAI,OAAO;AAAA,EAC1D;AACA,SAAO,qBAAqB,gBAAgB;AAC9C;AAMO,SAAS,iBAAiB,UAAsC;AACrE,QAAM,IAAI,YAAY,qBAAqB,gBAAgB;AAC3D,SAAO,cAAc,GAAM,WAAQ,GAAG,aAAa,KAAK,CAAC;AAC3D;AAOA,SAAS,kBAAkB,KAAa,UAAsC;AAC5E,QAAM,IAAI,YAAY,qBAAqB,gBAAgB;AAC3D,MAAI,MAAW,aAAQ,GAAG;AAC1B,QAAM,OAAY,WAAM,GAAG,EAAE;AAE7B,SAAO,MAAM;AACX,UAAM,MAAM,cAAc,GAAG,KAAK,aAAa;AAC/C,QAAI,IAAK,QAAO;AAChB,UAAM,SAAc,aAAQ,GAAG;AAC/B,QAAI,WAAW,OAAO,QAAQ,KAAM;AACpC,UAAM;AAAA,EACR;AAEA,SAAO,CAAC;AACV;AAOO,SAAS,cAAc,KAAwB;AAEpD,QAAM,oBAAoB,qBAAqB,gBAAgB;AAC/D,QAAM,kBAAkB,iBAAiB,iBAAiB;AAC1D,QAAM,mBAAmB,kBAAkB,KAAK,iBAAiB;AAGjE,QAAM,WAAW,iBAAiB,WAAW,gBAAgB;AAC7D,MAAI,UAAU;AACZ,UAAM,WAAW,qBAAqB,QAAQ;AAC9C,UAAM,SAAS,iBAAiB,QAAQ;AACxC,UAAM,UAAU,kBAAkB,KAAK,QAAQ;AAC/C,WAAO,EAAE,GAAG,QAAQ,GAAG,QAAQ;AAAA,EACjC;AAEA,SAAO,EAAE,GAAG,iBAAiB,GAAG,iBAAiB;AACnD;AAMO,SAAS,kBAAkB,QAAmC;AACnE,SAAO,oBAAoB,MAAM;AACnC;AAiBO,SAAS,YACd,QACA,OACc;AACd,QAAM,MAAO,MAAM,OAAkB,QAAQ,IAAI;AACjD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,MAAM,aAAa,UAAa,EAAE,UAAU,MAAM,SAAmB;AAAA,IACzE,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAgB;AAAA,IAChE,GAAI,MAAM,WAAW,UAAa,EAAE,QAAQ,MAAM,OAAiB;AAAA,IACnE,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAkB;AAAA,IACtE,GAAI,MAAM,eAAe,UAAa,EAAE,aAAa,MAAM,WAAqB;AAAA,IAChF,GAAI,MAAM,aAAa,UAAa,EAAE,UAAU,MAAM,SAAmB;AAAA,IACzE,GAAI,MAAM,aAAa,UAAa,EAAE,UAAU,MAAM,SAAmB;AAAA,IACzE,GAAI,MAAM,iBAAiB,UAAa,EAAE,cAAc,MAAM,aAAuB;AAAA,IACrF;AAAA,IACA,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM;AAAA,IACb,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,QAAQ,MAAM;AAAA,IACd,WAAW,MAAM,YAAY,QAAQ,OAAO;AAAA,IAC5C,mBAAmB,MAAM;AAAA,IACzB,oBAAoB,MAAM;AAAA,EAC5B;AACF;;;AC5KA,YAAY,cAAc;AAC1B,OAAO,WAAW;AAQlB,eAAsB,UACpB,MACA,QACA,SACe;AACf,QAAM,KAAc,yBAAgB;AAAA,IAClC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,UAAU;AAAA,EACZ,CAAC;AAED,MAAI,SAAS,MAAM,KAAK,aAAa;AAAA,IACnC,kBAAkB,CAAC,MAAM,iBAAiB,IAAI,SAAS,CAAC,EAAE,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI;AAAA,EAC1F,CAAC;AAED,MAAI,cAAc;AAClB,MAAI,gBAAwB;AAE5B,QAAM,gBAAgB,MAAM;AAC1B,QAAI,aAAa;AACf,oBAAc,MAAM;AACpB,oBAAc;AACd,cAAQ,OAAO,MAAM,MAAM,OAAO,oBAAoB,CAAC;AAAA,IACzD,OAAO;AACL,cAAQ,OAAO,MAAM,MAAM,IAAI,cAAc,CAAC;AAC9C,SAAG,MAAM;AACT,gBAAU,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC,EAAE,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC;AAAA,IAC3D;AAAA,EACF;AACA,UAAQ,GAAG,UAAU,aAAa;AAElC,eAAa,MAAM;AAEnB,MAAI;AACF,WAAO,MAAM;AACX,UAAI;AACJ,UAAI;AACF,gBAAQ,MAAM,GAAG,SAAS,MAAM,KAAK,IAAI,CAAC;AAAA,MAC5C,QAAQ;AACN;AAAA,MACF;AAEA,UAAI,CAAC,MAAM,KAAK,EAAG;AAEnB,UAAI,MAAM,WAAW,GAAG,GAAG;AACzB,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,WAAW,OAAQ;AACvB,YAAI,WAAW,OAAO;AACpB,mBAAS,MAAM,KAAK,aAAa;AAAA,YAC/B,kBAAkB,CAAC,MAAM,iBAAiB,IAAI,SAAS,CAAC,EAAE,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI;AAAA,UAC1F,CAAC;AACD,0BAAgB;AAAA,QAClB;AACA;AAAA,MACF;AAEA,YAAM,QAAQ,kBAAkB;AAChC,YAAM,UAAU,OAAO,WAAW,EAAE,UAAU,OAAO,SAAS,IAAI;AAElE,YAAM,UACJ,CAAC,OAAO,QAAQ,CAAC,OAAO,QAAQ,aAAa,UAAU,IAAI;AAE7D,oBAAc;AACd,UAAI;AACF,yBAAiB,SAAS,OAAO,IAAI,OAAO,OAAO,GAAG;AACpD,cAAI,CAAC,MAAM,kBAAkB,WAAW,eAAe,OAAO,MAAM,GAAG;AACrE,oBAAQ,KAAK;AACb,kBAAM,iBAAiB;AAAA,UACzB;AACA,sBAAY,OAAO,QAAQ,KAAK;AAAA,QAClC;AAAA,MACF,SAAS,KAAK;AACZ,YAAK,KAAe,SAAS,cAAc;AAAA,QAE3C,OAAO;AACL,gBAAM;AAAA,QACR;AAAA,MACF,UAAE;AACA,iBAAS,KAAK;AACd,sBAAc;AAAA,MAChB;AAEA,UAAI,MAAM,mBAAmB,CAAC,MAAM,gBAAgB,SAAS,IAAI,GAAG;AAClE,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,UAAE;AACA,YAAQ,eAAe,UAAU,aAAa;AAC9C,OAAG,MAAM;AAAA,EACX;AACF;AAEA,SAAS,aAAa,QAA4B;AAChD,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,QAAQ,OAAO,SAAS,eAAe,QAAQ,KAAK;AAC1D,UAAQ,OAAO;AAAA,IACb,MAAM,KAAK,QAAQ,IACjB,MAAM,IAAI,WAAM,QAAQ,IAAI,KAAK,EAAE,IACnC,OACA,MAAM,IAAI,gEAAgE,IAC1E;AAAA,EACJ;AACF;AAIA,eAAe,mBACb,OACA,QACA,MACA,QACA,KACsB;AACtB,QAAM,CAAC,GAAG,IAAI,MAAM,KAAK,EAAE,MAAM,KAAK;AAEtC,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,OAAO,MAAM,MAAM,IAAI,YAAY,CAAC;AAC5C,aAAO;AAAA,IAET,KAAK;AACH,cAAQ,OAAO,MAAM,MAAM,IAAI,gCAAgC,CAAC;AAChE,aAAO;AAAA,IAET,KAAK;AACH,cAAQ,OAAO,MAAM,MAAM,IAAI,YAAY,OAAO,SAAS;AAAA,CAAI,CAAC;AAChE,aAAO;AAAA,IAET,KAAK,SAAS;AACZ,YAAM,UAAU,KAAK,eAAe;AACpC,UAAI,SAAS;AACX,gBAAQ,OAAO;AAAA,UACb,MAAM;AAAA,YACJ,UAAU,QAAQ,aAAa,QAAQ,CAAC,CAAC,aAC7B,QAAQ,gBAAgB,qBACvB,QAAQ,iBAAiB;AAAA;AAAA,UACxC;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ,OAAO,MAAM,MAAM,IAAI,8BAA8B,CAAC;AAAA,MAChE;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,WAAW,MAAM,KAAK,aAAa;AACzC,UAAI,SAAS,WAAW,GAAG;AACzB,gBAAQ,OAAO,MAAM,MAAM,IAAI,sBAAsB,CAAC;AAAA,MACxD,OAAO;AACL,mBAAW,KAAK,SAAS,MAAM,GAAG,EAAE,GAAG;AACrC,kBAAQ,OAAO;AAAA,YACb,MAAM;AAAA,cACJ,KAAK,EAAE,UAAU,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,gBAAgB,CAAC;AAAA;AAAA,YAC5E;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,UAAU;AACb,YAAM,MAAM,MAAM,KAAK,EAAE,MAAM,KAAK,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG;AACvD,UAAI,CAAC,KAAK;AACR,gBAAQ,OAAO,MAAM,MAAM,IAAI,kBAAkB,OAAO,SAAS,CAAC;AAAA,CAAI,CAAC;AAAA,MACzE,OAAO;AACL,eAAO,SAAS,GAAG;AACnB,gBAAQ,OAAO,MAAM,MAAM,IAAI,gBAAgB,GAAG;AAAA,CAAI,CAAC;AAAA,MACzD;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,QAAQ,MAAM,KAAK,EAAE,MAAM,KAAK,EAAE,MAAM,CAAC;AAC/C,YAAM,eAAe,MAAM,CAAC;AAC5B,YAAM,WAAW,MAAM,CAAC;AACxB,UAAI,CAAC,cAAc;AACjB,gBAAQ,OAAO;AAAA,UACb,MAAM,IAAI,YAAY,OAAO,YAAY,MAAM,IAAI,OAAO,SAAS,CAAC;AAAA,CAAI,IACxE,MAAM,IAAI,cAAc,oBAAoB,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,QAC5D;AACA,eAAO;AAAA,MACT;AACA,UAAI,CAAE,oBAA0C,SAAS,YAAY,GAAG;AACtE,gBAAQ,OAAO,MAAM,MAAM,IAAI,qBAAqB,YAAY,gBAAgB,oBAAoB,KAAK,IAAI,CAAC;AAAA,CAAI,CAAC;AACnH,eAAO;AAAA,MACT;AACA,UAAI;AACF,cAAM,QAAQ,YAAY,eAAe,YAAY;AACrD,cAAM,WAAW,MAAM,gBAAe,cAA8B;AAAA,UAClE,QAAQ,OAAO;AAAA,UACf;AAAA,UACA,SAAS,OAAO;AAAA,QAClB,CAAC;AACD,eAAO,YAAY,UAAU,KAAK;AAClC,eAAO,WAAW;AAClB,eAAO,QAAQ;AACf,gBAAQ,OAAO,MAAM,MAAM,IAAI,eAAe,YAAY,IAAI,KAAK;AAAA,CAAI,CAAC;AAAA,MAC1E,SAAS,KAAK;AACZ,gBAAQ,OAAO,MAAM,MAAM,IAAI,qBAAsB,IAAc,OAAO;AAAA,CAAI,CAAC;AAAA,MACjF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AACH,aAAO,UAAU,CAAC,OAAO;AACzB,cAAQ,OAAO;AAAA,QACb,MAAM,IAAI,iBAAiB,OAAO,UAAU,OAAO,KAAK;AAAA,CAAI;AAAA,MAC9D;AACA,aAAO;AAAA,IAET,KAAK;AACH,cAAQ,OAAO;AAAA,QACb,MAAM;AAAA,UACJ;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,EAAE,KAAK,IAAI;AAAA,QACb;AAAA,MACF;AACA,aAAO;AAAA,IAET;AACE,cAAQ,OAAO;AAAA,QACb,MAAM,OAAO,oBAAoB,GAAG;AAAA,CAAe;AAAA,MACrD;AACA,aAAO;AAAA,EACX;AACF;;;AChQA,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AACtB,YAAYC,eAAc;AAC1B,OAAOC,YAAW;AAIlB,IAAM,mBAAmB,CAAC,WAAW,QAAQ,eAAe,QAAQ,mBAAmB;AAEvF,eAAsB,UAAyB;AAC7C,QAAM,KAAc,0BAAgB;AAAA,IAClC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,MAAI;AACF,YAAQ,OAAO,MAAMC,OAAM,KAAK,aAAa,IAAI,MAAM;AAEvD,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,eAAe,eAAe,QAAQ,KAAK;AAE/C,QAAI,aAAa,UAAU;AACzB,YAAM,eAAe,MAAM,iBAAiB;AAC5C,UAAI,aAAa,SAAS,GAAG;AAC3B,gBAAQ,OAAO,MAAMA,OAAM,IAAI,uBAAuB,aAAa,KAAK,IAAI,CAAC;AAAA,CAAI,CAAC;AAClF,YAAI,aAAa,SAAS,YAAY,GAAG;AAAA,QAEzC,OAAO;AACL,yBAAe,aAAa,CAAC;AAAA,QAC/B;AAAA,MACF,OAAO;AACL,gBAAQ,OAAO;AAAA,UACbA,OAAM;AAAA,YACJ;AAAA,2CAA8C,cAAc,CAAC;AAAA;AAAA,kBAE1C,YAAY;AAAA;AAAA;AAAA;AAAA,UAEjC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,WAAW,IAAI,SAAS,YAAY;AAExD,UAAM,cAAc,MAAM;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,SAAkC,EAAE,SAAS;AACnD,QAAI,UAAU,aAAc,QAAO,QAAQ;AAC3C,QAAI,gBAAgB,UAAW,QAAO,cAAc;AAEpD,UAAM,WAAW,cAAc,QAAQ,IAAI,CAAC;AAC5C,UAAM,WAAW,kBAAkB,QAAQ;AAC3C,UAAM,MAAM,SAAS,UAAU,QAAQ,IAAI,CAAC;AAC5C,IAAG,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAErC,UAAM,aAAkB,WAAK,KAAK,aAAa;AAC/C,IAAG,kBAAc,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,IAAI;AACnE,YAAQ,OAAO,MAAMA,OAAM,MAAM,aAAa,UAAU;AAAA,CAAI,CAAC;AAE7D,UAAM,eAAoB,WAAK,QAAQ,IAAI,GAAG,WAAW;AACzD,QAAI,CAAI,eAAW,YAAY,GAAG;AAChC,YAAM,SAAS,MAAM,WAAW,IAAI,qBAAqB,GAAG;AAC5D,UAAI,OAAO,YAAY,MAAM,OAAO,OAAO,YAAY,MAAM,OAAO;AAClE,QAAG,kBAAc,cAAc,kBAAkB;AACjD,gBAAQ,OAAO,MAAMA,OAAM,MAAM,aAAa,YAAY;AAAA,CAAI,CAAC;AAAA,MACjE;AAAA,IACF;AAEA,YAAQ,OAAO;AAAA,MACb,OAAOA,OAAM,IAAI,kCAAkC,IAAI;AAAA,IACzD;AAAA,EACF,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEA,eAAe,mBAAsC;AACnD,MAAI,CAAE,MAAM,gBAAgB,EAAI,QAAO,CAAC;AACxC,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa;AAAA,MACrD,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO,CAAC;AACrB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,YAAQ,KAAK,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EAC9C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAe,UACb,IACA,OACA,SACA,cACiB;AACjB,QAAM,OAAO,QAAQ,KAAK,IAAI;AAC9B,QAAM,SAAS,MAAM,GAAG;AAAA,IACtB,KAAK,KAAK,KAAK,IAAI,MAAMA,OAAM,KAAK,YAAY,CAAC;AAAA,EACnD;AACA,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,QAAQ,SAAS,OAAO,EAAG,QAAO;AACtC,UAAQ,OAAO,MAAMA,OAAM,OAAO,2BAA2B,YAAY;AAAA,CAAI,CAAC;AAC9E,SAAO;AACT;AAEA,eAAe,WACb,IACA,OACA,cACiB;AACjB,QAAM,SAAS,MAAM,GAAG;AAAA,IACtB,KAAK,KAAK,KAAKA,OAAM,KAAK,YAAY,CAAC;AAAA,EACzC;AACA,SAAO,OAAO,KAAK,KAAK;AAC1B;AAEA,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AHxH3B,YAAYC,SAAQ;AAOpB,IAAM,UAAU;AAEhB,eAAe,sBAAsB,SAAoC;AACvE,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,OAAO,aAAa;AAAA,MAC7C,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO,CAAC;AACrB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,YAAQ,KAAK,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EAC9C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,cAAc,OAAuD;AAC5E,MAAI,CAAC,SAAS,UAAU,MAAO,QAAO,EAAE,MAAM,WAAW;AACzD,QAAM,UAAkC;AAAA,IACtC,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACA,QAAM,SAAS,QAAQ,KAAK;AAC5B,MAAI,OAAQ,QAAO,EAAE,MAAM,WAAW,cAAc,OAAO;AAC3D,SAAO;AACT;AAMA,SAAS,iBAAiB,QAA+B;AACvD,MAAI,OAAO,WAAW;AACpB,WAAO,iBAAiB,EAAE,KAAK,OAAO,IAAI,CAAC;AAAA,EAC7C;AAEA,QAAM,cAAmC;AAAA,IACvC,KAAK,OAAO;AAAA,EACd;AAEA,QAAM,aAAa,OAAO,oBACrB,OAAO,kBAA6B,MAAM,GAAG,EAAE,IAAI,CAAC,MAAc,EAAE,KAAK,CAAC,IAC3E;AACJ,QAAM,eAAe,OAAO,qBACvB,OAAO,mBAA8B,MAAM,GAAG,EAAE,IAAI,CAAC,MAAc,EAAE,KAAK,CAAC,IAC5E;AAEJ,MAAI,cAAc,cAAc;AAC9B,gBAAY,UAAU;AAAA,MACpB,YAAY,aAAa,EAAE,YAAY,CAAC,OAAO,KAAK,GAAG,UAAU,EAAE,IAAI;AAAA,MACvE,SAAS,eAAe,EAAE,gBAAgB,aAAa,IAAI;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO,aAAa,WAAW;AACjC;AAEA,eAAe,YAA6B;AAC1C,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ,OAAO;AACvC,WAAO,KAAK,KAAe;AAAA,EAC7B;AACA,SAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK;AACtD;AAEA,eAAe,OAAsB;AACnC,QAAM,UAAU,IAAI,QAAQ,QAAQ,EACjC,QAAQ,OAAO,EACf,YAAY,gDAA2C,EACvD,OAAO,yBAAyB,sEAAsE,EACtG,OAAO,uBAAuB,YAAY,EAC1C,OAAO,mBAAmB,8BAA8B,EACxD,OAAO,oBAAoB,4BAA4B,EACvD,OAAO,eAAe,mBAAmB,EACzC,OAAO,uBAAuB,gFAAgF,EAC9G,OAAO,sBAAsB,wCAAwC,EACrE,OAAO,mBAAmB,mBAAmB,QAAQ,EACrD,OAAO,UAAU,oCAAoC,EACrD,OAAO,WAAW,wBAAwB,EAC1C,OAAO,aAAa,8BAA8B,EAClD,OAAO,cAAc,uDAAuD,EAC5E,OAAO,gBAAgB,oDAAoD,EAC3E,OAAO,iCAAiC,mDAAmD,EAC3F,OAAO,oCAAoC,6CAA6C,EACxF,OAAO,uBAAuB,mCAAmC,EACjE,SAAS,eAAe,eAAe,EACvC,qBAAqB,IAAI,EACzB,OAAO,OAAO,SAAmB;AAChC,UAAM,OAAO,QAAQ,KAAK;AAE1B,QAAI,KAAK,SAAS,KAAK,CAAC,KAAK,QAAQ;AACnC,WAAK,SAAS,KAAK,KAAK,GAAG;AAAA,IAC7B;AAEA,QAAI,CAAC,QAAQ,MAAM,SAAS,CAAC,KAAK,QAAQ;AACxC,WAAK,SAAS,MAAM,UAAU;AAC9B,UAAI,CAAC,KAAK,QAAQ;AAChB,gBAAQ,OAAO,MAAMC,OAAM,IAAI,sBAAsB,CAAC;AACtD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,MAAM,KAAK,OAAO,QAAQ,IAAI;AACpC,UAAM,SAAS,cAAc,GAAG;AAChC,UAAM,SAAS,YAAY,QAAQ,IAAI;AAEvC,UAAM,SAAS,MAAM;AAAA,EACvB,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,qDAAqD,EACjE,OAAO,YAAY;AAClB,UAAM,QAAQ;AACd,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AAEH,UACG,QAAQ,UAAU,EAClB,YAAY,oBAAoB,EAChC,OAAO,YAAY;AAClB,UAAM,aAAa;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AAEH,UACG,QAAQ,qBAAqB,EAC7B,YAAY,2BAA2B,EACvC,OAAO,OAAO,cAAsB;AACnC,UAAM,cAAc,SAAS;AAAA,EAC/B,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,sDAAsD,EAClE,OAAO,YAAY;AAClB,UAAM,UAAU;AAAA,EAClB,CAAC;AAEH,QAAM,QAAQ,WAAW,QAAQ,IAAI;AACvC;AAEA,eAAe,SAAS,QAAqC;AAC3D,QAAM,eACH,OAAO,YAAyC,MAAM,eAAe;AAExE,MAAI,CAAC,cAAc;AACjB,QAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,cAAQ,OAAO,MAAMA,OAAM,IAAI,0BAA0B,CAAC;AAC1D,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,OAAO;AAAA,MACbA,OAAM,KAAK,wBAAwB,IACjCA,OAAM,IAAI,6CAA6C;AAAA,IAC3D;AAEA,UAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM,OAAO,mBAAwB;AACjE,UAAM,KAAKA,iBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,UAAU,KAAK,CAAC;AAE3F,QAAI;AACF,YAAM,EAAE,qBAAAC,sBAAqB,iBAAAC,kBAAiB,eAAAC,eAAc,IAAI,MAAM,OAAO,iCAAuB;AACpG,YAAM,iBAAiB,MAAM,GAAG;AAAA,QAC9B,eAAeF,qBAAoB,KAAK,IAAI,CAAC,MAAMF,OAAM,KAAK,QAAQ,CAAC;AAAA,MACzE;AACA,YAAM,SAAS,eAAe,KAAK,KAAK;AACxC,UAAI,CAAEE,qBAA0C,SAAS,MAAM,GAAG;AAChE,gBAAQ,OAAO,MAAMF,OAAM,IAAI,qBAAqB,MAAM;AAAA,CAAI,CAAC;AAC/D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,WAAW,UAAU;AACvB,YAAI,CAAE,MAAMG,iBAAgB,GAAI;AAC9B,kBAAQ,OAAO;AAAA,YACbH,OAAM,OAAO;AAAA,2CAA8CI,eAAc,CAAC;AAAA,CAAK,IAC/EJ,OAAM,OAAO;AAAA;AAAA,CAAqD,IAClE,OAAOA,OAAM,KAAK,+BAA+B,CAAC;AAAA,MAC3CA,OAAM,KAAK,cAAc,CAAC;AAAA;AAAA,IACjCA,OAAM,OAAO;AAAA,CAAyB;AAAA,UACxC;AACA,aAAG,MAAM;AACT,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,SAAS,MAAM,sBAAsBI,eAAc,CAAC;AAC1D,YAAI,OAAO,SAAS,GAAG;AACrB,kBAAQ,OAAO,MAAMJ,OAAM,IAAI,uBAAuB,OAAO,KAAK,IAAI,CAAC;AAAA,CAAI,CAAC;AAC5E,gBAAM,eAAe,OAAO,SAAS,mBAAmB,IAAI,sBAAsB,OAAO,CAAC;AAC1F,gBAAM,cAAc,MAAM,GAAG;AAAA,YAC3B,YAAYA,OAAM,KAAK,YAAY,CAAC;AAAA,UACtC;AACA,iBAAO,QAAQ,YAAY,KAAK,KAAK;AAAA,QACvC;AAAA,MACF;AAEA,YAAM,WAAW,CAAC,CAAC,WAAW,UAAU,QAAQ,EAAE,SAAS,MAAM;AACjE,UAAI;AACJ,UAAI,UAAU;AACZ,cAAM,YAAY,MAAM,GAAG,SAAS,aAAa;AACjD,iBAAS,UAAU,KAAK;AACxB,YAAI,CAAC,QAAQ;AACX,kBAAQ,OAAO,MAAMA,OAAM,IAAI,wBAAwB,CAAC;AACxD,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAEA,SAAG,MAAM;AACT,aAAO,WAAW;AAClB,UAAI,OAAQ,QAAO,SAAS;AAAA,IAC9B,QAAQ;AACN,SAAG,MAAM;AACT,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,WAAO,SAAS,MAAM;AAAA,EACxB;AAEA,MAAI,CAAC,OAAO,OAAO;AACjB,UAAM,EAAE,gBAAAK,gBAAe,IAAI,MAAM,OAAO,iCAAuB;AAC/D,QAAI,iBAAiB,UAAU;AAC7B,YAAM,EAAE,eAAAD,eAAc,IAAI,MAAM,OAAO,iCAAuB;AAC9D,YAAM,SAAS,MAAM,sBAAsBA,eAAc,CAAC;AAC1D,YAAM,YAAYC,gBAAe,YAAY;AAC7C,aAAO,QAAQ,OAAO,SAAS,SAAS,IAAI,YAAY,OAAO,CAAC,KAAK;AAAA,IACvE,OAAO;AACL,aAAO,QAAQA,gBAAe,YAAY;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,gBAAe,cAAc;AAAA,IAClD,QAAQ,OAAO;AAAA,IACf,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,WAAW,cAAc,OAAO,QAAQ;AAC9C,QAAM,iBAAkB,OAAO,eAAe;AAE9C,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB;AAAA,IACA,SAAS,iBAAiB,MAAM;AAAA,IAChC,SAAS;AAAA,MACP,KAAK,OAAO;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,cAAc,OAAO;AAAA,MACrB,aAAa;AAAA,QACX,MAAM;AAAA,MACR;AAAA,MACA;AAAA,MACA,aAAa,OAAO,eAAe;AAAA,MACnC,iBAAiB,OAAO,mBAAmB;AAAA,MAC3C,aAAa,OAAO,eAAe;AAAA,MACnC,gBAAgB,OAAO,kBAAkB;AAAA,MACzC,iBAAiB,OAAO,mBAAmB;AAAA,MAC3C,YAAY,OAAO;AAAA,MACnB,KAAK,OAAO;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,MAC7D,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MACpD,gBAAgB,EAAE,KAAK,OAAO,KAAK,SAAY,YAAQ,EAAE;AAAA,MACzD,cAAc,EAAE,SAAS,KAAK;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,OAAO,UAAU;AACnB,UAAM,EAAE,YAAY,IAAI,MAAM,OAAO,yBAAe;AACpD,UAAM,YAAY,OAAO,MAAM;AAC/B;AAAA,EACF;AAEA,QAAM,MAAM,KAAK;AAEjB,MAAI;AACF,QAAI,OAAO,QAAQ;AACjB,YAAM,WAAW,OAAO,MAAM;AAAA,IAChC,OAAO;AACL,UAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,gBAAQ,OAAO;AAAA,UACbL,OAAM,IAAI,0DAA0D;AAAA,QACtE;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM,UAAU,OAAO,QAAQ,MAAM,MAAM,MAAM,CAAC;AAAA,IACpD;AAAA,EACF,UAAE;AACA,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEA,eAAe,WAAW,OAAc,QAAqC;AAC3E,QAAM,EAAE,cAAAM,cAAa,IAAI,MAAM,OAAO,wBAAc;AACpD,QAAM,EAAE,gBAAAC,gBAAe,IAAI,MAAM,OAAO,uBAAa;AACrD,QAAM,SAAS,MAAM,MAAM,aAAa;AACxC,QAAM,QAAQ,kBAAkB;AAChC,QAAM,UAAU,OAAO,WAAW,EAAE,UAAU,OAAO,SAAS,IAAI;AAElE,QAAM,UACJ,CAAC,OAAO,QAAQ,CAAC,OAAO,QAAQD,cAAa,UAAU,IAAI;AAE7D,MAAI;AACF,qBAAiB,SAAS,OAAO,IAAI,OAAO,QAAS,OAAO,GAAG;AAC7D,UAAI,CAAC,MAAM,kBAAkB,WAAWC,gBAAe,OAAO,MAAM,GAAG;AACrE,gBAAQ,KAAK;AACb,cAAM,iBAAiB;AAAA,MACzB;AACA,kBAAY,OAAO,QAAQ,KAAK;AAAA,IAClC;AAAA,EACF,UAAE;AACA,aAAS,KAAK;AAAA,EAChB;AAEA,MAAI,OAAO,SAAS,MAAM,iBAAiB;AACzC,YAAQ,OAAO,MAAM,MAAM,eAAe;AAC1C,QAAI,CAAC,MAAM,gBAAgB,SAAS,IAAI,GAAG;AACzC,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,EACF,WAAW,MAAM,mBAAmB,CAAC,MAAM,gBAAgB,SAAS,IAAI,GAAG;AACzE,YAAQ,OAAO,MAAM,IAAI;AAAA,EAC3B;AACF;AAEA,eAAe,eAA8B;AAC3C,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,SAAS,cAAc,GAAG;AAChC,QAAM,SAAS,YAAY,QAAQ,EAAE,IAAI,CAAC;AAE1C,QAAM,eAA0C,OAAO,YAAyC,MAAM,eAAe;AACrH,MAAI,CAAC,cAAc;AACjB,YAAQ,OAAO,MAAMP,OAAM,IAAI,oDAAoD,CAAC;AACpF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,MAAM,gBAAe,cAAc;AAAA,IAClD,QAAQ,OAAO;AAAA,IACf,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB;AAAA,IACA,SAAS,iBAAiB,EAAE,IAAI,CAAC;AAAA,IACjC,SAAS;AAAA,MACP;AAAA,MACA,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,MAC7D,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,IACtD;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM,MAAM,aAAa;AAC1C,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,OAAO,MAAMA,OAAM,IAAI,sBAAsB,CAAC;AACtD;AAAA,EACF;AAEA,UAAQ,OAAO,MAAMA,OAAM,KAAK,aAAa,CAAC;AAC9C,aAAW,KAAK,UAAU;AACxB,UAAM,QAAQ,EAAE,QAAQA,OAAM,MAAM,IAAI,EAAE,KAAK,EAAE,IAAI;AACrD,YAAQ,OAAO;AAAA,MACb,KAAKA,OAAM,KAAK,EAAE,UAAU,MAAM,GAAG,CAAC,CAAC,CAAC,KAAKA,OAAM,IAAI,EAAE,SAAS,CAAC,KAAKA,OAAM,IAAI,GAAG,EAAE,YAAY,OAAO,CAAC,GAAG,KAAK;AAAA;AAAA,IACrH;AAAA,EACF;AACF;AAEA,eAAe,cAAc,WAAkC;AAC7D,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,SAAS,cAAc,GAAG;AAChC,QAAM,SAAS,YAAY,QAAQ,EAAE,IAAI,CAAC;AAE1C,QAAM,eAA0C,OAAO,YAAyC,MAAM,eAAe;AACrH,MAAI,CAAC,cAAc;AACjB,YAAQ,OAAO,MAAMA,OAAM,IAAI,oDAAoD,CAAC;AACpF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,MAAM,gBAAe,cAAc;AAAA,IAClD,QAAQ,OAAO;AAAA,IACf,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,WAAW,cAAc,OAAO,QAAQ;AAC9C,QAAM,iBAAkB,OAAO,eAAe;AAE9C,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB;AAAA,IACA,SAAS,iBAAiB,MAAM;AAAA,IAChC,SAAS;AAAA,MACP;AAAA,MACA,OAAO,OAAO;AAAA,MACd,aAAa,EAAE,MAAM,eAAe;AAAA,MACpC;AAAA,MACA,aAAa,OAAO,eAAe;AAAA,MACnC,iBAAiB,OAAO,mBAAmB;AAAA,MAC3C,gBAAgB,OAAO,kBAAkB;AAAA,MACzC,YAAY,OAAO;AAAA,MACnB,KAAK,OAAO;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,MAC7D,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MACpD,gBAAgB,EAAE,KAAK,SAAY,YAAQ,EAAE;AAAA,MAC7C,cAAc,EAAE,SAAS,KAAK;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,MAAM,KAAK;AAGjB,QAAM,WAAW,MAAM,MAAM,aAAa;AAC1C,QAAM,QAAQ,SAAS;AAAA,IACrB,CAAC,MAAM,EAAE,cAAc,aAAa,EAAE,UAAU,WAAW,SAAS;AAAA,EACtE;AAEA,MAAI,CAAC,OAAO;AACV,YAAQ,OAAO,MAAMA,OAAM,IAAI,sBAAsB,SAAS;AAAA,CAAI,CAAC;AACnE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,OAAO;AAAA,IACbA,OAAM,IAAI,oBAAoB,MAAM,UAAU,MAAM,GAAG,CAAC,CAAC;AAAA;AAAA,CAAS;AAAA,EACpE;AAEA,QAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM,OAAO,mBAAwB;AACjE,QAAM,KAAKA,iBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,UAAU,KAAK,CAAC;AAE3F,QAAM,SAAS,MAAM,MAAM,aAAa,MAAM,SAAS;AAGvD,QAAM,EAAE,aAAa,QAAQ,mBAAmB,UAAU,IAAI,MAAM,OAAO,uBAAa;AAExF,UAAQ,OAAO,MAAMD,OAAM,IAAI,kDAAkD,CAAC;AAElF,MAAI;AACF,WAAO,MAAM;AACX,UAAI;AACJ,UAAI;AACF,gBAAQ,MAAM,GAAG,SAASA,OAAM,KAAK,IAAI,CAAC;AAAA,MAC5C,QAAQ;AACN;AAAA,MACF;AACA,UAAI,CAAC,MAAM,KAAK,EAAG;AACnB,UAAI,MAAM,KAAK,MAAM,WAAW,MAAM,KAAK,MAAM,QAAS;AAE1D,YAAM,QAAQ,UAAU;AACxB,uBAAiB,SAAS,OAAO,IAAI,KAAK,GAAG;AAC3C,eAAO,OAAO,QAAQ,KAAK;AAAA,MAC7B;AACA,UAAI,MAAM,mBAAmB,CAAC,MAAM,gBAAgB,SAAS,IAAI,GAAG;AAClE,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,UAAE;AACA,OAAG,MAAM;AACT,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEA,eAAe,YAA2B;AACxC,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,SAAS,cAAc,GAAG;AAChC,QAAM,SAAS,YAAY,QAAQ,EAAE,IAAI,CAAC;AAE1C,QAAM,eAA0C,OAAO,YAAyC,MAAM,eAAe;AACrH,MAAI,CAAC,cAAc;AACjB,YAAQ,OAAO,MAAMA,OAAM,IAAI,oDAAoD,CAAC;AACpF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,MAAM,gBAAe,cAAc;AAAA,IAClD,QAAQ,OAAO;AAAA,IACf,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB;AAAA,IACA,SAAS,iBAAiB,MAAM;AAAA,IAChC,SAAS;AAAA,MACP;AAAA,MACA,OAAO,OAAO;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,KAAK,OAAO;AAAA,MACZ,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,MAC7D,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,IACtD;AAAA,EACF,CAAC;AAED,QAAM,MAAM,KAAK;AAEjB,UAAQ,OAAO,MAAMA,OAAM,KAAK,qBAAqB,CAAC;AACtD,QAAM,SAAS,MAAM,MAAM,SAAS;AACpC,sBAAoB,MAAM;AAC1B,QAAM,MAAM,MAAM;AAClB,UAAQ,KAAK,OAAO,UAAU,IAAI,CAAC;AACrC;AAEA,SAAS,gBAAgB,OAAe,OAA4B,OAAwB;AAC1F,QAAM,OAAO,MAAM,KAAKA,OAAM,MAAM,QAAG,IAAIA,OAAM,IAAI,QAAG;AACxD,QAAM,SAAS,MAAM,YAAY,IAAIA,OAAM,IAAI,KAAK,MAAM,SAAS,KAAK,IAAI;AAC5E,QAAM,SAAS,QAAQA,OAAM,IAAI,IAAI,KAAK,EAAE,IAAI;AAChD,QAAM,SAAS,MAAM,QAAQA,OAAM,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI;AAC7D,QAAM,UAAU,CAAC,MAAM,SAAS,MAAM,UAAUA,OAAM,OAAO,KAAK,MAAM,OAAO,EAAE,IAAI;AACrF,SAAO,KAAK,IAAI,IAAI,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;AAAA;AAChE;AAEA,SAAS,oBAAoB,GAAyB;AACpD,QAAM,aAAa,EAAE,SAAS,QAAQ,KAAK,EAAE,SAAS,KAAK,MAAM;AACjE,UAAQ,OAAO,MAAM,gBAAgB,WAAW,UAAU,IAAI,EAAE,QAAQ,CAAC;AACzE,UAAQ,OAAO,MAAM,gBAAgB,uBAAuB,EAAE,QAAQ,EAAE,CAAC;AACzE,UAAQ,OAAO,MAAM,gBAAgB,kBAAkB,EAAE,QAAQ,QAAQ,CAAC;AAC1E,UAAQ,OAAO,MAAM;AAAA,IACnB;AAAA,IACA,EAAE;AAAA,IACF,EAAE,eAAe;AAAA,EACnB,CAAC;AAED,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,EAAE,GAAG,GAAG;AACjD,UAAM,QAAkB,CAAC;AACzB,QAAI,MAAM,OAAQ,OAAM,KAAK,MAAM,MAAM;AACzC,QAAI,MAAM,aAAa,KAAM,OAAM,KAAK,GAAG,MAAM,SAAS,QAAQ;AAClE,UAAM,QAAQ,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;AAChD,YAAQ,OAAO,MAAM,gBAAgB,QAAQ,IAAI,IAAI,OAAO,KAAK,CAAC;AAAA,EACpE;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,EAAE,GAAG,GAAG;AACjD,UAAM,QAAQ,MAAM,SAAS;AAC7B,YAAQ,OAAO,MAAM,gBAAgB,QAAQ,IAAI,IAAI,OAAO,KAAK,CAAC;AAAA,EACpE;AAEA,UAAQ,OAAO,MAAM,IAAI;AACzB,MAAI,EAAE,SAAS;AACb,YAAQ,OAAO,MAAM,KAAKA,OAAM,MAAM,kBAAkB,CAAC;AAAA;AAAA,CAAM;AAAA,EACjE,OAAO;AACL,YAAQ,OAAO,MAAM,KAAKA,OAAM,IAAI,oBAAoB,CAAC;AAAA;AAAA,CAAM;AAAA,EACjE;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,OAAO,MAAMA,OAAM,IAAI,UAAU,IAAI,OAAO;AAAA,CAAI,CAAC;AACzD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["chalk","fs","path","readline","chalk","chalk","os","chalk","createInterface","SUPPORTED_PROVIDERS","isOllamaRunning","ollamaBaseURL","DEFAULT_MODELS","startSpinner","isVisibleEvent"]}
@@ -1,5 +1,4 @@
1
- import { S as StreamEvent } from '../types-kiGBF35b.js';
2
- import { P as PermissionResponse } from '../types-CD0rUKKT.js';
1
+ import { P as PermissionResponse, S as StreamEvent } from '../types-DLZNyF5t.js';
3
2
 
4
3
  interface ClientOptions {
5
4
  /** Base URL of the noumen server, e.g. "http://localhost:3001". */
@@ -1,5 +1,3 @@
1
- import "../chunk-DGUM43GV.js";
2
-
3
1
  // src/client/index.ts
4
2
  var RECONNECT_BASE_DELAY_MS = 1e3;
5
3
  var RECONNECT_MAX_DELAY_MS = 3e4;
@@ -1 +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":[]}
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,9 @@
1
+ import {
2
+ McpClientManager
3
+ } from "./chunk-NUCJXOUV.js";
4
+ import "./chunk-4SQA2UCV.js";
5
+ import "./chunk-HQISH4D7.js";
6
+ export {
7
+ McpClientManager
8
+ };
9
+ //# sourceMappingURL=client-JJFLE6RT.js.map
@@ -85,4 +85,4 @@ interface VirtualComputer {
85
85
  executeCommand(command: string, opts?: ExecOptions): Promise<CommandResult>;
86
86
  }
87
87
 
88
- export type { CommandResult as C, ExecOptions as E, FileEntry as F, ReadOptions as R, VirtualComputer as V, VirtualFs as a, FileStat as b };
88
+ export type { CommandResult as C, ExecOptions as E, FileEntry as F, ReadOptions as R, VirtualFs as V, VirtualComputer as a, FileStat as b };
package/dist/docker.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Sandbox } from './sandbox-9qeMTNrD.js';
2
- import { V as VirtualComputer, E as ExecOptions, C as CommandResult, a as VirtualFs, R as ReadOptions, F as FileEntry, b as FileStat } from './computer-BPdxSo6X.js';
1
+ import { S as Sandbox } from './sandbox-DAqQo0Tj.js';
2
+ import { a as VirtualComputer, E as ExecOptions, C as CommandResult, V as VirtualFs, R as ReadOptions, F as FileEntry, b as FileStat } from './computer-DzMR92tK.js';
3
3
 
4
4
  /**
5
5
  * Minimal subset of the dockerode Container interface used by DockerComputer.
package/dist/docker.js CHANGED
@@ -2,7 +2,6 @@ import {
2
2
  createComputerProxy,
3
3
  createFsProxy
4
4
  } from "./chunk-I5SBSOS6.js";
5
- import "./chunk-DGUM43GV.js";
6
5
 
7
6
  // src/virtual/docker-fs.ts
8
7
  import * as path from "path";