negotium 0.1.17 → 0.1.18

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 (133) hide show
  1. package/README.md +211 -3
  2. package/dist/agent-helpers.js +1764 -0
  3. package/dist/agent-helpers.js.map +36 -0
  4. package/dist/background-bash.js +413 -0
  5. package/dist/background-bash.js.map +16 -0
  6. package/dist/{chunk-38pf4yqx.js → chunk-7azk83mw.js} +56 -23
  7. package/dist/{chunk-38pf4yqx.js.map → chunk-7azk83mw.js.map} +8 -6
  8. package/dist/cron.js +1039 -607
  9. package/dist/cron.js.map +30 -24
  10. package/dist/hosted-agent.js +582 -259
  11. package/dist/hosted-agent.js.map +20 -13
  12. package/dist/main.js +1146 -1078
  13. package/dist/main.js.map +38 -34
  14. package/dist/mcp-catalog.js +36 -0
  15. package/dist/mcp-catalog.js.map +10 -0
  16. package/dist/mcp-factories.js +1998 -0
  17. package/dist/mcp-factories.js.map +33 -0
  18. package/dist/outbox.js +272 -0
  19. package/dist/outbox.js.map +14 -0
  20. package/dist/platform-runtime.js +73 -0
  21. package/dist/platform-runtime.js.map +12 -0
  22. package/dist/prompts.js +30 -18
  23. package/dist/prompts.js.map +6 -5
  24. package/dist/query-runtime.js +595 -0
  25. package/dist/query-runtime.js.map +17 -0
  26. package/dist/registry.js +1 -1
  27. package/dist/rollout.js +1 -1
  28. package/dist/runtime/src/agents/auth-check.ts +42 -18
  29. package/dist/runtime/src/agents/claude-provider.ts +11 -10
  30. package/dist/runtime/src/agents/claude-runtime-inspection.ts +43 -0
  31. package/dist/runtime/src/agents/codex-tree-kill.ts +35 -349
  32. package/dist/runtime/src/agents/codex-tree-manager.ts +230 -0
  33. package/dist/runtime/src/agents/fork.ts +49 -20
  34. package/dist/runtime/src/agents/hosted-agent.ts +15 -0
  35. package/dist/runtime/src/agents/mcp-tools/common.ts +5 -3
  36. package/dist/runtime/src/agents/public-helpers.ts +45 -0
  37. package/dist/runtime/src/agents/task-events.ts +17 -5
  38. package/dist/runtime/src/agents/vault-tool-policy.ts +35 -14
  39. package/dist/runtime/src/index.ts +10 -1
  40. package/dist/runtime/src/mcp/factories/index.ts +53 -0
  41. package/dist/runtime/src/mcp/factories/session-comm.ts +120 -0
  42. package/dist/runtime/src/mcp/factories/stdio-protection.ts +24 -0
  43. package/dist/runtime/src/mcp/factories/system-health.ts +157 -0
  44. package/dist/runtime/src/mcp/factories/task.ts +185 -0
  45. package/dist/runtime/src/mcp/factories/token-stats.ts +123 -0
  46. package/dist/runtime/src/mcp/factories/vault-host.ts +8 -0
  47. package/dist/runtime/src/mcp/factories/vault.ts +128 -0
  48. package/dist/runtime/src/mcp/mcp-helpers.ts +3 -3
  49. package/dist/runtime/src/mcp/session-comm/context.ts +47 -0
  50. package/dist/runtime/src/mcp/session-comm/runtime.ts +12 -17
  51. package/dist/runtime/src/mcp/stdio-protect.ts +6 -83
  52. package/dist/runtime/src/mcp/system-health-server.ts +3 -128
  53. package/dist/runtime/src/mcp/task-server.ts +8 -164
  54. package/dist/runtime/src/mcp/token-stats-server.ts +4 -92
  55. package/dist/runtime/src/mcp/vault-http.ts +31 -15
  56. package/dist/runtime/src/mcp/vault-run.ts +8 -7
  57. package/dist/runtime/src/mcp/vault-server.ts +18 -95
  58. package/dist/runtime/src/mcp/wiki-server.ts +149 -116
  59. package/dist/runtime/src/outbox/file-ops.ts +74 -16
  60. package/dist/runtime/src/outbox/index.ts +13 -1
  61. package/dist/runtime/src/outbox/utils.ts +63 -40
  62. package/dist/runtime/src/platform/background-bash/manager.ts +197 -197
  63. package/dist/runtime/src/platform/config-helpers.ts +33 -0
  64. package/dist/runtime/src/platform/config.ts +4 -11
  65. package/dist/runtime/src/platform/file-utils.ts +25 -6
  66. package/dist/runtime/src/platform/jsonl.ts +27 -0
  67. package/dist/runtime/src/platform/lifecycle.ts +136 -143
  68. package/dist/runtime/src/platform/logger.ts +19 -8
  69. package/dist/runtime/src/platform/mcp-catalog-policy.ts +51 -0
  70. package/dist/runtime/src/platform/mcp-config.ts +20 -39
  71. package/dist/runtime/src/platform/public-runtime.ts +18 -0
  72. package/dist/runtime/src/query/active-rooms.ts +25 -116
  73. package/dist/runtime/src/query/public-runtime.ts +19 -0
  74. package/dist/runtime/src/query/room-query-registry.ts +215 -0
  75. package/dist/runtime/src/runtime/context-warning.ts +131 -0
  76. package/dist/runtime/src/runtime/public-helpers.ts +57 -0
  77. package/dist/runtime/src/runtime/usage-alert.ts +9 -42
  78. package/dist/runtime/src/storage/runtime-turn-requests.ts +13 -12
  79. package/dist/runtime/src/version.ts +1 -1
  80. package/dist/runtime-helpers.js +521 -49
  81. package/dist/runtime-helpers.js.map +19 -6
  82. package/dist/sqlite.js +74 -0
  83. package/dist/sqlite.js.map +10 -0
  84. package/dist/storage.js +33 -20
  85. package/dist/storage.js.map +5 -5
  86. package/dist/types/packages/core/src/agents/auth-check.d.ts +16 -0
  87. package/dist/types/packages/core/src/agents/claude-runtime-inspection.d.ts +9 -0
  88. package/dist/types/packages/core/src/agents/codex-tree-kill.d.ts +9 -74
  89. package/dist/types/packages/core/src/agents/codex-tree-manager.d.ts +28 -0
  90. package/dist/types/packages/core/src/agents/fork.d.ts +49 -0
  91. package/dist/types/packages/core/src/agents/hosted-agent.d.ts +4 -0
  92. package/dist/types/packages/core/src/agents/mcp-tools/common.d.ts +14 -0
  93. package/dist/types/packages/core/src/agents/public-helpers.d.ts +5 -0
  94. package/dist/types/packages/core/src/agents/task-events.d.ts +19 -0
  95. package/dist/types/packages/core/src/agents/vault-tool-policy.d.ts +13 -3
  96. package/dist/types/packages/core/src/mcp/factories/index.d.ts +10 -0
  97. package/dist/types/packages/core/src/mcp/factories/session-comm.d.ts +30 -0
  98. package/dist/types/packages/core/src/mcp/factories/stdio-protection.d.ts +10 -0
  99. package/dist/types/packages/core/src/mcp/factories/system-health.d.ts +17 -0
  100. package/dist/types/packages/core/src/mcp/factories/task.d.ts +13 -0
  101. package/dist/types/packages/core/src/mcp/factories/token-stats.d.ts +18 -0
  102. package/dist/types/packages/core/src/mcp/factories/vault-host.d.ts +7 -0
  103. package/dist/types/packages/core/src/mcp/factories/vault.d.ts +17 -0
  104. package/dist/types/packages/core/src/mcp/mcp-helpers.d.ts +26 -0
  105. package/dist/types/packages/core/src/mcp/session-comm/context.d.ts +16 -0
  106. package/dist/types/packages/core/src/mcp/vault-http.d.ts +23 -0
  107. package/dist/types/packages/core/src/mcp/vault-run.d.ts +19 -0
  108. package/dist/types/packages/core/src/mcp/wiki-server.d.ts +24 -0
  109. package/dist/types/packages/core/src/outbox/file-ops.d.ts +79 -0
  110. package/dist/types/packages/core/src/outbox/index.d.ts +2 -0
  111. package/dist/types/packages/core/src/outbox/utils.d.ts +16 -0
  112. package/dist/types/packages/core/src/platform/background-bash/manager.d.ts +28 -10
  113. package/dist/types/packages/core/src/platform/config-helpers.d.ts +10 -0
  114. package/dist/types/packages/core/src/platform/file-utils.d.ts +10 -0
  115. package/dist/types/packages/core/src/platform/jsonl.d.ts +2 -0
  116. package/dist/types/packages/core/src/platform/lifecycle.d.ts +40 -0
  117. package/dist/types/packages/core/src/platform/logger.d.ts +6 -0
  118. package/dist/types/packages/core/src/platform/mcp-catalog-policy.d.ts +61 -0
  119. package/dist/types/packages/core/src/platform/mcp-config.d.ts +2 -2
  120. package/dist/types/packages/core/src/platform/public-runtime.d.ts +3 -0
  121. package/dist/types/packages/core/src/query/active-rooms.d.ts +207 -0
  122. package/dist/types/packages/core/src/query/public-runtime.d.ts +2 -0
  123. package/dist/types/packages/core/src/query/room-query-registry.d.ts +70 -0
  124. package/dist/types/packages/core/src/query/types.d.ts +64 -0
  125. package/dist/types/packages/core/src/runtime/context-warning.d.ts +46 -0
  126. package/dist/types/packages/core/src/runtime/public-helpers.d.ts +11 -0
  127. package/dist/types/packages/core/src/storage/runtime-leases.d.ts +27 -0
  128. package/dist/types/packages/core/src/storage/runtime-topic-state.d.ts +30 -0
  129. package/dist/types/packages/core/src/topics/links.d.ts +2 -0
  130. package/dist/types/packages/core/src/version.d.ts +1 -1
  131. package/dist/vault.js +30 -18
  132. package/dist/vault.js.map +6 -5
  133. package/package.json +41 -1
@@ -0,0 +1,1764 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = import.meta.require;
19
+
20
+ // ../../packages/core/src/agents/auth-check.ts
21
+ import { execFileSync } from "child_process";
22
+ import { existsSync as existsSync2 } from "fs";
23
+ import { homedir as homedir2, platform } from "os";
24
+ import { join as join2 } from "path";
25
+
26
+ // ../../packages/core/src/platform/config.ts
27
+ import { randomBytes } from "crypto";
28
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
29
+ import { homedir } from "os";
30
+ import { dirname, join, resolve } from "path";
31
+ import { fileURLToPath } from "url";
32
+
33
+ // ../../packages/core/src/platform/config-helpers.ts
34
+ function readEnvText(env, key) {
35
+ const value = env[key]?.trim();
36
+ return value || undefined;
37
+ }
38
+ function parseRuntimePort(value, fallback) {
39
+ if (!value)
40
+ return fallback;
41
+ const port = Number.parseInt(value, 10);
42
+ return Number.isInteger(port) && port > 0 && port <= 65535 ? port : fallback;
43
+ }
44
+
45
+ // ../../packages/core/src/platform/logger.ts
46
+ import pino from "pino";
47
+ function createStdioLogger(options = {}) {
48
+ const development = options.development ?? true;
49
+ return pino({
50
+ level: options.level ?? process.env.LOG_LEVEL ?? "info",
51
+ transport: development ? {
52
+ target: "pino-pretty",
53
+ options: {
54
+ colorize: true,
55
+ translateTime: "SYS:yyyy-mm-dd HH:MM:ss",
56
+ destination: 2
57
+ }
58
+ } : undefined
59
+ }, pino.destination(2));
60
+ }
61
+ var logger = createStdioLogger();
62
+
63
+ // ../../packages/core/src/types.ts
64
+ var SUPPORTED_AGENTS = ["maestro", "claude", "codex"];
65
+ function isAgentKind(value) {
66
+ return typeof value === "string" && SUPPORTED_AGENTS.includes(value);
67
+ }
68
+ var CLAUDE_EFFORT_VALUES = ["low", "medium", "high", "xhigh", "max"];
69
+ var CODEX_EFFORT_VALUES = ["low", "medium", "high", "xhigh", "max"];
70
+
71
+ // ../../packages/core/src/platform/config.ts
72
+ function envText(envKey) {
73
+ return readEnvText(process.env, envKey);
74
+ }
75
+ function resolveAgentEnv(envKey, fallback, legacyEnvKey) {
76
+ const value = envText(envKey) ?? (legacyEnvKey ? envText(legacyEnvKey) : undefined);
77
+ return isAgentKind(value) ? value : fallback;
78
+ }
79
+ var HOME = homedir();
80
+ function resolveProjectRoot() {
81
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
82
+ const packagedRuntime = resolve(moduleDir, "runtime");
83
+ if (existsSync(resolve(packagedRuntime, "src")))
84
+ return packagedRuntime;
85
+ return resolve(moduleDir, "../..");
86
+ }
87
+ var PROJECT_ROOT = resolveProjectRoot();
88
+ function resolveDependencyBin(name) {
89
+ let dir = PROJECT_ROOT;
90
+ while (true) {
91
+ const candidate = resolve(dir, "node_modules", ".bin", name);
92
+ if (existsSync(candidate))
93
+ return candidate;
94
+ const parent = dirname(dir);
95
+ if (parent === dir)
96
+ return candidate;
97
+ dir = parent;
98
+ }
99
+ }
100
+ var STATE_DIR_ENV = envText("NEGOTIUM_STATE_DIR");
101
+ var STATE_DIR = STATE_DIR_ENV ? resolve(STATE_DIR_ENV) : resolve(HOME, ".negotium");
102
+ function resolveLocalStateDir(envKey, stateName) {
103
+ const envValue = envText(envKey);
104
+ if (envValue)
105
+ return resolve(envValue);
106
+ return resolve(STATE_DIR, stateName);
107
+ }
108
+ function parsePortEnv(envValue, fallback) {
109
+ return parseRuntimePort(envValue, fallback);
110
+ }
111
+ var WORKSPACE_DIR = resolveLocalStateDir("NEGOTIUM_WORKSPACE_DIR", "workspace");
112
+ var TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "topics");
113
+ var SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, "wiki");
114
+ var CONTEXTS_DIR = resolve(WORKSPACE_DIR, "contexts");
115
+ var BROWSER_PROFILES_DIR = resolve(WORKSPACE_DIR, "browser-profiles");
116
+ var DM_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "dm");
117
+ var SESSION_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "sessions");
118
+ var CLAUDE_EXECUTABLE = resolve(HOME, ".local/bin/claude");
119
+ function resolveBrowserMcpBin(envValue) {
120
+ const override = envValue?.trim();
121
+ if (override) {
122
+ if (!/(^|\/)(mcp-patchright|mcp-patchright-http\.mjs)$/.test(override)) {
123
+ throw new Error("NEGOTIUM_BROWSER_MCP_BIN must point to the authenticated mcp-patchright wrapper.");
124
+ }
125
+ return override;
126
+ }
127
+ return PATCHRIGHT_MCP_BIN;
128
+ }
129
+ var PATCHRIGHT_MCP_BIN = resolve(PROJECT_ROOT, "scripts/mcp-patchright-http.mjs");
130
+ var PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText("NEGOTIUM_BROWSER_MCP_BIN"));
131
+ var TSX_BIN = resolveDependencyBin("tsx");
132
+ var TSCONFIG_PATH = resolve(PROJECT_ROOT, "tsconfig.json");
133
+ var SESSION_COMM_SERVER = resolve(PROJECT_ROOT, "src/mcp/session-comm/server.ts");
134
+ var TASK_SERVER = resolve(PROJECT_ROOT, "src/mcp/task-server.ts");
135
+ var CANONICAL_MCP_PROXY_SERVER = resolve(PROJECT_ROOT, "src/mcp/canonical-proxy-server.ts");
136
+ var WIKI_SERVER = resolve(PROJECT_ROOT, "src/mcp/wiki-server.ts");
137
+ var TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, "src/mcp/token-stats-server.ts");
138
+ var SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, "src/mcp/system-health-server.ts");
139
+ var AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, "src/mcp/agent-health-server.ts");
140
+ var BACKGROUND_BASH_SERVER = resolve(PROJECT_ROOT, "src/mcp/background-bash-server.ts");
141
+ var VAULT_SERVER = resolve(PROJECT_ROOT, "src/mcp/vault-server.ts");
142
+ var BG_BASH_BASE_PORT = parsePortEnv(process.env.BG_BASH_BASE_PORT, 9700);
143
+ var BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);
144
+ function loadOrCreateLocalSecret(envKey, filename, options = {}) {
145
+ const envValue = envText(envKey);
146
+ const secretFile = resolve(STATE_DIR, filename);
147
+ mkdirSync(dirname(secretFile), { recursive: true });
148
+ if (envValue) {
149
+ if (options.persistEnvValue) {
150
+ writeFileSync(secretFile, `${envValue}
151
+ `, { mode: 384 });
152
+ chmodSync(secretFile, 384);
153
+ }
154
+ return envValue;
155
+ }
156
+ if (existsSync(secretFile)) {
157
+ const stored = readFileSync(secretFile, "utf-8").trim();
158
+ if (stored) {
159
+ chmodSync(secretFile, 384);
160
+ return stored;
161
+ }
162
+ }
163
+ const secret = randomBytes(32).toString("base64url");
164
+ try {
165
+ writeFileSync(secretFile, `${secret}
166
+ `, { mode: 384, flag: "wx" });
167
+ return secret;
168
+ } catch (error) {
169
+ if (error.code !== "EEXIST")
170
+ throw error;
171
+ const stored = readFileSync(secretFile, "utf-8").trim();
172
+ if (!stored)
173
+ throw new Error(`Secret file exists but is empty: ${secretFile}`);
174
+ chmodSync(secretFile, 384);
175
+ return stored;
176
+ }
177
+ }
178
+ var RUNTIME_MCP_SECRET = loadOrCreateLocalSecret("RUNTIME_MCP_SECRET", "runtime-mcp-secret");
179
+ var NODE_CONTROL_TOKEN = loadOrCreateLocalSecret("NEGOTIUM_CONTROL_TOKEN", "node-control-token");
180
+ var VAULT_MASTER_KEY = loadOrCreateLocalSecret("NEGOTIUM_VAULT_MASTER_KEY", "vault-master-key", { persistEnvValue: true });
181
+ delete process.env.NEGOTIUM_VAULT_MASTER_KEY;
182
+ var NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || "7777", 10);
183
+ var hostname = process.env.HOSTNAME || "127.0.0.1";
184
+ var DATA_DIR = resolveLocalStateDir("NEGOTIUM_DATA_DIR", "data");
185
+ var LOG_DIR = resolveLocalStateDir("NEGOTIUM_LOG_DIR", "logs");
186
+ var SESSIONS_DB = process.env.SESSIONS_DB_PATH ? resolve(process.env.SESSIONS_DB_PATH) : resolve(DATA_DIR, "sessions.db");
187
+ var DEBUG_FILE = resolve(DATA_DIR, "debug-users.json");
188
+ var USERS_LOG_DIR = resolve(DATA_DIR, "users");
189
+ var RUN_DIR = resolveLocalStateDir("NEGOTIUM_RUN_DIR", "run");
190
+ var PROGRESS_DIR = resolve(RUN_DIR, "progress");
191
+ var DM_CMD_DIR = resolve(RUN_DIR, "dm-commands");
192
+ var DM_RESP_DIR = resolve(RUN_DIR, "dm-responses");
193
+ var SESSION_INBOX_DIR = resolve(RUN_DIR, "session-inbox");
194
+ var SESSION_ASKS_DIR = resolve(RUN_DIR, "session-asks");
195
+ var PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);
196
+ var PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);
197
+ var PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, "playwright-ports");
198
+ mkdirSync(STATE_DIR, { recursive: true });
199
+ mkdirSync(DATA_DIR, { recursive: true });
200
+ mkdirSync(LOG_DIR, { recursive: true });
201
+ mkdirSync(PROGRESS_DIR, { recursive: true });
202
+ mkdirSync(DM_CMD_DIR, { recursive: true });
203
+ mkdirSync(DM_RESP_DIR, { recursive: true });
204
+ mkdirSync(SESSION_INBOX_DIR, { recursive: true });
205
+ mkdirSync(SESSION_ASKS_DIR, { recursive: true });
206
+ mkdirSync(PLAYWRIGHT_PORTS_DIR, { recursive: true });
207
+ mkdirSync(WORKSPACE_DIR, { recursive: true });
208
+ mkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });
209
+ mkdirSync(SHARED_WIKI_DIR, { recursive: true });
210
+ mkdirSync(CONTEXTS_DIR, { recursive: true });
211
+ mkdirSync(BROWSER_PROFILES_DIR, { recursive: true });
212
+ mkdirSync(DM_WORKSPACE_DIR, { recursive: true });
213
+ mkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });
214
+ var ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000;
215
+ var AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, "src/prompts/agents");
216
+ var RESOURCES_DIR = resolve(PROJECT_ROOT, "src/resources");
217
+ var MODEL_SONNET = "claude-sonnet-5";
218
+ var MODEL_OPUS = "claude-opus-4-8";
219
+ var MODEL_FABLE = "claude-fable-5";
220
+ var FALLBACK_AGENT = resolveAgentEnv("FALLBACK_AGENT", "maestro", "DEFAULT_AGENT");
221
+ var SESSION_AGENT = resolveAgentEnv("SESSION_AGENT", FALLBACK_AGENT);
222
+ var GATEWAY_AGENT = resolveAgentEnv("GATEWAY_AGENT", FALLBACK_AGENT);
223
+ var FALLBACK_MODEL = envText("FALLBACK_MODEL") ?? envText("DEFAULT_MODEL");
224
+ function resolveModelEnv(envKey, agentConst) {
225
+ return envText(envKey) ?? (agentConst === FALLBACK_AGENT ? FALLBACK_MODEL : undefined);
226
+ }
227
+ var SESSION_MODEL = resolveModelEnv("SESSION_MODEL", SESSION_AGENT);
228
+ var GATEWAY_MODEL = resolveModelEnv("GATEWAY_MODEL", GATEWAY_AGENT);
229
+ var FFMPEG_BIN = envText("FFMPEG_BIN");
230
+ var FFPROBE_BIN = envText("FFPROBE_BIN");
231
+ var PYTHON_BIN = envText("PYTHON_BIN") ?? "python3";
232
+ var FASTER_WHISPER_WRAPPER = envText("FASTER_WHISPER_WRAPPER") ?? resolve(PROJECT_ROOT, "scripts/faster-whisper-wrapper.py");
233
+ var WHISPER_MODEL = envText("WHISPER_MODEL_FILE") ?? "turbo";
234
+ var TESSERACT_BIN = envText("TESSERACT_BIN") ?? "tesseract";
235
+ var PDFTOTEXT_BIN = envText("PDFTOTEXT_BIN") ?? "pdftotext";
236
+ var _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? "", 10);
237
+ var MAX_TELL_DEPTH = Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;
238
+ function codexAuthFilePath() {
239
+ return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(homedir(), ".codex", "auth.json");
240
+ }
241
+
242
+ // ../../packages/core/src/agents/auth-check.ts
243
+ var defaultAgentAuthHost = {
244
+ codexAuthFilePath,
245
+ exists: existsSync2,
246
+ environment: process.env,
247
+ homeDirectory: homedir2,
248
+ operatingSystem: platform,
249
+ hasMacOsCredential(service) {
250
+ try {
251
+ execFileSync("security", ["find-generic-password", "-s", service], { stdio: "ignore" });
252
+ return true;
253
+ } catch {
254
+ return false;
255
+ }
256
+ }
257
+ };
258
+ function checkAgentAuth(agent, host = defaultAgentAuthHost) {
259
+ switch (agent) {
260
+ case "codex": {
261
+ const path = host.codexAuthFilePath();
262
+ if (host.exists(path))
263
+ return { ok: true };
264
+ return {
265
+ ok: false,
266
+ error: `codex is not logged in (auth file missing at ${path}). Run \`codex login\` first`
267
+ };
268
+ }
269
+ case "claude": {
270
+ if (host.environment.ANTHROPIC_API_KEY)
271
+ return { ok: true };
272
+ if (host.operatingSystem() === "darwin") {
273
+ if (host.hasMacOsCredential("Claude Code-credentials")) {
274
+ return { ok: true };
275
+ }
276
+ return {
277
+ ok: false,
278
+ error: "claude is not logged in (no macOS keychain entry 'Claude Code-credentials'). Run `claude` and complete login first"
279
+ };
280
+ }
281
+ const path = join2(host.homeDirectory(), ".claude", ".credentials.json");
282
+ if (host.exists(path))
283
+ return { ok: true };
284
+ return {
285
+ ok: false,
286
+ error: `claude is not logged in (credentials missing at ${path}). Run \`claude\` and complete login first`
287
+ };
288
+ }
289
+ case "maestro": {
290
+ if (host.environment.DEEPSEEK_API_KEY)
291
+ return { ok: true };
292
+ return {
293
+ ok: false,
294
+ error: "maestro is not authenticated (DEEPSEEK_API_KEY env var not set)"
295
+ };
296
+ }
297
+ }
298
+ }
299
+ // ../../packages/core/src/agents/codex-tree-kill.ts
300
+ import { execFileSync as execFileSync2 } from "child_process";
301
+
302
+ // ../../packages/core/src/agents/codex-tree-manager.ts
303
+ function createCodexTreeManager(host, options = {}) {
304
+ const sigkillDelayMs = options.sigkillDelayMs ?? 5000;
305
+ const treeDepthCap = options.treeDepthCap ?? 16;
306
+ const processNamePattern = options.processNamePattern ?? /codex/i;
307
+ const ownedPids = new Set;
308
+ let spawnChain = Promise.resolve();
309
+ function collectTree(rootPid, out = new Set, depth = 0) {
310
+ if (out.has(rootPid))
311
+ return out;
312
+ out.add(rootPid);
313
+ if (depth >= treeDepthCap) {
314
+ host.logger.warn({ rootPid, depth, cap: treeDepthCap }, "codex-tree-kill: tree depth cap reached, descendants beyond this point not collected");
315
+ return out;
316
+ }
317
+ for (const child of host.getDirectChildren(rootPid)) {
318
+ collectTree(child, out, depth + 1);
319
+ }
320
+ return out;
321
+ }
322
+ function snapshotChildren() {
323
+ const snapshot = new Map;
324
+ for (const pid of host.getDirectChildren(host.parentPid)) {
325
+ const name = host.getProcessName(pid);
326
+ if (!name || !processNamePattern.test(name))
327
+ continue;
328
+ snapshot.set(pid, host.getProcessStart(pid));
329
+ }
330
+ return snapshot;
331
+ }
332
+ function registerOwnedPids(pids) {
333
+ for (const pid of pids)
334
+ ownedPids.add(pid);
335
+ }
336
+ function unregisterOwnedPids(pids) {
337
+ for (const pid of pids)
338
+ ownedPids.delete(pid);
339
+ }
340
+ function findNewChildren(baseline) {
341
+ const novel = [];
342
+ for (const [pid, start] of snapshotChildren()) {
343
+ const previousStart = baseline.get(pid);
344
+ if (previousStart !== undefined && previousStart === start)
345
+ continue;
346
+ if (!ownedPids.has(pid))
347
+ novel.push(pid);
348
+ }
349
+ return novel;
350
+ }
351
+ async function acquireSpawnLock() {
352
+ const previous = spawnChain;
353
+ let release;
354
+ let released = false;
355
+ spawnChain = new Promise((resolve2) => {
356
+ release = () => {
357
+ if (released)
358
+ return;
359
+ released = true;
360
+ resolve2();
361
+ };
362
+ });
363
+ await previous;
364
+ return release;
365
+ }
366
+ async function withSpawnSerial(fn) {
367
+ const release = await acquireSpawnLock();
368
+ try {
369
+ return await fn();
370
+ } finally {
371
+ release();
372
+ }
373
+ }
374
+ function isAlive(pid) {
375
+ try {
376
+ host.kill(pid, 0);
377
+ return true;
378
+ } catch {
379
+ return false;
380
+ }
381
+ }
382
+ function isSameProcess(pid, start) {
383
+ return start !== "" && isAlive(pid) && host.getProcessStart(pid) === start;
384
+ }
385
+ function signalTrees(rootPids) {
386
+ if (rootPids.length === 0)
387
+ return null;
388
+ const targets = new Map;
389
+ for (const rootPid of rootPids) {
390
+ for (const pid of collectTree(rootPid)) {
391
+ if (!targets.has(pid))
392
+ targets.set(pid, host.getProcessStart(pid));
393
+ }
394
+ }
395
+ host.logger.warn({ rootPids, totalPids: targets.size }, "codex-tree-kill: SIGTERM process tree");
396
+ for (const pid of targets.keys()) {
397
+ try {
398
+ host.kill(pid, "SIGTERM");
399
+ } catch {}
400
+ }
401
+ return { rootPids, targets };
402
+ }
403
+ function hasSurvivors(targets) {
404
+ for (const [pid, start] of targets) {
405
+ if (isSameProcess(pid, start))
406
+ return true;
407
+ }
408
+ return false;
409
+ }
410
+ function killStragglers(plan) {
411
+ const aliveTargets = [];
412
+ let droppedAsPossibleReuse = 0;
413
+ for (const [pid, start] of plan.targets) {
414
+ if (isSameProcess(pid, start))
415
+ aliveTargets.push(pid);
416
+ else if (isAlive(pid))
417
+ droppedAsPossibleReuse++;
418
+ }
419
+ if (aliveTargets.length === 0)
420
+ return;
421
+ const reachable = new Set(aliveTargets);
422
+ for (const rootPid of plan.rootPids) {
423
+ const start = plan.targets.get(rootPid);
424
+ if (start && isSameProcess(rootPid, start)) {
425
+ for (const pid of collectTree(rootPid))
426
+ reachable.add(pid);
427
+ }
428
+ }
429
+ const stragglers = [];
430
+ for (const pid of reachable) {
431
+ const start = plan.targets.get(pid);
432
+ if (start && isSameProcess(pid, start))
433
+ stragglers.push(pid);
434
+ else if (isAlive(pid))
435
+ droppedAsPossibleReuse++;
436
+ }
437
+ host.logger.warn({
438
+ aliveRoots: plan.rootPids.filter((pid) => {
439
+ const start = plan.targets.get(pid);
440
+ return start ? isSameProcess(pid, start) : false;
441
+ }),
442
+ totalStragglers: stragglers.length,
443
+ droppedAsPossibleReuse
444
+ }, "codex-tree-kill: SIGKILL fallback after SIGTERM timeout");
445
+ for (const pid of stragglers) {
446
+ try {
447
+ host.kill(pid, "SIGKILL");
448
+ } catch {}
449
+ }
450
+ }
451
+ function killTrees(rootPids) {
452
+ const plan = signalTrees(rootPids);
453
+ if (!plan)
454
+ return;
455
+ const timer = setTimeout(() => killStragglers(plan), sigkillDelayMs);
456
+ timer.unref?.();
457
+ }
458
+ async function killOwnedTreesForShutdown(graceMs = 3000) {
459
+ const roots = new Set(ownedPids);
460
+ for (const pid of snapshotChildren().keys())
461
+ roots.add(pid);
462
+ const plan = signalTrees([...roots]);
463
+ if (!plan)
464
+ return;
465
+ const deadline = Date.now() + Math.max(0, graceMs);
466
+ while (Date.now() < deadline && hasSurvivors(plan.targets)) {
467
+ await new Promise((resolve2) => setTimeout(resolve2, Math.min(100, Math.max(1, deadline - Date.now()))));
468
+ }
469
+ killStragglers(plan);
470
+ }
471
+ return {
472
+ snapshotChildren,
473
+ findNewChildren,
474
+ registerOwnedPids,
475
+ unregisterOwnedPids,
476
+ acquireSpawnLock,
477
+ withSpawnSerial,
478
+ killTrees,
479
+ killOwnedTreesForShutdown
480
+ };
481
+ }
482
+
483
+ // ../../packages/core/src/agents/codex-tree-kill.ts
484
+ function execText(command, args) {
485
+ try {
486
+ return execFileSync2(command, args, {
487
+ encoding: "utf8",
488
+ stdio: ["ignore", "pipe", "ignore"]
489
+ }).trim();
490
+ } catch {
491
+ return "";
492
+ }
493
+ }
494
+ var posixHost = {
495
+ parentPid: process.pid,
496
+ getDirectChildren(parentPid) {
497
+ const output = execText("pgrep", ["-P", String(parentPid)]);
498
+ if (!output)
499
+ return [];
500
+ return output.split(`
501
+ `).map(Number).filter((pid) => Number.isFinite(pid) && pid > 0);
502
+ },
503
+ getProcessName: (pid) => execText("ps", ["-p", String(pid), "-o", "comm="]),
504
+ getProcessStart: (pid) => execText("ps", ["-p", String(pid), "-o", "lstart="]),
505
+ kill: (pid, signal) => process.kill(pid, signal),
506
+ logger
507
+ };
508
+ var manager = createCodexTreeManager(posixHost);
509
+ var snapshotCodexChildren = manager.snapshotChildren;
510
+ var findNewCodexChildren = manager.findNewChildren;
511
+ var registerOwnedCodexPids = manager.registerOwnedPids;
512
+ var unregisterOwnedCodexPids = manager.unregisterOwnedPids;
513
+ var acquireCodexSpawnLock = manager.acquireSpawnLock;
514
+ var withCodexSpawnSerial = manager.withSpawnSerial;
515
+ var killCodexTrees = manager.killTrees;
516
+ var killOwnedCodexTreesForShutdown = manager.killOwnedTreesForShutdown;
517
+ // ../../packages/core/src/agents/fork.ts
518
+ import { existsSync as existsSync7, unlinkSync as unlinkSync7 } from "fs";
519
+
520
+ // ../../packages/core/src/agents/claude-registry.ts
521
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readdirSync, renameSync as renameSync2, unlinkSync as unlinkSync3 } from "fs";
522
+ import { homedir as homedir4 } from "os";
523
+ import { join as join5 } from "path";
524
+
525
+ // ../../packages/core/src/agents/rollout/claude.ts
526
+ import { randomUUID } from "crypto";
527
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
528
+ import { homedir as homedir3 } from "os";
529
+ import { join as join4 } from "path";
530
+
531
+ // ../../packages/core/src/agents/rollout/shared.ts
532
+ import { mkdirSync as mkdirSync2 } from "fs";
533
+ import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
534
+ import { fileURLToPath as fileURLToPath2 } from "url";
535
+ var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
536
+ var trustedWorkspaceRoots = [WORKSPACE_DIR, DM_WORKSPACE_DIR, TOPIC_WORKSPACE_DIR].map((root) => resolve2(root));
537
+ var FIXTURES_DIR = join3(__dirname2, "..", "fixtures");
538
+ function clone(obj) {
539
+ return structuredClone(obj);
540
+ }
541
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
542
+ function assertUuidLike(label, value) {
543
+ if (!UUID_RE.test(value)) {
544
+ throw new Error(`rollout: ${label} is not a UUID-shaped string: ${value}`);
545
+ }
546
+ }
547
+ function assertCwdInWorkspace(cwd) {
548
+ const abs = resolve2(cwd);
549
+ const ok = trustedWorkspaceRoots.some((root) => abs === root || abs.startsWith(`${root}/`));
550
+ if (!ok) {
551
+ throw new Error(`rollout: cwd outside trusted workspace roots: ${cwd} (resolved=${abs})`);
552
+ }
553
+ }
554
+ function ensureCwdExists(cwd) {
555
+ assertCwdInWorkspace(cwd);
556
+ try {
557
+ mkdirSync2(cwd, { recursive: true });
558
+ } catch (err) {
559
+ logger.warn({ err, cwd }, "rollout: ensureCwdExists failed \u2014 caller should pre-create cwd");
560
+ }
561
+ }
562
+ function truncate(text, n) {
563
+ const cps = Array.from(text);
564
+ return cps.length > n ? `${cps.slice(0, n).join("")}\u2026` : text;
565
+ }
566
+ function extractChatPairs(entries, opts = { includeToolAnnotations: true }) {
567
+ const pairs = [];
568
+ let pendingUser = null;
569
+ let pendingAssistantParts = [];
570
+ let toolBuffer = [];
571
+ const flushAssistant = () => {
572
+ if (pendingUser === null)
573
+ return;
574
+ const tools = opts.includeToolAnnotations && toolBuffer.length > 0 ? `
575
+
576
+ ${toolBuffer.join(`
577
+ `)}` : "";
578
+ const assistantText = pendingAssistantParts.join("").trim() + tools;
579
+ if (assistantText.trim()) {
580
+ pairs.push({ userText: pendingUser, assistantText });
581
+ }
582
+ pendingUser = null;
583
+ pendingAssistantParts = [];
584
+ toolBuffer = [];
585
+ };
586
+ for (const entry of entries) {
587
+ const ev = entry.event;
588
+ switch (ev.type) {
589
+ case "user_message": {
590
+ flushAssistant();
591
+ pendingUser = ev.content;
592
+ break;
593
+ }
594
+ case "session":
595
+ if (pendingAssistantParts.length > 0 || toolBuffer.length > 0) {
596
+ flushAssistant();
597
+ }
598
+ break;
599
+ case "text": {
600
+ if (pendingUser === null) {
601
+ pendingUser = "(continued)";
602
+ }
603
+ pendingAssistantParts.push(ev.content);
604
+ break;
605
+ }
606
+ case "result": {
607
+ if (pendingUser === null) {
608
+ pendingUser = "(continued)";
609
+ }
610
+ pendingAssistantParts = [ev.content];
611
+ flushAssistant();
612
+ break;
613
+ }
614
+ case "text_delta":
615
+ break;
616
+ case "tool_use": {
617
+ const u = ev;
618
+ toolBuffer.push(`<!-- Tool: ${u.name} ${truncate(JSON.stringify(u.input), 200)} -->`);
619
+ break;
620
+ }
621
+ case "tool_result": {
622
+ const u = ev;
623
+ toolBuffer.push(`<!-- Tool result: ${truncate(u.content, 200)} -->`);
624
+ break;
625
+ }
626
+ case "error": {
627
+ const u = ev;
628
+ toolBuffer.push(`[Error: ${truncate(u.content, 200)}]`);
629
+ break;
630
+ }
631
+ case "tool_progress":
632
+ case "tool_use_summary":
633
+ case "file":
634
+ case "status":
635
+ break;
636
+ }
637
+ }
638
+ flushAssistant();
639
+ return pairs;
640
+ }
641
+
642
+ // ../../packages/core/src/platform/jsonl.ts
643
+ import {
644
+ appendFileSync,
645
+ closeSync,
646
+ fsyncSync,
647
+ mkdirSync as mkdirSync3,
648
+ openSync,
649
+ readFileSync as readFileSync2,
650
+ renameSync,
651
+ statSync,
652
+ unlinkSync as unlinkSync2,
653
+ writeFileSync as writeFileSync2
654
+ } from "fs";
655
+ import { dirname as dirname3 } from "path";
656
+
657
+ // ../../packages/core/src/platform/file-utils.ts
658
+ import { unlinkSync } from "fs";
659
+ function createSafeUnlink(host) {
660
+ return (path, warnLabel) => {
661
+ try {
662
+ host.unlink(path);
663
+ } catch (e) {
664
+ if (e?.code === "ENOENT")
665
+ return;
666
+ if (warnLabel)
667
+ host.warn({ err: e, path }, warnLabel);
668
+ }
669
+ };
670
+ }
671
+ var defaultSafeUnlink = createSafeUnlink({
672
+ unlink: unlinkSync,
673
+ warn: (context, message) => logger.warn(context, message)
674
+ });
675
+
676
+ // ../../packages/core/src/platform/jsonl.ts
677
+ function parseJsonlText(raw) {
678
+ return raw.trim().split(`
679
+ `).filter(Boolean).map((line) => JSON.parse(line));
680
+ }
681
+ var LOCK_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
682
+ function writeJsonlFile(filePath, entries) {
683
+ const dir = dirname3(filePath);
684
+ mkdirSync3(dir, { recursive: true });
685
+ const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
686
+ const payload = `${entries.map((e) => JSON.stringify(e)).join(`
687
+ `)}
688
+ `;
689
+ let fd = null;
690
+ try {
691
+ fd = openSync(tmpPath, "w");
692
+ writeFileSync2(fd, payload);
693
+ fsyncSync(fd);
694
+ closeSync(fd);
695
+ fd = null;
696
+ renameSync(tmpPath, filePath);
697
+ fsyncDirectoryBestEffort(dir);
698
+ } catch (err) {
699
+ if (fd !== null) {
700
+ try {
701
+ closeSync(fd);
702
+ } catch {}
703
+ }
704
+ try {
705
+ unlinkSync2(tmpPath);
706
+ } catch {}
707
+ throw err;
708
+ }
709
+ }
710
+ function fsyncDirectoryBestEffort(dir) {
711
+ let fd = null;
712
+ try {
713
+ fd = openSync(dir, "r");
714
+ fsyncSync(fd);
715
+ } catch {} finally {
716
+ if (fd !== null) {
717
+ try {
718
+ closeSync(fd);
719
+ } catch {}
720
+ }
721
+ }
722
+ }
723
+
724
+ // ../../packages/core/src/agents/rollout/claude.ts
725
+ var _attachmentsCache = null;
726
+ function loadClaudeAttachments() {
727
+ if (_attachmentsCache)
728
+ return _attachmentsCache;
729
+ const raw = readFileSync3(join4(FIXTURES_DIR, "claude-attachments.jsonl"), "utf8");
730
+ const lines = parseJsonlText(raw);
731
+ if (lines.length < 2) {
732
+ throw new Error(`loadClaudeAttachments: expected >=2 entries in claude-attachments.jsonl, got ${lines.length}`);
733
+ }
734
+ _attachmentsCache = {
735
+ deferredToolsDelta: lines[0],
736
+ skillListing: lines[1]
737
+ };
738
+ return _attachmentsCache;
739
+ }
740
+ var CLAUDE_SDK_VERSION = "2.1.126";
741
+ var CLAUDE_DEFAULT_MODEL = "claude-sonnet-5";
742
+ var CLAUDE_DEFAULT_GIT_BRANCH = "HEAD";
743
+ function encodeClaudeCwd(cwd) {
744
+ const realCwd = cwd.startsWith("/tmp/") ? cwd.replace(/^\/tmp\//, "/private/tmp/") : cwd;
745
+ return `-${realCwd.replaceAll(/[^a-zA-Z0-9]/g, "-").replace(/^-/, "")}`;
746
+ }
747
+ function writeClaudeRollout(opts) {
748
+ const sessionId = opts.sessionId ?? randomUUID();
749
+ assertUuidLike("sessionId", sessionId);
750
+ ensureCwdExists(opts.cwd);
751
+ const pairs = opts.pairs ?? extractChatPairs(opts.entries ?? []);
752
+ const cwdReal = opts.cwd.startsWith("/tmp/") ? opts.cwd.replace(/^\/tmp\//, "/private/tmp/") : opts.cwd;
753
+ const lines = [];
754
+ const ts = () => new Date().toISOString();
755
+ let lastUuid = null;
756
+ lines.push({ type: "queue-operation", operation: "enqueue", timestamp: ts(), sessionId });
757
+ lines.push({ type: "queue-operation", operation: "dequeue", timestamp: ts(), sessionId });
758
+ const attachments = loadClaudeAttachments();
759
+ for (const pair of pairs) {
760
+ const userUuid = randomUUID();
761
+ lines.push({
762
+ parentUuid: lastUuid,
763
+ isSidechain: false,
764
+ promptId: randomUUID(),
765
+ type: "user",
766
+ message: { role: "user", content: [{ type: "text", text: pair.userText }] },
767
+ uuid: userUuid,
768
+ timestamp: ts(),
769
+ permissionMode: "bypassPermissions",
770
+ userType: "external",
771
+ entrypoint: "sdk-ts",
772
+ cwd: cwdReal,
773
+ sessionId,
774
+ version: CLAUDE_SDK_VERSION,
775
+ gitBranch: CLAUDE_DEFAULT_GIT_BRANCH
776
+ });
777
+ const att1Uuid = randomUUID();
778
+ const att1 = clone(attachments.deferredToolsDelta);
779
+ att1.parentUuid = userUuid;
780
+ att1.uuid = att1Uuid;
781
+ att1.timestamp = ts();
782
+ att1.sessionId = sessionId;
783
+ att1.cwd = cwdReal;
784
+ lines.push(att1);
785
+ const att2Uuid = randomUUID();
786
+ const att2 = clone(attachments.skillListing);
787
+ att2.parentUuid = att1Uuid;
788
+ att2.uuid = att2Uuid;
789
+ att2.timestamp = ts();
790
+ att2.sessionId = sessionId;
791
+ att2.cwd = cwdReal;
792
+ lines.push(att2);
793
+ const assistantUuid = randomUUID();
794
+ lines.push({
795
+ parentUuid: att2Uuid,
796
+ isSidechain: false,
797
+ message: {
798
+ model: opts.model ?? CLAUDE_DEFAULT_MODEL,
799
+ id: `msg_${randomUUID().replace(/-/g, "").slice(0, 24)}`,
800
+ type: "message",
801
+ role: "assistant",
802
+ content: [{ type: "text", text: pair.assistantText }],
803
+ stop_reason: "end_turn",
804
+ stop_sequence: null,
805
+ stop_details: null,
806
+ usage: {
807
+ input_tokens: 0,
808
+ cache_creation_input_tokens: 0,
809
+ cache_read_input_tokens: 0,
810
+ output_tokens: 0,
811
+ server_tool_use: { web_search_requests: 0, web_fetch_requests: 0 },
812
+ service_tier: "standard",
813
+ cache_creation: { ephemeral_1h_input_tokens: 0, ephemeral_5m_input_tokens: 0 },
814
+ inference_geo: "",
815
+ iterations: [],
816
+ speed: "standard"
817
+ },
818
+ diagnostics: null
819
+ },
820
+ requestId: `req_${randomUUID().replace(/-/g, "").slice(0, 22)}`,
821
+ type: "assistant",
822
+ uuid: assistantUuid,
823
+ timestamp: ts(),
824
+ userType: "external",
825
+ entrypoint: "sdk-ts",
826
+ cwd: cwdReal,
827
+ sessionId,
828
+ version: CLAUDE_SDK_VERSION,
829
+ gitBranch: CLAUDE_DEFAULT_GIT_BRANCH
830
+ });
831
+ lastUuid = assistantUuid;
832
+ }
833
+ const projectsDir = join4(homedir3(), ".claude", "projects", encodeClaudeCwd(opts.cwd));
834
+ const path = join4(projectsDir, `${sessionId}.jsonl`);
835
+ writeJsonlFile(path, lines);
836
+ logger.info({ sessionId, path, pairs: pairs.length }, "writeClaudeRollout: synthetic rollout placed");
837
+ return { sessionId, rolloutPath: path };
838
+ }
839
+
840
+ // ../../packages/core/src/agents/claude-registry.ts
841
+ var ALIAS_MAP = {
842
+ sonnet: MODEL_SONNET,
843
+ opus: MODEL_OPUS,
844
+ fable: MODEL_FABLE
845
+ };
846
+ var VALID_ALIASES = new Set(Object.keys(ALIAS_MAP));
847
+ var VALID_EFFORTS = new Set(CLAUDE_EFFORT_VALUES);
848
+ var claudeRegistry = {
849
+ kind: "claude",
850
+ defaultModel: "sonnet",
851
+ defaultEffort: "high",
852
+ expandModelAlias(s) {
853
+ return ALIAS_MAP[s] ?? s;
854
+ },
855
+ validateModel(s) {
856
+ return VALID_ALIASES.has(s);
857
+ },
858
+ validEfforts: CLAUDE_EFFORT_VALUES,
859
+ validateEffort(s) {
860
+ return VALID_EFFORTS.has(s);
861
+ },
862
+ footerLabel(model, effort) {
863
+ return effort ? `${model} \xB7 ${effort}` : model;
864
+ },
865
+ writeRollout(opts) {
866
+ const { sessionId, rolloutPath } = writeClaudeRollout({
867
+ cwd: opts.cwd,
868
+ entries: opts.entries,
869
+ model: claudeRegistry.expandModelAlias(opts.model ?? claudeRegistry.defaultModel),
870
+ ...opts.reuseSessionId ? { sessionId: opts.reuseSessionId } : {}
871
+ });
872
+ return { sessionId, rolloutPath };
873
+ },
874
+ async forkSession({ parentSessionId, cwd, title }) {
875
+ const { forkSession } = await import("@anthropic-ai/claude-agent-sdk");
876
+ const result = await forkSession(parentSessionId, {
877
+ ...title ? { title } : {}
878
+ });
879
+ const projectsRoot = join5(homedir4(), ".claude", "projects");
880
+ const destDir = join5(projectsRoot, encodeClaudeCwd(cwd));
881
+ const destPath = join5(destDir, `${result.sessionId}.jsonl`);
882
+ if (!existsSync4(destPath)) {
883
+ const sourcePath = readdirSync(projectsRoot).map((d) => join5(projectsRoot, d, `${result.sessionId}.jsonl`)).find((p) => existsSync4(p));
884
+ if (!sourcePath) {
885
+ throw new Error(`claude forkSession: fork rollout ${result.sessionId}.jsonl not found under ${projectsRoot}`);
886
+ }
887
+ mkdirSync4(destDir, { recursive: true });
888
+ renameSync2(sourcePath, destPath);
889
+ }
890
+ return {
891
+ forkId: result.sessionId,
892
+ rolloutPath: destPath
893
+ };
894
+ },
895
+ async cleanupRollouts({ cwd, sessionIds }) {
896
+ const projectsDir = join5(homedir4(), ".claude", "projects", encodeClaudeCwd(cwd));
897
+ const failures = [];
898
+ for (const sid of sessionIds) {
899
+ const path = join5(projectsDir, `${sid}.jsonl`);
900
+ try {
901
+ unlinkSync3(path);
902
+ } catch (e) {
903
+ if (e?.code !== "ENOENT") {
904
+ logger.warn({ err: e, path }, "claude cleanupRollouts: unlink failed");
905
+ failures.push(e);
906
+ }
907
+ }
908
+ }
909
+ if (failures.length > 0) {
910
+ throw new AggregateError(failures, "claude cleanupRollouts failed");
911
+ }
912
+ }
913
+ };
914
+
915
+ // ../../packages/core/src/agents/codex-registry.ts
916
+ import { unlinkSync as unlinkSync6 } from "fs";
917
+ import { homedir as homedir7 } from "os";
918
+ import { join as join9 } from "path";
919
+
920
+ // ../../packages/core/src/agents/rollout/codex.ts
921
+ import { randomBytes as randomBytes2 } from "crypto";
922
+ import { existsSync as existsSync5, readFileSync as readFileSync4, statSync as statSync2, unlinkSync as unlinkSync4 } from "fs";
923
+ import { homedir as homedir5 } from "os";
924
+ import { join as join6 } from "path";
925
+ function codexSessionsDir() {
926
+ return join6(process.env.CODEX_HOME || join6(homedir5(), ".codex"), "sessions");
927
+ }
928
+ var _shellCache = null;
929
+ function loadCodexShell() {
930
+ if (_shellCache)
931
+ return _shellCache;
932
+ const raw = readFileSync4(join6(FIXTURES_DIR, "codex-shell.jsonl"), "utf8");
933
+ const lines = parseJsonlText(raw);
934
+ if (lines.length < 5) {
935
+ throw new Error(`loadCodexShell: expected >=5 entries in codex-shell.jsonl, got ${lines.length}`);
936
+ }
937
+ _shellCache = {
938
+ sessionMeta: lines[0],
939
+ taskStarted: lines[1],
940
+ developerSetup: lines[2],
941
+ envContext: lines[3],
942
+ turnContext: lines[4]
943
+ };
944
+ return _shellCache;
945
+ }
946
+ function uuidv7() {
947
+ const ts = Date.now();
948
+ const tsHex = ts.toString(16).padStart(12, "0");
949
+ const rand = randomBytes2(10);
950
+ rand[0] = rand[0] & 15 | 112;
951
+ rand[2] = rand[2] & 63 | 128;
952
+ return [
953
+ tsHex.slice(0, 8),
954
+ tsHex.slice(8, 12),
955
+ rand.slice(0, 2).toString("hex"),
956
+ rand.slice(2, 4).toString("hex"),
957
+ rand.slice(4, 10).toString("hex")
958
+ ].join("-");
959
+ }
960
+ function patchDeveloperSetup(developerSetup) {
961
+ const payload = developerSetup.payload;
962
+ if (!payload)
963
+ return;
964
+ payload.content = [
965
+ {
966
+ type: "input_text",
967
+ text: [
968
+ "<permissions instructions>",
969
+ "Filesystem sandboxing is disabled for this runtime turn (`danger-full-access`).",
970
+ "Approval policy is `never`.",
971
+ "</permissions instructions>"
972
+ ].join(`
973
+ `)
974
+ }
975
+ ];
976
+ }
977
+ function patchEnvContext(envContext, cwd, currentDate, timezone) {
978
+ const payload = envContext.payload;
979
+ if (!payload)
980
+ return;
981
+ const content = payload.content;
982
+ if (!Array.isArray(content))
983
+ return;
984
+ for (const block of content) {
985
+ if (block.type === "input_text" && typeof block.text === "string") {
986
+ block.text = block.text.replace(/<cwd>[^<]*<\/cwd>/, `<cwd>${cwd}</cwd>`).replace(/<current_date>[^<]*<\/current_date>/, `<current_date>${currentDate}</current_date>`).replace(/<timezone>[^<]*<\/timezone>/, `<timezone>${timezone}</timezone>`);
987
+ }
988
+ }
989
+ }
990
+ function writeCodexRollout(opts) {
991
+ const threadId = opts.threadId ?? uuidv7();
992
+ assertUuidLike("threadId", threadId);
993
+ ensureCwdExists(opts.cwd);
994
+ const pairs = opts.pairs ?? extractChatPairs(opts.entries ?? []);
995
+ const now = new Date;
996
+ const tsIso = now.toISOString();
997
+ const currentDate = [
998
+ now.getFullYear(),
999
+ String(now.getMonth() + 1).padStart(2, "0"),
1000
+ String(now.getDate()).padStart(2, "0")
1001
+ ].join("-");
1002
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || process.env.TZ || "UTC";
1003
+ const shell = loadCodexShell();
1004
+ const sessionMeta = clone(shell.sessionMeta);
1005
+ sessionMeta.payload.id = threadId;
1006
+ sessionMeta.payload.timestamp = tsIso;
1007
+ sessionMeta.payload.cwd = opts.cwd;
1008
+ sessionMeta.payload.multi_agent_version = "disabled";
1009
+ sessionMeta.timestamp = tsIso;
1010
+ const taskStarted = clone(shell.taskStarted);
1011
+ taskStarted.timestamp = tsIso;
1012
+ const developerSetup = clone(shell.developerSetup);
1013
+ developerSetup.timestamp = tsIso;
1014
+ patchDeveloperSetup(developerSetup);
1015
+ const envContext = clone(shell.envContext);
1016
+ envContext.timestamp = tsIso;
1017
+ patchEnvContext(envContext, opts.cwd, currentDate, timezone);
1018
+ const turnContext = clone(shell.turnContext);
1019
+ turnContext.timestamp = tsIso;
1020
+ const turnPayload = turnContext.payload;
1021
+ turnPayload.cwd = opts.cwd;
1022
+ turnPayload.current_date = currentDate;
1023
+ turnPayload.timezone = timezone;
1024
+ turnPayload.approval_policy = "never";
1025
+ turnPayload.sandbox_policy = { type: "danger-full-access" };
1026
+ turnPayload.multi_agent_version = "disabled";
1027
+ delete turnPayload.permission_profile;
1028
+ if (opts.model)
1029
+ turnPayload.model = opts.model;
1030
+ const collaborationMode = turnPayload.collaboration_mode;
1031
+ const collaborationSettings = collaborationMode?.settings;
1032
+ if (collaborationSettings) {
1033
+ if (opts.model)
1034
+ collaborationSettings.model = opts.model;
1035
+ if (opts.effort !== undefined)
1036
+ collaborationSettings.reasoning_effort = opts.effort;
1037
+ }
1038
+ const lines = [sessionMeta, taskStarted, developerSetup, envContext, turnContext];
1039
+ for (const pair of pairs) {
1040
+ lines.push({
1041
+ timestamp: tsIso,
1042
+ type: "response_item",
1043
+ payload: {
1044
+ type: "message",
1045
+ role: "user",
1046
+ content: [{ type: "input_text", text: pair.userText }]
1047
+ }
1048
+ });
1049
+ lines.push({
1050
+ timestamp: tsIso,
1051
+ type: "event_msg",
1052
+ payload: {
1053
+ type: "user_message",
1054
+ message: pair.userText,
1055
+ images: [],
1056
+ local_images: [],
1057
+ text_elements: []
1058
+ }
1059
+ });
1060
+ lines.push({
1061
+ timestamp: tsIso,
1062
+ type: "event_msg",
1063
+ payload: {
1064
+ type: "agent_message",
1065
+ message: pair.assistantText,
1066
+ phase: "final_answer",
1067
+ memory_citation: null
1068
+ }
1069
+ });
1070
+ lines.push({
1071
+ timestamp: tsIso,
1072
+ type: "response_item",
1073
+ payload: {
1074
+ type: "message",
1075
+ role: "assistant",
1076
+ content: [{ type: "output_text", text: pair.assistantText }],
1077
+ phase: "final_answer"
1078
+ }
1079
+ });
1080
+ }
1081
+ lines.push({
1082
+ timestamp: tsIso,
1083
+ type: "event_msg",
1084
+ payload: { type: "task_complete" }
1085
+ });
1086
+ const yyyy = now.getUTCFullYear();
1087
+ const mm = String(now.getUTCMonth() + 1).padStart(2, "0");
1088
+ const dd = String(now.getUTCDate()).padStart(2, "0");
1089
+ const tsStr = tsIso.replace(/[:.]/g, "-").slice(0, 19);
1090
+ const dir = join6(codexSessionsDir(), String(yyyy), mm, dd);
1091
+ const path = join6(dir, `rollout-${tsStr}-${threadId}.jsonl`);
1092
+ if (opts.threadId) {
1093
+ sweepPriorRolloutsForThread(opts.threadId);
1094
+ }
1095
+ writeJsonlFile(path, lines);
1096
+ logger.info({ threadId, path, pairs: pairs.length }, "writeCodexRollout: synthetic rollout placed");
1097
+ return { threadId, rolloutPath: path };
1098
+ }
1099
+ function sweepPriorRolloutsForThread(threadId) {
1100
+ const sessionsDir = codexSessionsDir();
1101
+ const buckets = candidateDateBuckets(threadId);
1102
+ if (!buckets) {
1103
+ sweepPriorRolloutsFullTree(threadId, sessionsDir);
1104
+ return;
1105
+ }
1106
+ for (const bucket of buckets) {
1107
+ const dir = join6(sessionsDir, bucket);
1108
+ if (!existsSync5(dir))
1109
+ continue;
1110
+ try {
1111
+ const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
1112
+ for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
1113
+ const fullPath = join6(dir, rel);
1114
+ try {
1115
+ unlinkSync4(fullPath);
1116
+ } catch (e) {
1117
+ if (e?.code !== "ENOENT") {
1118
+ logger.warn({ err: e, path: fullPath }, "writeCodexRollout: prior-rollout unlink failed (continuing)");
1119
+ }
1120
+ }
1121
+ }
1122
+ } catch (e) {
1123
+ logger.warn({ err: e, threadId, bucket }, "writeCodexRollout: prior-rollout bucket scan failed (continuing)");
1124
+ }
1125
+ }
1126
+ }
1127
+ function sweepPriorRolloutsFullTree(threadId, sessionsDir) {
1128
+ try {
1129
+ const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
1130
+ for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
1131
+ const fullPath = join6(sessionsDir, rel);
1132
+ try {
1133
+ unlinkSync4(fullPath);
1134
+ } catch (e) {
1135
+ if (e?.code !== "ENOENT") {
1136
+ logger.warn({ err: e, path: fullPath }, "writeCodexRollout: prior-rollout unlink failed (continuing)");
1137
+ }
1138
+ }
1139
+ }
1140
+ } catch (e) {
1141
+ logger.warn({ err: e, threadId }, "writeCodexRollout: full-tree prior-rollout sweep failed (continuing)");
1142
+ }
1143
+ }
1144
+ var MAX_DAY_SPAN = 30;
1145
+ var DAY_MS = 86400000;
1146
+ var LOCAL_DATE_SKEW_DAYS = 1;
1147
+ function candidateDateBuckets(threadId) {
1148
+ const tidMs = decodeUuidV7Timestamp(threadId);
1149
+ if (tidMs === null)
1150
+ return null;
1151
+ const nowMs = Date.now();
1152
+ const tidDay = Math.floor(tidMs / DAY_MS);
1153
+ const todayDay = Math.floor(nowMs / DAY_MS);
1154
+ const minDay = Math.min(tidDay, todayDay);
1155
+ const maxDay = Math.max(tidDay, todayDay);
1156
+ const span = maxDay - minDay;
1157
+ if (span > MAX_DAY_SPAN)
1158
+ return null;
1159
+ const buckets = new Set;
1160
+ for (let d = minDay - LOCAL_DATE_SKEW_DAYS;d <= maxDay + LOCAL_DATE_SKEW_DAYS; d++) {
1161
+ buckets.add(formatDateBucket(new Date(d * DAY_MS)));
1162
+ }
1163
+ return buckets;
1164
+ }
1165
+ function decodeUuidV7Timestamp(threadId) {
1166
+ if (typeof threadId !== "string")
1167
+ return null;
1168
+ const m = /^([0-9a-fA-F]{8})-([0-9a-fA-F]{4})-7[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.exec(threadId);
1169
+ if (!m)
1170
+ return null;
1171
+ const hex = `${m[1]}${m[2]}`;
1172
+ const ms = Number.parseInt(hex, 16);
1173
+ if (!Number.isFinite(ms))
1174
+ return null;
1175
+ const MIN = 1577836800000;
1176
+ const MAX = 4102444800000;
1177
+ if (ms < MIN || ms > MAX)
1178
+ return null;
1179
+ return ms;
1180
+ }
1181
+ function formatDateBucket(d) {
1182
+ const yyyy = d.getUTCFullYear();
1183
+ const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
1184
+ const dd = String(d.getUTCDate()).padStart(2, "0");
1185
+ return `${yyyy}/${mm}/${dd}`;
1186
+ }
1187
+
1188
+ // ../../packages/core/src/storage/conversations.ts
1189
+ import {
1190
+ existsSync as existsSync6,
1191
+ mkdirSync as mkdirSync6,
1192
+ readFileSync as readFileSync5,
1193
+ renameSync as renameSync3,
1194
+ unlinkSync as unlinkSync5,
1195
+ writeFileSync as writeFileSync4
1196
+ } from "fs";
1197
+ import { dirname as dirname5, join as join8 } from "path";
1198
+
1199
+ // ../../packages/core/src/security/sanitize.ts
1200
+ function sanitizeTopicName(name, lowercase = false) {
1201
+ const safe = name.replace(/[^a-zA-Z0-9\uAC00-\uD7A3_-]/g, "_") || "_";
1202
+ return lowercase ? safe.toLowerCase() : safe;
1203
+ }
1204
+ function sanitizeFileName(name) {
1205
+ const safe = name.replace(/[^a-zA-Z0-9._-]/g, "_") || "_";
1206
+ if (safe === "." || safe === "..")
1207
+ return "_";
1208
+ return safe;
1209
+ }
1210
+
1211
+ // ../../packages/core/src/storage/storage-host.ts
1212
+ import { mkdirSync as mkdirSync5 } from "fs";
1213
+ import { homedir as homedir6 } from "os";
1214
+ import { dirname as dirname4, join as join7, resolve as resolve3 } from "path";
1215
+
1216
+ // ../../packages/core/src/storage/sqlite.ts
1217
+ var isBun = typeof process.versions.bun === "string";
1218
+ var Database;
1219
+ if (isBun) {
1220
+ ({ Database } = await import("bun:sqlite"));
1221
+ } else {
1222
+ const nodeSqliteSpecifier = ["node", "sqlite"].join(":");
1223
+ const { DatabaseSync } = await import(nodeSqliteSpecifier);
1224
+
1225
+ class NodeDatabase {
1226
+ #db;
1227
+ constructor(path, options = {}) {
1228
+ this.#db = options.readonly ? new DatabaseSync(path, { readOnly: true }) : new DatabaseSync(path);
1229
+ }
1230
+ query(sql) {
1231
+ return this.#db.prepare(sql);
1232
+ }
1233
+ prepare(sql) {
1234
+ return this.#db.prepare(sql);
1235
+ }
1236
+ exec(sql) {
1237
+ this.#db.exec(sql);
1238
+ }
1239
+ run(sql, ...params) {
1240
+ return this.#db.prepare(sql).run(...params);
1241
+ }
1242
+ transaction(fn) {
1243
+ const run = (begin) => (...args) => {
1244
+ this.#db.exec(begin);
1245
+ try {
1246
+ const result = fn(...args);
1247
+ this.#db.exec("COMMIT");
1248
+ return result;
1249
+ } catch (err) {
1250
+ this.#db.exec("ROLLBACK");
1251
+ throw err;
1252
+ }
1253
+ };
1254
+ const tx = run("BEGIN");
1255
+ tx.deferred = run("BEGIN DEFERRED");
1256
+ tx.immediate = run("BEGIN IMMEDIATE");
1257
+ tx.exclusive = run("BEGIN EXCLUSIVE");
1258
+ return tx;
1259
+ }
1260
+ close() {
1261
+ this.#db.close();
1262
+ }
1263
+ }
1264
+ Database = NodeDatabase;
1265
+ }
1266
+
1267
+ // ../../packages/core/src/storage/storage-host.ts
1268
+ var configuredHost = {};
1269
+ var fallbackDatabase = null;
1270
+ var fallbackDatabasePath = null;
1271
+ var schemaInitializers = [];
1272
+ var initializedSchemas = new WeakMap;
1273
+ var initializingDatabases = new WeakSet;
1274
+ function envPath(name, fallback) {
1275
+ const value = process.env[name]?.trim();
1276
+ return resolve3(value || fallback);
1277
+ }
1278
+ function defaultStateDir() {
1279
+ return envPath("NEGOTIUM_STATE_DIR", join7(homedir6(), ".negotium"));
1280
+ }
1281
+ function defaultDataDir() {
1282
+ return envPath("NEGOTIUM_DATA_DIR", join7(defaultStateDir(), "data"));
1283
+ }
1284
+ function defaultSessionsDatabasePath() {
1285
+ return envPath("SESSIONS_DB_PATH", join7(resolveStorageDataDir(), "sessions.db"));
1286
+ }
1287
+ function initializeDatabase(database) {
1288
+ database.exec("PRAGMA journal_mode = WAL");
1289
+ database.exec("PRAGMA foreign_keys = ON");
1290
+ database.exec("PRAGMA busy_timeout = 5000");
1291
+ database.exec("PRAGMA wal_autocheckpoint = 1000");
1292
+ try {
1293
+ database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
1294
+ } catch {}
1295
+ }
1296
+ function defaultDatabase() {
1297
+ const path = defaultSessionsDatabasePath();
1298
+ if (fallbackDatabase && fallbackDatabasePath === path)
1299
+ return fallbackDatabase;
1300
+ if (fallbackDatabase)
1301
+ fallbackDatabase.close();
1302
+ mkdirSync5(dirname4(path), { recursive: true });
1303
+ fallbackDatabase = new Database(path, { create: true });
1304
+ fallbackDatabasePath = path;
1305
+ initializeDatabase(fallbackDatabase);
1306
+ return fallbackDatabase;
1307
+ }
1308
+ function resolveStorageDatabase() {
1309
+ return configuredHost.database ?? defaultDatabase();
1310
+ }
1311
+ function resolveStorageDataDir() {
1312
+ return configuredHost.dataDir ?? defaultDataDir();
1313
+ }
1314
+ function ensureStorageSchemas(database = resolveStorageDatabase()) {
1315
+ if (initializingDatabases.has(database))
1316
+ return;
1317
+ let initialized = initializedSchemas.get(database);
1318
+ if (!initialized) {
1319
+ initialized = new Set;
1320
+ initializedSchemas.set(database, initialized);
1321
+ }
1322
+ initializingDatabases.add(database);
1323
+ try {
1324
+ for (const entry of schemaInitializers) {
1325
+ if (initialized.has(entry.initialize))
1326
+ continue;
1327
+ initialized.add(entry.initialize);
1328
+ try {
1329
+ entry.initialize(database);
1330
+ } catch (error) {
1331
+ initialized.delete(entry.initialize);
1332
+ throw error;
1333
+ }
1334
+ }
1335
+ } finally {
1336
+ initializingDatabases.delete(database);
1337
+ }
1338
+ }
1339
+ var internalStorageDatabase = new Proxy({}, {
1340
+ get(_target, property) {
1341
+ const database = resolveStorageDatabase();
1342
+ ensureStorageSchemas(database);
1343
+ const value = Reflect.get(database, property, database);
1344
+ return typeof value === "function" ? value.bind(database) : value;
1345
+ },
1346
+ set(_target, property, value) {
1347
+ const database = resolveStorageDatabase();
1348
+ ensureStorageSchemas(database);
1349
+ return Reflect.set(database, property, value, database);
1350
+ }
1351
+ });
1352
+
1353
+ // ../../packages/core/src/storage/conversations.ts
1354
+ function safeUserIdComponent(userId) {
1355
+ const str = String(userId);
1356
+ if (!str || /[/\\]|\.\./.test(str)) {
1357
+ throw new Error(`conversations: refusing unsafe userId path component: ${str}`);
1358
+ }
1359
+ return str;
1360
+ }
1361
+ function conversationDir(userId) {
1362
+ return join8(resolveStorageDataDir(), "conversations", safeUserIdComponent(userId));
1363
+ }
1364
+ function topicFilename(topicName) {
1365
+ const t = sanitizeTopicName(topicName, true);
1366
+ return `${t}.jsonl`;
1367
+ }
1368
+ function getConversationPath(userId, topicName) {
1369
+ return join8(conversationDir(userId), topicFilename(topicName));
1370
+ }
1371
+ function readConversation(userId, topicName) {
1372
+ const path = getConversationPath(userId, topicName);
1373
+ const out = [];
1374
+ if (!existsSync6(path))
1375
+ return out;
1376
+ let raw;
1377
+ try {
1378
+ raw = readFileSync5(path, "utf8");
1379
+ } catch (err) {
1380
+ logger.warn({ err, path }, "readConversation: read failed");
1381
+ return out;
1382
+ }
1383
+ for (const line of raw.split(`
1384
+ `)) {
1385
+ if (!line.trim())
1386
+ continue;
1387
+ try {
1388
+ out.push(JSON.parse(line));
1389
+ } catch (err) {
1390
+ logger.warn({ err, line: line.slice(0, 200) }, "readConversation: malformed JSONL line skipped");
1391
+ }
1392
+ }
1393
+ return out;
1394
+ }
1395
+
1396
+ // ../../packages/core/src/agents/codex-registry.ts
1397
+ var VALID_EFFORTS2 = new Set(CODEX_EFFORT_VALUES);
1398
+ var codexRegistry = {
1399
+ kind: "codex",
1400
+ defaultModel: "gpt-5.6-luna",
1401
+ expandModelAlias(s) {
1402
+ return s;
1403
+ },
1404
+ validateModel(s) {
1405
+ return typeof s === "string" && s.length > 0;
1406
+ },
1407
+ validEfforts: CODEX_EFFORT_VALUES,
1408
+ validateEffort(s) {
1409
+ return VALID_EFFORTS2.has(s);
1410
+ },
1411
+ footerLabel(model, effort) {
1412
+ return `${model} \xB7 ${effort ?? "(off)"}`;
1413
+ },
1414
+ writeRollout(opts) {
1415
+ const { threadId, rolloutPath } = writeCodexRollout({
1416
+ cwd: opts.cwd,
1417
+ entries: opts.entries,
1418
+ model: opts.model ?? codexRegistry.defaultModel,
1419
+ ...opts.effort ? { effort: opts.effort } : {},
1420
+ ...opts.reuseSessionId ? { threadId: opts.reuseSessionId } : {}
1421
+ });
1422
+ return { sessionId: threadId, rolloutPath };
1423
+ },
1424
+ async forkSession({ cwd, userId, topicName, model, effort }) {
1425
+ const entries = readConversation(userId, topicName);
1426
+ const { threadId, rolloutPath } = writeCodexRollout({
1427
+ cwd,
1428
+ entries,
1429
+ model: model ?? codexRegistry.defaultModel,
1430
+ ...effort ? { effort } : {}
1431
+ });
1432
+ return { forkId: threadId, rolloutPath };
1433
+ },
1434
+ async cleanupRollouts({ sessionIds }) {
1435
+ if (sessionIds.length === 0)
1436
+ return;
1437
+ const sessionsDir = join9(process.env.CODEX_HOME || join9(homedir7(), ".codex"), "sessions");
1438
+ const failures = [];
1439
+ for (const tid of sessionIds) {
1440
+ try {
1441
+ const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);
1442
+ for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
1443
+ const path = join9(sessionsDir, rel);
1444
+ try {
1445
+ unlinkSync6(path);
1446
+ } catch (e) {
1447
+ if (e?.code !== "ENOENT") {
1448
+ logger.warn({ err: e, path }, "codex cleanupRollouts: unlink failed");
1449
+ failures.push(e);
1450
+ }
1451
+ }
1452
+ }
1453
+ } catch (e) {
1454
+ logger.warn({ err: e, threadId: tid }, "codex cleanupRollouts: scan failed");
1455
+ failures.push(e);
1456
+ }
1457
+ }
1458
+ if (failures.length > 0) {
1459
+ throw new AggregateError(failures, "codex cleanupRollouts failed");
1460
+ }
1461
+ }
1462
+ };
1463
+
1464
+ // ../../packages/core/src/platform/maestro-bootstrap-env.ts
1465
+ process.env.MAESTRO_SDK_SILENT_BOOTSTRAP ??= "1";
1466
+
1467
+ // ../../packages/core/src/agents/maestro-registry.ts
1468
+ import {
1469
+ setConversationReader,
1470
+ maestroRegistry as upstreamMaestroRegistry
1471
+ } from "maestro-agent-sdk";
1472
+ setConversationReader(readConversation);
1473
+ var maestroRegistry = {
1474
+ ...upstreamMaestroRegistry,
1475
+ defaultModel: "deepseek-pro"
1476
+ };
1477
+
1478
+ // ../../packages/core/src/agents/registry.ts
1479
+ var REGISTRIES = {
1480
+ claude: claudeRegistry,
1481
+ codex: codexRegistry,
1482
+ maestro: maestroRegistry
1483
+ };
1484
+ function getRegistry(agent) {
1485
+ return REGISTRIES[agent];
1486
+ }
1487
+
1488
+ // ../../packages/core/src/agents/fork.ts
1489
+ function createAgentForkHelpers(host) {
1490
+ return {
1491
+ async forkAgentSession(options) {
1492
+ const { agent, ...forkOptions } = options;
1493
+ const { forkId, rolloutPath } = await host.forkSession(agent, forkOptions);
1494
+ return { agent, forkId, rolloutPath };
1495
+ },
1496
+ cleanupAgentFork(handle) {
1497
+ try {
1498
+ if (host.exists(handle.rolloutPath))
1499
+ host.unlink(handle.rolloutPath);
1500
+ } catch (error) {
1501
+ host.warn({
1502
+ error,
1503
+ agent: handle.agent,
1504
+ forkId: handle.forkId,
1505
+ rolloutPath: handle.rolloutPath
1506
+ }, "cleanupAgentFork: failed to remove rollout");
1507
+ }
1508
+ }
1509
+ };
1510
+ }
1511
+ var defaultForkHelpers = createAgentForkHelpers({
1512
+ forkSession: (agent, options) => getRegistry(agent).forkSession(options),
1513
+ exists: existsSync7,
1514
+ unlink: unlinkSync7,
1515
+ warn: (details, message) => logger.warn(details, message)
1516
+ });
1517
+ async function forkAgentSession(opts) {
1518
+ return defaultForkHelpers.forkAgentSession(opts);
1519
+ }
1520
+ function cleanupAgentFork(handle) {
1521
+ defaultForkHelpers.cleanupAgentFork(handle);
1522
+ }
1523
+ // ../../packages/core/src/storage/tasks.ts
1524
+ import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync6, renameSync as renameSync4, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
1525
+ import { dirname as dirname6, join as join10 } from "path";
1526
+ function safeUserIdComponent2(userId) {
1527
+ const str = String(userId);
1528
+ if (!str || /[/\\]|\.\./.test(str)) {
1529
+ throw new Error(`tasks: refusing unsafe userId path component: ${str}`);
1530
+ }
1531
+ return str;
1532
+ }
1533
+ function safeTaskScopeKey(scopeKey) {
1534
+ const safe = sanitizeFileName(scopeKey);
1535
+ if (!safe || safe === "." || safe === "..") {
1536
+ throw new Error(`tasks: refusing unsafe scope key: ${scopeKey}`);
1537
+ }
1538
+ return safe;
1539
+ }
1540
+ function taskScopeKey(opts) {
1541
+ return opts.topicId?.trim() || opts.session || "default";
1542
+ }
1543
+ function getTaskFilePath(userId, scopeKey) {
1544
+ return join10(resolveStorageDataDir(), "tasks", safeUserIdComponent2(userId), `${safeTaskScopeKey(scopeKey)}.json`);
1545
+ }
1546
+ function readTasks(userId, scopeKey) {
1547
+ const path = getTaskFilePath(userId, scopeKey);
1548
+ if (!existsSync8(path))
1549
+ return [];
1550
+ try {
1551
+ const parsed = JSON.parse(readFileSync6(path, "utf-8"));
1552
+ return Array.isArray(parsed?.tasks) ? parsed.tasks : [];
1553
+ } catch (e) {
1554
+ logger.warn({ err: e, path }, "tasks: failed to read task store");
1555
+ return [];
1556
+ }
1557
+ }
1558
+ function taskFileMtimeNs(userId, scopeKey) {
1559
+ try {
1560
+ return statSync3(getTaskFilePath(userId, scopeKey), { bigint: true }).mtimeNs;
1561
+ } catch {
1562
+ return null;
1563
+ }
1564
+ }
1565
+
1566
+ // ../../packages/core/src/agents/task-events.ts
1567
+ var defaultTaskEventHost = { readTasks, taskFileMtimeNs, taskScopeKey };
1568
+ function resolveTaskEventScope(opts, host = defaultTaskEventHost) {
1569
+ if (opts.silent)
1570
+ return null;
1571
+ if (!opts.userId)
1572
+ return null;
1573
+ if (opts.sessionType === "dm" || opts.sessionType === "ephemeral") {
1574
+ return { userId: opts.userId, scopeKey: "dm" };
1575
+ }
1576
+ if (opts.sessionType === "manager") {
1577
+ return { userId: opts.userId, scopeKey: opts.topicId ?? "general" };
1578
+ }
1579
+ if (!opts.session)
1580
+ return null;
1581
+ return {
1582
+ userId: opts.userId,
1583
+ scopeKey: host.taskScopeKey({ topicId: opts.topicId, session: opts.session })
1584
+ };
1585
+ }
1586
+ async function* withTaskSnapshots(inner, scope, host = defaultTaskEventHost) {
1587
+ let lastMtime = host.taskFileMtimeNs(scope.userId, scope.scopeKey);
1588
+ for await (const event of inner) {
1589
+ yield event;
1590
+ if (event.type !== "tool_result" && event.type !== "result")
1591
+ continue;
1592
+ const mtime = host.taskFileMtimeNs(scope.userId, scope.scopeKey);
1593
+ if (mtime === lastMtime)
1594
+ continue;
1595
+ lastMtime = mtime;
1596
+ yield { type: "tasks", tasks: host.readTasks(scope.userId, scope.scopeKey) };
1597
+ }
1598
+ }
1599
+ // ../../packages/core/src/security/sensitive-path.ts
1600
+ import { realpathSync } from "fs";
1601
+ import { resolve as resolve4 } from "path";
1602
+ var SENSITIVE_PATH_PATTERNS = [
1603
+ /\/\.env(\.|$)/i,
1604
+ /\/\.ssh\//i,
1605
+ /\/\.aws\//i,
1606
+ /\/\.gnupg\//i,
1607
+ /\/\.netrc$/i,
1608
+ /\/\.npmrc$/i,
1609
+ /\/(id_rsa|id_ed25519|id_ecdsa|id_dsa)(\.pub)?$/i,
1610
+ /\.(pem|key|p12|pfx|cer|crt)$/i,
1611
+ /\/Library\/Keychains\//i,
1612
+ /\/vault\.db(-wal|-shm|-journal)?$/i,
1613
+ /\/vault-master-key$/i,
1614
+ /\/runtime-mcp-secret$/i,
1615
+ /\/sessions\.db(-wal|-shm|-journal)?$/i
1616
+ ];
1617
+ function isSensitivePath(filePath) {
1618
+ const normalized = resolve4(filePath);
1619
+ if (SENSITIVE_PATH_PATTERNS.some((p) => p.test(normalized)))
1620
+ return true;
1621
+ try {
1622
+ const real = realpathSync(normalized);
1623
+ if (real !== normalized)
1624
+ return SENSITIVE_PATH_PATTERNS.some((p) => p.test(real));
1625
+ } catch {}
1626
+ return false;
1627
+ }
1628
+
1629
+ // ../../packages/core/src/storage/vault.ts
1630
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync8 } from "fs";
1631
+ import { join as join11 } from "path";
1632
+ var vaultDb;
1633
+ function initializeVaultDatabase(database) {
1634
+ database.exec("PRAGMA journal_mode = WAL");
1635
+ database.exec("PRAGMA busy_timeout = 5000");
1636
+ database.exec(`
1637
+ CREATE TABLE IF NOT EXISTS vault (
1638
+ user_id TEXT NOT NULL,
1639
+ key TEXT NOT NULL,
1640
+ value TEXT NOT NULL,
1641
+ description TEXT NOT NULL DEFAULT '',
1642
+ PRIMARY KEY (user_id, key)
1643
+ )
1644
+ `);
1645
+ {
1646
+ const cols = database.prepare("PRAGMA table_info(vault)").all();
1647
+ const uid = cols.find((c) => c.name === "user_id");
1648
+ if (uid && uid.type.toUpperCase() === "INTEGER") {
1649
+ database.exec("BEGIN");
1650
+ database.exec(`
1651
+ CREATE TABLE vault_migrated (
1652
+ user_id TEXT NOT NULL,
1653
+ key TEXT NOT NULL,
1654
+ value TEXT NOT NULL,
1655
+ description TEXT NOT NULL DEFAULT '',
1656
+ PRIMARY KEY (user_id, key)
1657
+ )
1658
+ `);
1659
+ database.exec("INSERT INTO vault_migrated SELECT CAST(user_id AS TEXT), key, value, description FROM vault");
1660
+ database.exec("DROP TABLE vault");
1661
+ database.exec("ALTER TABLE vault_migrated RENAME TO vault");
1662
+ database.exec("COMMIT");
1663
+ }
1664
+ }
1665
+ }
1666
+ function openVaultDatabase(dataDir) {
1667
+ const path = join11(dataDir, "vault.db");
1668
+ mkdirSync8(dataDir, { recursive: true });
1669
+ const database = new Database(path, { create: true });
1670
+ chmodSync2(path, 384);
1671
+ initializeVaultDatabase(database);
1672
+ return database;
1673
+ }
1674
+ function activeVaultDatabase() {
1675
+ if (!vaultDb)
1676
+ vaultDb = openVaultDatabase(DATA_DIR);
1677
+ return vaultDb;
1678
+ }
1679
+ var VAULT_VALUE_MAX_BYTES = 64 * 1024;
1680
+ function normalizeVaultKey(key) {
1681
+ return key.trim().toUpperCase();
1682
+ }
1683
+ function vaultList(userId) {
1684
+ return activeVaultDatabase().prepare("SELECT key, description FROM vault WHERE user_id = ? ORDER BY key").all(userId);
1685
+ }
1686
+ function valueReferencesVaultKey(userId, value) {
1687
+ const keys = new Set(vaultList(userId).map((entry) => entry.key));
1688
+ const visit = (candidate) => {
1689
+ if (typeof candidate === "string") {
1690
+ for (const match of candidate.matchAll(/\{\{([^}]+)\}\}/g)) {
1691
+ if (keys.has(normalizeVaultKey(match[1] ?? "")))
1692
+ return true;
1693
+ }
1694
+ return false;
1695
+ }
1696
+ if (Array.isArray(candidate))
1697
+ return candidate.some(visit);
1698
+ if (candidate && typeof candidate === "object") {
1699
+ return Object.values(candidate).some(visit);
1700
+ }
1701
+ return false;
1702
+ };
1703
+ return visit(value);
1704
+ }
1705
+
1706
+ // ../../packages/core/src/agents/vault-tool-policy.ts
1707
+ var SENSITIVE_RUNTIME_NAMES = [
1708
+ "vault.db",
1709
+ "vault-master-key",
1710
+ "runtime-mcp-secret",
1711
+ "sessions.db"
1712
+ ];
1713
+ var VAULT_BROKER_REDIRECT_ERROR = "Vault placeholders must be executed through mcp__vault__vault_run (shell/CLI) or mcp__vault__vault_http_request (HTTP) so secret values cannot enter the model transcript.";
1714
+ function createVaultToolPolicy(host) {
1715
+ function isVaultBrokerTool(toolName) {
1716
+ return toolName.includes("vault_run") || toolName.includes("vault_http_request");
1717
+ }
1718
+ function referencesRuntimeSecretStorage(value) {
1719
+ if (typeof value === "string") {
1720
+ const lower = value.toLowerCase();
1721
+ if (SENSITIVE_RUNTIME_NAMES.some((name) => lower.includes(name)))
1722
+ return true;
1723
+ return value.startsWith("/") && host.isSensitivePath(value);
1724
+ }
1725
+ if (Array.isArray(value))
1726
+ return value.some(referencesRuntimeSecretStorage);
1727
+ if (value && typeof value === "object") {
1728
+ return Object.values(value).some(referencesRuntimeSecretStorage);
1729
+ }
1730
+ return false;
1731
+ }
1732
+ function shouldRedirectVaultTool(userId, toolName, input) {
1733
+ return !isVaultBrokerTool(toolName) && host.valueReferencesVaultKey(userId, input);
1734
+ }
1735
+ return { isVaultBrokerTool, referencesRuntimeSecretStorage, shouldRedirectVaultTool };
1736
+ }
1737
+ var defaultVaultToolPolicy = createVaultToolPolicy({ isSensitivePath, valueReferencesVaultKey });
1738
+ var isVaultBrokerTool = defaultVaultToolPolicy.isVaultBrokerTool;
1739
+ var referencesRuntimeSecretStorage = defaultVaultToolPolicy.referencesRuntimeSecretStorage;
1740
+ var shouldRedirectVaultTool = defaultVaultToolPolicy.shouldRedirectVaultTool;
1741
+ export {
1742
+ withTaskSnapshots,
1743
+ withCodexSpawnSerial,
1744
+ unregisterOwnedCodexPids,
1745
+ snapshotCodexChildren,
1746
+ shouldRedirectVaultTool,
1747
+ resolveTaskEventScope,
1748
+ registerOwnedCodexPids,
1749
+ referencesRuntimeSecretStorage,
1750
+ killOwnedCodexTreesForShutdown,
1751
+ killCodexTrees,
1752
+ isVaultBrokerTool,
1753
+ forkAgentSession,
1754
+ findNewCodexChildren,
1755
+ createVaultToolPolicy,
1756
+ createCodexTreeManager,
1757
+ createAgentForkHelpers,
1758
+ cleanupAgentFork,
1759
+ checkAgentAuth,
1760
+ acquireCodexSpawnLock,
1761
+ VAULT_BROKER_REDIRECT_ERROR
1762
+ };
1763
+
1764
+ //# debugId=3205ED8BFB73168364756E2164756E21