negotium 0.1.35 → 0.1.37

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 (98) hide show
  1. package/dist/agent-helpers.js +243 -69
  2. package/dist/agent-helpers.js.map +22 -21
  3. package/dist/background-bash.js +4 -3
  4. package/dist/background-bash.js.map +4 -4
  5. package/dist/{chunk-s56ynvmp.js → chunk-5eq2xrmy.js} +4 -3
  6. package/dist/{chunk-s56ynvmp.js.map → chunk-5eq2xrmy.js.map} +4 -4
  7. package/dist/cron.js +1 -15004
  8. package/dist/hosted-agent.js +96 -15
  9. package/dist/hosted-agent.js.map +10 -10
  10. package/dist/main.js +4513 -3224
  11. package/dist/main.js.map +56 -53
  12. package/dist/mcp-factories.js +57 -50
  13. package/dist/mcp-factories.js.map +7 -6
  14. package/dist/prompts.js +9 -8
  15. package/dist/prompts.js.map +6 -6
  16. package/dist/registry.js +38 -5
  17. package/dist/registry.js.map +5 -5
  18. package/dist/rollout.js +1 -1
  19. package/dist/runtime/cron/background-sessions.ts +29 -4
  20. package/dist/runtime/cron/context.ts +1 -1
  21. package/dist/runtime/cron/host.ts +1 -1
  22. package/dist/runtime/cron/module.ts +1 -1
  23. package/dist/runtime/cron/package.json +6 -0
  24. package/dist/runtime/cron/scheduler.ts +1 -1
  25. package/dist/runtime/cron/scripts.ts +1 -1
  26. package/dist/runtime/cron/store.ts +1 -1
  27. package/dist/runtime/cron/summarize.ts +1 -1
  28. package/dist/runtime/package.json +6 -0
  29. package/dist/runtime/src/agents/archiver.ts +119 -17
  30. package/dist/runtime/src/agents/claude-provider.ts +7 -0
  31. package/dist/runtime/src/agents/codex-provider.ts +51 -2
  32. package/dist/runtime/src/agents/codex-registry.ts +3 -1
  33. package/dist/runtime/src/agents/execution-host.ts +5 -0
  34. package/dist/runtime/src/agents/idle-archiver.ts +2 -0
  35. package/dist/runtime/src/agents/index.ts +3 -3
  36. package/dist/runtime/src/agents/maestro-provider.ts +22 -3
  37. package/dist/runtime/src/agents/maestro-registry.ts +25 -1
  38. package/dist/runtime/src/agents/model-catalog.ts +18 -1
  39. package/dist/runtime/src/agents/self-config-core.ts +6 -3
  40. package/dist/runtime/src/agents/topic-cleanup.ts +37 -21
  41. package/dist/runtime/src/application/topic-service.ts +1 -0
  42. package/dist/runtime/src/cron-host.ts +29 -0
  43. package/dist/runtime/src/index.ts +2 -0
  44. package/dist/runtime/src/mcp/compaction-log-server.ts +25 -0
  45. package/dist/runtime/src/mcp/factories/compaction-log.ts +135 -0
  46. package/dist/runtime/src/mcp/factories/index.ts +4 -0
  47. package/dist/runtime/src/platform/config.ts +5 -3
  48. package/dist/runtime/src/platform/mcp-config.ts +5 -0
  49. package/dist/runtime/src/prompts/agents/wiki-archiver.md +1 -1
  50. package/dist/runtime/src/prompts/builders.ts +6 -9
  51. package/dist/runtime/src/runtime/background-session-policy.ts +1 -0
  52. package/dist/runtime/src/runtime/background-sessions.ts +201 -13
  53. package/dist/runtime/src/storage/api-messages.ts +29 -2
  54. package/dist/runtime/src/storage/conversation-migration.ts +179 -0
  55. package/dist/runtime/src/storage/conversations.ts +89 -22
  56. package/dist/runtime/src/storage/topic-archive.ts +85 -0
  57. package/dist/runtime/src/topics/derive.ts +153 -52
  58. package/dist/runtime/src/topics/lifecycle.ts +45 -10
  59. package/dist/runtime/src/topics/session.ts +525 -76
  60. package/dist/runtime/src/types/api.ts +3 -1
  61. package/dist/runtime/src/types.ts +11 -1
  62. package/dist/runtime/src/version.ts +1 -1
  63. package/dist/runtime-helpers.js +4 -3
  64. package/dist/runtime-helpers.js.map +5 -5
  65. package/dist/storage.js +143 -7
  66. package/dist/storage.js.map +6 -6
  67. package/dist/types/packages/core/src/agents/archiver.d.ts +2 -0
  68. package/dist/types/packages/core/src/agents/claude-provider.d.ts +1 -0
  69. package/dist/types/packages/core/src/agents/idle-archiver.d.ts +1 -0
  70. package/dist/types/packages/core/src/agents/index.d.ts +6 -1
  71. package/dist/types/packages/core/src/agents/maestro-provider.d.ts +1 -1
  72. package/dist/types/packages/core/src/agents/maestro-registry.d.ts +1 -1
  73. package/dist/types/packages/core/src/agents/model-catalog.d.ts +12 -1
  74. package/dist/types/packages/core/src/agents/topic-cleanup.d.ts +13 -11
  75. package/dist/types/packages/core/src/mcp/factories/compaction-log.d.ts +8 -0
  76. package/dist/types/packages/core/src/mcp/factories/index.d.ts +1 -0
  77. package/dist/types/packages/core/src/platform/config.d.ts +4 -3
  78. package/dist/types/packages/core/src/runtime/background-session-policy.d.ts +1 -0
  79. package/dist/types/packages/core/src/runtime/background-sessions.d.ts +19 -0
  80. package/dist/types/packages/core/src/storage/api-messages.d.ts +10 -0
  81. package/dist/types/packages/core/src/storage/conversations.d.ts +22 -13
  82. package/dist/types/packages/core/src/storage/topic-archive.d.ts +10 -0
  83. package/dist/types/packages/core/src/topics/derive.d.ts +7 -2
  84. package/dist/types/packages/core/src/topics/lifecycle.d.ts +8 -0
  85. package/dist/types/packages/core/src/topics/session.d.ts +49 -0
  86. package/dist/types/packages/core/src/types/api.d.ts +3 -1
  87. package/dist/types/packages/core/src/types.d.ts +11 -0
  88. package/dist/types/packages/core/src/version.d.ts +1 -1
  89. package/dist/types/packages/module-cron/src/background-sessions.d.ts +1 -1
  90. package/dist/types/packages/module-cron/src/host.d.ts +1 -1
  91. package/dist/types/packages/module-cron/src/module.d.ts +1 -1
  92. package/dist/types/packages/module-cron/src/scheduler.d.ts +1 -1
  93. package/dist/types/packages/module-cron/src/store.d.ts +1 -1
  94. package/dist/vault.js +4 -3
  95. package/dist/vault.js.map +4 -4
  96. package/install-browser-rs.mjs +3 -3
  97. package/package.json +2 -2
  98. package/dist/cron.js.map +0 -153
@@ -142,8 +142,8 @@ function resolveBrowserMcpBin(envValue) {
142
142
  }
143
143
  var PATCHRIGHT_MCP_BIN = resolve(PROJECT_ROOT, "scripts/mcp-patchright-http.mjs");
144
144
  var PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText("NEGOTIUM_BROWSER_MCP_BIN"));
145
- var BROWSER_RS_VERSION = "v0.1.12";
146
- var BROWSER_RS_MIN_SECURE_VERSION = "0.1.12";
145
+ var BROWSER_RS_VERSION = "v0.1.13";
146
+ var BROWSER_RS_MIN_SECURE_VERSION = "0.1.13";
147
147
  function versionAtLeast(actualVersion, minimumVersion) {
148
148
  const actual = actualVersion.split(".").map(Number);
149
149
  const minimum = minimumVersion.split(".").map(Number);
@@ -194,6 +194,7 @@ var BROWSER_MCP_SSE_PROXY_SERVER = resolve(PROJECT_ROOT, "src/mcp/browser-sse-pr
194
194
  var CANONICAL_MCP_PROXY_SERVER = resolve(PROJECT_ROOT, "src/mcp/canonical-proxy-server.ts");
195
195
  var WIKI_SERVER = resolve(PROJECT_ROOT, "src/mcp/wiki-server.ts");
196
196
  var TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, "src/mcp/token-stats-server.ts");
197
+ var COMPACTION_LOG_SERVER = resolve(PROJECT_ROOT, "src/mcp/compaction-log-server.ts");
197
198
  var SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, "src/mcp/system-health-server.ts");
198
199
  var AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, "src/mcp/agent-health-server.ts");
199
200
  var BACKGROUND_BASH_SERVER = resolve(PROJECT_ROOT, "src/mcp/background-bash-server.ts");
@@ -833,7 +834,7 @@ var withCodexSpawnSerial = manager.withSpawnSerial;
833
834
  var killCodexTrees = manager.killTrees;
834
835
  var killOwnedCodexTreesForShutdown = manager.killOwnedTreesForShutdown;
835
836
  // ../../packages/core/src/agents/fork.ts
836
- import { existsSync as existsSync7, unlinkSync as unlinkSync7 } from "fs";
837
+ import { existsSync as existsSync9, unlinkSync as unlinkSync7 } from "fs";
837
838
 
838
839
  // ../../packages/core/src/agents/claude-registry.ts
839
840
  import { existsSync as existsSync4, mkdirSync as mkdirSync5, readdirSync, renameSync as renameSync2, unlinkSync as unlinkSync3 } from "fs";
@@ -1290,7 +1291,7 @@ var claudeRegistry = {
1290
1291
  };
1291
1292
 
1292
1293
  // ../../packages/core/src/agents/codex-registry.ts
1293
- import { unlinkSync as unlinkSync6 } from "fs";
1294
+ import { existsSync as existsSync7, unlinkSync as unlinkSync6 } from "fs";
1294
1295
  import { homedir as homedir7 } from "os";
1295
1296
  import { join as join10 } from "path";
1296
1297
 
@@ -1921,6 +1922,10 @@ function topicFilename(topicName) {
1921
1922
  function getConversationPath(userId, topicName) {
1922
1923
  return join9(conversationDir(userId), topicFilename(topicName));
1923
1924
  }
1925
+ function getActiveConversationPath(userId, topicName) {
1926
+ const rawPath = getConversationPath(userId, topicName);
1927
+ return rawPath.endsWith(".jsonl") ? `${rawPath.slice(0, -".jsonl".length)}.active.jsonl` : `${rawPath}.active`;
1928
+ }
1924
1929
  function appendConversationEvent(userId, topicName, agent, event) {
1925
1930
  try {
1926
1931
  appendConversationEventStrict(userId, topicName, agent, event);
@@ -1935,11 +1940,14 @@ function appendConversationEventStrict(userId, topicName, agent, event) {
1935
1940
  agent,
1936
1941
  event
1937
1942
  };
1943
+ const line = JSON.stringify(entry);
1938
1944
  mkdirSync7(dirname6(path), { recursive: true });
1939
- appendJsonlLine(path, JSON.stringify(entry));
1945
+ appendJsonlLine(path, line);
1946
+ const activePath = getActiveConversationPath(userId, topicName);
1947
+ if (existsSync6(activePath))
1948
+ appendJsonlLine(activePath, line);
1940
1949
  }
1941
- function readConversation(userId, topicName) {
1942
- const path = getConversationPath(userId, topicName);
1950
+ function readConversationPath(path) {
1943
1951
  const out = [];
1944
1952
  if (!existsSync6(path))
1945
1953
  return out;
@@ -1962,6 +1970,10 @@ function readConversation(userId, topicName) {
1962
1970
  }
1963
1971
  return out;
1964
1972
  }
1973
+ function readConversation(userId, topicName) {
1974
+ const activePath = getActiveConversationPath(userId, topicName);
1975
+ return readConversationPath(existsSync6(activePath) ? activePath : getConversationPath(userId, topicName));
1976
+ }
1965
1977
 
1966
1978
  // ../../packages/core/src/agents/codex-registry.ts
1967
1979
  var VALID_EFFORTS2 = new Set(CODEX_EFFORT_VALUES);
@@ -2005,6 +2017,8 @@ var codexRegistry = {
2005
2017
  if (sessionIds.length === 0)
2006
2018
  return;
2007
2019
  const sessionsDir = join10(process.env.CODEX_HOME || join10(homedir7(), ".codex"), "sessions");
2020
+ if (!existsSync7(sessionsDir))
2021
+ return;
2008
2022
  const failures = [];
2009
2023
  for (const tid of sessionIds) {
2010
2024
  try {
@@ -2035,7 +2049,11 @@ var codexRegistry = {
2035
2049
  process.env.MAESTRO_SDK_SILENT_BOOTSTRAP ??= "1";
2036
2050
 
2037
2051
  // ../../packages/core/src/agents/maestro-registry.ts
2052
+ import { existsSync as existsSync8 } from "fs";
2038
2053
  import {
2054
+ deleteMaestroSession,
2055
+ maestroActiveSessionPath,
2056
+ maestroSessionPath,
2039
2057
  setConversationReader,
2040
2058
  maestroRegistry as upstreamMaestroRegistry
2041
2059
  } from "maestro-agent-sdk";
@@ -2045,6 +2063,26 @@ setConversationReader(readConversation);
2045
2063
  var maestroRegistry = {
2046
2064
  ...upstream,
2047
2065
  defaultModel: "deepseek-pro",
2066
+ async cleanupRollouts({ sessionIds }) {
2067
+ const failures = [];
2068
+ for (const sessionId of sessionIds) {
2069
+ try {
2070
+ deleteMaestroSession(sessionId);
2071
+ const remaining = [
2072
+ maestroSessionPath(sessionId),
2073
+ maestroActiveSessionPath(sessionId)
2074
+ ].filter(existsSync8);
2075
+ if (remaining.length > 0) {
2076
+ throw new Error(`Maestro session files remain after cleanup: ${remaining.join(", ")}`);
2077
+ }
2078
+ } catch (error) {
2079
+ failures.push(error);
2080
+ }
2081
+ }
2082
+ if (failures.length > 0) {
2083
+ throw new AggregateError(failures, "Maestro rollout cleanup failed");
2084
+ }
2085
+ },
2048
2086
  validateModel(model) {
2049
2087
  return !DISABLED_MODEL_ALIASES.has(model) && upstream.validateModel(model);
2050
2088
  }
@@ -2085,7 +2123,7 @@ function createAgentForkHelpers(host) {
2085
2123
  }
2086
2124
  var defaultForkHelpers = createAgentForkHelpers({
2087
2125
  forkSession: (agent, options) => getRegistry(agent).forkSession(options),
2088
- exists: existsSync7,
2126
+ exists: existsSync9,
2089
2127
  unlink: unlinkSync7,
2090
2128
  warn: (details, message) => logger.warn(details, message)
2091
2129
  });
@@ -2097,17 +2135,18 @@ function cleanupAgentFork(handle) {
2097
2135
  }
2098
2136
  // ../../packages/core/src/agents/archiver.ts
2099
2137
  import { randomUUID as randomUUID5 } from "crypto";
2100
- import { existsSync as existsSync13, readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync5 } from "fs";
2101
- import { join as join15 } from "path";
2138
+ import { existsSync as existsSync15, readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync5 } from "fs";
2139
+ import { join as join16 } from "path";
2102
2140
 
2103
2141
  // ../../packages/core/src/agents/index.ts
2104
- import { existsSync as existsSync12 } from "fs";
2142
+ import { existsSync as existsSync14 } from "fs";
2105
2143
  import { homedir as homedir8 } from "os";
2106
- import { join as join13 } from "path";
2144
+ import { join as join14 } from "path";
2145
+ import { hasActiveMaestroSession, maestroSessionPath as maestroSessionPath2 } from "maestro-agent-sdk";
2107
2146
 
2108
2147
  // ../../packages/core/src/agents/claude-provider.ts
2109
2148
  import { spawn as spawn2 } from "child_process";
2110
- import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
2149
+ import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
2111
2150
  import { query } from "@anthropic-ai/claude-agent-sdk";
2112
2151
 
2113
2152
  // ../../packages/core/src/agents/deep-map.ts
@@ -2901,6 +2940,12 @@ function getCronMcpServers(opts) {
2901
2940
  });
2902
2941
  }
2903
2942
  function getMcpServersForQuery(opts) {
2943
+ if (opts.toolPolicy === "none")
2944
+ return {};
2945
+ if (opts.toolPolicy === "compaction-log") {
2946
+ const compactLog = opts.mcpExtra?.compact_log;
2947
+ return compactLog ? { compact_log: compactLog } : {};
2948
+ }
2904
2949
  if (opts.sessionType === "cron") {
2905
2950
  if (!opts.topicId)
2906
2951
  throw new Error("getMcpServersForQuery: cron sessionType requires topicId");
@@ -2993,6 +3038,12 @@ function activeHost() {
2993
3038
  return host;
2994
3039
  }
2995
3040
  function hostedMcpServers(opts) {
3041
+ if (opts.toolPolicy === "none")
3042
+ return {};
3043
+ if (opts.toolPolicy === "compaction-log") {
3044
+ const compactLog = opts.mcpExtra?.compact_log;
3045
+ return compactLog ? { compact_log: compactLog } : {};
3046
+ }
2996
3047
  return activeHost().getMcpServersForQuery(opts);
2997
3048
  }
2998
3049
  function redactHostedSecrets(userId, value) {
@@ -3055,6 +3106,9 @@ var CLAUDE_DEFAULT_DISALLOWED_TOOLS = [
3055
3106
  "TaskGet"
3056
3107
  ];
3057
3108
  var CLAUDE_NATIVE_AGENT_TOOLS = ["Task", "Agent", "TaskOutput", "TaskStop"];
3109
+ function claudeBuiltInTools(opts) {
3110
+ return opts.toolPolicy ? [] : undefined;
3111
+ }
3058
3112
  function substituteClaudeToolInput(userId, toolName, input) {
3059
3113
  if (!shouldSubstituteVaultToolInput(toolName))
3060
3114
  return input;
@@ -3239,7 +3293,7 @@ function isAbortError(err) {
3239
3293
  }
3240
3294
  async function* claudeProvider(opts) {
3241
3295
  const claudeExecutable = hostedClaudeCodeExecutablePath();
3242
- if (claudeExecutable && !existsSync8(claudeExecutable)) {
3296
+ if (claudeExecutable && !existsSync10(claudeExecutable)) {
3243
3297
  yield {
3244
3298
  type: "error",
3245
3299
  content: `Claude CLI not found at ${claudeExecutable}. Install Claude Code or configure the executable path.`
@@ -3261,6 +3315,7 @@ async function* claudeProvider(opts) {
3261
3315
  includePartialMessages: true,
3262
3316
  env: cleanEnv,
3263
3317
  mcpServers: hostedMcpServers(opts),
3318
+ ...claudeBuiltInTools(opts) ? { tools: claudeBuiltInTools(opts) } : {},
3264
3319
  abortController: opts.abortController,
3265
3320
  disallowedTools: buildClaudeDisallowedTools(opts.disallowedTools),
3266
3321
  ...opts.model ? { model: opts.model } : {},
@@ -3509,8 +3564,8 @@ async function* claudeProvider(opts) {
3509
3564
 
3510
3565
  // ../../packages/core/src/agents/codex-provider.ts
3511
3566
  import { execFileSync as execFileSync5 } from "child_process";
3512
- import { existsSync as existsSync10, readFileSync as readFileSync8, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
3513
- import { isAbsolute, relative, resolve as resolve6 } from "path";
3567
+ import { existsSync as existsSync12, readFileSync as readFileSync8, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
3568
+ import { dirname as dirname8, isAbsolute, join as join12, relative, resolve as resolve6 } from "path";
3514
3569
  import { Codex } from "@openai/codex-sdk";
3515
3570
 
3516
3571
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
@@ -3519,7 +3574,7 @@ import { randomUUID as randomUUID2 } from "crypto";
3519
3574
  import {
3520
3575
  chmodSync as chmodSync3,
3521
3576
  copyFileSync,
3522
- existsSync as existsSync9,
3577
+ existsSync as existsSync11,
3523
3578
  mkdtempSync,
3524
3579
  readFileSync as readFileSync7,
3525
3580
  renameSync as renameSync4,
@@ -3532,7 +3587,7 @@ import { tmpdir } from "os";
3532
3587
  import { dirname as dirname7, join as join11 } from "path";
3533
3588
 
3534
3589
  // ../../packages/core/src/version.ts
3535
- var NEGOTIUM_VERSION = "0.1.35";
3590
+ var NEGOTIUM_VERSION = "0.1.37";
3536
3591
 
3537
3592
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3538
3593
  var moduleRequire = createRequire(import.meta.url);
@@ -3578,7 +3633,7 @@ function readCompatibleCodexModelCache(cachePath) {
3578
3633
  return cache;
3579
3634
  }
3580
3635
  function writePrivateFileAtomic(path, contents) {
3581
- if (existsSync9(path) && readFileSync7(path, "utf8") === contents)
3636
+ if (existsSync11(path) && readFileSync7(path, "utf8") === contents)
3582
3637
  return;
3583
3638
  const tempPath = `${path}.${process.pid}.${randomUUID2()}.tmp`;
3584
3639
  try {
@@ -3615,7 +3670,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
3615
3670
  } catch {}
3616
3671
  if (error)
3617
3672
  reject(error);
3618
- else if (!existsSync9(cachePath))
3673
+ else if (!existsSync11(cachePath))
3619
3674
  reject(new Error("Codex did not create its model cache"));
3620
3675
  else
3621
3676
  resolve6();
@@ -3685,7 +3740,7 @@ async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
3685
3740
  copyFileSync(authFilePath, isolatedAuthPath);
3686
3741
  chmodSync3(isolatedAuthPath, 384);
3687
3742
  const sourceConfigPath = join11(sourceHome, "config.toml");
3688
- if (existsSync9(sourceConfigPath)) {
3743
+ if (existsSync11(sourceConfigPath)) {
3689
3744
  const isolatedConfigPath = join11(isolatedHome, "config.toml");
3690
3745
  copyFileSync(sourceConfigPath, isolatedConfigPath);
3691
3746
  chmodSync3(isolatedConfigPath, 384);
@@ -3700,7 +3755,7 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
3700
3755
  const codexHome = dirname7(authFilePath);
3701
3756
  const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;
3702
3757
  if (configuredCachePath) {
3703
- if (!existsSync9(configuredCachePath)) {
3758
+ if (!existsSync11(configuredCachePath)) {
3704
3759
  throw new Error(`Configured Codex model cache does not exist: ${configuredCachePath}`);
3705
3760
  }
3706
3761
  readCompatibleCodexModelCache(configuredCachePath);
@@ -3708,14 +3763,14 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
3708
3763
  }
3709
3764
  const bundledCachePath = bundledCodexModelCachePath(authFilePath);
3710
3765
  const sharedCachePath = join11(codexHome, "models_cache.json");
3711
- if (existsSync9(sharedCachePath)) {
3766
+ if (existsSync11(sharedCachePath)) {
3712
3767
  try {
3713
3768
  const shared = readCompatibleCodexModelCache(sharedCachePath);
3714
3769
  writePrivateFileAtomic(bundledCachePath, shared.contents);
3715
3770
  return bundledCachePath;
3716
3771
  } catch {}
3717
3772
  }
3718
- if (existsSync9(bundledCachePath)) {
3773
+ if (existsSync11(bundledCachePath)) {
3719
3774
  try {
3720
3775
  readCompatibleCodexModelCache(bundledCachePath);
3721
3776
  return bundledCachePath;
@@ -3825,6 +3880,34 @@ var CODEX_MCP_SERVER_NAME_OVERRIDES = {
3825
3880
  function codexMcpServerName(name) {
3826
3881
  return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;
3827
3882
  }
3883
+ function globalCodexMcpServerNames(authFilePath) {
3884
+ const configPath = join12(dirname8(authFilePath), "config.toml");
3885
+ if (!existsSync12(configPath))
3886
+ return [];
3887
+ try {
3888
+ const names = new Set;
3889
+ for (const line of readFileSync8(configPath, "utf8").split(`
3890
+ `)) {
3891
+ const match = line.match(/^\s*\[\s*mcp_servers\.((?:"(?:\\.|[^"])*")|(?:'[^']*')|[^.\]\s]+)(?:[.\]])/);
3892
+ const raw = match?.[1];
3893
+ if (!raw)
3894
+ continue;
3895
+ if (raw.startsWith('"')) {
3896
+ try {
3897
+ names.add(JSON.parse(raw));
3898
+ } catch {}
3899
+ } else if (raw.startsWith("'")) {
3900
+ names.add(raw.slice(1, -1));
3901
+ } else {
3902
+ names.add(raw);
3903
+ }
3904
+ }
3905
+ return [...names];
3906
+ } catch (error) {
3907
+ logger.warn({ err: error, configPath }, "codexProvider: failed to inspect global MCP config");
3908
+ return [];
3909
+ }
3910
+ }
3828
3911
  function parsePositiveInt(value, fallback) {
3829
3912
  if (!value)
3830
3913
  return fallback;
@@ -3903,7 +3986,7 @@ function canonicalPath(path) {
3903
3986
  }
3904
3987
  }
3905
3988
  function textFile(path, maxBytes = CODEX_DIFF_FILE_LIMIT) {
3906
- if (!existsSync10(path))
3989
+ if (!existsSync12(path))
3907
3990
  return null;
3908
3991
  try {
3909
3992
  const byteLimit = Math.min(CODEX_DIFF_FILE_LIMIT, Math.max(0, maxBytes));
@@ -4116,7 +4199,7 @@ async function* codexProvider(opts) {
4116
4199
  const filePreviews = new CodexFilePreviewTracker(opts.cwd);
4117
4200
  const consumedPatchCallIds = new Set(opts.sessionId ? readCodexPatchCallIds(opts.sessionId) : []);
4118
4201
  const codexAuthPath = hostedCodexAuthFilePath();
4119
- if (!existsSync10(codexAuthPath)) {
4202
+ if (!existsSync12(codexAuthPath)) {
4120
4203
  yield {
4121
4204
  type: "error",
4122
4205
  content: `Codex auth file not found at ${codexAuthPath}. Run \`codex login\` to authenticate.`
@@ -4137,13 +4220,25 @@ async function* codexProvider(opts) {
4137
4220
  return;
4138
4221
  }
4139
4222
  const codexMcpServers = toCodexMcpServers(hostedMcpServers(opts));
4223
+ if (opts.toolPolicy) {
4224
+ const allowed = new Set(Object.keys(codexMcpServers));
4225
+ for (const name of globalCodexMcpServerNames(codexAuthPath)) {
4226
+ if (allowed.has(name))
4227
+ continue;
4228
+ codexMcpServers[name] = {
4229
+ command: process.execPath,
4230
+ args: ["-e", "process.exit(0)"],
4231
+ enabled: false
4232
+ };
4233
+ }
4234
+ }
4140
4235
  const browserOwner = browserOwnerForContext(opts);
4141
4236
  const scopedBrowserCapability = opts.playwrightCapability && browserOwner ? browserOwnerCapability(opts.playwrightCapability, browserOwner) : undefined;
4142
4237
  logger.info({
4143
4238
  model: opts.model ?? "(sdk default)",
4144
4239
  effort: opts.effort ?? "(off)",
4145
4240
  cwd: opts.cwd,
4146
- cwdExists: existsSync10(opts.cwd),
4241
+ cwdExists: existsSync12(opts.cwd),
4147
4242
  resume: Boolean(opts.sessionId),
4148
4243
  mcpServerCount: Object.keys(codexMcpServers).length
4149
4244
  }, "codexProvider: starting turn");
@@ -4157,14 +4252,20 @@ async function* codexProvider(opts) {
4157
4252
  config: {
4158
4253
  features: { multi_agent: false, multi_agent_v2: false, enable_fanout: false },
4159
4254
  model_catalog_json: codexModelCatalogPath,
4160
- mcp_servers: codexMcpServers
4255
+ mcp_servers: codexMcpServers,
4256
+ ...opts.toolPolicy ? { sandbox_permissions: [] } : {}
4161
4257
  }
4162
4258
  });
4163
4259
  const threadOptions = {
4164
4260
  workingDirectory: opts.cwd,
4165
4261
  skipGitRepoCheck: true,
4166
- sandboxMode: "danger-full-access",
4262
+ sandboxMode: opts.toolPolicy ? "read-only" : "danger-full-access",
4167
4263
  approvalPolicy: "never",
4264
+ ...opts.toolPolicy ? {
4265
+ networkAccessEnabled: false,
4266
+ webSearchMode: "disabled",
4267
+ webSearchEnabled: false
4268
+ } : {},
4168
4269
  ...opts.model ? { model: opts.model } : {},
4169
4270
  ...opts.effort ? { modelReasoningEffort: mapEffort(opts.effort) } : {}
4170
4271
  };
@@ -4432,8 +4533,26 @@ var DEFAULT_MAESTRO_DISALLOWED_TOOLS = [
4432
4533
  PROVIDER_SUBAGENT_TOOL,
4433
4534
  ...MAESTRO_NATIVE_TASK_TOOLS
4434
4535
  ];
4435
- function buildMaestroDisallowedTools(callerDisallowedTools = []) {
4436
- return [...new Set([...DEFAULT_MAESTRO_DISALLOWED_TOOLS, ...callerDisallowedTools])];
4536
+ var MAESTRO_ALL_BUILTIN_TOOLS = [
4537
+ "Bash",
4538
+ "Read",
4539
+ "ReadToolOutput",
4540
+ "Write",
4541
+ "Edit",
4542
+ "Glob",
4543
+ "Grep",
4544
+ "WebFetch",
4545
+ "GeminiImageQA",
4546
+ "ToolSearch",
4547
+ ...DEFAULT_MAESTRO_DISALLOWED_TOOLS
4548
+ ];
4549
+ function buildMaestroDisallowedTools(callerDisallowedTools = [], toolPolicy) {
4550
+ return [
4551
+ ...new Set([
4552
+ ...toolPolicy ? MAESTRO_ALL_BUILTIN_TOOLS : DEFAULT_MAESTRO_DISALLOWED_TOOLS,
4553
+ ...callerDisallowedTools
4554
+ ])
4555
+ ];
4437
4556
  }
4438
4557
  function buildVaultHook(userId) {
4439
4558
  return {
@@ -4500,19 +4619,19 @@ function maestroProvider(opts) {
4500
4619
  const callerToolHooks = opts.toolHooks ?? [];
4501
4620
  const sdkOpts = {
4502
4621
  maxTokens: MAESTRO_DEFAULT_MAX_TOKENS,
4503
- enableToolSearch: true,
4504
4622
  ...opts,
4623
+ enableToolSearch: !opts.toolPolicy && opts.enableToolSearch !== false,
4505
4624
  apiKeyOverrides: resolveMaestroApiKeyOverrides(userId),
4506
4625
  agent: "maestro",
4507
- disallowedTools: buildMaestroDisallowedTools(callerDisallowedTools),
4626
+ disallowedTools: buildMaestroDisallowedTools(callerDisallowedTools, opts.toolPolicy),
4508
4627
  toolHooks: [...buildMaestroToolHooks(userId), ...callerToolHooks]
4509
4628
  };
4510
4629
  return sdkMaestroProvider(sdkOpts);
4511
4630
  }
4512
4631
 
4513
4632
  // ../../packages/core/src/storage/tasks.ts
4514
- import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync5, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
4515
- import { dirname as dirname8, join as join12 } from "path";
4633
+ import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync5, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
4634
+ import { dirname as dirname9, join as join13 } from "path";
4516
4635
  function safeUserIdComponent2(userId) {
4517
4636
  const str = String(userId);
4518
4637
  if (!str || /[/\\]|\.\./.test(str)) {
@@ -4531,11 +4650,11 @@ function taskScopeKey(opts) {
4531
4650
  return opts.topicId?.trim() || opts.session || "default";
4532
4651
  }
4533
4652
  function getTaskFilePath(userId, scopeKey) {
4534
- return join12(resolveStorageDataDir(), "tasks", safeUserIdComponent2(userId), `${safeTaskScopeKey(scopeKey)}.json`);
4653
+ return join13(resolveStorageDataDir(), "tasks", safeUserIdComponent2(userId), `${safeTaskScopeKey(scopeKey)}.json`);
4535
4654
  }
4536
4655
  function readTasks(userId, scopeKey) {
4537
4656
  const path = getTaskFilePath(userId, scopeKey);
4538
- if (!existsSync11(path))
4657
+ if (!existsSync13(path))
4539
4658
  return [];
4540
4659
  try {
4541
4660
  const parsed = JSON.parse(readFileSync9(path, "utf-8"));
@@ -4618,11 +4737,11 @@ async function resolveSessionFileMissing(agent, sessionId, cwd) {
4618
4737
  switch (agent) {
4619
4738
  case "claude": {
4620
4739
  const encodedCwd = encodeClaudeCwd(cwd);
4621
- const path = join13(homedir8(), ".claude", "projects", encodedCwd, `${sessionId}.jsonl`);
4622
- return !existsSync12(path);
4740
+ const path = join14(homedir8(), ".claude", "projects", encodedCwd, `${sessionId}.jsonl`);
4741
+ return !existsSync14(path);
4623
4742
  }
4624
4743
  case "codex": {
4625
- const sessionsDir = join13(process.env.CODEX_HOME || join13(homedir8(), ".codex"), "sessions");
4744
+ const sessionsDir = join14(process.env.CODEX_HOME || join14(homedir8(), ".codex"), "sessions");
4626
4745
  const glob = new Bun.Glob(`**/rollout-*-${sessionId}.jsonl`);
4627
4746
  for await (const _rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
4628
4747
  return false;
@@ -4630,8 +4749,7 @@ async function resolveSessionFileMissing(agent, sessionId, cwd) {
4630
4749
  return true;
4631
4750
  }
4632
4751
  case "maestro": {
4633
- const path = join13(homedir8(), ".maestro", "sessions", `${sessionId}.jsonl`);
4634
- return !existsSync12(path);
4752
+ return !existsSync14(maestroSessionPath2(sessionId)) && !hasActiveMaestroSession(sessionId);
4635
4753
  }
4636
4754
  default: {
4637
4755
  const _exhaustive = agent;
@@ -5058,6 +5176,9 @@ function loadAgentPrompt(filename) {
5058
5176
  };
5059
5177
  }
5060
5178
 
5179
+ // ../../packages/core/src/runtime/background-session-policy.ts
5180
+ var COMPLETED_BACKGROUND_SESSION_RETENTION_MS = 5 * 60 * 1000;
5181
+
5061
5182
  // ../../packages/core/src/storage/api-messages.ts
5062
5183
  function initializeApiMessagesSchema() {
5063
5184
  db.exec(`
@@ -5207,9 +5328,9 @@ function setTopicBrief(topicId, fields) {
5207
5328
  }
5208
5329
 
5209
5330
  // ../../packages/core/src/storage/wiki.ts
5210
- import { basename as basename2, dirname as dirname9, join as join14 } from "path";
5331
+ import { basename as basename2, dirname as dirname10, join as join15 } from "path";
5211
5332
  function getSharedWikiDir(workspaceDir = resolveStorageWorkspaceDir()) {
5212
- return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() : join14(workspaceDir, "wiki");
5333
+ return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() : join15(workspaceDir, "wiki");
5213
5334
  }
5214
5335
 
5215
5336
  // ../../packages/core/src/storage/wiki-summary-names.ts
@@ -5803,22 +5924,34 @@ function ensurePersonalGeneral(userId) {
5803
5924
 
5804
5925
  // ../../packages/core/src/agents/archiver.ts
5805
5926
  var MAX_BRIEF_ENTRIES = 8;
5806
- var MAX_SESSION_STEPS = 20;
5807
5927
  var activeArchiverSessions = new Map;
5808
- function boundedSessionText(value) {
5809
- return value.replace(/\s+/g, " ").trim().slice(0, 160);
5928
+ function sessionText(value, maxLength) {
5929
+ const normalized = value.replace(/\s+/g, " ").trim();
5930
+ return maxLength === undefined ? normalized : normalized.slice(0, maxLength);
5931
+ }
5932
+ function formatArchiverBytes(bytes) {
5933
+ if (bytes < 1024)
5934
+ return `${bytes} B`;
5935
+ if (bytes < 1024 * 1024)
5936
+ return `${(bytes / 1024).toFixed(1)} KB`;
5937
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5938
+ }
5939
+ function formatArchiverTool(name, input) {
5940
+ const params = Object.entries(input).map(([key, value]) => {
5941
+ const rendered = typeof value === "string" ? value : JSON.stringify(value);
5942
+ return `${key}: ${sessionText(rendered ?? "")}`;
5943
+ }).join(", ");
5944
+ return `${name}${params ? `(${params})` : ""}`;
5810
5945
  }
5811
5946
  function updateArchiverSession(id, status, step) {
5812
5947
  const session = activeArchiverSessions.get(id);
5813
5948
  if (!session)
5814
5949
  return;
5815
- session.status = boundedSessionText(status) || session.status;
5950
+ session.status = sessionText(status, 160) || session.status;
5816
5951
  if (step) {
5817
- const text = boundedSessionText(step);
5952
+ const text = sessionText(step);
5818
5953
  if (text && session.steps.at(-1) !== text) {
5819
5954
  session.steps.push(text);
5820
- if (session.steps.length > MAX_SESSION_STEPS)
5821
- session.steps.shift();
5822
5955
  }
5823
5956
  }
5824
5957
  }
@@ -5829,7 +5962,15 @@ function getArchiverDef() {
5829
5962
  return _archiverDef;
5830
5963
  }
5831
5964
  function runArchiverTurn(params) {
5832
- const { userId, topicId, topicTitle, archivePath, messageCount, mode = "deleted-topic" } = params;
5965
+ const {
5966
+ userId,
5967
+ topicId,
5968
+ topicTitle,
5969
+ archivePath,
5970
+ rawArchivePaths = [],
5971
+ messageCount,
5972
+ mode = "deleted-topic"
5973
+ } = params;
5833
5974
  let archiverDef;
5834
5975
  try {
5835
5976
  archiverDef = getArchiverDef();
@@ -5844,11 +5985,13 @@ function runArchiverTurn(params) {
5844
5985
  const prompt = mode === "active-topic" ? [
5845
5986
  `\uC138\uC158 "${topicTitle}" \uC758 \uCD5C\uADFC idle \uB300\uD654 snapshot\uC785\uB2C8\uB2E4. \uC544\uB798 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uAE30\uC5B5\uC744 \uCD94\uCD9C\uD574 \uC774 \uD1A0\uD53D \uC704\uD0A4\uC5D0 \uC800\uC7A5\uD574\uC918.`,
5846
5987
  `archive_path: ${archivePath}`,
5988
+ ...rawArchivePaths.map((path) => `raw_archive_path: ${path}`),
5847
5989
  `wiki_dir: ${wikiDir}`
5848
5990
  ].join(`
5849
5991
  `) : [
5850
5992
  `\uC138\uC158 "${topicTitle}" \uC774(\uAC00) \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC544\uB798 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uAE30\uC5B5\uC744 \uCD94\uCD9C\uD574 \uC704\uD0A4\uC5D0 \uC800\uC7A5\uD574\uC918.`,
5851
5993
  `archive_path: ${archivePath}`,
5994
+ ...rawArchivePaths.map((path) => `raw_archive_path: ${path}`),
5852
5995
  `wiki_dir: ${wikiDir}`,
5853
5996
  "",
5854
5997
  "#General\uC5D0 \uD45C\uC2DC\uB420 \uC9E7\uC740 \uD55C\uAD6D\uC5B4 \uC644\uB8CC \uBA54\uC2DC\uC9C0\uB85C \uCD5C\uC885 \uC751\uB2F5\uD574\uC918. " + "\uB3C4\uAD6C \uD638\uCD9C \uB85C\uADF8\uB098 \uC6D0\uBB38 \uC804\uBB38\uC740 \uC4F0\uC9C0 \uB9D0\uACE0, \uC800\uC7A5\uD55C \uC694\uC57D/\uBE0C\uB9AC\uD504/\uBB38\uC11C\uB9CC \uAC04\uB2E8\uD788 \uB9D0\uD574\uC918."
@@ -5870,6 +6013,10 @@ function runArchiverTurn(params) {
5870
6013
  silent: true
5871
6014
  });
5872
6015
  const activeSessionId = `memory:${randomUUID5()}`;
6016
+ let archiveBytes = 0;
6017
+ try {
6018
+ archiveBytes = statSync5(archivePath).size;
6019
+ } catch {}
5873
6020
  activeArchiverSessions.set(activeSessionId, {
5874
6021
  id: activeSessionId,
5875
6022
  kind: "memory",
@@ -5883,7 +6030,9 @@ function runArchiverTurn(params) {
5883
6030
  model: model ?? archiverDef.model,
5884
6031
  prompt,
5885
6032
  promptTitle: "Prompt",
5886
- steps: ["Preparing archived conversation"]
6033
+ steps: [
6034
+ `Archive prepared \xB7 ${messageCount.toLocaleString()} messages \xB7 ${formatArchiverBytes(archiveBytes)}`
6035
+ ]
5887
6036
  });
5888
6037
  logger.info({ userId, topicTitle, archivePath, agent, model }, "archiver: starting background turn");
5889
6038
  const startMs = Date.now();
@@ -5892,12 +6041,17 @@ function runArchiverTurn(params) {
5892
6041
  let sawDelta = false;
5893
6042
  let accumulatedText = "";
5894
6043
  let resultText = "";
6044
+ let finalText = "";
6045
+ let errorText = "";
5895
6046
  let usage;
5896
6047
  try {
5897
6048
  for await (const event of events) {
5898
6049
  switch (event.type) {
6050
+ case "session":
6051
+ updateArchiverSession(activeSessionId, "Running", "Provider session started");
6052
+ break;
5899
6053
  case "tool_use":
5900
- updateArchiverSession(activeSessionId, `Running ${event.name}`, `Tool: ${event.name}`);
6054
+ updateArchiverSession(activeSessionId, `Running ${event.name}`, formatArchiverTool(event.name, event.input));
5901
6055
  break;
5902
6056
  case "tool_progress":
5903
6057
  {
@@ -5915,7 +6069,7 @@ function runArchiverTurn(params) {
5915
6069
  updateArchiverSession(activeSessionId, event.content, event.content);
5916
6070
  break;
5917
6071
  case "tool_result":
5918
- updateArchiverSession(activeSessionId, "Processing tool result");
6072
+ updateArchiverSession(activeSessionId, event.isError ? "Tool failed" : "Processing tool result", event.isError ? `Tool failed: ${sessionText(event.content) || "unknown error"}` : `Tool result \xB7 ${formatArchiverBytes(event.metadata?.returnedBytes ?? Buffer.byteLength(event.content))}`);
5919
6073
  break;
5920
6074
  case "text_delta":
5921
6075
  sawDelta = true;
@@ -5926,21 +6080,40 @@ function runArchiverTurn(params) {
5926
6080
  accumulatedText += event.content;
5927
6081
  break;
5928
6082
  case "result":
5929
- updateArchiverSession(activeSessionId, "Finalizing memory");
6083
+ updateArchiverSession(activeSessionId, "Finalizing memory", `Memory received \xB7 ${formatArchiverBytes(Buffer.byteLength(event.content))}${event.usage ? ` \xB7 ${event.usage.inputTokens.toLocaleString()} in / ${event.usage.outputTokens.toLocaleString()} out` : ""}`);
5930
6084
  resultText = event.content;
5931
6085
  usage = event.usage ? { input: event.usage.inputTokens, output: event.usage.outputTokens } : undefined;
5932
6086
  break;
6087
+ case "error":
6088
+ errorText = event.content;
6089
+ updateArchiverSession(activeSessionId, "Failed", `Memory archive failed: ${sessionText(event.content)}`);
6090
+ break;
5933
6091
  default:
5934
6092
  break;
5935
6093
  }
5936
6094
  }
5937
- ok = true;
6095
+ ok = !errorText;
5938
6096
  logger.info({ userId, topicTitle }, "archiver: background turn completed");
5939
6097
  } catch (err) {
5940
- updateArchiverSession(activeSessionId, "Failed", "Memory archive failed");
6098
+ errorText = err instanceof Error ? err.message : String(err);
6099
+ updateArchiverSession(activeSessionId, "Failed", `Memory archive failed: ${sessionText(errorText)}`);
5941
6100
  logger.warn({ err, userId, topicTitle }, "archiver: background turn failed");
5942
6101
  } finally {
5943
- activeArchiverSessions.delete(activeSessionId);
6102
+ finalText = (accumulatedText.trim() ? accumulatedText : resultText).trim();
6103
+ const completedSession = activeArchiverSessions.get(activeSessionId);
6104
+ if (completedSession) {
6105
+ if (finalText)
6106
+ completedSession.output = finalText;
6107
+ updateArchiverSession(activeSessionId, ok ? "Completed" : "Failed", ok ? `Memory archive completed \xB7 ${formatArchiverBytes(Buffer.byteLength(finalText))}` : `Memory archive failed: ${sessionText(errorText) || "unknown error"}`);
6108
+ completedSession.active = false;
6109
+ completedSession.expiresAt = Date.now() + COMPLETED_BACKGROUND_SESSION_RETENTION_MS;
6110
+ completedSession.expiryTimer = setTimeout(() => {
6111
+ if (activeArchiverSessions.get(activeSessionId) === completedSession) {
6112
+ activeArchiverSessions.delete(activeSessionId);
6113
+ }
6114
+ }, COMPLETED_BACKGROUND_SESSION_RETENTION_MS);
6115
+ completedSession.expiryTimer.unref?.();
6116
+ }
5944
6117
  try {
5945
6118
  params.onSettled?.(ok);
5946
6119
  } catch (err) {
@@ -5948,7 +6121,7 @@ function runArchiverTurn(params) {
5948
6121
  }
5949
6122
  }
5950
6123
  if (mode === "deleted-topic") {
5951
- const text = (accumulatedText.trim() ? accumulatedText : resultText).trimEnd();
6124
+ const text = finalText.trimEnd();
5952
6125
  finalizeGeneralMemory(userId, topicTitle, messageCount, startMs, ok, topicId, ok && text ? { text, agent, model, usage } : undefined);
5953
6126
  }
5954
6127
  })();
@@ -5966,17 +6139,17 @@ function distillOneLine(summaryMd) {
5966
6139
  return "";
5967
6140
  }
5968
6141
  function findSummaryFile(topicTitle, date, sinceMs, topicId) {
5969
- const dir = join15(getSharedWikiDir(), "summaries");
5970
- if (!existsSync13(dir))
6142
+ const dir = join16(getSharedWikiDir(), "summaries");
6143
+ if (!existsSync15(dir))
5971
6144
  return null;
5972
- const predicted = join15(dir, wikiSummaryFilename(date, topicTitle, topicId));
5973
- if (existsSync13(predicted))
6145
+ const predicted = join16(dir, wikiSummaryFilename(date, topicTitle, topicId));
6146
+ if (existsSync15(predicted))
5974
6147
  return predicted;
5975
6148
  let best = null;
5976
6149
  for (const f of readdirSync2(dir)) {
5977
6150
  if (!f.endsWith(".md"))
5978
6151
  continue;
5979
- const p = join15(dir, f);
6152
+ const p = join16(dir, f);
5980
6153
  try {
5981
6154
  const m = statSync5(p).mtimeMs;
5982
6155
  if (m >= sinceMs && (!best || m > best.mtime))
@@ -6460,7 +6633,7 @@ var interSessionQueue = new InterSessionQueue;
6460
6633
 
6461
6634
  // ../../packages/core/src/storage/topic-archive.ts
6462
6635
  import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync7 } from "fs";
6463
- import { join as join16 } from "path";
6636
+ import { join as join17 } from "path";
6464
6637
 
6465
6638
  // ../../packages/core/src/storage/topic-transcript.ts
6466
6639
  function parseJsonField(value) {
@@ -6524,7 +6697,7 @@ function archiveTopicMessages(topicId, topicTitle, options = {}) {
6524
6697
  if (rows.length === 0)
6525
6698
  return null;
6526
6699
  const safeTopic = sanitizeTopicName(topicTitle, true);
6527
- const archiveDir = join16(getSharedWikiDir(), "archive");
6700
+ const archiveDir = join17(getSharedWikiDir(), "archive");
6528
6701
  mkdirSync9(archiveDir, { recursive: true });
6529
6702
  const date = new Date().toISOString().slice(0, 10);
6530
6703
  const reasonSuffix = options.reason && options.reason !== "delete" ? `_${options.reason}` : "";
@@ -6537,7 +6710,7 @@ function archiveTopicMessages(topicId, topicTitle, options = {}) {
6537
6710
  let path;
6538
6711
  while (true) {
6539
6712
  filename = `${safeTopic}_${date}${reasonSuffix}${counter === 1 ? "" : `_${counter}`}.jsonl`;
6540
- path = join16(archiveDir, filename);
6713
+ path = join17(archiveDir, filename);
6541
6714
  try {
6542
6715
  writeFileSync7(path, body, { flag: "wx" });
6543
6716
  break;
@@ -6792,6 +6965,7 @@ function archiveActiveTopicForMemory(topicId, userId, options) {
6792
6965
  topicId: memoryTopic.id,
6793
6966
  topicTitle: memoryTopic.title,
6794
6967
  archivePath: job.archivePath,
6968
+ ...options.rawArchivePaths ? { rawArchivePaths: options.rawArchivePaths } : {},
6795
6969
  messageCount: job.messageCount,
6796
6970
  mode: "active-topic",
6797
6971
  onSettled: (success) => {
@@ -6950,4 +7124,4 @@ export {
6950
7124
  MIN_MEMORY_ARCHIVE_EXCHANGES
6951
7125
  };
6952
7126
 
6953
- //# debugId=D36BB5FA96D755FD64756E2164756E21
7127
+ //# debugId=36EFDC8A6D3D373C64756E2164756E21