negotium 0.18.2 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/codex-sdk-window-hide.mjs +40 -0
- package/bin/negotium.mjs +4 -0
- package/dist/agent-helpers.js +432 -152
- package/dist/agent-helpers.js.map +7 -6
- package/dist/canonical-mcp-bridge.js +3 -2
- package/dist/canonical-mcp-bridge.js.map +1 -1
- package/dist/chunk-22mtr8np.js +200 -0
- package/dist/chunk-22mtr8np.js.map +9 -0
- package/dist/chunk-2mx7fq49.js +6 -0
- package/dist/chunk-2mx7fq49.js.map +9 -0
- package/dist/{chunk-44ajn328.js → chunk-4bzehg8t.js} +2 -2
- package/dist/chunk-4bzehg8t.js.map +12 -0
- package/dist/{chunk-r0xs3t81.js → chunk-f7p0h1gs.js} +2 -4
- package/dist/{chunk-r0xs3t81.js.map → chunk-f7p0h1gs.js.map} +2 -2
- package/dist/chunk-y8rtedjb.js +374 -0
- package/dist/chunk-y8rtedjb.js.map +13 -0
- package/dist/hosted-agent.js +355 -476
- package/dist/hosted-agent.js.map +7 -10
- package/dist/main.js +773 -473
- package/dist/main.js.map +8 -7
- package/dist/mcp-factories.js +407 -127
- package/dist/mcp-factories.js.map +7 -6
- package/dist/registry.js +1 -1
- package/dist/runtime/src/agents/codex-native-multi-agent.ts +45 -3
- package/dist/runtime/src/agents/codex-vault-hook-bridge.ts +36 -23
- package/dist/runtime/src/agents/codex-windows-wrapper.ts +174 -0
- package/dist/runtime/src/prompts/sessions/_shared-tools.md +19 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/agents/codex-windows-wrapper.d.ts +30 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-44ajn328.js.map +0 -12
package/dist/hosted-agent.js
CHANGED
|
@@ -1,351 +1,61 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
__require,
|
|
4
3
|
canonicalMcpBridgeEnv,
|
|
5
4
|
revokeCanonicalMcpBridgeTurn
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-f7p0h1gs.js";
|
|
6
|
+
import {
|
|
7
|
+
AGENT_HEALTH_SERVER,
|
|
8
|
+
BASHRS_SPILL_ROOT,
|
|
9
|
+
BASH_RS_BIN,
|
|
10
|
+
BASH_RS_VERSION,
|
|
11
|
+
BG_BASH_BASE_PORT,
|
|
12
|
+
BG_BASH_MAX_PORT,
|
|
13
|
+
CANONICAL_MCP_PROXY_SERVER,
|
|
14
|
+
CLAUDE_EFFORT_VALUES,
|
|
15
|
+
CLAUDE_EXECUTABLE,
|
|
16
|
+
DECISION_SERVER,
|
|
17
|
+
DM_WORKSPACE_DIR,
|
|
18
|
+
FALLBACK_AGENT,
|
|
19
|
+
FILE_TAG_REGEX,
|
|
20
|
+
MODEL_FABLE,
|
|
21
|
+
MODEL_OPUS,
|
|
22
|
+
MODEL_SONNET,
|
|
23
|
+
NEGOTIUM_PORT,
|
|
24
|
+
PROJECT_ROOT,
|
|
25
|
+
RUNTIME_MCP_SECRET,
|
|
26
|
+
RUN_DIR,
|
|
27
|
+
SESSION_COMM_SERVER,
|
|
28
|
+
SESSION_WORKSPACE_DIR,
|
|
29
|
+
SYSTEM_HEALTH_SERVER,
|
|
30
|
+
TASK_SERVER,
|
|
31
|
+
TOKEN_STATS_SERVER,
|
|
32
|
+
TOPIC_WORKSPACE_DIR,
|
|
33
|
+
TSCONFIG_PATH,
|
|
34
|
+
TSX_LOADER,
|
|
35
|
+
VAULT_MASTER_KEY,
|
|
36
|
+
VAULT_SERVER,
|
|
37
|
+
WIKI_SERVER,
|
|
38
|
+
WORKSPACE_DIR,
|
|
39
|
+
codexAuthFilePath,
|
|
40
|
+
envText,
|
|
41
|
+
logger,
|
|
42
|
+
resolveFallbackAgent,
|
|
43
|
+
resolveTopicWorkspaceDir
|
|
44
|
+
} from "./chunk-y8rtedjb.js";
|
|
45
|
+
import {
|
|
46
|
+
__require
|
|
47
|
+
} from "./chunk-2mx7fq49.js";
|
|
7
48
|
|
|
8
49
|
// ../../packages/core/src/agents/claude-provider.ts
|
|
9
50
|
import { spawn as spawn2 } from "child_process";
|
|
10
|
-
import { existsSync
|
|
51
|
+
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
11
52
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
12
53
|
|
|
13
54
|
// ../../packages/core/src/agents/rollout/shared.ts
|
|
14
|
-
import { resolve as
|
|
15
|
-
|
|
16
|
-
// ../../packages/core/src/platform/config.ts
|
|
17
|
-
import { execFileSync } from "child_process";
|
|
18
|
-
import { randomBytes } from "crypto";
|
|
19
|
-
import {
|
|
20
|
-
accessSync,
|
|
21
|
-
chmodSync,
|
|
22
|
-
constants,
|
|
23
|
-
existsSync,
|
|
24
|
-
mkdirSync,
|
|
25
|
-
readFileSync,
|
|
26
|
-
writeFileSync
|
|
27
|
-
} from "fs";
|
|
28
|
-
import { createRequire } from "module";
|
|
29
|
-
import { homedir } from "os";
|
|
30
|
-
import { dirname, join, resolve } from "path";
|
|
31
|
-
import { fileURLToPath, pathToFileURL } from "url";
|
|
32
|
-
|
|
33
|
-
// ../../packages/core/src/types.ts
|
|
34
|
-
var SUPPORTED_AGENTS = ["maestro", "claude", "codex"];
|
|
35
|
-
function isAgentKind(value) {
|
|
36
|
-
return typeof value === "string" && SUPPORTED_AGENTS.includes(value);
|
|
37
|
-
}
|
|
38
|
-
var CLAUDE_EFFORT_VALUES = ["low", "medium", "high", "xhigh", "max"];
|
|
39
|
-
var EFFORT_VALUES = [
|
|
40
|
-
"low",
|
|
41
|
-
"medium",
|
|
42
|
-
"high",
|
|
43
|
-
"xhigh",
|
|
44
|
-
"max"
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
// ../../packages/core/src/platform/config-helpers.ts
|
|
48
|
-
function readEnvText(env, key) {
|
|
49
|
-
const value = env[key]?.trim();
|
|
50
|
-
return value || undefined;
|
|
51
|
-
}
|
|
52
|
-
function resolveFallbackAgent(env = process.env) {
|
|
53
|
-
const value = readEnvText(env, "FALLBACK_AGENT") ?? readEnvText(env, "DEFAULT_AGENT");
|
|
54
|
-
return isAgentKind(value) ? value : "claude";
|
|
55
|
-
}
|
|
56
|
-
function parseRuntimePort(value, fallback) {
|
|
57
|
-
if (!value)
|
|
58
|
-
return fallback;
|
|
59
|
-
const port = Number.parseInt(value, 10);
|
|
60
|
-
return Number.isInteger(port) && port > 0 && port <= 65535 ? port : fallback;
|
|
61
|
-
}
|
|
62
|
-
function safeRuntimePathSegment(value, fallback, maxLength = 160) {
|
|
63
|
-
const cleaned = value.trim().replace(/[^A-Za-z0-9._-]/g, "_").replace(/^_+|_+$/g, "").slice(0, maxLength);
|
|
64
|
-
return cleaned || fallback;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ../../packages/core/src/platform/logger.ts
|
|
68
|
-
import pino from "pino";
|
|
69
|
-
function createStdioLogger(options = {}) {
|
|
70
|
-
const development = options.development ?? true;
|
|
71
|
-
return pino({
|
|
72
|
-
level: options.level ?? process.env.LOG_LEVEL ?? "info",
|
|
73
|
-
transport: development ? {
|
|
74
|
-
target: "pino-pretty",
|
|
75
|
-
options: {
|
|
76
|
-
colorize: true,
|
|
77
|
-
translateTime: "SYS:yyyy-mm-dd HH:MM:ss",
|
|
78
|
-
destination: 2
|
|
79
|
-
}
|
|
80
|
-
} : undefined
|
|
81
|
-
}, pino.destination(2));
|
|
82
|
-
}
|
|
83
|
-
var logger = createStdioLogger();
|
|
84
|
-
|
|
85
|
-
// ../../packages/core/src/platform/config.ts
|
|
86
|
-
function envText(envKey) {
|
|
87
|
-
return readEnvText(process.env, envKey);
|
|
88
|
-
}
|
|
89
|
-
var HOME = homedir();
|
|
90
|
-
function resolveStateDir() {
|
|
91
|
-
const configured = envText("NEGOTIUM_STATE_DIR");
|
|
92
|
-
if (false) {}
|
|
93
|
-
return configured ? resolve(configured) : resolve(HOME, ".negotium");
|
|
94
|
-
}
|
|
95
|
-
function resolveProjectRoot() {
|
|
96
|
-
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
97
|
-
const packagedRuntime = resolve(moduleDir, "runtime");
|
|
98
|
-
if (existsSync(resolve(packagedRuntime, "src")))
|
|
99
|
-
return packagedRuntime;
|
|
100
|
-
return resolve(moduleDir, "../..");
|
|
101
|
-
}
|
|
102
|
-
var PROJECT_ROOT = resolveProjectRoot();
|
|
103
|
-
function dependencyBinNames(name) {
|
|
104
|
-
if (process.platform !== "win32")
|
|
105
|
-
return [name];
|
|
106
|
-
return [name, `${name}.exe`, `${name}.cmd`, `${name}.bat`, `${name}.bunx`];
|
|
107
|
-
}
|
|
108
|
-
function resolveDependencyBin(name) {
|
|
109
|
-
let dir = PROJECT_ROOT;
|
|
110
|
-
while (true) {
|
|
111
|
-
const binDir = resolve(dir, "node_modules", ".bin");
|
|
112
|
-
for (const candidate of dependencyBinNames(name)) {
|
|
113
|
-
const path = resolve(binDir, candidate);
|
|
114
|
-
if (existsSync(path))
|
|
115
|
-
return path;
|
|
116
|
-
}
|
|
117
|
-
const parent = dirname(dir);
|
|
118
|
-
if (parent === dir)
|
|
119
|
-
return resolve(binDir, name);
|
|
120
|
-
dir = parent;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
var STATE_DIR = resolveStateDir();
|
|
124
|
-
function resolveLocalStateDir(envKey, stateName) {
|
|
125
|
-
const envValue = envText(envKey);
|
|
126
|
-
if (envValue)
|
|
127
|
-
return resolve(envValue);
|
|
128
|
-
return resolve(STATE_DIR, stateName);
|
|
129
|
-
}
|
|
130
|
-
function parsePortEnv(envValue, fallback) {
|
|
131
|
-
return parseRuntimePort(envValue, fallback);
|
|
132
|
-
}
|
|
133
|
-
var WORKSPACE_DIR = resolveLocalStateDir("NEGOTIUM_WORKSPACE_DIR", "workspace");
|
|
134
|
-
var TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "topics");
|
|
135
|
-
var SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, "wiki");
|
|
136
|
-
var CRON_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "cron");
|
|
137
|
-
var BROWSER_DIR = resolveLocalStateDir("NEGOTIUM_BROWSER_DIR", "browser");
|
|
138
|
-
var BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, "profiles");
|
|
139
|
-
var BINARIES_DIR = resolve(STATE_DIR, "binaries");
|
|
140
|
-
var SECRETS_DIR = resolve(STATE_DIR, "secrets");
|
|
141
|
-
var DM_WORKSPACE_DIR = resolve(STATE_DIR, "data", "dm");
|
|
142
|
-
var SESSION_WORKSPACE_DIR = resolve(STATE_DIR, "data", "sessions");
|
|
143
|
-
var CLAUDE_EXECUTABLE_ENV = envText("NEGOTIUM_CLAUDE_EXECUTABLE");
|
|
144
|
-
var CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;
|
|
145
|
-
var BINARY_EXTENSION = process.platform === "win32" ? ".exe" : "";
|
|
146
|
-
var BROWSER_RS_VERSION = "v0.6.0";
|
|
147
|
-
var BROWSER_RS_MIN_SECURE_VERSION = "0.2.1";
|
|
148
|
-
function versionAtLeast(actualVersion, minimumVersion) {
|
|
149
|
-
const actual = actualVersion.split(".").map(Number);
|
|
150
|
-
const minimum = minimumVersion.split(".").map(Number);
|
|
151
|
-
if (actual.some(Number.isNaN) || minimum.some(Number.isNaN))
|
|
152
|
-
return false;
|
|
153
|
-
for (let index = 0;index < minimum.length; index += 1) {
|
|
154
|
-
if ((actual[index] ?? 0) > (minimum[index] ?? 0))
|
|
155
|
-
return true;
|
|
156
|
-
if ((actual[index] ?? 0) < (minimum[index] ?? 0))
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
return true;
|
|
160
|
-
}
|
|
161
|
-
var BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000;
|
|
162
|
-
function browserRsMeetsMinimumVersion(candidate) {
|
|
163
|
-
try {
|
|
164
|
-
const output = execFileSync(candidate, ["--version"], {
|
|
165
|
-
encoding: "utf8",
|
|
166
|
-
timeout: BROWSER_RS_VERSION_PROBE_TIMEOUT_MS,
|
|
167
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
168
|
-
windowsHide: true
|
|
169
|
-
}).trim();
|
|
170
|
-
const match = output.match(/^browser-rs (\d+)\.(\d+)\.(\d+)$/);
|
|
171
|
-
if (!match)
|
|
172
|
-
return false;
|
|
173
|
-
return versionAtLeast(match.slice(1).join("."), BROWSER_RS_MIN_SECURE_VERSION);
|
|
174
|
-
} catch {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
function resolveBrowserRsBin(envValue) {
|
|
179
|
-
const override = envValue?.trim();
|
|
180
|
-
if (!override && !versionAtLeast(BROWSER_RS_VERSION.replace(/^v/, ""), BROWSER_RS_MIN_SECURE_VERSION)) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
const candidate = override ? resolve(override) : resolve(BINARIES_DIR, "browser-rs", BROWSER_RS_VERSION, `browser-rs${BINARY_EXTENSION}`);
|
|
184
|
-
try {
|
|
185
|
-
accessSync(candidate, constants.X_OK);
|
|
186
|
-
return browserRsMeetsMinimumVersion(candidate) ? candidate : undefined;
|
|
187
|
-
} catch {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
var SNIPPETS_API_URL = (envText("NEGOTIUM_SNIPPETS_API_URL") ?? envText("SNIPPETS_API_URL") ?? "").replace(/\/+$/, "");
|
|
192
|
-
var BROWSER_RS_BIN = resolveBrowserRsBin(envText("NEGOTIUM_BROWSER_RS_BIN"));
|
|
193
|
-
var BASH_RS_VERSION = "v0.1.10";
|
|
194
|
-
function resolveBashRsBin(envValue) {
|
|
195
|
-
const override = envValue?.trim();
|
|
196
|
-
const candidate = override ? resolve(override) : resolve(BINARIES_DIR, "bash-rs", BASH_RS_VERSION, `bash-rs${BINARY_EXTENSION}`);
|
|
197
|
-
try {
|
|
198
|
-
accessSync(candidate, constants.X_OK);
|
|
199
|
-
return candidate;
|
|
200
|
-
} catch {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
var BASH_RS_BIN = resolveBashRsBin(envText("NEGOTIUM_BASH_RS_BIN"));
|
|
205
|
-
function resolveBrowserMcpBin(envValue) {
|
|
206
|
-
const override = envValue?.trim();
|
|
207
|
-
if (override)
|
|
208
|
-
return resolve(override);
|
|
209
|
-
return BROWSER_RS_BIN ?? resolve(BINARIES_DIR, "browser-rs", BROWSER_RS_VERSION, `browser-rs${BINARY_EXTENSION}`);
|
|
210
|
-
}
|
|
211
|
-
var PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText("NEGOTIUM_BROWSER_MCP_BIN"));
|
|
212
|
-
var TSX_BIN = resolveDependencyBin("tsx");
|
|
213
|
-
var TSX_LOADER_PATH = createRequire(import.meta.url).resolve("tsx");
|
|
214
|
-
var TSX_LOADER = process.platform === "win32" ? pathToFileURL(TSX_LOADER_PATH).href : TSX_LOADER_PATH;
|
|
215
|
-
var TSCONFIG_PATH = resolve(PROJECT_ROOT, "tsconfig.json");
|
|
216
|
-
var SESSION_COMM_SERVER = resolve(PROJECT_ROOT, "src/mcp/session-comm/server.ts");
|
|
217
|
-
var TASK_SERVER = resolve(PROJECT_ROOT, "src/mcp/task-server.ts");
|
|
218
|
-
var DECISION_SERVER = resolve(PROJECT_ROOT, "src/mcp/decision-server.ts");
|
|
219
|
-
var CANONICAL_MCP_PROXY_SERVER = resolve(PROJECT_ROOT, "src/mcp/canonical-proxy-server.ts");
|
|
220
|
-
var WIKI_SERVER = resolve(PROJECT_ROOT, "src/mcp/wiki-server.ts");
|
|
221
|
-
var TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, "src/mcp/token-stats-server.ts");
|
|
222
|
-
var COMPACTION_LOG_SERVER = resolve(PROJECT_ROOT, "src/mcp/compaction-log-server.ts");
|
|
223
|
-
var SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, "src/mcp/system-health-server.ts");
|
|
224
|
-
var AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, "src/mcp/agent-health-server.ts");
|
|
225
|
-
var VAULT_SERVER = resolve(PROJECT_ROOT, "src/mcp/vault-server.ts");
|
|
226
|
-
var BG_BASH_BASE_PORT = parsePortEnv(process.env.BG_BASH_BASE_PORT, 9700);
|
|
227
|
-
var BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);
|
|
228
|
-
function safeWorkspaceSegment(value, fallback) {
|
|
229
|
-
return safeRuntimePathSegment(value, fallback);
|
|
230
|
-
}
|
|
231
|
-
function resolveTopicWorkspaceDir(topicId) {
|
|
232
|
-
return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, "topic"));
|
|
233
|
-
}
|
|
234
|
-
function loadOrCreateLocalSecret(envKey, filename, options = {}) {
|
|
235
|
-
const envValue = envText(envKey);
|
|
236
|
-
const secretFile = resolve(SECRETS_DIR, filename);
|
|
237
|
-
mkdirSync(dirname(secretFile), { recursive: true });
|
|
238
|
-
if (envValue) {
|
|
239
|
-
if (options.persistEnvValue) {
|
|
240
|
-
writeFileSync(secretFile, `${envValue}
|
|
241
|
-
`, { mode: 384 });
|
|
242
|
-
chmodSync(secretFile, 384);
|
|
243
|
-
}
|
|
244
|
-
return envValue;
|
|
245
|
-
}
|
|
246
|
-
if (existsSync(secretFile)) {
|
|
247
|
-
const stored = readFileSync(secretFile, "utf-8").trim();
|
|
248
|
-
if (stored) {
|
|
249
|
-
chmodSync(secretFile, 384);
|
|
250
|
-
return stored;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
const secret = randomBytes(32).toString("base64url");
|
|
254
|
-
try {
|
|
255
|
-
writeFileSync(secretFile, `${secret}
|
|
256
|
-
`, { mode: 384, flag: "wx" });
|
|
257
|
-
return secret;
|
|
258
|
-
} catch (error) {
|
|
259
|
-
if (error.code !== "EEXIST")
|
|
260
|
-
throw error;
|
|
261
|
-
const stored = readFileSync(secretFile, "utf-8").trim();
|
|
262
|
-
if (!stored)
|
|
263
|
-
throw new Error(`Secret file exists but is empty: ${secretFile}`);
|
|
264
|
-
chmodSync(secretFile, 384);
|
|
265
|
-
return stored;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
var RUNTIME_MCP_SECRET = loadOrCreateLocalSecret("RUNTIME_MCP_SECRET", "runtime-mcp-secret");
|
|
269
|
-
var NODE_CONTROL_TOKEN = loadOrCreateLocalSecret("NEGOTIUM_CONTROL_TOKEN", "node-control-token");
|
|
270
|
-
var NODE_ID = loadOrCreateLocalSecret("NEGOTIUM_NODE_ID", "node-id");
|
|
271
|
-
var VAULT_MASTER_KEY = loadOrCreateLocalSecret("NEGOTIUM_VAULT_MASTER_KEY", "vault-master-key", { persistEnvValue: true });
|
|
272
|
-
delete process.env.NEGOTIUM_VAULT_MASTER_KEY;
|
|
273
|
-
var NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || "7777", 10);
|
|
274
|
-
var hostname = process.env.HOSTNAME || "127.0.0.1";
|
|
275
|
-
var DATA_DIR = resolveLocalStateDir("NEGOTIUM_DATA_DIR", "data");
|
|
276
|
-
var LOG_DIR = resolveLocalStateDir("NEGOTIUM_LOG_DIR", "logs");
|
|
277
|
-
var UPLOADS_DIR = resolve(DATA_DIR, "uploads");
|
|
278
|
-
var VAULT_DIR = resolve(DATA_DIR, "vault");
|
|
279
|
-
var SESSIONS_DB = process.env.SESSIONS_DB_PATH ? resolve(process.env.SESSIONS_DB_PATH) : resolve(DATA_DIR, "sessions.db");
|
|
280
|
-
var DEBUG_FILE = resolve(DATA_DIR, "debug-users.json");
|
|
281
|
-
var USERS_LOG_DIR = resolve(DATA_DIR, "users");
|
|
282
|
-
var RUN_DIR = resolveLocalStateDir("NEGOTIUM_RUN_DIR", "runtime");
|
|
283
|
-
var PROGRESS_DIR = resolve(RUN_DIR, "progress");
|
|
284
|
-
var DM_CMD_DIR = resolve(RUN_DIR, "dm-commands");
|
|
285
|
-
var DM_RESP_DIR = resolve(RUN_DIR, "dm-responses");
|
|
286
|
-
var SESSION_INBOX_DIR = resolve(RUN_DIR, "session-inbox");
|
|
287
|
-
var SESSION_ASKS_DIR = resolve(RUN_DIR, "session-asks");
|
|
288
|
-
var BASHRS_SPILL_ROOT = resolve(RUN_DIR, "bashrs");
|
|
289
|
-
var PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);
|
|
290
|
-
var PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);
|
|
291
|
-
var PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, "playwright-ports");
|
|
292
|
-
mkdirSync(STATE_DIR, { recursive: true });
|
|
293
|
-
mkdirSync(DATA_DIR, { recursive: true });
|
|
294
|
-
mkdirSync(UPLOADS_DIR, { recursive: true });
|
|
295
|
-
mkdirSync(VAULT_DIR, { recursive: true, mode: 448 });
|
|
296
|
-
mkdirSync(LOG_DIR, { recursive: true });
|
|
297
|
-
mkdirSync(PROGRESS_DIR, { recursive: true });
|
|
298
|
-
mkdirSync(DM_CMD_DIR, { recursive: true });
|
|
299
|
-
mkdirSync(DM_RESP_DIR, { recursive: true });
|
|
300
|
-
mkdirSync(SESSION_INBOX_DIR, { recursive: true });
|
|
301
|
-
mkdirSync(SESSION_ASKS_DIR, { recursive: true });
|
|
302
|
-
mkdirSync(PLAYWRIGHT_PORTS_DIR, { recursive: true });
|
|
303
|
-
mkdirSync(WORKSPACE_DIR, { recursive: true });
|
|
304
|
-
mkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });
|
|
305
|
-
mkdirSync(SHARED_WIKI_DIR, { recursive: true });
|
|
306
|
-
mkdirSync(CRON_WORKSPACE_DIR, { recursive: true });
|
|
307
|
-
mkdirSync(DM_WORKSPACE_DIR, { recursive: true });
|
|
308
|
-
mkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });
|
|
309
|
-
mkdirSync(BROWSER_DIR, { recursive: true });
|
|
310
|
-
mkdirSync(BROWSER_PROFILES_DIR, { recursive: true });
|
|
311
|
-
mkdirSync(BINARIES_DIR, { recursive: true });
|
|
312
|
-
mkdirSync(SECRETS_DIR, { recursive: true, mode: 448 });
|
|
313
|
-
var ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000;
|
|
314
|
-
var AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, "src/prompts/agents");
|
|
315
|
-
var RESOURCES_DIR = resolve(PROJECT_ROOT, "src/resources");
|
|
316
|
-
var ABSOLUTE_PATH_PREFIX = String.raw`(?:[A-Za-z]:[\\/]|\\\\|\/)`;
|
|
317
|
-
var FILE_EXTENSIONS_REGEX = new RegExp(`(?:${ABSOLUTE_PATH_PREFIX}[^\\s"'<>|*?[\\]]+\\.(?:png|jpg|jpeg|gif|webp|svg|pdf|csv|xlsx|xls|json|txt|md|html|zip|py|js|ts|tsx|jsx|css|xml|yaml|yml|docx|pptx))`, "gi");
|
|
318
|
-
var FILE_TAG_REGEX = new RegExp(`\\[FILE:(${ABSOLUTE_PATH_PREFIX}[^\\]]+)\\]`, "gi");
|
|
319
|
-
var MODEL_SONNET = "claude-sonnet-5";
|
|
320
|
-
var MODEL_OPUS = "claude-opus-5";
|
|
321
|
-
var MODEL_FABLE = "claude-fable-5-1";
|
|
322
|
-
var FALLBACK_AGENT = resolveFallbackAgent(process.env);
|
|
323
|
-
var FALLBACK_MODEL = envText("FALLBACK_MODEL") ?? envText("DEFAULT_MODEL");
|
|
324
|
-
var DEFAULT_TOPIC_EFFORT = (() => {
|
|
325
|
-
const raw = envText("NEGOTIUM_DEFAULT_EFFORT")?.toLowerCase();
|
|
326
|
-
return raw && EFFORT_VALUES.includes(raw) ? raw : "medium";
|
|
327
|
-
})();
|
|
328
|
-
var FFMPEG_BIN = envText("FFMPEG_BIN");
|
|
329
|
-
var FFPROBE_BIN = envText("FFPROBE_BIN");
|
|
330
|
-
var PYTHON_BIN = envText("PYTHON_BIN") ?? "python3";
|
|
331
|
-
var FASTER_WHISPER_WRAPPER = envText("FASTER_WHISPER_WRAPPER") ?? resolve(PROJECT_ROOT, "scripts/faster-whisper-wrapper.py");
|
|
332
|
-
var WHISPER_MODEL = envText("WHISPER_MODEL_FILE") ?? "turbo";
|
|
333
|
-
var TESSERACT_BIN = envText("TESSERACT_BIN") ?? "tesseract";
|
|
334
|
-
var PDFTOTEXT_BIN = envText("PDFTOTEXT_BIN") ?? "pdftotext";
|
|
335
|
-
function resolveWhisperBackend() {
|
|
336
|
-
return envText("WHISPER_BACKEND") === "mlx-whisper" ? "mlx-whisper" : "faster-whisper";
|
|
337
|
-
}
|
|
338
|
-
var WHISPER_BACKEND = resolveWhisperBackend();
|
|
339
|
-
var MLX_WHISPER_BIN = envText("MLX_WHISPER_BIN");
|
|
340
|
-
var WHISPER_MODEL_MLX = envText("WHISPER_MODEL_MLX") ?? "mlx-community/whisper-large-v3-turbo";
|
|
341
|
-
var _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? "", 10);
|
|
342
|
-
var MAX_TELL_DEPTH = Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;
|
|
343
|
-
function codexAuthFilePath() {
|
|
344
|
-
return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
|
|
345
|
-
}
|
|
55
|
+
import { resolve as resolve2 } from "path";
|
|
346
56
|
|
|
347
57
|
// ../../packages/core/src/platform/paths.ts
|
|
348
|
-
import { dirname
|
|
58
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "path";
|
|
349
59
|
function toDisplayPath(filePath) {
|
|
350
60
|
return filePath.split(sep).join("/");
|
|
351
61
|
}
|
|
@@ -356,23 +66,23 @@ var trustedWorkspaceRoots = [
|
|
|
356
66
|
DM_WORKSPACE_DIR,
|
|
357
67
|
SESSION_WORKSPACE_DIR,
|
|
358
68
|
TOPIC_WORKSPACE_DIR
|
|
359
|
-
].map((root) =>
|
|
360
|
-
var FIXTURES_DIR =
|
|
69
|
+
].map((root) => resolve2(root));
|
|
70
|
+
var FIXTURES_DIR = resolve2(PROJECT_ROOT, "src", "agents", "fixtures");
|
|
361
71
|
|
|
362
72
|
// ../../packages/core/src/platform/jsonl.ts
|
|
363
73
|
import {
|
|
364
74
|
appendFileSync,
|
|
365
75
|
closeSync,
|
|
366
76
|
fsyncSync,
|
|
367
|
-
mkdirSync
|
|
77
|
+
mkdirSync,
|
|
368
78
|
openSync,
|
|
369
|
-
readFileSync
|
|
79
|
+
readFileSync,
|
|
370
80
|
renameSync,
|
|
371
81
|
statSync,
|
|
372
82
|
unlinkSync as unlinkSync2,
|
|
373
|
-
writeFileSync
|
|
83
|
+
writeFileSync
|
|
374
84
|
} from "fs";
|
|
375
|
-
import { dirname as
|
|
85
|
+
import { dirname as dirname2 } from "path";
|
|
376
86
|
|
|
377
87
|
// ../../packages/core/src/platform/file-utils.ts
|
|
378
88
|
import { unlinkSync } from "fs";
|
|
@@ -400,8 +110,8 @@ function parseJsonlText(raw) {
|
|
|
400
110
|
}
|
|
401
111
|
var LOCK_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
402
112
|
function writeJsonlFile(filePath, entries) {
|
|
403
|
-
const dir =
|
|
404
|
-
|
|
113
|
+
const dir = dirname2(filePath);
|
|
114
|
+
mkdirSync(dir, { recursive: true });
|
|
405
115
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
406
116
|
const payload = `${entries.map((e) => JSON.stringify(e)).join(`
|
|
407
117
|
`)}
|
|
@@ -409,7 +119,7 @@ function writeJsonlFile(filePath, entries) {
|
|
|
409
119
|
let fd = null;
|
|
410
120
|
try {
|
|
411
121
|
fd = openSync(tmpPath, "w");
|
|
412
|
-
|
|
122
|
+
writeFileSync(fd, payload);
|
|
413
123
|
fsyncSync(fd);
|
|
414
124
|
closeSync(fd);
|
|
415
125
|
fd = null;
|
|
@@ -486,11 +196,11 @@ function deepMapStrings(value, fn) {
|
|
|
486
196
|
|
|
487
197
|
// ../../packages/core/src/agents/execution-host.ts
|
|
488
198
|
import { AsyncLocalStorage } from "async_hooks";
|
|
489
|
-
import { dirname as
|
|
199
|
+
import { dirname as dirname4 } from "path";
|
|
490
200
|
|
|
491
201
|
// ../../packages/core/src/security/sensitive-path.ts
|
|
492
202
|
import { realpathSync } from "fs";
|
|
493
|
-
import { resolve as
|
|
203
|
+
import { resolve as resolve3 } from "path";
|
|
494
204
|
var SENSITIVE_PATH_PATTERNS = [
|
|
495
205
|
/\/\.env(\.|$)/i,
|
|
496
206
|
/\/\.ssh\//i,
|
|
@@ -507,7 +217,7 @@ var SENSITIVE_PATH_PATTERNS = [
|
|
|
507
217
|
/\/sessions\.db(-wal|-shm|-journal)?$/i
|
|
508
218
|
];
|
|
509
219
|
function isSensitivePath(filePath) {
|
|
510
|
-
const normalized =
|
|
220
|
+
const normalized = resolve3(filePath);
|
|
511
221
|
if (SENSITIVE_PATH_PATTERNS.some((p) => p.test(toDisplayPath(normalized))))
|
|
512
222
|
return true;
|
|
513
223
|
try {
|
|
@@ -669,8 +379,8 @@ function peerSessionBridgeIpcEnv() {
|
|
|
669
379
|
}
|
|
670
380
|
|
|
671
381
|
// ../../packages/core/src/platform/background-bash/manager.ts
|
|
672
|
-
import { execFileSync
|
|
673
|
-
import { randomBytes
|
|
382
|
+
import { execFileSync, spawn } from "child_process";
|
|
383
|
+
import { randomBytes } from "crypto";
|
|
674
384
|
|
|
675
385
|
// ../../packages/core/src/platform/delay.ts
|
|
676
386
|
var delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -687,7 +397,7 @@ function makeBgBashKey(_userId, _topic) {
|
|
|
687
397
|
}
|
|
688
398
|
function defaultPortPids(port) {
|
|
689
399
|
try {
|
|
690
|
-
return
|
|
400
|
+
return execFileSync("lsof", ["-i", `:${port}`, "-t"], { stdio: "pipe" }).toString().trim().split(`
|
|
691
401
|
`).map((pid) => Number.parseInt(pid, 10)).filter((pid) => !Number.isNaN(pid));
|
|
692
402
|
} catch {
|
|
693
403
|
return [];
|
|
@@ -698,8 +408,8 @@ function createBackgroundBashManager(options = {}) {
|
|
|
698
408
|
const usedPorts = new Set;
|
|
699
409
|
const spawning = new Map;
|
|
700
410
|
const knownContexts = new Map;
|
|
701
|
-
const runtimeCapability = options.capability ??
|
|
702
|
-
const runtimeServerId = options.serverId ??
|
|
411
|
+
const runtimeCapability = options.capability ?? randomBytes(32).toString("hex");
|
|
412
|
+
const runtimeServerId = options.serverId ?? randomBytes(16).toString("hex");
|
|
703
413
|
const bashRsBin = options.bashRsBin ?? BASH_RS_BIN;
|
|
704
414
|
const basePort = options.basePort ?? BG_BASH_BASE_PORT;
|
|
705
415
|
const maxPort = options.maxPort ?? BG_BASH_MAX_PORT;
|
|
@@ -859,12 +569,12 @@ function createBackgroundBashManager(options = {}) {
|
|
|
859
569
|
usedPorts.clear();
|
|
860
570
|
knownContexts.clear();
|
|
861
571
|
const deadline = now() + 3000;
|
|
862
|
-
await Promise.all(entries.map((instance) => new Promise((
|
|
572
|
+
await Promise.all(entries.map((instance) => new Promise((resolve4) => {
|
|
863
573
|
if (instance.process.exitCode !== null || instance.process.killed)
|
|
864
|
-
return
|
|
865
|
-
instance.process.once("exit",
|
|
866
|
-
instance.process.once("error",
|
|
867
|
-
const timer = setTimeout(
|
|
574
|
+
return resolve4();
|
|
575
|
+
instance.process.once("exit", resolve4);
|
|
576
|
+
instance.process.once("error", resolve4);
|
|
577
|
+
const timer = setTimeout(resolve4, Math.max(0, deadline - now()));
|
|
868
578
|
timer.unref?.();
|
|
869
579
|
})));
|
|
870
580
|
}
|
|
@@ -959,9 +669,9 @@ var RESERVED_TOPIC_NAMES = new Set([
|
|
|
959
669
|
var GENERAL_TOPIC_ID = "general";
|
|
960
670
|
|
|
961
671
|
// ../../packages/core/src/storage/storage-host.ts
|
|
962
|
-
import { mkdirSync as
|
|
963
|
-
import { homedir
|
|
964
|
-
import { dirname as
|
|
672
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
673
|
+
import { homedir } from "os";
|
|
674
|
+
import { dirname as dirname3, join, resolve as resolve4 } from "path";
|
|
965
675
|
|
|
966
676
|
// ../../packages/core/src/storage/sqlite.ts
|
|
967
677
|
var isBun = typeof process.versions.bun === "string";
|
|
@@ -1049,16 +759,16 @@ function storageState() {
|
|
|
1049
759
|
}
|
|
1050
760
|
function envPath(name, fallback) {
|
|
1051
761
|
const value = process.env[name]?.trim();
|
|
1052
|
-
return
|
|
762
|
+
return resolve4(value || fallback);
|
|
1053
763
|
}
|
|
1054
764
|
function defaultStateDir() {
|
|
1055
|
-
return envPath("NEGOTIUM_STATE_DIR",
|
|
765
|
+
return envPath("NEGOTIUM_STATE_DIR", join(homedir(), ".negotium"));
|
|
1056
766
|
}
|
|
1057
767
|
function defaultDataDir() {
|
|
1058
|
-
return envPath("NEGOTIUM_DATA_DIR",
|
|
768
|
+
return envPath("NEGOTIUM_DATA_DIR", join(defaultStateDir(), "data"));
|
|
1059
769
|
}
|
|
1060
770
|
function defaultSessionsDatabasePath() {
|
|
1061
|
-
return envPath("SESSIONS_DB_PATH",
|
|
771
|
+
return envPath("SESSIONS_DB_PATH", join(resolveStorageDataDir(), "sessions.db"));
|
|
1062
772
|
}
|
|
1063
773
|
var SQLITE_INIT_RETRY_MS = 25;
|
|
1064
774
|
var SQLITE_INIT_TIMEOUT_MS = 5000;
|
|
@@ -1096,7 +806,7 @@ function defaultDatabase() {
|
|
|
1096
806
|
return state.fallbackDatabase;
|
|
1097
807
|
if (state.fallbackDatabase)
|
|
1098
808
|
closeDatabase(state.fallbackDatabase);
|
|
1099
|
-
|
|
809
|
+
mkdirSync2(dirname3(path), { recursive: true });
|
|
1100
810
|
state.fallbackDatabase = new Database(path, { create: true });
|
|
1101
811
|
state.fallbackDatabasePath = path;
|
|
1102
812
|
initializeDatabase(state.fallbackDatabase);
|
|
@@ -2153,11 +1863,11 @@ function hideProviderIntrospectionForOtium(servers, topicId) {
|
|
|
2153
1863
|
}
|
|
2154
1864
|
|
|
2155
1865
|
// ../../packages/core/src/storage/vault.ts
|
|
2156
|
-
import { chmodSync
|
|
2157
|
-
import { join as
|
|
1866
|
+
import { chmodSync, mkdirSync as mkdirSync3 } from "fs";
|
|
1867
|
+
import { join as join2 } from "path";
|
|
2158
1868
|
|
|
2159
1869
|
// ../../packages/core/src/storage/vault-crypto-core.ts
|
|
2160
|
-
import { createCipheriv, createDecipheriv, createHash as createHash2, randomBytes as
|
|
1870
|
+
import { createCipheriv, createDecipheriv, createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
2161
1871
|
var ENVELOPE_PREFIX = "otium-vault:v1:";
|
|
2162
1872
|
var IV_BYTES = 12;
|
|
2163
1873
|
var KEY_BYTES = 32;
|
|
@@ -2171,7 +1881,7 @@ function isEncryptedVaultValue(value) {
|
|
|
2171
1881
|
return value.startsWith(ENVELOPE_PREFIX);
|
|
2172
1882
|
}
|
|
2173
1883
|
function encryptVaultValueWithKey(userId, key, value, masterKey) {
|
|
2174
|
-
const iv =
|
|
1884
|
+
const iv = randomBytes2(IV_BYTES);
|
|
2175
1885
|
const cipher = createCipheriv("aes-256-gcm", encryptionKey(masterKey), iv);
|
|
2176
1886
|
cipher.setAAD(aad(userId, key));
|
|
2177
1887
|
const ciphertext = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
|
|
@@ -2245,11 +1955,11 @@ function initializeVaultDatabase(database) {
|
|
|
2245
1955
|
}
|
|
2246
1956
|
}
|
|
2247
1957
|
function openVaultDatabase(dataDir) {
|
|
2248
|
-
const vaultDir =
|
|
2249
|
-
const path =
|
|
2250
|
-
|
|
1958
|
+
const vaultDir = join2(dataDir, "vault");
|
|
1959
|
+
const path = join2(vaultDir, "vault.db");
|
|
1960
|
+
mkdirSync3(vaultDir, { recursive: true, mode: 448 });
|
|
2251
1961
|
const database = new Database(path, { create: true });
|
|
2252
|
-
|
|
1962
|
+
chmodSync(path, 384);
|
|
2253
1963
|
initializeVaultDatabase(database);
|
|
2254
1964
|
return database;
|
|
2255
1965
|
}
|
|
@@ -2411,7 +2121,7 @@ function hostedCodexAuthFilePath() {
|
|
|
2411
2121
|
return activeHost().codexAuthFilePath();
|
|
2412
2122
|
}
|
|
2413
2123
|
function hostedCodexHomePath() {
|
|
2414
|
-
return
|
|
2124
|
+
return dirname4(hostedCodexAuthFilePath());
|
|
2415
2125
|
}
|
|
2416
2126
|
|
|
2417
2127
|
// ../../packages/core/src/media/file-events.ts
|
|
@@ -2531,7 +2241,7 @@ function buildClaudePrompt(opts) {
|
|
|
2531
2241
|
source: {
|
|
2532
2242
|
type: "base64",
|
|
2533
2243
|
media_type: attachment.mimeType,
|
|
2534
|
-
data:
|
|
2244
|
+
data: readFileSync2(attachment.path).toString("base64")
|
|
2535
2245
|
}
|
|
2536
2246
|
});
|
|
2537
2247
|
} catch (err) {
|
|
@@ -2558,8 +2268,8 @@ var CLAUDE_ABORT_SIGKILL_DELAY_MS = 2500;
|
|
|
2558
2268
|
var claudeProcessExitListeners = new WeakMap;
|
|
2559
2269
|
function watchClaudeProcessExit(signal) {
|
|
2560
2270
|
let listener;
|
|
2561
|
-
const exited = new Promise((
|
|
2562
|
-
listener =
|
|
2271
|
+
const exited = new Promise((resolve5) => {
|
|
2272
|
+
listener = resolve5;
|
|
2563
2273
|
const listeners = claudeProcessExitListeners.get(signal) ?? new Set;
|
|
2564
2274
|
listeners.add(listener);
|
|
2565
2275
|
claudeProcessExitListeners.set(signal, listeners);
|
|
@@ -2693,7 +2403,7 @@ function isAbortError(err) {
|
|
|
2693
2403
|
}
|
|
2694
2404
|
async function* claudeProvider(opts) {
|
|
2695
2405
|
const claudeExecutable = hostedClaudeCodeExecutablePath();
|
|
2696
|
-
if (claudeExecutable && !
|
|
2406
|
+
if (claudeExecutable && !existsSync(claudeExecutable)) {
|
|
2697
2407
|
yield {
|
|
2698
2408
|
type: "error",
|
|
2699
2409
|
content: `Claude CLI not found at ${claudeExecutable}. Install Claude Code or configure the executable path.`
|
|
@@ -2991,40 +2701,40 @@ async function* claudeProvider(opts) {
|
|
|
2991
2701
|
}
|
|
2992
2702
|
|
|
2993
2703
|
// ../../packages/core/src/agents/codex-provider.ts
|
|
2994
|
-
import { execFileSync as
|
|
2995
|
-
import { existsSync as existsSync6, readFileSync as
|
|
2996
|
-
import { homedir as
|
|
2997
|
-
import { dirname as
|
|
2704
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
2705
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
2706
|
+
import { homedir as homedir2 } from "os";
|
|
2707
|
+
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join7, relative as relative2, resolve as resolve7 } from "path";
|
|
2998
2708
|
import { Codex } from "@openai/codex-sdk";
|
|
2999
2709
|
|
|
3000
2710
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3001
2711
|
import { spawn as spawn3 } from "child_process";
|
|
3002
2712
|
import { randomUUID } from "crypto";
|
|
3003
2713
|
import {
|
|
3004
|
-
chmodSync as
|
|
2714
|
+
chmodSync as chmodSync2,
|
|
3005
2715
|
copyFileSync,
|
|
3006
|
-
existsSync as
|
|
2716
|
+
existsSync as existsSync2,
|
|
3007
2717
|
mkdtempSync,
|
|
3008
|
-
readFileSync as
|
|
2718
|
+
readFileSync as readFileSync3,
|
|
3009
2719
|
renameSync as renameSync2,
|
|
3010
2720
|
rmSync,
|
|
3011
2721
|
unlinkSync as unlinkSync3,
|
|
3012
|
-
writeFileSync as
|
|
2722
|
+
writeFileSync as writeFileSync2
|
|
3013
2723
|
} from "fs";
|
|
3014
|
-
import { createRequire
|
|
2724
|
+
import { createRequire } from "module";
|
|
3015
2725
|
import { tmpdir } from "os";
|
|
3016
|
-
import { dirname as
|
|
2726
|
+
import { dirname as dirname5, join as join3 } from "path";
|
|
3017
2727
|
|
|
3018
2728
|
// ../../packages/core/src/version.ts
|
|
3019
|
-
var NEGOTIUM_VERSION = "0.
|
|
2729
|
+
var NEGOTIUM_VERSION = "0.19.0";
|
|
3020
2730
|
|
|
3021
2731
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3022
|
-
var moduleRequire =
|
|
2732
|
+
var moduleRequire = createRequire(import.meta.url);
|
|
3023
2733
|
var codexSdkPackagePath = moduleRequire.resolve("@openai/codex-sdk/package.json");
|
|
3024
|
-
var codexSdkRequire =
|
|
2734
|
+
var codexSdkRequire = createRequire(codexSdkPackagePath);
|
|
3025
2735
|
var bundledCodexPackagePath = codexSdkRequire.resolve("@openai/codex/package.json");
|
|
3026
2736
|
function readPackageVersion(packageJsonPath) {
|
|
3027
|
-
const parsed = JSON.parse(
|
|
2737
|
+
const parsed = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
|
|
3028
2738
|
if (typeof parsed.version !== "string" || !parsed.version.trim()) {
|
|
3029
2739
|
throw new Error(`Codex package has no valid version: ${packageJsonPath}`);
|
|
3030
2740
|
}
|
|
@@ -3035,7 +2745,7 @@ var SAFE_BUNDLED_CODEX_VERSION = BUNDLED_CODEX_VERSION.replace(/[^a-zA-Z0-9._-]/
|
|
|
3035
2745
|
var NEGOTIUM_MODEL_CACHE = `negotium-models-cache-${SAFE_BUNDLED_CODEX_VERSION}.json`;
|
|
3036
2746
|
var NEGOTIUM_MODEL_CATALOG = `negotium-model-catalog-${SAFE_BUNDLED_CODEX_VERSION}.json`;
|
|
3037
2747
|
function codexCliScriptPath() {
|
|
3038
|
-
return
|
|
2748
|
+
return join3(dirname5(bundledCodexPackagePath), "bin", "codex.js");
|
|
3039
2749
|
}
|
|
3040
2750
|
function parseCodexModelCache(contents, sourcePath) {
|
|
3041
2751
|
let parsed;
|
|
@@ -3050,7 +2760,7 @@ function parseCodexModelCache(contents, sourcePath) {
|
|
|
3050
2760
|
return parsed;
|
|
3051
2761
|
}
|
|
3052
2762
|
function readCodexModelCache(cachePath) {
|
|
3053
|
-
const contents =
|
|
2763
|
+
const contents = readFileSync3(cachePath, "utf8");
|
|
3054
2764
|
return { contents, parsed: parseCodexModelCache(contents, cachePath) };
|
|
3055
2765
|
}
|
|
3056
2766
|
function readCompatibleCodexModelCache(cachePath) {
|
|
@@ -3062,13 +2772,13 @@ function readCompatibleCodexModelCache(cachePath) {
|
|
|
3062
2772
|
return cache;
|
|
3063
2773
|
}
|
|
3064
2774
|
function writePrivateFileAtomic(path, contents) {
|
|
3065
|
-
if (
|
|
2775
|
+
if (existsSync2(path) && readFileSync3(path, "utf8") === contents)
|
|
3066
2776
|
return;
|
|
3067
2777
|
const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
3068
2778
|
try {
|
|
3069
|
-
|
|
2779
|
+
writeFileSync2(tempPath, contents, { encoding: "utf8", mode: 384 });
|
|
3070
2780
|
renameSync2(tempPath, path);
|
|
3071
|
-
|
|
2781
|
+
chmodSync2(path, 384);
|
|
3072
2782
|
} finally {
|
|
3073
2783
|
try {
|
|
3074
2784
|
unlinkSync3(tempPath);
|
|
@@ -3076,7 +2786,7 @@ function writePrivateFileAtomic(path, contents) {
|
|
|
3076
2786
|
}
|
|
3077
2787
|
}
|
|
3078
2788
|
function bundledCodexModelCachePath(authFilePath) {
|
|
3079
|
-
return
|
|
2789
|
+
return join3(dirname5(authFilePath), NEGOTIUM_MODEL_CACHE);
|
|
3080
2790
|
}
|
|
3081
2791
|
async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
3082
2792
|
const child = spawn3(process.execPath, [codexCliScriptPath(), "app-server", "--stdio"], {
|
|
@@ -3084,7 +2794,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
3084
2794
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3085
2795
|
windowsHide: true
|
|
3086
2796
|
});
|
|
3087
|
-
|
|
2797
|
+
const refreshed = new Promise((resolve5, reject) => {
|
|
3088
2798
|
let settled = false;
|
|
3089
2799
|
let stdoutBuffer = "";
|
|
3090
2800
|
let stderr = "";
|
|
@@ -3100,10 +2810,10 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
3100
2810
|
} catch {}
|
|
3101
2811
|
if (error)
|
|
3102
2812
|
reject(error);
|
|
3103
|
-
else if (!
|
|
2813
|
+
else if (!existsSync2(cachePath))
|
|
3104
2814
|
reject(new Error("Codex did not create its model cache"));
|
|
3105
2815
|
else
|
|
3106
|
-
|
|
2816
|
+
resolve5();
|
|
3107
2817
|
};
|
|
3108
2818
|
const send = (message) => {
|
|
3109
2819
|
child.stdin.write(`${JSON.stringify(message)}
|
|
@@ -3160,47 +2870,74 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
3160
2870
|
}
|
|
3161
2871
|
});
|
|
3162
2872
|
});
|
|
2873
|
+
try {
|
|
2874
|
+
await refreshed;
|
|
2875
|
+
} finally {
|
|
2876
|
+
await waitForChildExit(child, CODEX_BOOTSTRAP_EXIT_WAIT_MS);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
var CODEX_BOOTSTRAP_EXIT_WAIT_MS = 3000;
|
|
2880
|
+
function waitForChildExit(child, timeoutMs) {
|
|
2881
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
2882
|
+
return Promise.resolve();
|
|
2883
|
+
return new Promise((resolve5) => {
|
|
2884
|
+
const timer = setTimeout(resolve5, timeoutMs);
|
|
2885
|
+
timer.unref?.();
|
|
2886
|
+
child.once("exit", () => {
|
|
2887
|
+
clearTimeout(timer);
|
|
2888
|
+
resolve5();
|
|
2889
|
+
});
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2892
|
+
function removeIsolatedCodexHome(dir) {
|
|
2893
|
+
if (process.platform !== "win32") {
|
|
2894
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2895
|
+
return;
|
|
2896
|
+
}
|
|
2897
|
+
try {
|
|
2898
|
+
rmSync(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
|
|
2899
|
+
} catch {}
|
|
3163
2900
|
}
|
|
3164
2901
|
async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
|
|
3165
|
-
const sourceHome =
|
|
3166
|
-
const isolatedHome = mkdtempSync(
|
|
3167
|
-
const isolatedCachePath =
|
|
2902
|
+
const sourceHome = dirname5(authFilePath);
|
|
2903
|
+
const isolatedHome = mkdtempSync(join3(tmpdir(), "negotium-codex-models-"));
|
|
2904
|
+
const isolatedCachePath = join3(isolatedHome, "models_cache.json");
|
|
3168
2905
|
try {
|
|
3169
|
-
const isolatedAuthPath =
|
|
2906
|
+
const isolatedAuthPath = join3(isolatedHome, "auth.json");
|
|
3170
2907
|
copyFileSync(authFilePath, isolatedAuthPath);
|
|
3171
|
-
|
|
3172
|
-
const sourceConfigPath =
|
|
3173
|
-
if (
|
|
3174
|
-
const isolatedConfigPath =
|
|
2908
|
+
chmodSync2(isolatedAuthPath, 384);
|
|
2909
|
+
const sourceConfigPath = join3(sourceHome, "config.toml");
|
|
2910
|
+
if (existsSync2(sourceConfigPath)) {
|
|
2911
|
+
const isolatedConfigPath = join3(isolatedHome, "config.toml");
|
|
3175
2912
|
copyFileSync(sourceConfigPath, isolatedConfigPath);
|
|
3176
|
-
|
|
2913
|
+
chmodSync2(isolatedConfigPath, 384);
|
|
3177
2914
|
}
|
|
3178
2915
|
await bootstrap(isolatedHome, isolatedCachePath);
|
|
3179
2916
|
return readCompatibleCodexModelCache(isolatedCachePath).contents;
|
|
3180
2917
|
} finally {
|
|
3181
|
-
|
|
2918
|
+
removeIsolatedCodexHome(isolatedHome);
|
|
3182
2919
|
}
|
|
3183
2920
|
}
|
|
3184
2921
|
async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexModelCache) {
|
|
3185
|
-
const codexHome =
|
|
2922
|
+
const codexHome = dirname5(authFilePath);
|
|
3186
2923
|
const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;
|
|
3187
2924
|
if (configuredCachePath) {
|
|
3188
|
-
if (!
|
|
2925
|
+
if (!existsSync2(configuredCachePath)) {
|
|
3189
2926
|
throw new Error(`Configured Codex model cache does not exist: ${configuredCachePath}`);
|
|
3190
2927
|
}
|
|
3191
2928
|
readCompatibleCodexModelCache(configuredCachePath);
|
|
3192
2929
|
return configuredCachePath;
|
|
3193
2930
|
}
|
|
3194
2931
|
const bundledCachePath = bundledCodexModelCachePath(authFilePath);
|
|
3195
|
-
const sharedCachePath =
|
|
3196
|
-
if (
|
|
2932
|
+
const sharedCachePath = join3(codexHome, "models_cache.json");
|
|
2933
|
+
if (existsSync2(sharedCachePath)) {
|
|
3197
2934
|
try {
|
|
3198
2935
|
const shared = readCompatibleCodexModelCache(sharedCachePath);
|
|
3199
2936
|
writePrivateFileAtomic(bundledCachePath, shared.contents);
|
|
3200
2937
|
return bundledCachePath;
|
|
3201
2938
|
} catch {}
|
|
3202
2939
|
}
|
|
3203
|
-
if (
|
|
2940
|
+
if (existsSync2(bundledCachePath)) {
|
|
3204
2941
|
try {
|
|
3205
2942
|
readCompatibleCodexModelCache(bundledCachePath);
|
|
3206
2943
|
return bundledCachePath;
|
|
@@ -3211,8 +2948,8 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
|
|
|
3211
2948
|
return bundledCachePath;
|
|
3212
2949
|
}
|
|
3213
2950
|
function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath) {
|
|
3214
|
-
const codexHome =
|
|
3215
|
-
const outputPath =
|
|
2951
|
+
const codexHome = dirname5(authFilePath);
|
|
2952
|
+
const outputPath = join3(codexHome, NEGOTIUM_MODEL_CATALOG);
|
|
3216
2953
|
const parsed = readCodexModelCache(sourcePath).parsed;
|
|
3217
2954
|
const models = parsed.models.map((model, index) => {
|
|
3218
2955
|
if (!model || typeof model !== "object" || Array.isArray(model)) {
|
|
@@ -3227,7 +2964,7 @@ function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath)
|
|
|
3227
2964
|
}
|
|
3228
2965
|
|
|
3229
2966
|
// ../../packages/core/src/agents/codex-tree-kill.ts
|
|
3230
|
-
import { execFileSync as
|
|
2967
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
3231
2968
|
|
|
3232
2969
|
// ../../packages/core/src/agents/codex-tree-manager.ts
|
|
3233
2970
|
function createCodexTreeManager(host, options = {}) {
|
|
@@ -3282,12 +3019,12 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
3282
3019
|
const previous = spawnChain;
|
|
3283
3020
|
let release;
|
|
3284
3021
|
let released = false;
|
|
3285
|
-
spawnChain = new Promise((
|
|
3022
|
+
spawnChain = new Promise((resolve5) => {
|
|
3286
3023
|
release = () => {
|
|
3287
3024
|
if (released)
|
|
3288
3025
|
return;
|
|
3289
3026
|
released = true;
|
|
3290
|
-
|
|
3027
|
+
resolve5();
|
|
3291
3028
|
};
|
|
3292
3029
|
});
|
|
3293
3030
|
await previous;
|
|
@@ -3394,7 +3131,7 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
3394
3131
|
return;
|
|
3395
3132
|
const deadline = Date.now() + Math.max(0, graceMs);
|
|
3396
3133
|
while (Date.now() < deadline && hasSurvivors(plan.targets)) {
|
|
3397
|
-
await new Promise((
|
|
3134
|
+
await new Promise((resolve5) => setTimeout(resolve5, Math.min(100, Math.max(1, deadline - Date.now()))));
|
|
3398
3135
|
}
|
|
3399
3136
|
killStragglers(plan);
|
|
3400
3137
|
}
|
|
@@ -3413,7 +3150,7 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
3413
3150
|
// ../../packages/core/src/agents/codex-tree-kill.ts
|
|
3414
3151
|
function execText(command, args) {
|
|
3415
3152
|
try {
|
|
3416
|
-
return
|
|
3153
|
+
return execFileSync2(command, args, {
|
|
3417
3154
|
encoding: "utf8",
|
|
3418
3155
|
stdio: ["ignore", "pipe", "ignore"],
|
|
3419
3156
|
windowsHide: true
|
|
@@ -3447,30 +3184,162 @@ var killCodexTrees = manager.killTrees;
|
|
|
3447
3184
|
var killOwnedCodexTreesForShutdown = manager.killOwnedTreesForShutdown;
|
|
3448
3185
|
|
|
3449
3186
|
// ../../packages/core/src/agents/codex-vault-hook-bridge.ts
|
|
3450
|
-
import { randomBytes as
|
|
3187
|
+
import { randomBytes as randomBytes3 } from "crypto";
|
|
3451
3188
|
import { existsSync as existsSync4 } from "fs";
|
|
3452
|
-
import { chmod, mkdtemp, rm, writeFile } from "fs/promises";
|
|
3189
|
+
import { chmod, copyFile, mkdtemp, rm as rm2, writeFile as writeFile2 } from "fs/promises";
|
|
3453
3190
|
import { createServer } from "net";
|
|
3454
3191
|
import { tmpdir as tmpdir2 } from "os";
|
|
3455
|
-
import { dirname as
|
|
3456
|
-
import { fileURLToPath
|
|
3192
|
+
import { dirname as dirname6, join as join5, resolve as resolve5 } from "path";
|
|
3193
|
+
import { fileURLToPath } from "url";
|
|
3194
|
+
|
|
3195
|
+
// ../../packages/core/src/agents/codex-windows-wrapper.ts
|
|
3196
|
+
import { execFile } from "child_process";
|
|
3197
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
|
|
3198
|
+
import { existsSync as existsSync3 } from "fs";
|
|
3199
|
+
import { mkdir, rename, rm, writeFile } from "fs/promises";
|
|
3200
|
+
import { join as join4 } from "path";
|
|
3201
|
+
import { promisify } from "util";
|
|
3202
|
+
var execFileAsync = promisify(execFile);
|
|
3203
|
+
var CODEX_WINDOWS_WRAPPER_SOURCE = String.raw`
|
|
3204
|
+
using System;
|
|
3205
|
+
using System.Diagnostics;
|
|
3206
|
+
using System.IO;
|
|
3207
|
+
using System.Runtime.InteropServices;
|
|
3208
|
+
using System.Text;
|
|
3209
|
+
|
|
3210
|
+
static class CodexHookWrapper {
|
|
3211
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
3212
|
+
struct IO_COUNTERS { public ulong a, b, c, d, e, f; }
|
|
3213
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
3214
|
+
struct BASIC {
|
|
3215
|
+
public long PerProcessUserTimeLimit, PerJobUserTimeLimit;
|
|
3216
|
+
public uint LimitFlags;
|
|
3217
|
+
public UIntPtr MinimumWorkingSetSize, MaximumWorkingSetSize;
|
|
3218
|
+
public uint ActiveProcessLimit;
|
|
3219
|
+
public UIntPtr Affinity;
|
|
3220
|
+
public uint PriorityClass, SchedulingClass;
|
|
3221
|
+
}
|
|
3222
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
3223
|
+
struct EXTENDED {
|
|
3224
|
+
public BASIC Basic;
|
|
3225
|
+
public IO_COUNTERS Io;
|
|
3226
|
+
public UIntPtr ProcessMemoryLimit, JobMemoryLimit, PeakProcessMemoryUsed, PeakJobMemoryUsed;
|
|
3227
|
+
}
|
|
3228
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
3229
|
+
static extern IntPtr CreateJobObject(IntPtr attrs, string name);
|
|
3230
|
+
[DllImport("kernel32.dll")]
|
|
3231
|
+
static extern bool SetInformationJobObject(IntPtr job, int cls, IntPtr info, uint len);
|
|
3232
|
+
[DllImport("kernel32.dll")]
|
|
3233
|
+
static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
|
|
3234
|
+
|
|
3235
|
+
static string Quote(string a) {
|
|
3236
|
+
if (a.Length > 0 && a.IndexOfAny(new[] { ' ', '\t', '\n', '\v', '"' }) < 0) return a;
|
|
3237
|
+
var sb = new StringBuilder("\"");
|
|
3238
|
+
int bs = 0;
|
|
3239
|
+
foreach (char c in a) {
|
|
3240
|
+
if (c == '\\') { bs++; }
|
|
3241
|
+
else if (c == '"') { sb.Append('\\', bs * 2 + 1); sb.Append('"'); bs = 0; }
|
|
3242
|
+
else { sb.Append('\\', bs); bs = 0; sb.Append(c); }
|
|
3243
|
+
}
|
|
3244
|
+
sb.Append('\\', bs * 2);
|
|
3245
|
+
sb.Append('"');
|
|
3246
|
+
return sb.ToString();
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
static IntPtr KillOnCloseJob() {
|
|
3250
|
+
IntPtr job = CreateJobObject(IntPtr.Zero, null);
|
|
3251
|
+
if (job == IntPtr.Zero) return IntPtr.Zero;
|
|
3252
|
+
var info = new EXTENDED();
|
|
3253
|
+
info.Basic.LimitFlags = 0x2000; // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
|
|
3254
|
+
int size = Marshal.SizeOf(typeof(EXTENDED));
|
|
3255
|
+
IntPtr mem = Marshal.AllocHGlobal(size);
|
|
3256
|
+
try {
|
|
3257
|
+
Marshal.StructureToPtr(info, mem, false);
|
|
3258
|
+
if (!SetInformationJobObject(job, 9, mem, (uint)size)) return IntPtr.Zero;
|
|
3259
|
+
} finally { Marshal.FreeHGlobal(mem); }
|
|
3260
|
+
return job;
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
static int Main(string[] args) {
|
|
3264
|
+
string self = Process.GetCurrentProcess().MainModule.FileName;
|
|
3265
|
+
string[] cfg = File.ReadAllLines(Path.ChangeExtension(self, ".cfg"), Encoding.UTF8);
|
|
3266
|
+
if (cfg.Length < 4) { Console.Error.WriteLine("codex hook wrapper: bad config"); return 70; }
|
|
3267
|
+
var sb = new StringBuilder(Quote(cfg[1]));
|
|
3268
|
+
int i = 0;
|
|
3269
|
+
if (args.Length > 0 && args[0] == "exec") {
|
|
3270
|
+
sb.Append(" exec --dangerously-bypass-hook-trust");
|
|
3271
|
+
i = 1;
|
|
3272
|
+
}
|
|
3273
|
+
for (; i < args.Length; i++) sb.Append(' ').Append(Quote(args[i]));
|
|
3274
|
+
|
|
3275
|
+
// No CreateNoWindow: with it the child stops inheriting our stdio handles.
|
|
3276
|
+
var psi = new ProcessStartInfo(cfg[0], sb.ToString());
|
|
3277
|
+
psi.UseShellExecute = false;
|
|
3278
|
+
psi.EnvironmentVariables["NEGOTIUM_CODEX_VAULT_HOOK_SOCKET"] = cfg[2];
|
|
3279
|
+
psi.EnvironmentVariables["NEGOTIUM_CODEX_VAULT_HOOK_TOKEN"] = cfg[3];
|
|
3280
|
+
IntPtr job = KillOnCloseJob();
|
|
3281
|
+
using (Process p = Process.Start(psi)) {
|
|
3282
|
+
if (job != IntPtr.Zero) AssignProcessToJobObject(job, p.Handle);
|
|
3283
|
+
p.WaitForExit();
|
|
3284
|
+
return p.ExitCode;
|
|
3285
|
+
}
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
`;
|
|
3289
|
+
function cscPath() {
|
|
3290
|
+
const windir = process.env.WINDIR ?? process.env.SystemRoot ?? "C:\\Windows";
|
|
3291
|
+
for (const framework of ["Framework64", "Framework"]) {
|
|
3292
|
+
const candidate = join4(windir, "Microsoft.NET", framework, "v4.0.30319", "csc.exe");
|
|
3293
|
+
if (existsSync3(candidate))
|
|
3294
|
+
return candidate;
|
|
3295
|
+
}
|
|
3296
|
+
throw new Error("csc.exe (.NET Framework 4) was not found, so the Codex hook wrapper cannot be built");
|
|
3297
|
+
}
|
|
3298
|
+
async function ensureCodexWindowsWrapperExe(cacheDir) {
|
|
3299
|
+
const digest = createHash3("sha256").update(CODEX_WINDOWS_WRAPPER_SOURCE).digest("hex").slice(0, 12);
|
|
3300
|
+
const exePath = join4(cacheDir, `codex-hook-wrapper-${digest}.exe`);
|
|
3301
|
+
if (existsSync3(exePath))
|
|
3302
|
+
return exePath;
|
|
3303
|
+
await mkdir(cacheDir, { recursive: true });
|
|
3304
|
+
const stamp = randomUUID2();
|
|
3305
|
+
const sourcePath = join4(cacheDir, `wrapper-${stamp}.cs`);
|
|
3306
|
+
const tempExe = join4(cacheDir, `wrapper-${stamp}.exe`);
|
|
3307
|
+
try {
|
|
3308
|
+
await writeFile(sourcePath, CODEX_WINDOWS_WRAPPER_SOURCE, "utf8");
|
|
3309
|
+
await execFileAsync(cscPath(), ["/nologo", "/target:exe", "/optimize+", `/out:${tempExe}`, sourcePath], { windowsHide: true, timeout: 60000 });
|
|
3310
|
+
try {
|
|
3311
|
+
await rename(tempExe, exePath);
|
|
3312
|
+
} catch (error) {
|
|
3313
|
+
if (!existsSync3(exePath))
|
|
3314
|
+
throw error;
|
|
3315
|
+
}
|
|
3316
|
+
return exePath;
|
|
3317
|
+
} catch (error) {
|
|
3318
|
+
const detail = error && typeof error === "object" && "stdout" in error ? String(error.stdout ?? "").trim() : "";
|
|
3319
|
+
throw new Error(`Failed to build the Codex hook wrapper: ${error instanceof Error ? error.message : String(error)}${detail ? `
|
|
3320
|
+
${detail}` : ""}`);
|
|
3321
|
+
} finally {
|
|
3322
|
+
await rm(sourcePath, { force: true });
|
|
3323
|
+
await rm(tempExe, { force: true });
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3457
3326
|
|
|
3458
3327
|
// ../../packages/core/src/platform/ipc.ts
|
|
3459
|
-
import { createHash as
|
|
3460
|
-
import { chmodSync as
|
|
3328
|
+
import { createHash as createHash4 } from "crypto";
|
|
3329
|
+
import { chmodSync as chmodSync3 } from "fs";
|
|
3461
3330
|
import { basename } from "path";
|
|
3462
3331
|
var IS_WINDOWS = process.platform === "win32";
|
|
3463
3332
|
function ipcEndpoint(posixSocketPath) {
|
|
3464
3333
|
if (!IS_WINDOWS)
|
|
3465
3334
|
return posixSocketPath;
|
|
3466
3335
|
const label = basename(posixSocketPath).replace(/\.sock$/, "").replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 48) || "endpoint";
|
|
3467
|
-
const digest =
|
|
3336
|
+
const digest = createHash4("sha256").update(posixSocketPath).digest("hex").slice(0, 16);
|
|
3468
3337
|
return `\\\\.\\pipe\\negotium-${label}-${digest}`;
|
|
3469
3338
|
}
|
|
3470
3339
|
function restrictIpcEndpoint(endpoint) {
|
|
3471
3340
|
if (IS_WINDOWS)
|
|
3472
3341
|
return;
|
|
3473
|
-
|
|
3342
|
+
chmodSync3(endpoint, 384);
|
|
3474
3343
|
}
|
|
3475
3344
|
|
|
3476
3345
|
// ../../packages/core/src/agents/codex-vault-hook-bridge.ts
|
|
@@ -3505,11 +3374,11 @@ function shellQuote(value) {
|
|
|
3505
3374
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
3506
3375
|
}
|
|
3507
3376
|
function hookClientPath() {
|
|
3508
|
-
const moduleDir =
|
|
3509
|
-
const adjacent =
|
|
3377
|
+
const moduleDir = dirname6(fileURLToPath(import.meta.url));
|
|
3378
|
+
const adjacent = resolve5(moduleDir, "codex-vault-hook.mjs");
|
|
3510
3379
|
if (existsSync4(adjacent))
|
|
3511
3380
|
return adjacent;
|
|
3512
|
-
const packaged =
|
|
3381
|
+
const packaged = resolve5(moduleDir, "runtime/src/agents/codex-vault-hook.mjs");
|
|
3513
3382
|
if (existsSync4(packaged))
|
|
3514
3383
|
return packaged;
|
|
3515
3384
|
throw new Error("Codex Vault hook client is missing from this installation");
|
|
@@ -3528,15 +3397,16 @@ function privateCodexWrapper(codexScript, socketPath, token) {
|
|
|
3528
3397
|
].join(`
|
|
3529
3398
|
`);
|
|
3530
3399
|
}
|
|
3531
|
-
var
|
|
3400
|
+
var IS_WINDOWS2 = process.platform === "win32";
|
|
3401
|
+
function windowsQuote(value) {
|
|
3402
|
+
return `"${value.replaceAll('"', "\\\"")}"`;
|
|
3403
|
+
}
|
|
3532
3404
|
async function createCodexVaultHookBridge(userId) {
|
|
3533
|
-
if (process.platform === "win32")
|
|
3534
|
-
throw new Error(WINDOWS_BRIDGE_UNSUPPORTED);
|
|
3535
3405
|
const root = await mkdtemp(join5(tmpdir2(), "negotium-codex-vault-"));
|
|
3536
3406
|
await chmod(root, 448);
|
|
3537
3407
|
const socketPath = ipcEndpoint(join5(root, "hook.sock"));
|
|
3538
|
-
const wrapperPath = join5(root, "codex-with-hooks");
|
|
3539
|
-
const token =
|
|
3408
|
+
const wrapperPath = join5(root, IS_WINDOWS2 ? "codex-with-hooks.exe" : "codex-with-hooks");
|
|
3409
|
+
const token = randomBytes3(32).toString("hex");
|
|
3540
3410
|
const connections = new Set;
|
|
3541
3411
|
const server = createServer((socket) => {
|
|
3542
3412
|
connections.add(socket);
|
|
@@ -3584,10 +3454,19 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
3584
3454
|
});
|
|
3585
3455
|
});
|
|
3586
3456
|
restrictIpcEndpoint(socketPath);
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3457
|
+
if (IS_WINDOWS2) {
|
|
3458
|
+
const { BINARIES_DIR } = await import("./chunk-22mtr8np.js");
|
|
3459
|
+
const cached = await ensureCodexWindowsWrapperExe(join5(BINARIES_DIR, "codex-hook-wrapper"));
|
|
3460
|
+
await copyFile(cached, wrapperPath);
|
|
3461
|
+
await writeFile2(join5(root, "codex-with-hooks.cfg"), [process.execPath, codexCliScriptPath(), socketPath, token].join(`
|
|
3462
|
+
`), { encoding: "utf8", mode: 384 });
|
|
3463
|
+
} else {
|
|
3464
|
+
await writeFile2(wrapperPath, privateCodexWrapper(codexCliScriptPath(), socketPath, token), {
|
|
3465
|
+
mode: 448
|
|
3466
|
+
});
|
|
3467
|
+
}
|
|
3468
|
+
const quote = IS_WINDOWS2 ? windowsQuote : shellQuote;
|
|
3469
|
+
const command = [quote(process.execPath), quote(hookClientPath())].join(" ");
|
|
3591
3470
|
return {
|
|
3592
3471
|
codexPathOverride: wrapperPath,
|
|
3593
3472
|
environment: { [HOOK_SOCKET_ENV]: socketPath, [HOOK_TOKEN_ENV]: token },
|
|
@@ -3610,29 +3489,29 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
3610
3489
|
for (const socket of connections)
|
|
3611
3490
|
socket.destroy();
|
|
3612
3491
|
await new Promise((resolveClose) => server.close(() => resolveClose()));
|
|
3613
|
-
await
|
|
3492
|
+
await rm2(root, { recursive: true, force: true });
|
|
3614
3493
|
}
|
|
3615
3494
|
};
|
|
3616
3495
|
} catch (error) {
|
|
3617
3496
|
server.close();
|
|
3618
|
-
await
|
|
3497
|
+
await rm2(root, { recursive: true, force: true });
|
|
3619
3498
|
throw error;
|
|
3620
3499
|
}
|
|
3621
3500
|
}
|
|
3622
3501
|
|
|
3623
3502
|
// ../../packages/core/src/agents/rollout/codex.ts
|
|
3624
|
-
import { existsSync as existsSync5, readFileSync as
|
|
3625
|
-
import { basename as basename2, dirname as
|
|
3503
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync4 } from "fs";
|
|
3504
|
+
import { basename as basename2, dirname as dirname7, join as join6, resolve as resolve6 } from "path";
|
|
3626
3505
|
function codexSessionsDir() {
|
|
3627
3506
|
return join6(hostedCodexHomePath(), "sessions");
|
|
3628
3507
|
}
|
|
3629
3508
|
function canonicalFilePath(path) {
|
|
3630
|
-
const absolute =
|
|
3509
|
+
const absolute = resolve6(path);
|
|
3631
3510
|
try {
|
|
3632
3511
|
return realpathSync2(absolute);
|
|
3633
3512
|
} catch {
|
|
3634
3513
|
try {
|
|
3635
|
-
return join6(realpathSync2(
|
|
3514
|
+
return join6(realpathSync2(dirname7(absolute)), basename2(absolute));
|
|
3636
3515
|
} catch {
|
|
3637
3516
|
return absolute;
|
|
3638
3517
|
}
|
|
@@ -3742,7 +3621,7 @@ function readCodexPatchCallIds(threadId) {
|
|
|
3742
3621
|
if (!path)
|
|
3743
3622
|
return [];
|
|
3744
3623
|
try {
|
|
3745
|
-
return extractCodexPatchCallIds(
|
|
3624
|
+
return extractCodexPatchCallIds(readFileSync4(path, "utf8"));
|
|
3746
3625
|
} catch (error) {
|
|
3747
3626
|
logger.debug({ error, threadId }, "codex patch ids: rollout read failed");
|
|
3748
3627
|
return [];
|
|
@@ -3753,7 +3632,7 @@ function readLatestCodexPatchPreview(threadId, expectedPaths, consumedCallIds =
|
|
|
3753
3632
|
if (!path)
|
|
3754
3633
|
return;
|
|
3755
3634
|
try {
|
|
3756
|
-
return extractLatestCodexPatchPreview(
|
|
3635
|
+
return extractLatestCodexPatchPreview(readFileSync4(path, "utf8"), expectedPaths, consumedCallIds, expectedCallId);
|
|
3757
3636
|
} catch (error) {
|
|
3758
3637
|
logger.debug({ error, threadId }, "codex patch preview: rollout read failed");
|
|
3759
3638
|
return;
|
|
@@ -3811,7 +3690,7 @@ function readLatestCodexContextUsage(threadId) {
|
|
|
3811
3690
|
if (!path)
|
|
3812
3691
|
return;
|
|
3813
3692
|
try {
|
|
3814
|
-
return extractLatestCodexContextUsage(
|
|
3693
|
+
return extractLatestCodexContextUsage(readFileSync4(path, "utf8"));
|
|
3815
3694
|
} catch (error) {
|
|
3816
3695
|
logger.debug({ error, threadId }, "codex context usage: rollout read failed");
|
|
3817
3696
|
return;
|
|
@@ -3822,7 +3701,7 @@ function readLatestCodexTokenTotals(threadId) {
|
|
|
3822
3701
|
if (!path)
|
|
3823
3702
|
return;
|
|
3824
3703
|
try {
|
|
3825
|
-
return extractLatestCodexTokenTotals(
|
|
3704
|
+
return extractLatestCodexTokenTotals(readFileSync4(path, "utf8"));
|
|
3826
3705
|
} catch (error) {
|
|
3827
3706
|
logger.debug({ error, threadId }, "codex token totals: rollout read failed");
|
|
3828
3707
|
return;
|
|
@@ -3833,7 +3712,7 @@ function migrateCodexRolloutNativeMultiAgentMetadata(threadId) {
|
|
|
3833
3712
|
if (!path)
|
|
3834
3713
|
return false;
|
|
3835
3714
|
try {
|
|
3836
|
-
const entries = parseJsonlText(
|
|
3715
|
+
const entries = parseJsonlText(readFileSync4(path, "utf8"));
|
|
3837
3716
|
let changed = false;
|
|
3838
3717
|
for (const entry of entries) {
|
|
3839
3718
|
if (entry.type !== "session_meta" && entry.type !== "turn_context")
|
|
@@ -4028,12 +3907,12 @@ function codexMcpServerName(name) {
|
|
|
4028
3907
|
return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;
|
|
4029
3908
|
}
|
|
4030
3909
|
function globalCodexMcpServerNames(authFilePath) {
|
|
4031
|
-
const configPath = join7(
|
|
3910
|
+
const configPath = join7(dirname8(authFilePath), "config.toml");
|
|
4032
3911
|
if (!existsSync6(configPath))
|
|
4033
3912
|
return [];
|
|
4034
3913
|
try {
|
|
4035
3914
|
const names = new Set;
|
|
4036
|
-
for (const line of
|
|
3915
|
+
for (const line of readFileSync5(configPath, "utf8").split(`
|
|
4037
3916
|
`)) {
|
|
4038
3917
|
const match = line.match(/^\s*\[\s*mcp_servers\.((?:"(?:\\.|[^"])*")|(?:'[^']*')|[^.\]\s]+)(?:[.\]])/);
|
|
4039
3918
|
const raw = match?.[1];
|
|
@@ -4131,9 +4010,9 @@ var CODEX_DIFF_BASELINE_FILE_LIMIT = 200;
|
|
|
4131
4010
|
var CODEX_DIFF_BASELINE_BYTE_LIMIT = 16 * 1024 * 1024;
|
|
4132
4011
|
function canonicalPath(path) {
|
|
4133
4012
|
try {
|
|
4134
|
-
return realpathSync3(
|
|
4013
|
+
return realpathSync3(resolve7(path));
|
|
4135
4014
|
} catch {
|
|
4136
|
-
return
|
|
4015
|
+
return resolve7(path);
|
|
4137
4016
|
}
|
|
4138
4017
|
}
|
|
4139
4018
|
function textFile(path, maxBytes = CODEX_DIFF_FILE_LIMIT) {
|
|
@@ -4143,7 +4022,7 @@ function textFile(path, maxBytes = CODEX_DIFF_FILE_LIMIT) {
|
|
|
4143
4022
|
const byteLimit = Math.min(CODEX_DIFF_FILE_LIMIT, Math.max(0, maxBytes));
|
|
4144
4023
|
if (statSync3(path).size > byteLimit)
|
|
4145
4024
|
return;
|
|
4146
|
-
const content =
|
|
4025
|
+
const content = readFileSync5(path);
|
|
4147
4026
|
if (content.byteLength > byteLimit || content.includes(0))
|
|
4148
4027
|
return;
|
|
4149
4028
|
return content.toString("utf8");
|
|
@@ -4177,7 +4056,7 @@ class CodexFilePreviewTracker {
|
|
|
4177
4056
|
const code = record.slice(0, 2);
|
|
4178
4057
|
const path = record.slice(3);
|
|
4179
4058
|
const remainingBytes = CODEX_DIFF_BASELINE_BYTE_LIMIT - loadedBytes;
|
|
4180
|
-
const content = loadedFiles < CODEX_DIFF_BASELINE_FILE_LIMIT && remainingBytes > 0 ? textFile(
|
|
4059
|
+
const content = loadedFiles < CODEX_DIFF_BASELINE_FILE_LIMIT && remainingBytes > 0 ? textFile(resolve7(this.#root, path), remainingBytes) : undefined;
|
|
4181
4060
|
this.#baseline.set(path, content);
|
|
4182
4061
|
if (typeof content === "string") {
|
|
4183
4062
|
loadedFiles += 1;
|
|
@@ -4190,7 +4069,7 @@ class CodexFilePreviewTracker {
|
|
|
4190
4069
|
preview(path, succeeded) {
|
|
4191
4070
|
if (!this.#root || !this.#baselineAvailable || !succeeded)
|
|
4192
4071
|
return {};
|
|
4193
|
-
const absolute = canonicalPath(isAbsolute2(path) ? path :
|
|
4072
|
+
const absolute = canonicalPath(isAbsolute2(path) ? path : resolve7(this.#cwd, path));
|
|
4194
4073
|
const relativePath = relative2(this.#root, absolute);
|
|
4195
4074
|
if (!relativePath || relativePath.startsWith("..") || isAbsolute2(relativePath))
|
|
4196
4075
|
return {};
|
|
@@ -4214,7 +4093,7 @@ class CodexFilePreviewTracker {
|
|
|
4214
4093
|
}
|
|
4215
4094
|
#git(args, cwd = this.#root ?? undefined) {
|
|
4216
4095
|
try {
|
|
4217
|
-
return
|
|
4096
|
+
return execFileSync3("git", ["-C", cwd ?? ".", ...args], {
|
|
4218
4097
|
encoding: "utf8",
|
|
4219
4098
|
maxBuffer: CODEX_DIFF_FILE_LIMIT * 4,
|
|
4220
4099
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -4226,7 +4105,7 @@ class CodexFilePreviewTracker {
|
|
|
4226
4105
|
}
|
|
4227
4106
|
}
|
|
4228
4107
|
async function fileChangeEvents(item, previews, cwd, threadId, consumedPatchCallIds) {
|
|
4229
|
-
const expectedPaths = item.changes.map((change) => isAbsolute2(change.path) ? change.path :
|
|
4108
|
+
const expectedPaths = item.changes.map((change) => isAbsolute2(change.path) ? change.path : resolve7(cwd, change.path));
|
|
4230
4109
|
let nativePreview;
|
|
4231
4110
|
if (threadId && item.status === "completed") {
|
|
4232
4111
|
await new Promise((resolveDelay) => setTimeout(resolveDelay, 20));
|
|
@@ -4395,8 +4274,8 @@ async function* codexProvider(opts) {
|
|
|
4395
4274
|
mcpServerCount: Object.keys(codexMcpServers).length
|
|
4396
4275
|
}, "codexProvider: starting turn");
|
|
4397
4276
|
const hostedCodexHome = hostedCodexHomePath();
|
|
4398
|
-
const inheritedCodexHome = process.env.CODEX_HOME || join7(
|
|
4399
|
-
const codexEnvironment = scopedBrowserCapability ||
|
|
4277
|
+
const inheritedCodexHome = process.env.CODEX_HOME || join7(homedir2(), ".codex");
|
|
4278
|
+
const codexEnvironment = scopedBrowserCapability || resolve7(hostedCodexHome) !== resolve7(inheritedCodexHome) ? {
|
|
4400
4279
|
...Object.fromEntries(Object.entries(process.env).filter((entry) => typeof entry[1] === "string")),
|
|
4401
4280
|
CODEX_HOME: hostedCodexHome,
|
|
4402
4281
|
...scopedBrowserCapability ? { [CODEX_BROWSER_CAPABILITY_ENV]: scopedBrowserCapability } : {}
|
|
@@ -4695,7 +4574,7 @@ async function* codexProvider(opts) {
|
|
|
4695
4574
|
process.env.MAESTRO_SDK_SILENT_BOOTSTRAP ??= "1";
|
|
4696
4575
|
|
|
4697
4576
|
// ../../packages/core/src/agents/maestro-provider.ts
|
|
4698
|
-
import { resolve as
|
|
4577
|
+
import { resolve as resolve8 } from "path";
|
|
4699
4578
|
import { maestroProvider as sdkMaestroProvider, setMcpResolver } from "maestro-agent-sdk";
|
|
4700
4579
|
var MAESTRO_DEFAULT_MAX_TOKENS = 32768;
|
|
4701
4580
|
var PROVIDER_ASK_USER_TOOL = "AskUserQuestion";
|
|
@@ -4773,7 +4652,7 @@ function buildProviderOwnedToolBlockHook() {
|
|
|
4773
4652
|
}
|
|
4774
4653
|
};
|
|
4775
4654
|
}
|
|
4776
|
-
var MAESTRO_TOOL_OUTPUT_DIR =
|
|
4655
|
+
var MAESTRO_TOOL_OUTPUT_DIR = resolve8(RUN_DIR, "maestro-tool-outputs");
|
|
4777
4656
|
function buildMaestroToolResultTruncation(opts) {
|
|
4778
4657
|
if (opts.toolResultTruncation)
|
|
4779
4658
|
return opts.toolResultTruncation;
|
|
@@ -4806,18 +4685,18 @@ function maestroProvider(opts) {
|
|
|
4806
4685
|
return sdkMaestroProvider(sdkOpts);
|
|
4807
4686
|
}
|
|
4808
4687
|
// ../../packages/core/src/agents/claude-runtime-inspection.ts
|
|
4809
|
-
import { readFileSync as
|
|
4810
|
-
import { createRequire as
|
|
4811
|
-
import { dirname as
|
|
4688
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
4689
|
+
import { createRequire as createRequire2 } from "module";
|
|
4690
|
+
import { dirname as dirname9, join as join8 } from "path";
|
|
4812
4691
|
var cached;
|
|
4813
4692
|
function inspectBundledClaudeRuntime() {
|
|
4814
4693
|
if (cached)
|
|
4815
4694
|
return cached;
|
|
4816
4695
|
try {
|
|
4817
|
-
const require2 =
|
|
4818
|
-
const sdkDir =
|
|
4819
|
-
const sdkPackage = JSON.parse(
|
|
4820
|
-
const manifest = JSON.parse(
|
|
4696
|
+
const require2 = createRequire2(import.meta.url);
|
|
4697
|
+
const sdkDir = dirname9(require2.resolve("@anthropic-ai/claude-agent-sdk"));
|
|
4698
|
+
const sdkPackage = JSON.parse(readFileSync6(join8(sdkDir, "package.json"), "utf8"));
|
|
4699
|
+
const manifest = JSON.parse(readFileSync6(join8(sdkDir, "manifest.json"), "utf8"));
|
|
4821
4700
|
const sdkVersion = typeof sdkPackage.version === "string" ? sdkPackage.version : "";
|
|
4822
4701
|
const claudeCodeVersion = typeof manifest.version === "string" ? manifest.version : "";
|
|
4823
4702
|
if (!sdkVersion || !claudeCodeVersion) {
|
|
@@ -4890,4 +4769,4 @@ export {
|
|
|
4890
4769
|
buildClaudeDisallowedTools
|
|
4891
4770
|
};
|
|
4892
4771
|
|
|
4893
|
-
//# debugId=
|
|
4772
|
+
//# debugId=71D580BB622B76C964756E2164756E21
|