negotium 0.16.4 → 0.17.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 (33) hide show
  1. package/dist/agent-helpers.js +138 -54
  2. package/dist/agent-helpers.js.map +10 -10
  3. package/dist/{chunk-33exyd19.js → chunk-61n4gy9n.js} +1 -1
  4. package/dist/{chunk-zt9dey0p.js → chunk-7hdtbre6.js} +51 -19
  5. package/dist/{chunk-zt9dey0p.js.map → chunk-7hdtbre6.js.map} +5 -5
  6. package/dist/{chunk-atdgzpwv.js → chunk-93tfzcmm.js} +3 -3
  7. package/dist/{chunk-atdgzpwv.js.map → chunk-93tfzcmm.js.map} +2 -2
  8. package/dist/hosted-agent.js +72 -34
  9. package/dist/hosted-agent.js.map +8 -8
  10. package/dist/main.js +305 -101
  11. package/dist/main.js.map +18 -18
  12. package/dist/mcp-factories.js +137 -53
  13. package/dist/mcp-factories.js.map +10 -10
  14. package/dist/prompts.js +2 -2
  15. package/dist/prompts.js.map +2 -2
  16. package/dist/registry.js +3 -3
  17. package/dist/rollout.js +2 -2
  18. package/dist/runtime/src/agents/claude-provider.ts +20 -1
  19. package/dist/runtime/src/agents/codex-provider.ts +17 -6
  20. package/dist/runtime/src/agents/index.ts +3 -0
  21. package/dist/runtime/src/mcp/runtime-spec.ts +4 -0
  22. package/dist/runtime/src/node-host.ts +1 -0
  23. package/dist/runtime/src/platform/mcp-config.ts +107 -25
  24. package/dist/runtime/src/platform/paths.ts +16 -2
  25. package/dist/runtime/src/prompts/builders.ts +1 -1
  26. package/dist/runtime/src/version.ts +1 -1
  27. package/dist/runtime-helpers.js +2 -2
  28. package/dist/runtime-helpers.js.map +3 -3
  29. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +3 -0
  30. package/dist/types/packages/core/src/platform/mcp-config.d.ts +25 -13
  31. package/dist/types/packages/core/src/version.d.ts +1 -1
  32. package/package.json +1 -1
  33. /package/dist/{chunk-33exyd19.js.map → chunk-61n4gy9n.js.map} +0 -0
@@ -19,11 +19,22 @@ var __require = import.meta.require;
19
19
 
20
20
  // ../../packages/core/src/platform/paths.ts
21
21
  import { existsSync, realpathSync } from "fs";
22
- import { isAbsolute, relative, resolve, sep } from "path";
22
+ import { dirname, isAbsolute, relative, resolve, sep } from "path";
23
23
  function normalizeExistingOrResolved(filePath) {
24
24
  const resolved = resolve(filePath);
25
25
  try {
26
- return existsSync(resolved) ? realpathSync(resolved) : resolved;
26
+ if (existsSync(resolved))
27
+ return realpathSync(resolved);
28
+ let ancestor = resolved;
29
+ for (;; ) {
30
+ const parent = dirname(ancestor);
31
+ if (parent === ancestor)
32
+ return resolved;
33
+ ancestor = parent;
34
+ if (existsSync(ancestor)) {
35
+ return resolve(realpathSync(ancestor), relative(ancestor, resolved));
36
+ }
37
+ }
27
38
  } catch {
28
39
  return resolved;
29
40
  }
@@ -186,7 +197,7 @@ import {
186
197
  } from "fs";
187
198
  import { createRequire } from "module";
188
199
  import { homedir } from "os";
189
- import { dirname, join, resolve as resolve3 } from "path";
200
+ import { dirname as dirname2, join, resolve as resolve3 } from "path";
190
201
  import { fileURLToPath, pathToFileURL } from "url";
191
202
  function envText(envKey) {
192
203
  return readEnvText(process.env, envKey);
@@ -197,7 +208,7 @@ function resolveStateDir() {
197
208
  return configured ? resolve3(configured) : resolve3(HOME, ".negotium");
198
209
  }
199
210
  function resolveProjectRoot() {
200
- const moduleDir = dirname(fileURLToPath(import.meta.url));
211
+ const moduleDir = dirname2(fileURLToPath(import.meta.url));
201
212
  const packagedRuntime = resolve3(moduleDir, "runtime");
202
213
  if (existsSync2(resolve3(packagedRuntime, "src")))
203
214
  return packagedRuntime;
@@ -217,7 +228,7 @@ function resolveDependencyBin(name) {
217
228
  if (existsSync2(path))
218
229
  return path;
219
230
  }
220
- const parent = dirname(dir);
231
+ const parent = dirname2(dir);
221
232
  if (parent === dir)
222
233
  return resolve3(binDir, name);
223
234
  dir = parent;
@@ -325,7 +336,7 @@ function resolveTopicWorkspaceDir(topicId) {
325
336
  function loadOrCreateLocalSecret(envKey, filename, options = {}) {
326
337
  const envValue = envText(envKey);
327
338
  const secretFile = resolve3(SECRETS_DIR, filename);
328
- mkdirSync(dirname(secretFile), { recursive: true });
339
+ mkdirSync(dirname2(secretFile), { recursive: true });
329
340
  if (envValue) {
330
341
  if (options.persistEnvValue) {
331
342
  writeFileSync(secretFile, `${envValue}
@@ -1024,9 +1035,12 @@ function backgroundBashTransport(agent, port, userId, topic) {
1024
1035
  }
1025
1036
  function refreshForumCatalogViews() {
1026
1037
  const { all, required, optional } = classifyForumMcpServers(MCP_CATALOG);
1027
- allForumMcpServerNames.splice(0, allForumMcpServerNames.length, ...all);
1038
+ const nodeNames = nodeMcpEntries.map((entry) => entry.key);
1039
+ const allWithNodeEntries = [...new Set([...all, ...nodeNames])];
1040
+ const optionalWithNodeEntries = [...new Set([...optional, ...nodeNames])];
1041
+ allForumMcpServerNames.splice(0, allForumMcpServerNames.length, ...allWithNodeEntries);
1028
1042
  requiredForumMcpServers.splice(0, requiredForumMcpServers.length, ...required);
1029
- optionalForumMcpServers.splice(0, optionalForumMcpServers.length, ...optional);
1043
+ optionalForumMcpServers.splice(0, optionalForumMcpServers.length, ...optionalWithNodeEntries);
1030
1044
  }
1031
1045
  function isReservedRuntimeMcpServerName(name) {
1032
1046
  return Object.hasOwn(MCP_CATALOG, name) || nodeMcpEntries.some((entry) => entry.key === name);
@@ -1041,12 +1055,22 @@ function mergeHostMcpServers(base, hostMcpServers) {
1041
1055
  }
1042
1056
  return { ...base, ...hostMcpServers };
1043
1057
  }
1044
- function buildNodeMcpSpecs(agent, filter) {
1058
+ function buildNodeMcpSpecs(agent, filter, ctx) {
1045
1059
  const out = {};
1046
1060
  for (const entry of nodeMcpEntries) {
1047
1061
  if (!filter(entry.key))
1048
1062
  continue;
1049
- out[entry.key] = entry.kind === "http" ? longLivedHttpMcp(agent, entry.port) : {
1063
+ if (entry.kind === "http") {
1064
+ out[entry.key] = longLivedHttpMcp(agent, entry.port);
1065
+ continue;
1066
+ }
1067
+ if (entry.kind === "http-instance") {
1068
+ const port = resolvedNodeMcpPorts.get(entry)?.get(nodeMcpInstanceKey(ctx));
1069
+ if (port !== undefined)
1070
+ out[entry.key] = longLivedHttpMcp(agent, port);
1071
+ continue;
1072
+ }
1073
+ out[entry.key] = {
1050
1074
  command: entry.command,
1051
1075
  args: entry.args ?? [],
1052
1076
  ...entry.env ? { env: entry.env } : {}
@@ -1054,6 +1078,42 @@ function buildNodeMcpSpecs(agent, filter) {
1054
1078
  }
1055
1079
  return out;
1056
1080
  }
1081
+ function nodeMcpInstanceKey(ctx) {
1082
+ return ctx.topicId ?? `user:${ctx.userId}:session:${ctx.session}`;
1083
+ }
1084
+ async function prepareNodeMcpServersForQuery(opts) {
1085
+ if (opts.toolPolicy || opts.sessionType === "cron" || nodeMcpEntries.every((entry) => entry.kind !== "http-instance")) {
1086
+ return;
1087
+ }
1088
+ const forum = !["dm", "ephemeral", "manager"].includes(opts.sessionType ?? "forum");
1089
+ const enabled = opts.mcpEnabled ?? null;
1090
+ const instanceKey = nodeMcpInstanceKey({
1091
+ topicId: opts.topicId,
1092
+ userId: opts.userId || "local",
1093
+ session: opts.session || "default"
1094
+ });
1095
+ await Promise.all(nodeMcpEntries.map(async (entry) => {
1096
+ if (entry.kind !== "http-instance")
1097
+ return;
1098
+ if (forum && enabled !== null && !enabled.includes(entry.key))
1099
+ return;
1100
+ let ports = resolvedNodeMcpPorts.get(entry);
1101
+ if (!ports) {
1102
+ ports = new Map;
1103
+ resolvedNodeMcpPorts.set(entry, ports);
1104
+ }
1105
+ try {
1106
+ const port = await entry.ensurePort(instanceKey);
1107
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
1108
+ throw new Error(`invalid port ${port}`);
1109
+ }
1110
+ ports.set(instanceKey, port);
1111
+ } catch (err) {
1112
+ ports.delete(instanceKey);
1113
+ logger.warn({ err, key: entry.key, instanceKey }, "node mcp: failed to prepare instance-scoped server");
1114
+ }
1115
+ }));
1116
+ }
1057
1117
  function buildScope(scope, ctx, filter = () => true) {
1058
1118
  const out = {};
1059
1119
  for (const [name, entry] of Object.entries(MCP_CATALOG)) {
@@ -1067,14 +1127,15 @@ function buildScope(scope, ctx, filter = () => true) {
1067
1127
  out[name] = spec;
1068
1128
  }
1069
1129
  if (scope !== "cron") {
1070
- Object.assign(out, buildNodeMcpSpecs(ctx.agent, filter));
1130
+ Object.assign(out, buildNodeMcpSpecs(ctx.agent, filter, ctx));
1071
1131
  }
1072
1132
  return out;
1073
1133
  }
1074
1134
  function getDmMcpServers(opts) {
1075
1135
  return buildScope("dm", {
1076
1136
  userId: opts.userId,
1077
- session: "dm",
1137
+ session: opts.session ?? "dm",
1138
+ topicId: opts.topicId,
1078
1139
  agent: opts.agent,
1079
1140
  playwrightPort: opts.playwrightPort,
1080
1141
  playwrightCapability: opts.playwrightCapability
@@ -1211,6 +1272,8 @@ function getMcpServersForQuery(opts) {
1211
1272
  if (opts.sessionType === "dm" || opts.sessionType === "ephemeral") {
1212
1273
  return getDmMcpServers({
1213
1274
  userId: opts.userId || "local",
1275
+ session: opts.session,
1276
+ topicId: opts.topicId,
1214
1277
  agent: opts.agent,
1215
1278
  playwrightPort: opts.playwrightPort,
1216
1279
  playwrightCapability: opts.playwrightCapability
@@ -1262,7 +1325,7 @@ function getMcpServersForQuery(opts) {
1262
1325
  peerBridge: opts.peerBridge
1263
1326
  });
1264
1327
  }
1265
- var _playwrightUnavailableNotifier, _playwrightUnavailableLastNotifiedAt, _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS, _playwrightUnavailableThisTurn, cuaRsMcpPort, cuaRsMcpToken, MCP_CATALOG, allForumMcpServerNames, requiredForumMcpServers, REQUIRED_FORUM_MCP_SERVERS, optionalForumMcpServers, nodeMcpEntries;
1328
+ var _playwrightUnavailableNotifier, _playwrightUnavailableLastNotifiedAt, _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS, _playwrightUnavailableThisTurn, cuaRsMcpPort, cuaRsMcpToken, MCP_CATALOG, nodeMcpEntries, resolvedNodeMcpPorts, allForumMcpServerNames, requiredForumMcpServers, REQUIRED_FORUM_MCP_SERVERS, optionalForumMcpServers;
1266
1329
  var init_mcp_config = __esm(() => {
1267
1330
  init_canonical_bridge_config();
1268
1331
  init_runtime_spec();
@@ -1316,7 +1379,8 @@ var init_mcp_config = __esm(() => {
1316
1379
  if (!topicId || !agent)
1317
1380
  return null;
1318
1381
  return buildRuntimeMcpSpec(agent, {
1319
- userId: actorUserId ?? userId,
1382
+ userId,
1383
+ ...actorUserId ? { actorUserId } : {},
1320
1384
  topicId,
1321
1385
  topicTitle: session,
1322
1386
  queryId,
@@ -1496,12 +1560,13 @@ var init_mcp_config = __esm(() => {
1496
1560
  }
1497
1561
  }
1498
1562
  };
1563
+ nodeMcpEntries = [];
1564
+ resolvedNodeMcpPorts = new WeakMap;
1499
1565
  allForumMcpServerNames = [];
1500
1566
  requiredForumMcpServers = [];
1501
1567
  REQUIRED_FORUM_MCP_SERVERS = requiredForumMcpServers;
1502
1568
  optionalForumMcpServers = [];
1503
1569
  refreshForumCatalogViews();
1504
- nodeMcpEntries = [];
1505
1570
  });
1506
1571
 
1507
1572
  // ../../packages/core/src/storage/sqlite.ts
@@ -1569,7 +1634,7 @@ var init_sqlite = __esm(async () => {
1569
1634
  // ../../packages/core/src/storage/storage-host.ts
1570
1635
  import { mkdirSync as mkdirSync2 } from "fs";
1571
1636
  import { homedir as homedir2 } from "os";
1572
- import { dirname as dirname2, join as join2, resolve as resolve4 } from "path";
1637
+ import { dirname as dirname3, join as join2, resolve as resolve4 } from "path";
1573
1638
  function storageState() {
1574
1639
  const holder = globalThis;
1575
1640
  const existing = holder[STORAGE_HOST_STATE];
@@ -1648,7 +1713,7 @@ function defaultDatabase() {
1648
1713
  return state.fallbackDatabase;
1649
1714
  if (state.fallbackDatabase)
1650
1715
  closeDatabase(state.fallbackDatabase);
1651
- mkdirSync2(dirname2(path), { recursive: true });
1716
+ mkdirSync2(dirname3(path), { recursive: true });
1652
1717
  state.fallbackDatabase = new Database(path, { create: true });
1653
1718
  state.fallbackDatabasePath = path;
1654
1719
  initializeDatabase(state.fallbackDatabase);
@@ -1926,7 +1991,7 @@ var init_vault = __esm(async () => {
1926
1991
 
1927
1992
  // ../../packages/core/src/agents/execution-host.ts
1928
1993
  import { AsyncLocalStorage } from "async_hooks";
1929
- import { dirname as dirname3 } from "path";
1994
+ import { dirname as dirname4 } from "path";
1930
1995
  function activeHost() {
1931
1996
  const scoped = scopedHost.getStore();
1932
1997
  if (scoped)
@@ -1961,7 +2026,7 @@ function hostedCodexAuthFilePath() {
1961
2026
  return activeHost().codexAuthFilePath();
1962
2027
  }
1963
2028
  function hostedCodexHomePath() {
1964
- return dirname3(hostedCodexAuthFilePath());
2029
+ return dirname4(hostedCodexAuthFilePath());
1965
2030
  }
1966
2031
  var defaultHost, hostRegistrations, scopedHost;
1967
2032
  var init_execution_host = __esm(async () => {
@@ -2246,7 +2311,7 @@ import {
2246
2311
  unlinkSync as unlinkSync2,
2247
2312
  writeFileSync as writeFileSync2
2248
2313
  } from "fs";
2249
- import { dirname as dirname4 } from "path";
2314
+ import { dirname as dirname5 } from "path";
2250
2315
  function readJsonlLines(filePath) {
2251
2316
  return readFileSync2(filePath, "utf-8").trim().split(`
2252
2317
  `).filter(Boolean);
@@ -2287,7 +2352,7 @@ function appendJsonlEntry(filePath, entry) {
2287
2352
  `);
2288
2353
  }
2289
2354
  function appendJsonlLine(filePath, line) {
2290
- mkdirSync5(dirname4(filePath), { recursive: true });
2355
+ mkdirSync5(dirname5(filePath), { recursive: true });
2291
2356
  const lockPath = `${filePath}${LOCK_SUFFIX}`;
2292
2357
  const payload = line.endsWith(`
2293
2358
  `) ? line : `${line}
@@ -2318,7 +2383,7 @@ function appendJsonlLine(filePath, line) {
2318
2383
  }
2319
2384
  }
2320
2385
  function writeJsonlFile(filePath, entries) {
2321
- const dir = dirname4(filePath);
2386
+ const dir = dirname5(filePath);
2322
2387
  mkdirSync5(dir, { recursive: true });
2323
2388
  const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
2324
2389
  const payload = `${entries.map((e) => JSON.stringify(e)).join(`
@@ -2586,7 +2651,7 @@ var init_claude_registry = __esm(() => {
2586
2651
  // ../../packages/core/src/agents/rollout/codex.ts
2587
2652
  import { randomBytes as randomBytes4 } from "crypto";
2588
2653
  import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync2, unlinkSync as unlinkSync4 } from "fs";
2589
- import { basename, dirname as dirname5, join as join6, resolve as resolve6 } from "path";
2654
+ import { basename, dirname as dirname6, join as join6, resolve as resolve6 } from "path";
2590
2655
  function codexSessionsDir() {
2591
2656
  return join6(hostedCodexHomePath(), "sessions");
2592
2657
  }
@@ -2669,7 +2734,7 @@ function canonicalFilePath(path) {
2669
2734
  return realpathSync3(absolute);
2670
2735
  } catch {
2671
2736
  try {
2672
- return join6(realpathSync3(dirname5(absolute)), basename(absolute));
2737
+ return join6(realpathSync3(dirname6(absolute)), basename(absolute));
2673
2738
  } catch {
2674
2739
  return absolute;
2675
2740
  }
@@ -3118,7 +3183,7 @@ var init_codex = __esm(async () => {
3118
3183
  });
3119
3184
 
3120
3185
  // ../../packages/core/src/version.ts
3121
- var NEGOTIUM_VERSION = "0.16.4";
3186
+ var NEGOTIUM_VERSION = "0.17.0";
3122
3187
 
3123
3188
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3124
3189
  import { spawn as spawn2 } from "child_process";
@@ -3136,7 +3201,7 @@ import {
3136
3201
  } from "fs";
3137
3202
  import { createRequire as createRequire2 } from "module";
3138
3203
  import { tmpdir } from "os";
3139
- import { dirname as dirname6, join as join7 } from "path";
3204
+ import { dirname as dirname7, join as join7 } from "path";
3140
3205
  function readPackageVersion(packageJsonPath) {
3141
3206
  const parsed = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
3142
3207
  if (typeof parsed.version !== "string" || !parsed.version.trim()) {
@@ -3145,7 +3210,7 @@ function readPackageVersion(packageJsonPath) {
3145
3210
  return parsed.version;
3146
3211
  }
3147
3212
  function codexCliScriptPath() {
3148
- return join7(dirname6(bundledCodexPackagePath), "bin", "codex.js");
3213
+ return join7(dirname7(bundledCodexPackagePath), "bin", "codex.js");
3149
3214
  }
3150
3215
  function parseCodexModelCache(contents, sourcePath) {
3151
3216
  let parsed;
@@ -3186,7 +3251,7 @@ function writePrivateFileAtomic(path, contents) {
3186
3251
  }
3187
3252
  }
3188
3253
  function bundledCodexModelCachePath(authFilePath) {
3189
- return join7(dirname6(authFilePath), NEGOTIUM_MODEL_CACHE);
3254
+ return join7(dirname7(authFilePath), NEGOTIUM_MODEL_CACHE);
3190
3255
  }
3191
3256
  async function bootstrapCodexModelCache(codexHome, cachePath) {
3192
3257
  const child = spawn2(process.execPath, [codexCliScriptPath(), "app-server", "--stdio"], {
@@ -3272,7 +3337,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
3272
3337
  });
3273
3338
  }
3274
3339
  async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
3275
- const sourceHome = dirname6(authFilePath);
3340
+ const sourceHome = dirname7(authFilePath);
3276
3341
  const isolatedHome = mkdtempSync(join7(tmpdir(), "negotium-codex-models-"));
3277
3342
  const isolatedCachePath = join7(isolatedHome, "models_cache.json");
3278
3343
  try {
@@ -3292,7 +3357,7 @@ async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
3292
3357
  }
3293
3358
  }
3294
3359
  async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexModelCache) {
3295
- const codexHome = dirname6(authFilePath);
3360
+ const codexHome = dirname7(authFilePath);
3296
3361
  const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;
3297
3362
  if (configuredCachePath) {
3298
3363
  if (!existsSync6(configuredCachePath)) {
@@ -3321,7 +3386,7 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
3321
3386
  return bundledCachePath;
3322
3387
  }
3323
3388
  function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath) {
3324
- const codexHome = dirname6(authFilePath);
3389
+ const codexHome = dirname7(authFilePath);
3325
3390
  const outputPath = join7(codexHome, NEGOTIUM_MODEL_CATALOG);
3326
3391
  const parsed = readCodexModelCache(sourcePath).parsed;
3327
3392
  const models = parsed.models.map((model, index) => {
@@ -3738,7 +3803,7 @@ function sanitizeId(id) {
3738
3803
 
3739
3804
  // ../../packages/core/src/storage/tasks.ts
3740
3805
  import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync7, renameSync as renameSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
3741
- import { dirname as dirname7, join as join10 } from "path";
3806
+ import { dirname as dirname8, join as join10 } from "path";
3742
3807
  function safeTaskScopeKey(scopeKey) {
3743
3808
  const safe = sanitizeFileName(scopeKey);
3744
3809
  if (!safe || safe === "." || safe === "..") {
@@ -3850,7 +3915,7 @@ import {
3850
3915
  unlinkSync as unlinkSync7,
3851
3916
  writeFileSync as writeFileSync7
3852
3917
  } from "fs";
3853
- import { dirname as dirname8, join as join11 } from "path";
3918
+ import { dirname as dirname9, join as join11 } from "path";
3854
3919
  function conversationDir(_userId) {
3855
3920
  return join11(resolveStorageDataDir(), "conversations");
3856
3921
  }
@@ -3888,7 +3953,7 @@ function appendConversationEventStrict(userId, topicName, agent, event) {
3888
3953
  event
3889
3954
  };
3890
3955
  const line = JSON.stringify(entry);
3891
- mkdirSync9(dirname8(path), { recursive: true });
3956
+ mkdirSync9(dirname9(path), { recursive: true });
3892
3957
  appendJsonlLine(path, line);
3893
3958
  const activePath = getActiveConversationPath(userId, topicName);
3894
3959
  if (existsSync10(activePath)) {
@@ -3906,7 +3971,7 @@ function appendRawConversationEventStrict(userId, topicName, agent, event) {
3906
3971
  agent,
3907
3972
  event
3908
3973
  };
3909
- mkdirSync9(dirname8(path), { recursive: true });
3974
+ mkdirSync9(dirname9(path), { recursive: true });
3910
3975
  appendJsonlLine(path, JSON.stringify(entry));
3911
3976
  }
3912
3977
  function readConversationPath(path) {
@@ -3947,7 +4012,7 @@ function replaceRawConversationStrict(userId, topicName, entries) {
3947
4012
  }
3948
4013
  function replaceConversationPathStrict(path, entries) {
3949
4014
  const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
3950
- mkdirSync9(dirname8(path), { recursive: true });
4015
+ mkdirSync9(dirname9(path), { recursive: true });
3951
4016
  try {
3952
4017
  writeFileSync7(tempPath, entries.length > 0 ? `${entries.map((entry) => JSON.stringify(entry)).join(`
3953
4018
  `)}
@@ -4629,9 +4694,19 @@ var init_claude_provider = __esm(async () => {
4629
4694
  "ScheduleWakeup",
4630
4695
  "CronCreate",
4631
4696
  "CronList",
4632
- "CronDelete"
4697
+ "CronDelete",
4698
+ "RemoteTrigger"
4699
+ ];
4700
+ CLAUDE_NATIVE_AGENT_TOOLS = [
4701
+ "Task",
4702
+ "Agent",
4703
+ "TaskOutput",
4704
+ "TaskStop",
4705
+ "ListAgents",
4706
+ "SendMessage",
4707
+ "TeamCreate",
4708
+ "TeamDelete"
4633
4709
  ];
4634
- CLAUDE_NATIVE_AGENT_TOOLS = ["Task", "Agent", "TaskOutput", "TaskStop"];
4635
4710
  CLAUDE_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
4636
4711
  CLAUDE_IMAGE_MIME_TYPES = new Set([
4637
4712
  "image/jpeg",
@@ -4891,7 +4966,7 @@ import { existsSync as existsSync12 } from "fs";
4891
4966
  import { chmod, mkdtemp, rm, writeFile } from "fs/promises";
4892
4967
  import { createServer } from "net";
4893
4968
  import { tmpdir as tmpdir2 } from "os";
4894
- import { dirname as dirname9, join as join12, resolve as resolve8 } from "path";
4969
+ import { dirname as dirname10, join as join12, resolve as resolve8 } from "path";
4895
4970
  import { fileURLToPath as fileURLToPath2 } from "url";
4896
4971
  function evaluateCodexVaultPreToolUse(input, userId, operations) {
4897
4972
  if (operations.referencesSensitiveStorage(input.tool_input)) {
@@ -4920,7 +4995,7 @@ function shellQuote(value) {
4920
4995
  return `'${value.replaceAll("'", `'"'"'`)}'`;
4921
4996
  }
4922
4997
  function hookClientPath() {
4923
- const moduleDir = dirname9(fileURLToPath2(import.meta.url));
4998
+ const moduleDir = dirname10(fileURLToPath2(import.meta.url));
4924
4999
  const adjacent = resolve8(moduleDir, "codex-vault-hook.mjs");
4925
5000
  if (existsSync12(adjacent))
4926
5001
  return adjacent;
@@ -5569,7 +5644,7 @@ __export(exports_codex_provider, {
5569
5644
  import { execFileSync as execFileSync4 } from "child_process";
5570
5645
  import { existsSync as existsSync13, readFileSync as readFileSync11, realpathSync as realpathSync4, statSync as statSync5 } from "fs";
5571
5646
  import { homedir as homedir6 } from "os";
5572
- import { dirname as dirname10, isAbsolute as isAbsolute3, join as join13, relative as relative2, resolve as resolve10 } from "path";
5647
+ import { dirname as dirname11, isAbsolute as isAbsolute3, join as join13, relative as relative2, resolve as resolve10 } from "path";
5573
5648
  import { Codex } from "@openai/codex-sdk";
5574
5649
  function sameCodexUsage(usage, total) {
5575
5650
  return usage.input_tokens === total.inputTokens && usage.output_tokens === total.outputTokens && (usage.cached_input_tokens ?? 0) === total.cachedInputTokens && (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens;
@@ -5597,7 +5672,7 @@ function codexMcpServerName(name) {
5597
5672
  return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;
5598
5673
  }
5599
5674
  function globalCodexMcpServerNames(authFilePath) {
5600
- const configPath = join13(dirname10(authFilePath), "config.toml");
5675
+ const configPath = join13(dirname11(authFilePath), "config.toml");
5601
5676
  if (!existsSync13(configPath))
5602
5677
  return [];
5603
5678
  try {
@@ -5977,7 +6052,14 @@ async function* codexProvider(opts) {
5977
6052
  codexPathOverride: vaultHook.codexPathOverride,
5978
6053
  ...codexEnvironment ? { env: codexEnvironment } : {},
5979
6054
  config: {
5980
- features: { hooks: true, multi_agent: false, multi_agent_v2: false, enable_fanout: false },
6055
+ agents: { enabled: false },
6056
+ features: {
6057
+ hooks: true,
6058
+ goals: false,
6059
+ multi_agent: false,
6060
+ multi_agent_v2: false,
6061
+ enable_fanout: false
6062
+ },
5981
6063
  hooks: vaultHook.hooks,
5982
6064
  model_catalog_json: codexModelCatalogPath,
5983
6065
  mcp_servers: codexMcpServers,
@@ -6503,6 +6585,7 @@ async function* runAgent(opts) {
6503
6585
  return;
6504
6586
  }
6505
6587
  }
6588
+ await prepareNodeMcpServersForQuery(dispatchOpts);
6506
6589
  const taskScope = resolveTaskEventScope(dispatchOpts);
6507
6590
  const stream = taskScope ? withTaskSnapshots(dispatchAgent(dispatchOpts), taskScope) : dispatchAgent(dispatchOpts);
6508
6591
  for await (const event of stream) {
@@ -6516,6 +6599,7 @@ var loadClaudeProvider, loadCodexProvider, loadMaestroProvider;
6516
6599
  var init_agents = __esm(async () => {
6517
6600
  init_claude();
6518
6601
  init_logger();
6602
+ init_mcp_config();
6519
6603
  init_types();
6520
6604
  await __promiseAll([
6521
6605
  init_execution_host(),
@@ -7204,7 +7288,7 @@ function buildRuntimeToolSection(opts, extensions) {
7204
7288
  "A subagent starts fresh but inherits this room's agent, model, and effective topic memory; include all required context, paths, and acceptance criteria in `task`.",
7205
7289
  "Subagents run asynchronously. Choose one result path: `auto` returns the final body to the direct parent; `tell` requires child `tell_session` to its recipient and does not auto-return the body; `status-only` returns lifecycle without content. Runtime length alone does not justify `status-only`. Do not wait or poll; continue or finish the turn."
7206
7290
  ] : [];
7207
- const nativeTaskPolicyLine = agentKind === "claude" ? `Do not use provider-native todo/task/subagent tools such as "TodoWrite", "Task", "Agent", "TaskCreate", "TaskUpdate", "TaskList", "TaskOutput", or "TaskStop"; they are disabled or not shared across agents.${canSpawnSubagents ? " For delegation, use the runtime spawn_subagent tool instead." : ""}` : agentKind === "maestro" ? `Do not use provider-native task-store tools such as "TaskCreate", "TaskUpdate", "TaskList", "TaskGet", "TaskOutput", or "TaskStop"; they are disabled or not shared across agents. Do not use the Maestro "Agent" sub-agent tool either; it is disabled.${canSpawnSubagents ? " Use the runtime spawn_subagent tool for delegation so work is visible in its own room and reporting follows report_mode." : " Delegation is unavailable in this room."}` : 'Do not use provider-native todo/plan surfaces such as "todo_list" or "update_plan"; they are ignored or not shared across agents.';
7291
+ const nativeTaskPolicyLine = agentKind === "claude" ? `Do not use provider-native todo/task/subagent tools such as "TodoWrite", "Task", "Agent", "TaskCreate", "TaskUpdate", "TaskList", "TaskOutput", or "TaskStop"; they are disabled or not shared across agents.${canSpawnSubagents ? " For delegation, use the runtime spawn_subagent tool instead." : ""}` : agentKind === "maestro" ? `Do not use provider-native task-store tools such as "TaskCreate", "TaskUpdate", "TaskList", "TaskGet", "TaskOutput", or "TaskStop"; they are disabled or not shared across agents. Do not use the Maestro "Agent" sub-agent tool either; it is disabled.${canSpawnSubagents ? " Use the runtime spawn_subagent tool for delegation so work is visible in its own room and reporting follows report_mode." : " Delegation is unavailable in this room."}` : 'Do not use provider-native goal/todo/plan surfaces such as "create_goal", "get_goal", "update_goal", "todo_list", or "update_plan"; they are disabled, ignored, or not shared across agents.';
7208
7292
  const visualSection = visualTools ? [
7209
7293
  visualToolLine,
7210
7294
  mermaidToolLine,
@@ -8482,7 +8566,7 @@ var init_api_topics = __esm(async () => {
8482
8566
  });
8483
8567
 
8484
8568
  // ../../packages/core/src/storage/wiki.ts
8485
- import { basename as basename3, dirname as dirname11, join as join15 } from "path";
8569
+ import { basename as basename3, dirname as dirname12, join as join15 } from "path";
8486
8570
  function getSharedWikiDir(workspaceDir = resolveStorageWorkspaceDir()) {
8487
8571
  return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() : join15(workspaceDir, "wiki");
8488
8572
  }
@@ -11725,11 +11809,11 @@ import {
11725
11809
  unlinkSync as unlinkSync11,
11726
11810
  writeFileSync as writeFileSync9
11727
11811
  } from "fs";
11728
- import { dirname as dirname12, join as join20, resolve as resolve16 } from "path";
11812
+ import { dirname as dirname13, join as join20, resolve as resolve16 } from "path";
11729
11813
  function removeDefaultProfileDataDir(userDataDir) {
11730
11814
  const root = resolve16(BROWSER_PROFILES_DIR);
11731
11815
  const target = resolve16(userDataDir);
11732
- if (dirname12(target) !== root) {
11816
+ if (dirname13(target) !== root) {
11733
11817
  throw new Error(`Refusing to delete browser profile outside managed root: ${target}`);
11734
11818
  }
11735
11819
  const existed = existsSync19(target);
@@ -12309,7 +12393,7 @@ async function cloneProfileForChild(opts) {
12309
12393
  if (existsSync19(dstDir)) {
12310
12394
  rmSync3(dstDir, { recursive: true, force: true });
12311
12395
  }
12312
- mkdirSync11(dirname12(dstDir), { recursive: true });
12396
+ mkdirSync11(dirname13(dstDir), { recursive: true });
12313
12397
  if (process.platform === "darwin") {
12314
12398
  try {
12315
12399
  execFileSync7("cp", ["-cR", srcDir, dstDir], { stdio: "pipe" });
@@ -12910,7 +12994,7 @@ var init_idle_compact = __esm(async () => {
12910
12994
 
12911
12995
  // ../../packages/core/src/agents/topic-cleanup.ts
12912
12996
  import { mkdirSync as mkdirSync13, renameSync as renameSync6, unlinkSync as unlinkSync12, writeFileSync as writeFileSync11 } from "fs";
12913
- import { dirname as dirname13 } from "path";
12997
+ import { dirname as dirname14 } from "path";
12914
12998
  function collectSessionIdsByAgent(entries, extraSessions = []) {
12915
12999
  const out = new Map;
12916
13000
  for (const e of entries) {
@@ -12976,7 +13060,7 @@ function createTopicLogMaintenance(host) {
12976
13060
  const path = runtimeHost.activeConversationPath(opts.userId, opts.topicName);
12977
13061
  const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
12978
13062
  try {
12979
- mkdirSync13(dirname13(path), { recursive: true });
13063
+ mkdirSync13(dirname14(path), { recursive: true });
12980
13064
  writeFileSync11(tempPath, retained.length > 0 ? `${retained.map((entry) => JSON.stringify(entry)).join(`
12981
13065
  `)}
12982
13066
  ` : "", { flag: "wx" });
@@ -14843,7 +14927,7 @@ import {
14843
14927
  unlinkSync as unlinkSync16,
14844
14928
  writeFileSync as writeFileSync14
14845
14929
  } from "fs";
14846
- import { dirname as dirname14, join as join27 } from "path";
14930
+ import { dirname as dirname15, join as join27 } from "path";
14847
14931
  function pendingAskDir(userId) {
14848
14932
  const rawUserId = String(userId);
14849
14933
  const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash9("sha256").update(rawUserId).digest("hex")}`;
@@ -14866,7 +14950,7 @@ function legacyPendingAskPath(key) {
14866
14950
  }
14867
14951
  const dir = pendingAskDir(key.userId);
14868
14952
  const candidate = join27(dir, `${key.from}___${key.to}.pending`);
14869
- return dirname14(candidate) === dir ? candidate : null;
14953
+ return dirname15(candidate) === dir ? candidate : null;
14870
14954
  }
14871
14955
  function parsePendingAskFilename(fileName) {
14872
14956
  if (!fileName.endsWith(".pending"))
@@ -17329,7 +17413,7 @@ var init_turn_session = __esm(async () => {
17329
17413
 
17330
17414
  // ../../packages/core/src/storage/app-settings.ts
17331
17415
  import { existsSync as existsSync20, mkdirSync as mkdirSync18, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
17332
- import { dirname as dirname15, join as join29 } from "path";
17416
+ import { dirname as dirname16, join as join29 } from "path";
17333
17417
  function settingsFile() {
17334
17418
  return join29(resolveStorageDataDir(), "otium-settings.json");
17335
17419
  }
@@ -20885,4 +20969,4 @@ export {
20885
20969
  DEFAULT_SELF_CONFIG_PRODUCT
20886
20970
  };
20887
20971
 
20888
- //# debugId=0C381456723AA9D364756E2164756E21
20972
+ //# debugId=B662EA253049A7FE64756E2164756E21