negotium 0.14.2 → 0.14.4

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 (53) hide show
  1. package/dist/agent-helpers.js +137 -7
  2. package/dist/agent-helpers.js.map +12 -10
  3. package/dist/background-bash.js +2 -2
  4. package/dist/background-bash.js.map +4 -4
  5. package/dist/browser-runtime.js +2 -2
  6. package/dist/browser-runtime.js.map +4 -4
  7. package/dist/{chunk-z1nb140t.js → chunk-er68mpja.js} +17 -4
  8. package/dist/{chunk-z1nb140t.js.map → chunk-er68mpja.js.map} +5 -5
  9. package/dist/{chunk-m6aw1tb3.js → chunk-p7tprsvc.js} +1 -1
  10. package/dist/{chunk-bqdya494.js → chunk-zcazbmcs.js} +3 -3
  11. package/dist/{chunk-bqdya494.js.map → chunk-zcazbmcs.js.map} +2 -2
  12. package/dist/hosted-agent.js +23 -7
  13. package/dist/hosted-agent.js.map +7 -7
  14. package/dist/main.js +557 -390
  15. package/dist/main.js.map +15 -14
  16. package/dist/mcp-factories.js +137 -7
  17. package/dist/mcp-factories.js.map +12 -10
  18. package/dist/media.js +2 -2
  19. package/dist/media.js.map +4 -4
  20. package/dist/prompts.js +2 -2
  21. package/dist/prompts.js.map +4 -4
  22. package/dist/query-runtime.js +2 -2
  23. package/dist/query-runtime.js.map +4 -4
  24. package/dist/registry.js +3 -3
  25. package/dist/rollout.js +2 -2
  26. package/dist/runtime/src/agents/codex-provider.ts +8 -2
  27. package/dist/runtime/src/application/submit-runtime-gateway-turn.ts +21 -2
  28. package/dist/runtime/src/node-host.ts +1 -0
  29. package/dist/runtime/src/platform/config.ts +1 -1
  30. package/dist/runtime/src/platform/mcp-config.ts +38 -16
  31. package/dist/runtime/src/runtime/turn-runner.ts +13 -0
  32. package/dist/runtime/src/runtime-gateway.ts +86 -0
  33. package/dist/runtime/src/storage/topic-host-mcp-grants.ts +54 -0
  34. package/dist/runtime/src/topics/lifecycle.ts +2 -0
  35. package/dist/runtime/src/types.ts +4 -0
  36. package/dist/runtime/src/version.ts +1 -1
  37. package/dist/runtime-gateway.js +73 -1
  38. package/dist/runtime-gateway.js.map +3 -3
  39. package/dist/runtime-helpers.js +2 -2
  40. package/dist/runtime-helpers.js.map +4 -4
  41. package/dist/storage.js.map +2 -2
  42. package/dist/types/packages/core/src/platform/config.d.ts +1 -1
  43. package/dist/types/packages/core/src/platform/mcp-config.d.ts +2 -0
  44. package/dist/types/packages/core/src/runtime/turn-runner.d.ts +3 -1
  45. package/dist/types/packages/core/src/runtime-gateway.d.ts +11 -0
  46. package/dist/types/packages/core/src/storage/topic-host-mcp-grants.d.ts +5 -0
  47. package/dist/types/packages/core/src/types.d.ts +3 -0
  48. package/dist/types/packages/core/src/version.d.ts +1 -1
  49. package/dist/vault.js +2 -2
  50. package/dist/vault.js.map +4 -4
  51. package/install-browser-rs.mjs +3 -3
  52. package/package.json +1 -1
  53. /package/dist/{chunk-m6aw1tb3.js.map → chunk-p7tprsvc.js.map} +0 -0
@@ -7,7 +7,7 @@ import {
7
7
  logger,
8
8
  parseJsonlText,
9
9
  writeJsonlFile
10
- } from "./chunk-z1nb140t.js";
10
+ } from "./chunk-er68mpja.js";
11
11
 
12
12
  // ../../packages/core/src/agents/rollout/claude.ts
13
13
  import { randomUUID } from "crypto";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  hostedCodexHomePath,
4
4
  latestCodexRolloutPath
5
- } from "./chunk-z1nb140t.js";
5
+ } from "./chunk-er68mpja.js";
6
6
 
7
7
  // ../../packages/core/src/agents/codex-app-server.ts
8
8
  import { spawn } from "child_process";
@@ -23,7 +23,7 @@ import { createRequire } from "module";
23
23
  import { dirname, join } from "path";
24
24
 
25
25
  // ../../packages/core/src/version.ts
26
- var NEGOTIUM_VERSION = "0.14.2";
26
+ var NEGOTIUM_VERSION = "0.14.4";
27
27
 
28
28
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
29
29
  var moduleRequire = createRequire(import.meta.url);
@@ -157,4 +157,4 @@ export {
157
157
  createCodexAppServerForker
158
158
  };
159
159
 
160
- //# debugId=A73B5C8B2813098764756E2164756E21
160
+ //# debugId=BA015EF084159CBD64756E2164756E21
@@ -4,9 +4,9 @@
4
4
  "sourcesContent": [
5
5
  "import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { codexCliScriptPath } from \"#agents/codex-native-multi-agent\";\nimport { hostedCodexHomePath } from \"#agents/execution-host\";\nimport { latestCodexRolloutPath } from \"#agents/rollout/codex\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ninterface CodexAppServerForkResult {\n forkId: string;\n rolloutPath: string;\n}\n\ninterface CodexAppServerForkHost {\n spawnServer(): ChildProcessWithoutNullStreams;\n findRolloutPath(threadId: string): string | undefined;\n timeoutMs: number;\n}\n\ntype JsonRpcResponse = {\n id?: number;\n result?: { thread?: { id?: unknown } };\n error?: { message?: unknown };\n};\n\nexport function createCodexAppServerForker(host: CodexAppServerForkHost) {\n return async (parentThreadId: string): Promise<CodexAppServerForkResult> => {\n const child = host.spawnServer();\n\n return await new Promise<CodexAppServerForkResult>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"Codex thread fork timed out\")),\n host.timeoutMs,\n );\n\n const finish = (error?: Error, result?: CodexAppServerForkResult) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (result) resolve(result);\n else reject(new Error(\"Codex thread fork returned no result\"));\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 8_192) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (settled) return;\n const detail = signal ? `signal ${signal}` : `code ${code ?? 1}`;\n finish(\n new Error(\n `Codex app server exited with ${detail}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: JsonRpcResponse;\n try {\n message = JSON.parse(line) as JsonRpcResponse;\n } catch {\n continue;\n }\n\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(String(message.error.message || \"Codex initialization failed\")));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"thread/fork\", params: { threadId: parentThreadId } });\n continue;\n }\n if (message.id !== 2) continue;\n if (message.error) {\n finish(new Error(String(message.error.message || \"Codex thread fork failed\")));\n return;\n }\n const forkId = message.result?.thread?.id;\n if (typeof forkId !== \"string\" || !forkId) {\n finish(new Error(\"Codex thread fork returned no thread id\"));\n return;\n }\n const rolloutPath = host.findRolloutPath(forkId);\n if (!rolloutPath) {\n finish(new Error(`Codex thread fork rollout was not found for ${forkId}`));\n return;\n }\n finish(undefined, { forkId, rolloutPath });\n return;\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n },\n });\n });\n };\n}\n\nconst forkCodexThread = createCodexAppServerForker({\n spawnServer() {\n return spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: hostedCodexHomePath() },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n },\n findRolloutPath: latestCodexRolloutPath,\n timeoutMs: 15_000,\n});\n\nexport async function forkCodexSession(parentThreadId: string): Promise<CodexAppServerForkResult> {\n return await forkCodexThread(parentThreadId);\n}\n",
6
6
  "import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdtempSync,\n readFileSync,\n renameSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ntype CodexModel = Record<string, unknown>;\ntype CodexModelCache = {\n client_version?: unknown;\n models?: unknown;\n};\n\nconst moduleRequire = createRequire(import.meta.url);\nconst codexSdkPackagePath = moduleRequire.resolve(\"@openai/codex-sdk/package.json\");\nconst codexSdkRequire = createRequire(codexSdkPackagePath);\nconst bundledCodexPackagePath = codexSdkRequire.resolve(\"@openai/codex/package.json\");\n\nfunction readPackageVersion(packageJsonPath: string): string {\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n if (typeof parsed.version !== \"string\" || !parsed.version.trim()) {\n throw new Error(`Codex package has no valid version: ${packageJsonPath}`);\n }\n return parsed.version;\n}\n\nexport const BUNDLED_CODEX_VERSION = readPackageVersion(bundledCodexPackagePath);\nconst SAFE_BUNDLED_CODEX_VERSION = BUNDLED_CODEX_VERSION.replace(/[^a-zA-Z0-9._-]/g, \"_\");\nconst NEGOTIUM_MODEL_CACHE = `negotium-models-cache-${SAFE_BUNDLED_CODEX_VERSION}.json`;\nconst NEGOTIUM_MODEL_CATALOG = `negotium-model-catalog-${SAFE_BUNDLED_CODEX_VERSION}.json`;\n\nexport function codexCliScriptPath(): string {\n return join(dirname(bundledCodexPackagePath), \"bin\", \"codex.js\");\n}\n\nfunction parseCodexModelCache(contents: string, sourcePath: string): CodexModelCache {\n let parsed: CodexModelCache;\n try {\n parsed = JSON.parse(contents) as CodexModelCache;\n } catch (error) {\n throw new Error(`Codex model cache is invalid JSON: ${sourcePath}`, { cause: error });\n }\n if (!Array.isArray(parsed.models) || parsed.models.length === 0) {\n throw new Error(`Codex model cache has no models: ${sourcePath}`);\n }\n return parsed;\n}\n\nfunction readCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const contents = readFileSync(cachePath, \"utf8\");\n return { contents, parsed: parseCodexModelCache(contents, cachePath) };\n}\n\nfunction readCompatibleCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const cache = readCodexModelCache(cachePath);\n if (cache.parsed.client_version !== BUNDLED_CODEX_VERSION) {\n const found =\n typeof cache.parsed.client_version === \"string\"\n ? cache.parsed.client_version\n : \"missing or invalid\";\n throw new Error(\n `Codex model cache version ${found} does not match Negotium's bundled Codex ${BUNDLED_CODEX_VERSION}: ${cachePath}`,\n );\n }\n return cache;\n}\n\nfunction writePrivateFileAtomic(path: string, contents: string): void {\n if (existsSync(path) && readFileSync(path, \"utf8\") === contents) return;\n\n const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeFileSync(tempPath, contents, { encoding: \"utf8\", mode: 0o600 });\n renameSync(tempPath, path);\n chmodSync(path, 0o600);\n } finally {\n try {\n unlinkSync(tempPath);\n } catch {\n // renameSync normally consumed the temporary file.\n }\n }\n}\n\nexport function bundledCodexModelCachePath(authFilePath: string): string {\n return join(dirname(authFilePath), NEGOTIUM_MODEL_CACHE);\n}\n\nasync function bootstrapCodexModelCache(codexHome: string, cachePath: string): Promise<void> {\n const child = spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: codexHome },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"timed out while refreshing the Codex model catalog\")),\n 15_000,\n );\n\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (!existsSync(cachePath)) reject(new Error(\"Codex did not create its model cache\"));\n else resolve();\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 4_096) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (!settled) {\n finish(\n new Error(\n `Codex model catalog refresh exited with ${signal ? `signal ${signal}` : `code ${code ?? 1}`}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n }\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: { id?: number; error?: { message?: string } };\n try {\n message = JSON.parse(line) as typeof message;\n } catch {\n continue;\n }\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex initialization failed\"));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"model/list\", params: { includeHidden: true } });\n } else if (message.id === 2) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex model listing failed\"));\n } else {\n finish();\n }\n return;\n }\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n capabilities: { experimentalApi: true },\n },\n });\n });\n}\n\nasync function bootstrapIsolatedCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void>,\n): Promise<string> {\n const sourceHome = dirname(authFilePath);\n const isolatedHome = mkdtempSync(join(tmpdir(), \"negotium-codex-models-\"));\n const isolatedCachePath = join(isolatedHome, \"models_cache.json\");\n\n try {\n const isolatedAuthPath = join(isolatedHome, \"auth.json\");\n copyFileSync(authFilePath, isolatedAuthPath);\n chmodSync(isolatedAuthPath, 0o600);\n\n // Preserve custom provider configuration while keeping the bundled CLI's\n // cache write completely outside the user's shared CODEX_HOME.\n const sourceConfigPath = join(sourceHome, \"config.toml\");\n if (existsSync(sourceConfigPath)) {\n const isolatedConfigPath = join(isolatedHome, \"config.toml\");\n copyFileSync(sourceConfigPath, isolatedConfigPath);\n chmodSync(isolatedConfigPath, 0o600);\n }\n\n await bootstrap(isolatedHome, isolatedCachePath);\n return readCompatibleCodexModelCache(isolatedCachePath).contents;\n } finally {\n rmSync(isolatedHome, { recursive: true, force: true });\n }\n}\n\nexport async function ensureCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void> = bootstrapCodexModelCache,\n): Promise<string> {\n const codexHome = dirname(authFilePath);\n const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;\n if (configuredCachePath) {\n if (!existsSync(configuredCachePath)) {\n throw new Error(`Configured Codex model cache does not exist: ${configuredCachePath}`);\n }\n readCompatibleCodexModelCache(configuredCachePath);\n return configuredCachePath;\n }\n\n // The global Codex CLI owns models_cache.json and may update it to a schema\n // newer than the SDK bundled by Negotium. Snapshot a cache generated for our\n // exact bundled version so later global CLI updates cannot break turns.\n const bundledCachePath = bundledCodexModelCachePath(authFilePath);\n const sharedCachePath = join(codexHome, \"models_cache.json\");\n if (existsSync(sharedCachePath)) {\n try {\n const shared = readCompatibleCodexModelCache(sharedCachePath);\n // Keep model metadata fresh while the global CLI remains compatible.\n writePrivateFileAtomic(bundledCachePath, shared.contents);\n return bundledCachePath;\n } catch {\n // A compatible private snapshot is safer than failing because another\n // process briefly exposed an incomplete shared-cache write.\n }\n }\n\n if (existsSync(bundledCachePath)) {\n try {\n readCompatibleCodexModelCache(bundledCachePath);\n return bundledCachePath;\n } catch {\n // Re-bootstrap below instead of passing a corrupt or version-mismatched\n // private snapshot into this SDK version.\n }\n }\n\n const refreshedContents = await bootstrapIsolatedCodexModelCache(authFilePath, bootstrap);\n writePrivateFileAtomic(bundledCachePath, refreshedContents);\n return bundledCachePath;\n}\n\n/**\n * Codex can resolve model metadata before `features.multi_agent=false`, so a\n * model-advertised v1/v2 value may still register native collaboration tools.\n * Feed Codex an authoritative copy of its own catalog with only that field\n * disabled. Runtime MCP delegation remains available independently.\n */\nexport function writeCodexCatalogWithNativeMultiAgentDisabled(\n authFilePath: string,\n sourcePath: string,\n): string {\n const codexHome = dirname(authFilePath);\n const outputPath = join(codexHome, NEGOTIUM_MODEL_CATALOG);\n\n const parsed = readCodexModelCache(sourcePath).parsed;\n\n const models = (parsed.models as unknown[]).map((model, index): CodexModel => {\n if (!model || typeof model !== \"object\" || Array.isArray(model)) {\n throw new Error(`Codex model cache entry ${index} is invalid: ${sourcePath}`);\n }\n return { ...(model as CodexModel), multi_agent_version: \"disabled\" };\n });\n const contents = `${JSON.stringify({ models }, null, 2)}\\n`;\n writePrivateFileAtomic(outputPath, contents);\n return outputPath;\n}\n",
7
- "export const NEGOTIUM_VERSION = \"0.14.2\";\n"
7
+ "export const NEGOTIUM_VERSION = \"0.14.4\";\n"
8
8
  ],
9
9
  "mappings": ";;;;;;;AAAA;;;ACEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA;AAEA;;;ACfO,IAAM,mBAAmB;;;ADwBhC,IAAM,gBAAgB,cAAc,YAAY,GAAG;AACnD,IAAM,sBAAsB,cAAc,QAAQ,gCAAgC;AAClF,IAAM,kBAAkB,cAAc,mBAAmB;AACzD,IAAM,0BAA0B,gBAAgB,QAAQ,4BAA4B;AAEpF,SAAS,kBAAkB,CAAC,iBAAiC;AAAA,EAC3D,MAAM,SAAS,KAAK,MAAM,aAAa,iBAAiB,MAAM,CAAC;AAAA,EAC/D,IAAI,OAAO,OAAO,YAAY,aAAa,OAAO,QAAQ,KAAK,GAAG;AAAA,IAChE,MAAM,IAAI,MAAM,uCAAuC,iBAAiB;AAAA,EAC1E;AAAA,EACA,OAAO,OAAO;AAAA;AAGT,IAAM,wBAAwB,mBAAmB,uBAAuB;AAC/E,IAAM,6BAA6B,sBAAsB,QAAQ,oBAAoB,GAAG;AACxF,IAAM,uBAAuB,yBAAyB;AACtD,IAAM,yBAAyB,0BAA0B;AAElD,SAAS,kBAAkB,GAAW;AAAA,EAC3C,OAAO,KAAK,QAAQ,uBAAuB,GAAG,OAAO,UAAU;AAAA;;;ADpB1D,SAAS,0BAA0B,CAAC,MAA8B;AAAA,EACvE,OAAO,OAAO,mBAA8D;AAAA,IAC1E,MAAM,QAAQ,KAAK,YAAY;AAAA,IAE/B,OAAO,MAAM,IAAI,QAAkC,CAAC,SAAS,WAAW;AAAA,MACtE,IAAI,UAAU;AAAA,MACd,IAAI,eAAe;AAAA,MACnB,IAAI,SAAS;AAAA,MACb,MAAM,QAAQ,WACZ,MAAM,OAAO,IAAI,MAAM,6BAA6B,CAAC,GACrD,KAAK,SACP;AAAA,MAEA,MAAM,SAAS,CAAC,OAAe,WAAsC;AAAA,QACnE,IAAI;AAAA,UAAS;AAAA,QACb,UAAU;AAAA,QACV,aAAa,KAAK;AAAA,QAClB,IAAI;AAAA,UACF,MAAM,MAAM,IAAI;AAAA,UAChB,MAAM,KAAK;AAAA,UACX,MAAM;AAAA,QAGR,IAAI;AAAA,UAAO,OAAO,KAAK;AAAA,QAClB,SAAI;AAAA,UAAQ,QAAQ,MAAM;AAAA,QAC1B;AAAA,iBAAO,IAAI,MAAM,sCAAsC,CAAC;AAAA;AAAA,MAG/D,MAAM,OAAO,CAAC,YAAqC;AAAA,QACjD,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,OAAO;AAAA,CAAK;AAAA;AAAA,MAGlD,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU;AAAA,QACjC,IAAI,OAAO,SAAS;AAAA,UAAO,UAAU,OAAO,KAAK;AAAA,OAClD;AAAA,MACD,MAAM,GAAG,SAAS,CAAC,UAAU,OAAO,KAAK,CAAC;AAAA,MAC1C,MAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AAAA,QACjC,IAAI;AAAA,UAAS;AAAA,QACb,MAAM,SAAS,SAAS,UAAU,WAAW,QAAQ,QAAQ;AAAA,QAC7D,OACE,IAAI,MACF,gCAAgC,SAAS,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,MAAM,IAClF,CACF;AAAA,OACD;AAAA,MACD,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU;AAAA,QACjC,gBAAgB,OAAO,KAAK;AAAA,QAC5B,UAAS;AAAA,UACP,MAAM,UAAU,aAAa,QAAQ;AAAA,CAAI;AAAA,UACzC,IAAI,UAAU;AAAA,YAAG;AAAA,UACjB,MAAM,OAAO,aAAa,MAAM,GAAG,OAAO;AAAA,UAC1C,eAAe,aAAa,MAAM,UAAU,CAAC;AAAA,UAC7C,IAAI;AAAA,UACJ,IAAI;AAAA,YACF,UAAU,KAAK,MAAM,IAAI;AAAA,YACzB,MAAM;AAAA,YACN;AAAA;AAAA,UAGF,IAAI,QAAQ,OAAO,GAAG;AAAA,YACpB,IAAI,QAAQ,OAAO;AAAA,cACjB,OAAO,IAAI,MAAM,OAAO,QAAQ,MAAM,WAAW,6BAA6B,CAAC,CAAC;AAAA,cAChF;AAAA,YACF;AAAA,YACA,KAAK,EAAE,QAAQ,cAAc,CAAC;AAAA,YAC9B,KAAK,EAAE,IAAI,GAAG,QAAQ,eAAe,QAAQ,EAAE,UAAU,eAAe,EAAE,CAAC;AAAA,YAC3E;AAAA,UACF;AAAA,UACA,IAAI,QAAQ,OAAO;AAAA,YAAG;AAAA,UACtB,IAAI,QAAQ,OAAO;AAAA,YACjB,OAAO,IAAI,MAAM,OAAO,QAAQ,MAAM,WAAW,0BAA0B,CAAC,CAAC;AAAA,YAC7E;AAAA,UACF;AAAA,UACA,MAAM,SAAS,QAAQ,QAAQ,QAAQ;AAAA,UACvC,IAAI,OAAO,WAAW,aAAa,QAAQ;AAAA,YACzC,OAAO,IAAI,MAAM,yCAAyC,CAAC;AAAA,YAC3D;AAAA,UACF;AAAA,UACA,MAAM,cAAc,KAAK,gBAAgB,MAAM;AAAA,UAC/C,KAAK,aAAa;AAAA,YAChB,OAAO,IAAI,MAAM,+CAA+C,QAAQ,CAAC;AAAA,YACzE;AAAA,UACF;AAAA,UACA,OAAO,WAAW,EAAE,QAAQ,YAAY,CAAC;AAAA,UACzC;AAAA,QACF;AAAA,OACD;AAAA,MAED,KAAK;AAAA,QACH,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,QAAQ;AAAA,UACN,YAAY,EAAE,MAAM,YAAY,SAAS,iBAAiB;AAAA,QAC5D;AAAA,MACF,CAAC;AAAA,KACF;AAAA;AAAA;AAIL,IAAM,kBAAkB,2BAA2B;AAAA,EACjD,WAAW,GAAG;AAAA,IACZ,OAAO,MAAM,QAAQ,UAAU,CAAC,mBAAmB,GAAG,cAAc,SAAS,GAAG;AAAA,MAC9E,KAAK,KAAK,QAAQ,KAAK,YAAY,oBAAoB,EAAE;AAAA,MACzD,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAChC,CAAC;AAAA;AAAA,EAEH,iBAAiB;AAAA,EACjB,WAAW;AACb,CAAC;AAED,eAAsB,gBAAgB,CAAC,gBAA2D;AAAA,EAChG,OAAO,MAAM,gBAAgB,cAAc;AAAA;",
10
- "debugId": "A73B5C8B2813098764756E2164756E21",
10
+ "debugId": "BA015EF084159CBD64756E2164756E21",
11
11
  "names": []
12
12
  }
@@ -135,7 +135,7 @@ var DM_WORKSPACE_DIR = resolve(STATE_DIR, "data", "dm");
135
135
  var SESSION_WORKSPACE_DIR = resolve(STATE_DIR, "data", "sessions");
136
136
  var CLAUDE_EXECUTABLE_ENV = envText("NEGOTIUM_CLAUDE_EXECUTABLE");
137
137
  var CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;
138
- var BROWSER_RS_VERSION = "v0.3.2";
138
+ var BROWSER_RS_VERSION = "v0.4.0";
139
139
  var BROWSER_RS_MIN_SECURE_VERSION = "0.2.1";
140
140
  function versionAtLeast(actualVersion, minimumVersion) {
141
141
  const actual = actualVersion.split(".").map(Number);
@@ -1263,6 +1263,19 @@ function refreshForumCatalogViews() {
1263
1263
  }
1264
1264
  refreshForumCatalogViews();
1265
1265
  var nodeMcpEntries = [];
1266
+ function isReservedRuntimeMcpServerName(name) {
1267
+ return Object.hasOwn(MCP_CATALOG, name) || nodeMcpEntries.some((entry) => entry.key === name);
1268
+ }
1269
+ function mergeHostMcpServers(base, hostMcpServers) {
1270
+ if (!hostMcpServers)
1271
+ return base;
1272
+ for (const name of Object.keys(hostMcpServers)) {
1273
+ if (Object.hasOwn(base, name) || isReservedRuntimeMcpServerName(name)) {
1274
+ throw new Error(`host MCP server name conflicts with node catalog: ${name}`);
1275
+ }
1276
+ }
1277
+ return { ...base, ...hostMcpServers };
1278
+ }
1266
1279
  function buildNodeMcpSpecs(agent, filter) {
1267
1280
  const out = {};
1268
1281
  for (const entry of nodeMcpEntries) {
@@ -1439,7 +1452,7 @@ function getMcpServersForQuery(opts) {
1439
1452
  });
1440
1453
  }
1441
1454
  if (opts.sessionType === "manager") {
1442
- return getManagerMcpServers({
1455
+ return mergeHostMcpServers(getManagerMcpServers({
1443
1456
  userId: opts.userId || "local",
1444
1457
  session: opts.session,
1445
1458
  topicId: opts.topicId,
@@ -1454,7 +1467,7 @@ function getMcpServersForQuery(opts) {
1454
1467
  autoContinue: opts.autoContinue,
1455
1468
  visualTools: opts.visualTools,
1456
1469
  fileDeliveryTools: opts.fileDeliveryTools
1457
- });
1470
+ }), opts.hostMcpServers);
1458
1471
  }
1459
1472
  return getForumMcpServers({
1460
1473
  userId: opts.userId || "local",
@@ -2517,7 +2530,7 @@ import { tmpdir } from "os";
2517
2530
  import { dirname as dirname5, join as join4 } from "path";
2518
2531
 
2519
2532
  // ../../packages/core/src/version.ts
2520
- var NEGOTIUM_VERSION = "0.14.2";
2533
+ var NEGOTIUM_VERSION = "0.14.4";
2521
2534
 
2522
2535
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
2523
2536
  var moduleRequire = createRequire2(import.meta.url);
@@ -3571,8 +3584,11 @@ function toCodexMcpServers(claudeShape) {
3571
3584
  if (typeof s.url === "string" && s.type !== "sse") {
3572
3585
  out[codexName] = withCodexMcpServerOverrides(name, {
3573
3586
  url: s.url,
3574
- ...s.http_headers && typeof s.http_headers === "object" ? { http_headers: s.http_headers } : {},
3575
- ...s.env_http_headers && typeof s.env_http_headers === "object" ? { env_http_headers: s.env_http_headers } : {}
3587
+ ...s.http_headers && typeof s.http_headers === "object" || s.headers && typeof s.headers === "object" ? {
3588
+ http_headers: s.http_headers ?? s.headers
3589
+ } : {},
3590
+ ...s.env_http_headers && typeof s.env_http_headers === "object" ? { env_http_headers: s.env_http_headers } : {},
3591
+ ...typeof s.timeout === "number" ? { tool_timeout_sec: Math.max(1, Math.ceil(s.timeout / 1000)) } : {}
3576
3592
  });
3577
3593
  }
3578
3594
  }
@@ -4355,4 +4371,4 @@ export {
4355
4371
  buildClaudeDisallowedTools
4356
4372
  };
4357
4373
 
4358
- //# debugId=7DA4BF190CB60A1564756E2164756E21
4374
+ //# debugId=BC0B9A2EBC8D900E64756E2164756E21