negotium 0.19.0 → 0.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/agent-helpers.js +142 -77
  2. package/dist/agent-helpers.js.map +10 -10
  3. package/dist/background-bash.js.map +1 -1
  4. package/dist/browser-runtime.js.map +1 -1
  5. package/dist/{chunk-y8rtedjb.js → chunk-55dd0xw7.js} +2 -2
  6. package/dist/{chunk-y8rtedjb.js.map → chunk-55dd0xw7.js.map} +2 -2
  7. package/dist/{chunk-q2s5f70x.js → chunk-aqqmzmft.js} +1 -1
  8. package/dist/{chunk-3d1pjgfw.js → chunk-cv7vdsrn.js} +2 -2
  9. package/dist/{chunk-3d1pjgfw.js.map → chunk-cv7vdsrn.js.map} +2 -2
  10. package/dist/{chunk-4bzehg8t.js → chunk-exqz8bez.js} +3 -3
  11. package/dist/{chunk-4bzehg8t.js.map → chunk-exqz8bez.js.map} +2 -2
  12. package/dist/{chunk-22mtr8np.js → chunk-kkftbxh2.js} +1 -1
  13. package/dist/hosted-agent.js +4 -4
  14. package/dist/hosted-agent.js.map +2 -2
  15. package/dist/main.js +140 -82
  16. package/dist/main.js.map +11 -11
  17. package/dist/mcp-factories.js +214 -165
  18. package/dist/mcp-factories.js.map +9 -9
  19. package/dist/media.js.map +1 -1
  20. package/dist/prompts.js +23 -3
  21. package/dist/prompts.js.map +4 -4
  22. package/dist/query-runtime.js +56 -6
  23. package/dist/query-runtime.js.map +7 -5
  24. package/dist/registry.js +3 -3
  25. package/dist/rollout.js +2 -2
  26. package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +24 -4
  27. package/dist/runtime/src/agents/model-catalog.ts +27 -2
  28. package/dist/runtime/src/agents/self-config-core.ts +10 -1
  29. package/dist/runtime/src/platform/config.ts +1 -1
  30. package/dist/runtime/src/query/state.ts +19 -1
  31. package/dist/runtime/src/storage/token-stats.ts +4 -1
  32. package/dist/runtime/src/version.ts +1 -1
  33. package/dist/runtime-helpers.js.map +1 -1
  34. package/dist/storage.js +5 -2
  35. package/dist/storage.js.map +3 -3
  36. package/dist/types/packages/core/src/platform/config.d.ts +1 -1
  37. package/dist/types/packages/core/src/query/state.d.ts +8 -0
  38. package/dist/types/packages/core/src/version.d.ts +1 -1
  39. package/dist/vault.js.map +1 -1
  40. package/package.json +3 -3
  41. /package/dist/{chunk-q2s5f70x.js.map → chunk-aqqmzmft.js.map} +0 -0
  42. /package/dist/{chunk-22mtr8np.js.map → chunk-kkftbxh2.js.map} +0 -0
package/dist/main.js CHANGED
@@ -383,7 +383,7 @@ function resolveWhisperBackend() {
383
383
  function codexAuthFilePath() {
384
384
  return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
385
385
  }
386
- var HOME, PROJECT_ROOT, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BINARY_EXTENSION, BROWSER_RS_VERSION = "v0.6.0", BROWSER_RS_MIN_SECURE_VERSION = "0.2.1", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.10", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER_PATH, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, DECISION_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, NODE_ID, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, RUNTIME_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, ABSOLUTE_PATH_PREFIX, FILE_EXTENSIONS_REGEX, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5", MODEL_HAIKU = "claude-haiku-4-5-20251001", MODEL_FABLE = "claude-fable-5-1", MODEL_DEEPSEEK_V4_PRO = "deepseek-v4-pro", MODEL_DEEPSEEK_V4_FLASH = "deepseek-v4-flash", FALLBACK_AGENT, FALLBACK_MODEL, DEFAULT_TOPIC_EFFORT, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, WHISPER_BACKEND, MLX_WHISPER_BIN, WHISPER_MODEL_MLX, _envMaxTellDepth, MAX_TELL_DEPTH;
386
+ var HOME, PROJECT_ROOT, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BINARY_EXTENSION, BROWSER_RS_VERSION = "v0.6.0", BROWSER_RS_MIN_SECURE_VERSION = "0.2.1", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.10", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER_PATH, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, DECISION_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, NODE_ID, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, RUNTIME_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, ABSOLUTE_PATH_PREFIX, FILE_EXTENSIONS_REGEX, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5-5", MODEL_HAIKU = "claude-haiku-4-5-20251001", MODEL_FABLE = "claude-fable-5-1", MODEL_DEEPSEEK_V4_PRO = "deepseek-v4-pro", MODEL_DEEPSEEK_V4_FLASH = "deepseek-v4-flash", FALLBACK_AGENT, FALLBACK_MODEL, DEFAULT_TOPIC_EFFORT, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, WHISPER_BACKEND, MLX_WHISPER_BIN, WHISPER_MODEL_MLX, _envMaxTellDepth, MAX_TELL_DEPTH;
387
387
  var init_config = __esm(() => {
388
388
  init_config_helpers();
389
389
  init_logger();
@@ -4889,7 +4889,7 @@ var exports_version = {};
4889
4889
  __export(exports_version, {
4890
4890
  NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
4891
4891
  });
4892
- var NEGOTIUM_VERSION = "0.19.0";
4892
+ var NEGOTIUM_VERSION = "0.19.2";
4893
4893
 
4894
4894
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
4895
4895
  import { spawn as spawn2 } from "child_process";
@@ -10385,6 +10385,8 @@ var init_model_catalog = __esm(() => {
10385
10385
  haiku: "claude",
10386
10386
  fable: "claude",
10387
10387
  "gpt-6-astra": "codex",
10388
+ "gpt-6-sol": "codex",
10389
+ "gpt-6-luna": "codex",
10388
10390
  "gpt-5.6-luna": "codex",
10389
10391
  "gpt-5.6-terra": "codex",
10390
10392
  "gpt-5.6-sol": "codex",
@@ -10414,6 +10416,26 @@ var init_model_catalog = __esm(() => {
10414
10416
  marginalTokenCost: "Codex credits (OpenAI API rate): $10/M uncached input, $1/M cached input, $12.50/M cache write, $50/M output",
10415
10417
  estimatedUsage: `Released 2026-09-03; became Codex CLI's bundled default in v0.153.4 (2026-09-05). Local message-count/quota-weight ranges not yet published as of the last catalog check \u2014 expect a quota weight above gpt-5.6-sol given the higher per-token cost. ${CODEX_COMMUNITY_WEEKLY}`
10416
10418
  },
10419
+ {
10420
+ model: "gpt-6-sol",
10421
+ agent: "codex",
10422
+ description: "GPT-6 generation Sol route (2026-09-22) for demanding coding and agentic work.",
10423
+ intelligenceTier: "opus",
10424
+ routingSummary: "demanding coding work; about half as many mistakes as gpt-5.6-sol at half the price",
10425
+ accessCost: CODEX_PRO_20X_COST,
10426
+ marginalTokenCost: "Codex credits (OpenAI API rate): $2/M uncached input, $0.20/M cached input (assumed), $10/M output",
10427
+ estimatedUsage: `Released 2026-09-22; local message-count/quota-weight ranges not yet published. ${CODEX_COMMUNITY_WEEKLY}`
10428
+ },
10429
+ {
10430
+ model: "gpt-6-luna",
10431
+ agent: "codex",
10432
+ description: "GPT-6 generation Luna route (2026-09-22): fast, high-volume, lowest cost.",
10433
+ intelligenceTier: "sonnet",
10434
+ routingSummary: "fast high-volume work; cheapest Codex route",
10435
+ accessCost: CODEX_PRO_20X_COST,
10436
+ marginalTokenCost: "Codex credits (OpenAI API rate): $0.10/M uncached input, $0.01/M cached input (assumed), $0.50/M output",
10437
+ estimatedUsage: `Released 2026-09-22; local message-count/quota-weight ranges not yet published. ${CODEX_COMMUNITY_WEEKLY}`
10438
+ },
10417
10439
  {
10418
10440
  model: "gpt-5.6-sol",
10419
10441
  agent: "codex",
@@ -10459,9 +10481,9 @@ var init_model_catalog = __esm(() => {
10459
10481
  agent: "claude",
10460
10482
  description: "High-capability Claude route for complex reasoning and tool-heavy work.",
10461
10483
  intelligenceTier: "opus",
10462
- routingSummary: "complex reasoning and tool-heavy work; about 2.5x Sonnet marginal cost",
10484
+ routingSummary: "complex reasoning and tool-heavy work; about 2x Sonnet marginal cost",
10463
10485
  accessCost: CLAUDE_MAX_20X_COST,
10464
- marginalTokenCost: "Claude API/extra usage: $5/M input, $6.25/M cache write, $0.50/M cache read, $25/M output",
10486
+ marginalTokenCost: "Claude API/extra usage (Opus 5.5, 2026-09-22): $4/M input, $5/M cache write (assumed), $0.40/M cache read (assumed), $20/M output",
10465
10487
  estimatedUsage: `${CLAUDE_COMMUNITY_SESSION}; Opus uses the shared all-model weekly pool more quickly than Sonnet. No stable per-model token cap is published.`
10466
10488
  },
10467
10489
  {
@@ -14595,11 +14617,14 @@ var init_token_stats = __esm(async () => {
14595
14617
  ]);
14596
14618
  TOKEN_PRICES = {
14597
14619
  "codex:gpt-6-astra": { input: 10, cacheWrite: 12.5, cacheRead: 1, output: 50 },
14620
+ "codex:gpt-6-sol": { input: 2, cacheRead: 0.2, output: 10 },
14621
+ "codex:gpt-6-luna": { input: 0.1, cacheRead: 0.01, output: 0.5 },
14598
14622
  "codex:gpt-5.6-sol": { input: 5, cacheRead: 0.5, output: 30 },
14599
14623
  "codex:gpt-5.6-terra": { input: 2.5, cacheRead: 0.25, output: 15 },
14600
14624
  "codex:gpt-5.6-luna": { input: 1, cacheRead: 0.1, output: 6 },
14601
14625
  "claude:fable": { input: 10, cacheWrite: 12.5, cacheRead: 0.25, output: 50 },
14602
- "claude:opus": { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 },
14626
+ "claude:opus": { input: 4, cacheWrite: 5, cacheRead: 0.4, output: 20 },
14627
+ "claude:claude-opus-5-5": { input: 4, cacheWrite: 5, cacheRead: 0.4, output: 20 },
14603
14628
  "claude:sonnet": { input: 2, cacheWrite: 2.5, cacheRead: 0.2, output: 10 },
14604
14629
  "maestro:kimi-k3": { input: 3, cacheRead: 0.3, output: 15 },
14605
14630
  "maestro:kimi-k2.7-code": { input: 0.95, cacheRead: 0.19, output: 4 },
@@ -16619,7 +16644,16 @@ function escapeRegExp2(value) {
16619
16644
  function agentAliases(agent) {
16620
16645
  switch (agent) {
16621
16646
  case "codex":
16622
- return ["codex", "\uCF54\uB371\uC2A4", "gpt-5.6-luna", "gpt-5.6-terra", "gpt-5.6-sol", "gpt-6-astra"];
16647
+ return [
16648
+ "codex",
16649
+ "\uCF54\uB371\uC2A4",
16650
+ "gpt-6-luna",
16651
+ "gpt-6-sol",
16652
+ "gpt-5.6-luna",
16653
+ "gpt-5.6-terra",
16654
+ "gpt-5.6-sol",
16655
+ "gpt-6-astra"
16656
+ ];
16623
16657
  case "claude":
16624
16658
  return ["claude", "\uD074\uB85C\uB4DC", "sonnet", "opus", "fable"];
16625
16659
  case "maestro":
@@ -17195,15 +17229,84 @@ var init_self_config = __esm(async () => {
17195
17229
  AGENT_VALUES = SUPPORTED_AGENTS;
17196
17230
  });
17197
17231
 
17232
+ // ../../packages/core/src/query/state.ts
17233
+ import { mkdirSync as mkdirSync15, renameSync as renameSync7, unlinkSync as unlinkSync14, writeFileSync as writeFileSync13 } from "fs";
17234
+ import { basename as basename4, join as join25 } from "path";
17235
+ function createQueryStateStore(options) {
17236
+ const sanitize = options.sanitizeTopicId ?? sanitizeId;
17237
+ const queryStateDirPath = (userId) => join25(options.usersLogDir, String(userId), "active-queries");
17238
+ const queryStateFile = (userId, topicId) => join25(queryStateDirPath(userId), `${sanitize(topicId)}.json`);
17239
+ const legacyQueryStateFile = (userId, topicName) => {
17240
+ if (!topicName || topicName === "." || topicName === ".." || basename4(topicName) !== topicName) {
17241
+ return null;
17242
+ }
17243
+ return join25(queryStateDirPath(userId), `${topicName}.json`);
17244
+ };
17245
+ return {
17246
+ write(userId, topicId, topicName, task) {
17247
+ const dir = queryStateDirPath(userId);
17248
+ mkdirSync15(dir, { recursive: true });
17249
+ const state = { topicId, topicName, since: new Date().toISOString() };
17250
+ if (task)
17251
+ state.task = [...task.replace(/\n+/g, " ").trim()].slice(0, 100).join("");
17252
+ const target = queryStateFile(userId, topicId);
17253
+ const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
17254
+ writeFileSync13(tmp, JSON.stringify(state));
17255
+ renameSync7(tmp, target);
17256
+ },
17257
+ clear(userId, topicId, legacyTopicName) {
17258
+ const paths = [
17259
+ queryStateFile(userId, topicId),
17260
+ legacyQueryStateFile(userId, legacyTopicName)
17261
+ ].filter((path) => Boolean(path));
17262
+ for (const path of new Set(paths)) {
17263
+ try {
17264
+ unlinkSync14(path);
17265
+ } catch (error) {
17266
+ if (error?.code !== "ENOENT") {
17267
+ options.logger?.warn({ err: error, userId, topicId, path }, "Failed to clear query state file");
17268
+ }
17269
+ }
17270
+ }
17271
+ },
17272
+ hasActive(userId, topicId) {
17273
+ const state = readJsonFile(queryStateFile(userId, topicId));
17274
+ if (!state)
17275
+ return false;
17276
+ const sinceMs = new Date(state.since).getTime();
17277
+ return Date.now() - sinceMs <= ACTIVE_QUERY_STALE_MS;
17278
+ }
17279
+ };
17280
+ }
17281
+ function writeQueryState(userId, topicId, topicName, task) {
17282
+ defaultQueryStateStore.write(userId, topicId, topicName, task);
17283
+ }
17284
+ function clearQueryState(userId, topicId, legacyTopicName) {
17285
+ defaultQueryStateStore.clear(userId, topicId, legacyTopicName);
17286
+ }
17287
+ function hasActiveQuery(userId, topicId) {
17288
+ return defaultQueryStateStore.hasActive(userId, topicId);
17289
+ }
17290
+ var defaultQueryStateStore;
17291
+ var init_state = __esm(() => {
17292
+ init_config();
17293
+ init_jsonl();
17294
+ init_logger();
17295
+ defaultQueryStateStore = createQueryStateStore({
17296
+ usersLogDir: USERS_LOG_DIR,
17297
+ logger
17298
+ });
17299
+ });
17300
+
17198
17301
  // ../../packages/core/src/query/session-inbox-path.ts
17199
- import { join as join25 } from "path";
17302
+ import { join as join26 } from "path";
17200
17303
  function sessionInboxPath(userId, topicId) {
17201
17304
  const key = Buffer.from(topicId, "utf8").toString("base64url");
17202
- return join25(SESSION_INBOX_DIR, userId, `${TOPIC_ID_FILE_PREFIX}${key}${JSONL_SUFFIX}`);
17305
+ return join26(SESSION_INBOX_DIR, userId, `${TOPIC_ID_FILE_PREFIX}${key}${JSONL_SUFFIX}`);
17203
17306
  }
17204
17307
  function scheduledSessionInboxPath(userId, topicId) {
17205
17308
  const key = Buffer.from(topicId, "utf8").toString("base64url");
17206
- return join25(SESSION_INBOX_DIR, userId, `${TOPIC_ID_FILE_PREFIX}${key}${SCHEDULE_SUFFIX}`);
17309
+ return join26(SESSION_INBOX_DIR, userId, `${TOPIC_ID_FILE_PREFIX}${key}${SCHEDULE_SUFFIX}`);
17207
17310
  }
17208
17311
  function decodeTopicIdFileName(fileName, suffix) {
17209
17312
  if (!fileName.startsWith(TOPIC_ID_FILE_PREFIX) || !fileName.endsWith(suffix))
@@ -17230,8 +17333,8 @@ var init_session_inbox_path = __esm(() => {
17230
17333
  });
17231
17334
 
17232
17335
  // ../../packages/core/src/storage/session-inbox-signal.ts
17233
- import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync13 } from "fs";
17234
- import { join as join26 } from "path";
17336
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "fs";
17337
+ import { join as join27 } from "path";
17235
17338
  function subscribeSessionInboxWrite(listener) {
17236
17339
  listeners.add(listener);
17237
17340
  return () => {
@@ -17250,8 +17353,8 @@ function deliver() {
17250
17353
  return;
17251
17354
  }
17252
17355
  try {
17253
- mkdirSync15(SESSION_INBOX_DIR, { recursive: true });
17254
- writeFileSync13(SESSION_INBOX_WAKE_FILE, `${Date.now()}
17356
+ mkdirSync16(SESSION_INBOX_DIR, { recursive: true });
17357
+ writeFileSync14(SESSION_INBOX_WAKE_FILE, `${Date.now()}
17255
17358
  `);
17256
17359
  } catch (err2) {
17257
17360
  logger.debug({ err: err2 }, "session-inbox: could not touch the wake sentinel");
@@ -17269,7 +17372,7 @@ var SESSION_INBOX_WAKE_FILE, listeners, scheduled = null;
17269
17372
  var init_session_inbox_signal = __esm(() => {
17270
17373
  init_config();
17271
17374
  init_logger();
17272
- SESSION_INBOX_WAKE_FILE = join26(SESSION_INBOX_DIR, ".wake");
17375
+ SESSION_INBOX_WAKE_FILE = join27(SESSION_INBOX_DIR, ".wake");
17273
17376
  listeners = new Set;
17274
17377
  });
17275
17378
 
@@ -17371,14 +17474,14 @@ var init_session_inbox = __esm(async () => {
17371
17474
  });
17372
17475
 
17373
17476
  // ../../packages/core/src/query/session-inbox-cleanup.ts
17374
- import { unlinkSync as unlinkSync14 } from "fs";
17375
- import { basename as basename4, join as join27 } from "path";
17477
+ import { unlinkSync as unlinkSync15 } from "fs";
17478
+ import { basename as basename5, join as join28 } from "path";
17376
17479
  function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
17377
17480
  const live = sessionInboxPath(userId, topicId);
17378
17481
  const scheduled2 = scheduledSessionInboxPath(userId, topicId);
17379
17482
  const candidates = new Set([live, `${live}.processing`, scheduled2, `${scheduled2}.processing`]);
17380
- if (legacyTopicTitle && legacyTopicTitle !== "." && legacyTopicTitle !== ".." && basename4(legacyTopicTitle) === legacyTopicTitle) {
17381
- const legacyBase = join27(SESSION_INBOX_DIR, userId, legacyTopicTitle);
17483
+ if (legacyTopicTitle && legacyTopicTitle !== "." && legacyTopicTitle !== ".." && basename5(legacyTopicTitle) === legacyTopicTitle) {
17484
+ const legacyBase = join28(SESSION_INBOX_DIR, userId, legacyTopicTitle);
17382
17485
  for (const suffix of [".jsonl", ".jsonl.processing", ".schedule", ".schedule.processing"]) {
17383
17486
  candidates.add(`${legacyBase}${suffix}`);
17384
17487
  }
@@ -17386,7 +17489,7 @@ function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
17386
17489
  let deleted = deleteSessionInboxForTopic(topicId);
17387
17490
  for (const path of candidates) {
17388
17491
  try {
17389
- unlinkSync14(path);
17492
+ unlinkSync15(path);
17390
17493
  deleted++;
17391
17494
  } catch (err2) {
17392
17495
  if (err2?.code !== "ENOENT") {
@@ -17403,64 +17506,6 @@ var init_session_inbox_cleanup = __esm(async () => {
17403
17506
  await init_session_inbox();
17404
17507
  });
17405
17508
 
17406
- // ../../packages/core/src/query/state.ts
17407
- import { mkdirSync as mkdirSync16, renameSync as renameSync7, unlinkSync as unlinkSync15, writeFileSync as writeFileSync14 } from "fs";
17408
- import { basename as basename5, join as join28 } from "path";
17409
- function createQueryStateStore(options) {
17410
- const sanitize = options.sanitizeTopicId ?? sanitizeId;
17411
- const queryStateDirPath = (userId) => join28(options.usersLogDir, String(userId), "active-queries");
17412
- const queryStateFile = (userId, topicId) => join28(queryStateDirPath(userId), `${sanitize(topicId)}.json`);
17413
- const legacyQueryStateFile = (userId, topicName) => {
17414
- if (!topicName || topicName === "." || topicName === ".." || basename5(topicName) !== topicName) {
17415
- return null;
17416
- }
17417
- return join28(queryStateDirPath(userId), `${topicName}.json`);
17418
- };
17419
- return {
17420
- write(userId, topicId, topicName, task) {
17421
- const dir = queryStateDirPath(userId);
17422
- mkdirSync16(dir, { recursive: true });
17423
- const state = { topicId, topicName, since: new Date().toISOString() };
17424
- if (task)
17425
- state.task = [...task.replace(/\n+/g, " ").trim()].slice(0, 100).join("");
17426
- const target = queryStateFile(userId, topicId);
17427
- const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
17428
- writeFileSync14(tmp, JSON.stringify(state));
17429
- renameSync7(tmp, target);
17430
- },
17431
- clear(userId, topicId, legacyTopicName) {
17432
- const paths = [
17433
- queryStateFile(userId, topicId),
17434
- legacyQueryStateFile(userId, legacyTopicName)
17435
- ].filter((path) => Boolean(path));
17436
- for (const path of new Set(paths)) {
17437
- try {
17438
- unlinkSync15(path);
17439
- } catch (error) {
17440
- if (error?.code !== "ENOENT") {
17441
- options.logger?.warn({ err: error, userId, topicId, path }, "Failed to clear query state file");
17442
- }
17443
- }
17444
- }
17445
- }
17446
- };
17447
- }
17448
- function writeQueryState(userId, topicId, topicName, task) {
17449
- defaultQueryStateStore.write(userId, topicId, topicName, task);
17450
- }
17451
- function clearQueryState(userId, topicId, legacyTopicName) {
17452
- defaultQueryStateStore.clear(userId, topicId, legacyTopicName);
17453
- }
17454
- var defaultQueryStateStore;
17455
- var init_state = __esm(() => {
17456
- init_config();
17457
- init_logger();
17458
- defaultQueryStateStore = createQueryStateStore({
17459
- usersLogDir: USERS_LOG_DIR,
17460
- logger
17461
- });
17462
- });
17463
-
17464
17509
  // ../../packages/core/src/mcp/session-comm/peer-forward.ts
17465
17510
  var exports_peer_forward = {};
17466
17511
  __export(exports_peer_forward, {
@@ -22005,6 +22050,12 @@ var init_turn_runner = __esm(async () => {
22005
22050
 
22006
22051
  // ../../packages/core/src/agents/mcp-tools/spawn-subagent.ts
22007
22052
  import { z as z3 } from "zod";
22053
+ function activeQueryUserId(topic) {
22054
+ return topic?.participants.find((participant) => hasActiveQuery(participant.userId, topic.id))?.userId;
22055
+ }
22056
+ function persistedWatchUserId(topic) {
22057
+ return activeQueryUserId(topic) ?? topic?.participants.find((participant) => participant.role === "owner")?.userId ?? topic?.participants[0]?.userId;
22058
+ }
22008
22059
  function createSubagentLifecycle(host) {
22009
22060
  const runtimeOwnerId = host.runtime.ownerId;
22010
22061
  const limits = Object.freeze({
@@ -22119,7 +22170,7 @@ function createSubagentLifecycle(host) {
22119
22170
  }
22120
22171
  function watchFromPersistedCard(message, card, queryId) {
22121
22172
  const child = host.storage.getTopic(card.subagentTopicId);
22122
- const userId = child?.participants.find((participant) => participant.role === "owner")?.userId ?? child?.participants[0]?.userId;
22173
+ const userId = persistedWatchUserId(child);
22123
22174
  if (!userId)
22124
22175
  return null;
22125
22176
  return {
@@ -22478,6 +22529,10 @@ ${card.task}${reportInstruction}`;
22478
22529
  if (watch?.running)
22479
22530
  return "running";
22480
22531
  const card = host.storage.listSubagentMessages().filter((message) => message.topicId === parentTopicId && message.subagentCard?.subagentTopicId === childTopicId).at(-1)?.subagentCard;
22532
+ if (!card || card.status === "failed") {
22533
+ if (activeQueryUserId(host.storage.getTopic(childTopicId)))
22534
+ return "running";
22535
+ }
22481
22536
  return card?.status ?? "unknown";
22482
22537
  }
22483
22538
  function listMemoryTopicNames(ctx) {
@@ -22701,6 +22756,7 @@ var MAX_TASK_CHARS = 8000, MAX_NAME_CHARS = 80, MAX_LIVE_CHILDREN_PER_PARENT = 5
22701
22756
  var init_spawn_subagent = __esm(async () => {
22702
22757
  init_common();
22703
22758
  init_logger();
22759
+ init_state();
22704
22760
  init_wiki_summary_names();
22705
22761
  init_types();
22706
22762
  await __promiseAll([
@@ -22797,7 +22853,9 @@ var init_spawn_subagent = __esm(async () => {
22797
22853
  if (getRuntimeUserTurnRequest(childTopicId))
22798
22854
  return true;
22799
22855
  const lease = getRuntimeTurnLease(childTopicId);
22800
- return Boolean(lease && processOwnerIsAlive(lease.ownerId));
22856
+ if (lease && processOwnerIsAlive(lease.ownerId))
22857
+ return true;
22858
+ return Boolean(activeQueryUserId(getTopic(childTopicId)));
22801
22859
  }
22802
22860
  },
22803
22861
  config: {
@@ -42063,10 +42121,10 @@ function canvasFill(depth) {
42063
42121
  return `\x1B[48;2;${CANVAS_RGB[0]};${CANVAS_RGB[1]};${CANVAS_RGB[2]}m`;
42064
42122
  }
42065
42123
  }
42066
- function altScreenSequences(env = process.env) {
42124
+ function altScreenSequences(env = process.env, savedDepth) {
42067
42125
  const push = kittyKeyboardEnabled(env) ? KITTY_KEYBOARD_PUSH : "";
42068
42126
  const pop = kittyKeyboardEnabled(env) ? KITTY_KEYBOARD_POP : "";
42069
- const depth = detectColorDepth({ env, isTty: true });
42127
+ const depth = detectColorDepth({ env, isTty: true, savedDepth });
42070
42128
  const colored = depth !== "none";
42071
42129
  const setBackground = colored ? "\x1B]11;#0a0b0f\x07" : "";
42072
42130
  const fillCanvas = canvasFill(depth);
@@ -52002,4 +52060,4 @@ switch (command) {
52002
52060
  }
52003
52061
  }
52004
52062
 
52005
- //# debugId=25E3D8DB316A953564756E2164756E21
52063
+ //# debugId=2EEBEA0C0B30D31464756E2164756E21