negotium 0.3.14 → 0.4.1
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/README.md +2 -6
- package/dist/agent-helpers.js +333 -187
- package/dist/agent-helpers.js.map +9 -8
- package/dist/{chunk-0ynjwr50.js → chunk-zq2tcq4k.js} +12 -29
- package/dist/{chunk-0ynjwr50.js.map → chunk-zq2tcq4k.js.map} +4 -4
- package/dist/hosted-agent.js +214 -65
- package/dist/hosted-agent.js.map +8 -7
- package/dist/main.js +712 -895
- package/dist/main.js.map +10 -11
- package/dist/mcp-factories.js +305 -470
- package/dist/mcp-factories.js.map +9 -10
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/agents/codex-provider.ts +40 -9
- package/dist/runtime/src/agents/codex-vault-hook-bridge.ts +198 -0
- package/dist/runtime/src/agents/codex-vault-hook.mjs +50 -0
- package/dist/runtime/src/agents/execution-host.ts +1 -14
- package/dist/runtime/src/agents/public-helpers.ts +0 -9
- package/dist/runtime/src/agents/vault-tool-policy.ts +9 -51
- package/dist/runtime/src/mcp/factories/index.ts +1 -8
- package/dist/runtime/src/mcp/factories/vault.ts +6 -104
- package/dist/runtime/src/mcp/vault-server.ts +4 -20
- package/dist/runtime/src/prompts/sessions/_shared-tools.md +1 -1
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/agents/codex-vault-hook-bridge.d.ts +28 -0
- package/dist/types/packages/core/src/agents/execution-host.d.ts +0 -2
- package/dist/types/packages/core/src/agents/public-helpers.d.ts +0 -1
- package/dist/types/packages/core/src/agents/vault-tool-policy.d.ts +1 -14
- package/dist/types/packages/core/src/mcp/factories/index.d.ts +1 -3
- package/dist/types/packages/core/src/mcp/factories/vault.d.ts +4 -13
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/dist/runtime/src/mcp/factories/vault-host.ts +0 -8
- package/dist/runtime/src/mcp/vault-http.ts +0 -235
- package/dist/runtime/src/mcp/vault-run.ts +0 -154
- package/dist/types/packages/core/src/mcp/factories/vault-host.d.ts +0 -7
- package/dist/types/packages/core/src/mcp/vault-http.d.ts +0 -23
- package/dist/types/packages/core/src/mcp/vault-run.d.ts +0 -19
package/dist/hosted-agent.js
CHANGED
|
@@ -503,36 +503,20 @@ function shouldSubstituteVaultToolInput(toolName) {
|
|
|
503
503
|
const leaf = leafToolName(toolName);
|
|
504
504
|
return leaf.startsWith("browser_") || DIRECT_VAULT_EXECUTION_TOOLS.has(leaf);
|
|
505
505
|
}
|
|
506
|
-
function
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
const lower = value.toLowerCase();
|
|
513
|
-
if (SENSITIVE_RUNTIME_NAMES.some((name) => lower.includes(name)))
|
|
514
|
-
return true;
|
|
515
|
-
return value.startsWith("/") && host.isSensitivePath(value);
|
|
516
|
-
}
|
|
517
|
-
if (Array.isArray(value))
|
|
518
|
-
return value.some(referencesRuntimeSecretStorage);
|
|
519
|
-
if (value && typeof value === "object") {
|
|
520
|
-
return Object.values(value).some(referencesRuntimeSecretStorage);
|
|
521
|
-
}
|
|
522
|
-
return false;
|
|
506
|
+
function referencesRuntimeSecretStorage(value) {
|
|
507
|
+
if (typeof value === "string") {
|
|
508
|
+
const lower = value.toLowerCase();
|
|
509
|
+
if (SENSITIVE_RUNTIME_NAMES.some((name) => lower.includes(name)))
|
|
510
|
+
return true;
|
|
511
|
+
return value.startsWith("/") && isSensitivePath(value);
|
|
523
512
|
}
|
|
524
|
-
|
|
525
|
-
return
|
|
513
|
+
if (Array.isArray(value))
|
|
514
|
+
return value.some(referencesRuntimeSecretStorage);
|
|
515
|
+
if (value && typeof value === "object") {
|
|
516
|
+
return Object.values(value).some(referencesRuntimeSecretStorage);
|
|
526
517
|
}
|
|
527
|
-
return
|
|
518
|
+
return false;
|
|
528
519
|
}
|
|
529
|
-
var defaultVaultToolPolicy = createVaultToolPolicy({
|
|
530
|
-
isSensitivePath,
|
|
531
|
-
valueReferencesVaultKey: () => false
|
|
532
|
-
});
|
|
533
|
-
var isVaultBrokerTool = defaultVaultToolPolicy.isVaultBrokerTool;
|
|
534
|
-
var referencesRuntimeSecretStorage = defaultVaultToolPolicy.referencesRuntimeSecretStorage;
|
|
535
|
-
var shouldRedirectVaultTool = defaultVaultToolPolicy.shouldRedirectVaultTool;
|
|
536
520
|
|
|
537
521
|
// ../../packages/core/src/mcp/runtime-spec.ts
|
|
538
522
|
import { createHash, createHmac, timingSafeEqual } from "crypto";
|
|
@@ -1804,7 +1788,6 @@ var defaultHost = {
|
|
|
1804
1788
|
redactVaultSecrets,
|
|
1805
1789
|
substituteVaultSecrets: (userId, value) => vaultSubstituteDetailed(userId, value).text,
|
|
1806
1790
|
referencesRuntimeSecretStorage,
|
|
1807
|
-
shouldRedirectVaultTool,
|
|
1808
1791
|
claudeCodeExecutablePath: () => CLAUDE_EXECUTABLE,
|
|
1809
1792
|
codexAuthFilePath
|
|
1810
1793
|
};
|
|
@@ -2375,9 +2358,9 @@ async function* claudeProvider(opts) {
|
|
|
2375
2358
|
|
|
2376
2359
|
// ../../packages/core/src/agents/codex-provider.ts
|
|
2377
2360
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
2378
|
-
import { existsSync as
|
|
2361
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
2379
2362
|
import { homedir as homedir3 } from "os";
|
|
2380
|
-
import { dirname as
|
|
2363
|
+
import { dirname as dirname8, isAbsolute, join as join7, relative, resolve as resolve7 } from "path";
|
|
2381
2364
|
import { Codex } from "@openai/codex-sdk";
|
|
2382
2365
|
|
|
2383
2366
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
@@ -2399,7 +2382,7 @@ import { tmpdir } from "os";
|
|
|
2399
2382
|
import { dirname as dirname5, join as join4 } from "path";
|
|
2400
2383
|
|
|
2401
2384
|
// ../../packages/core/src/version.ts
|
|
2402
|
-
var NEGOTIUM_VERSION = "0.
|
|
2385
|
+
var NEGOTIUM_VERSION = "0.4.1";
|
|
2403
2386
|
|
|
2404
2387
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
2405
2388
|
var moduleRequire = createRequire2(import.meta.url);
|
|
@@ -2827,19 +2810,170 @@ var withCodexSpawnSerial = manager.withSpawnSerial;
|
|
|
2827
2810
|
var killCodexTrees = manager.killTrees;
|
|
2828
2811
|
var killOwnedCodexTreesForShutdown = manager.killOwnedTreesForShutdown;
|
|
2829
2812
|
|
|
2813
|
+
// ../../packages/core/src/agents/codex-vault-hook-bridge.ts
|
|
2814
|
+
import { randomBytes as randomBytes4 } from "crypto";
|
|
2815
|
+
import { existsSync as existsSync4 } from "fs";
|
|
2816
|
+
import { chmod, mkdtemp, rm, writeFile } from "fs/promises";
|
|
2817
|
+
import { createServer } from "net";
|
|
2818
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
2819
|
+
import { dirname as dirname6, join as join5, resolve as resolve5 } from "path";
|
|
2820
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2821
|
+
var MAX_HOOK_REQUEST_BYTES = 1024 * 1024;
|
|
2822
|
+
var SENSITIVE_STORAGE_DENIAL = "Runtime secret storage access is not permitted";
|
|
2823
|
+
var HOOK_SOCKET_ENV = "NEGOTIUM_CODEX_VAULT_HOOK_SOCKET";
|
|
2824
|
+
var HOOK_TOKEN_ENV = "NEGOTIUM_CODEX_VAULT_HOOK_TOKEN";
|
|
2825
|
+
function evaluateCodexVaultPreToolUse(input, userId, operations) {
|
|
2826
|
+
if (operations.referencesSensitiveStorage(input.tool_input)) {
|
|
2827
|
+
return {
|
|
2828
|
+
hookSpecificOutput: {
|
|
2829
|
+
hookEventName: "PreToolUse",
|
|
2830
|
+
permissionDecision: "deny",
|
|
2831
|
+
permissionDecisionReason: SENSITIVE_STORAGE_DENIAL
|
|
2832
|
+
}
|
|
2833
|
+
};
|
|
2834
|
+
}
|
|
2835
|
+
if (!shouldSubstituteVaultToolInput(input.tool_name))
|
|
2836
|
+
return {};
|
|
2837
|
+
const updatedInput = deepMapStrings(input.tool_input, (value) => operations.substitute(userId, value));
|
|
2838
|
+
if (JSON.stringify(updatedInput) === JSON.stringify(input.tool_input))
|
|
2839
|
+
return {};
|
|
2840
|
+
return {
|
|
2841
|
+
hookSpecificOutput: {
|
|
2842
|
+
hookEventName: "PreToolUse",
|
|
2843
|
+
permissionDecision: "allow",
|
|
2844
|
+
updatedInput
|
|
2845
|
+
}
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
function shellQuote(value) {
|
|
2849
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
2850
|
+
}
|
|
2851
|
+
function hookClientPath() {
|
|
2852
|
+
const moduleDir = dirname6(fileURLToPath2(import.meta.url));
|
|
2853
|
+
const adjacent = resolve5(moduleDir, "codex-vault-hook.mjs");
|
|
2854
|
+
if (existsSync4(adjacent))
|
|
2855
|
+
return adjacent;
|
|
2856
|
+
const packaged = resolve5(moduleDir, "runtime/src/agents/codex-vault-hook.mjs");
|
|
2857
|
+
if (existsSync4(packaged))
|
|
2858
|
+
return packaged;
|
|
2859
|
+
throw new Error("Codex Vault hook client is missing from this installation");
|
|
2860
|
+
}
|
|
2861
|
+
function privateCodexWrapper(codexScript, socketPath, token) {
|
|
2862
|
+
return [
|
|
2863
|
+
"#!/bin/sh",
|
|
2864
|
+
`export ${HOOK_SOCKET_ENV}=${shellQuote(socketPath)}`,
|
|
2865
|
+
`export ${HOOK_TOKEN_ENV}=${shellQuote(token)}`,
|
|
2866
|
+
'if [ "$1" = "exec" ]; then',
|
|
2867
|
+
" shift",
|
|
2868
|
+
` exec ${shellQuote(process.execPath)} ${shellQuote(codexScript)} exec --dangerously-bypass-hook-trust "$@"`,
|
|
2869
|
+
"fi",
|
|
2870
|
+
`exec ${shellQuote(process.execPath)} ${shellQuote(codexScript)} "$@"`,
|
|
2871
|
+
""
|
|
2872
|
+
].join(`
|
|
2873
|
+
`);
|
|
2874
|
+
}
|
|
2875
|
+
async function createCodexVaultHookBridge(userId) {
|
|
2876
|
+
const root = await mkdtemp(join5(tmpdir2(), "negotium-codex-vault-"));
|
|
2877
|
+
await chmod(root, 448);
|
|
2878
|
+
const socketPath = join5(root, "hook.sock");
|
|
2879
|
+
const wrapperPath = join5(root, "codex-with-hooks");
|
|
2880
|
+
const token = randomBytes4(32).toString("hex");
|
|
2881
|
+
const connections = new Set;
|
|
2882
|
+
const server = createServer((socket) => {
|
|
2883
|
+
connections.add(socket);
|
|
2884
|
+
socket.once("close", () => connections.delete(socket));
|
|
2885
|
+
socket.setEncoding("utf8");
|
|
2886
|
+
let request = "";
|
|
2887
|
+
let handled = false;
|
|
2888
|
+
const handleRequest = () => {
|
|
2889
|
+
if (handled)
|
|
2890
|
+
return;
|
|
2891
|
+
handled = true;
|
|
2892
|
+
try {
|
|
2893
|
+
const parsed = JSON.parse(request.trimEnd());
|
|
2894
|
+
if (parsed.token !== token)
|
|
2895
|
+
throw new Error("invalid hook capability");
|
|
2896
|
+
if (!parsed.input || typeof parsed.input !== "object" || typeof parsed.input.tool_name !== "string") {
|
|
2897
|
+
throw new Error("invalid PreToolUse payload");
|
|
2898
|
+
}
|
|
2899
|
+
const output = evaluateCodexVaultPreToolUse(parsed.input, userId, {
|
|
2900
|
+
referencesSensitiveStorage: referencesHostedSecretStorage,
|
|
2901
|
+
substitute: substituteHostedSecrets
|
|
2902
|
+
});
|
|
2903
|
+
socket.end(JSON.stringify({ ok: true, output }));
|
|
2904
|
+
} catch (error) {
|
|
2905
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2906
|
+
socket.end(JSON.stringify({ ok: false, error: message }));
|
|
2907
|
+
}
|
|
2908
|
+
};
|
|
2909
|
+
socket.on("data", (chunk) => {
|
|
2910
|
+
request += chunk;
|
|
2911
|
+
if (Buffer.byteLength(request) > MAX_HOOK_REQUEST_BYTES)
|
|
2912
|
+
socket.destroy();
|
|
2913
|
+
else if (request.endsWith(`
|
|
2914
|
+
`))
|
|
2915
|
+
handleRequest();
|
|
2916
|
+
});
|
|
2917
|
+
socket.on("end", handleRequest);
|
|
2918
|
+
});
|
|
2919
|
+
try {
|
|
2920
|
+
await new Promise((resolveListen, reject) => {
|
|
2921
|
+
server.once("error", reject);
|
|
2922
|
+
server.listen(socketPath, () => {
|
|
2923
|
+
server.off("error", reject);
|
|
2924
|
+
resolveListen();
|
|
2925
|
+
});
|
|
2926
|
+
});
|
|
2927
|
+
await chmod(socketPath, 384);
|
|
2928
|
+
await writeFile(wrapperPath, privateCodexWrapper(codexCliScriptPath(), socketPath, token), {
|
|
2929
|
+
mode: 448
|
|
2930
|
+
});
|
|
2931
|
+
const command = [shellQuote(process.execPath), shellQuote(hookClientPath())].join(" ");
|
|
2932
|
+
return {
|
|
2933
|
+
codexPathOverride: wrapperPath,
|
|
2934
|
+
environment: { [HOOK_SOCKET_ENV]: socketPath, [HOOK_TOKEN_ENV]: token },
|
|
2935
|
+
hooks: {
|
|
2936
|
+
PreToolUse: [
|
|
2937
|
+
{
|
|
2938
|
+
matcher: "*",
|
|
2939
|
+
hooks: [
|
|
2940
|
+
{
|
|
2941
|
+
type: "command",
|
|
2942
|
+
command,
|
|
2943
|
+
timeout: 30,
|
|
2944
|
+
statusMessage: "Resolving Vault placeholders"
|
|
2945
|
+
}
|
|
2946
|
+
]
|
|
2947
|
+
}
|
|
2948
|
+
]
|
|
2949
|
+
},
|
|
2950
|
+
async close() {
|
|
2951
|
+
for (const socket of connections)
|
|
2952
|
+
socket.destroy();
|
|
2953
|
+
await new Promise((resolveClose) => server.close(() => resolveClose()));
|
|
2954
|
+
await rm(root, { recursive: true, force: true });
|
|
2955
|
+
}
|
|
2956
|
+
};
|
|
2957
|
+
} catch (error) {
|
|
2958
|
+
server.close();
|
|
2959
|
+
await rm(root, { recursive: true, force: true });
|
|
2960
|
+
throw error;
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2830
2964
|
// ../../packages/core/src/agents/rollout/codex.ts
|
|
2831
|
-
import { existsSync as
|
|
2832
|
-
import { basename, dirname as
|
|
2965
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync4 } from "fs";
|
|
2966
|
+
import { basename, dirname as dirname7, join as join6, resolve as resolve6 } from "path";
|
|
2833
2967
|
function codexSessionsDir() {
|
|
2834
|
-
return
|
|
2968
|
+
return join6(hostedCodexHomePath(), "sessions");
|
|
2835
2969
|
}
|
|
2836
2970
|
function canonicalFilePath(path) {
|
|
2837
|
-
const absolute =
|
|
2971
|
+
const absolute = resolve6(path);
|
|
2838
2972
|
try {
|
|
2839
2973
|
return realpathSync2(absolute);
|
|
2840
2974
|
} catch {
|
|
2841
2975
|
try {
|
|
2842
|
-
return
|
|
2976
|
+
return join6(realpathSync2(dirname7(absolute)), basename(absolute));
|
|
2843
2977
|
} catch {
|
|
2844
2978
|
return absolute;
|
|
2845
2979
|
}
|
|
@@ -3069,19 +3203,19 @@ function latestCodexRolloutPath(threadId) {
|
|
|
3069
3203
|
try {
|
|
3070
3204
|
if (buckets) {
|
|
3071
3205
|
for (const bucket of buckets) {
|
|
3072
|
-
const dir =
|
|
3073
|
-
if (!
|
|
3206
|
+
const dir = join6(sessionsDir, bucket);
|
|
3207
|
+
if (!existsSync5(dir))
|
|
3074
3208
|
continue;
|
|
3075
3209
|
const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
|
|
3076
3210
|
for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
|
|
3077
|
-
candidates.push(
|
|
3211
|
+
candidates.push(join6(dir, rel));
|
|
3078
3212
|
}
|
|
3079
3213
|
}
|
|
3080
3214
|
}
|
|
3081
3215
|
if (candidates.length === 0) {
|
|
3082
3216
|
const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
|
|
3083
3217
|
for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
|
|
3084
|
-
candidates.push(
|
|
3218
|
+
candidates.push(join6(sessionsDir, rel));
|
|
3085
3219
|
}
|
|
3086
3220
|
}
|
|
3087
3221
|
return candidates.sort((a, b) => statSync2(b).mtimeMs - statSync2(a).mtimeMs)[0];
|
|
@@ -3204,6 +3338,7 @@ function buildNumberedDiffSummary(before, after, startLine = 1) {
|
|
|
3204
3338
|
}
|
|
3205
3339
|
|
|
3206
3340
|
// ../../packages/core/src/agents/codex-provider.ts
|
|
3341
|
+
var CODEX_HOOK_TRUST_BYPASS_NOTICE = "`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.";
|
|
3207
3342
|
function sameCodexUsage(usage, total) {
|
|
3208
3343
|
return usage.input_tokens === total.inputTokens && usage.output_tokens === total.outputTokens && (usage.cached_input_tokens ?? 0) === total.cachedInputTokens && (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens;
|
|
3209
3344
|
}
|
|
@@ -3233,8 +3368,8 @@ function codexMcpServerName(name) {
|
|
|
3233
3368
|
return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;
|
|
3234
3369
|
}
|
|
3235
3370
|
function globalCodexMcpServerNames(authFilePath) {
|
|
3236
|
-
const configPath =
|
|
3237
|
-
if (!
|
|
3371
|
+
const configPath = join7(dirname8(authFilePath), "config.toml");
|
|
3372
|
+
if (!existsSync6(configPath))
|
|
3238
3373
|
return [];
|
|
3239
3374
|
try {
|
|
3240
3375
|
const names = new Set;
|
|
@@ -3332,13 +3467,13 @@ var CODEX_DIFF_BASELINE_FILE_LIMIT = 200;
|
|
|
3332
3467
|
var CODEX_DIFF_BASELINE_BYTE_LIMIT = 16 * 1024 * 1024;
|
|
3333
3468
|
function canonicalPath(path) {
|
|
3334
3469
|
try {
|
|
3335
|
-
return realpathSync3(
|
|
3470
|
+
return realpathSync3(resolve7(path));
|
|
3336
3471
|
} catch {
|
|
3337
|
-
return
|
|
3472
|
+
return resolve7(path);
|
|
3338
3473
|
}
|
|
3339
3474
|
}
|
|
3340
3475
|
function textFile(path, maxBytes = CODEX_DIFF_FILE_LIMIT) {
|
|
3341
|
-
if (!
|
|
3476
|
+
if (!existsSync6(path))
|
|
3342
3477
|
return null;
|
|
3343
3478
|
try {
|
|
3344
3479
|
const byteLimit = Math.min(CODEX_DIFF_FILE_LIMIT, Math.max(0, maxBytes));
|
|
@@ -3378,7 +3513,7 @@ class CodexFilePreviewTracker {
|
|
|
3378
3513
|
const code = record.slice(0, 2);
|
|
3379
3514
|
const path = record.slice(3);
|
|
3380
3515
|
const remainingBytes = CODEX_DIFF_BASELINE_BYTE_LIMIT - loadedBytes;
|
|
3381
|
-
const content = loadedFiles < CODEX_DIFF_BASELINE_FILE_LIMIT && remainingBytes > 0 ? textFile(
|
|
3516
|
+
const content = loadedFiles < CODEX_DIFF_BASELINE_FILE_LIMIT && remainingBytes > 0 ? textFile(resolve7(this.#root, path), remainingBytes) : undefined;
|
|
3382
3517
|
this.#baseline.set(path, content);
|
|
3383
3518
|
if (typeof content === "string") {
|
|
3384
3519
|
loadedFiles += 1;
|
|
@@ -3391,7 +3526,7 @@ class CodexFilePreviewTracker {
|
|
|
3391
3526
|
preview(path, succeeded) {
|
|
3392
3527
|
if (!this.#root || !this.#baselineAvailable || !succeeded)
|
|
3393
3528
|
return {};
|
|
3394
|
-
const absolute = canonicalPath(isAbsolute(path) ? path :
|
|
3529
|
+
const absolute = canonicalPath(isAbsolute(path) ? path : resolve7(this.#cwd, path));
|
|
3395
3530
|
const relativePath = relative(this.#root, absolute);
|
|
3396
3531
|
if (!relativePath || relativePath.startsWith("..") || isAbsolute(relativePath))
|
|
3397
3532
|
return {};
|
|
@@ -3426,7 +3561,7 @@ class CodexFilePreviewTracker {
|
|
|
3426
3561
|
}
|
|
3427
3562
|
}
|
|
3428
3563
|
async function fileChangeEvents(item, previews, cwd, threadId, consumedPatchCallIds) {
|
|
3429
|
-
const expectedPaths = item.changes.map((change) => isAbsolute(change.path) ? change.path :
|
|
3564
|
+
const expectedPaths = item.changes.map((change) => isAbsolute(change.path) ? change.path : resolve7(cwd, change.path));
|
|
3430
3565
|
let nativePreview;
|
|
3431
3566
|
if (threadId && item.status === "completed") {
|
|
3432
3567
|
await new Promise((resolveDelay) => setTimeout(resolveDelay, 20));
|
|
@@ -3551,7 +3686,7 @@ async function* codexProvider(opts) {
|
|
|
3551
3686
|
const filePreviews = new CodexFilePreviewTracker(opts.cwd);
|
|
3552
3687
|
const consumedPatchCallIds = new Set(opts.sessionId ? readCodexPatchCallIds(opts.sessionId) : []);
|
|
3553
3688
|
const codexAuthPath = hostedCodexAuthFilePath();
|
|
3554
|
-
if (!
|
|
3689
|
+
if (!existsSync6(codexAuthPath)) {
|
|
3555
3690
|
yield {
|
|
3556
3691
|
type: "error",
|
|
3557
3692
|
content: `Codex auth file not found at ${codexAuthPath}. Run \`codex login\` to authenticate.`
|
|
@@ -3590,21 +3725,30 @@ async function* codexProvider(opts) {
|
|
|
3590
3725
|
model: opts.model ?? "(sdk default)",
|
|
3591
3726
|
effort: opts.effort ?? "(off)",
|
|
3592
3727
|
cwd: opts.cwd,
|
|
3593
|
-
cwdExists:
|
|
3728
|
+
cwdExists: existsSync6(opts.cwd),
|
|
3594
3729
|
resume: Boolean(opts.sessionId),
|
|
3595
3730
|
mcpServerCount: Object.keys(codexMcpServers).length
|
|
3596
3731
|
}, "codexProvider: starting turn");
|
|
3597
3732
|
const hostedCodexHome = hostedCodexHomePath();
|
|
3598
|
-
const inheritedCodexHome = process.env.CODEX_HOME ||
|
|
3599
|
-
const codexEnvironment = scopedBrowserCapability ||
|
|
3733
|
+
const inheritedCodexHome = process.env.CODEX_HOME || join7(homedir3(), ".codex");
|
|
3734
|
+
const codexEnvironment = scopedBrowserCapability || resolve7(hostedCodexHome) !== resolve7(inheritedCodexHome) ? {
|
|
3600
3735
|
...Object.fromEntries(Object.entries(process.env).filter((entry) => typeof entry[1] === "string")),
|
|
3601
3736
|
CODEX_HOME: hostedCodexHome,
|
|
3602
3737
|
...scopedBrowserCapability ? { [CODEX_BROWSER_CAPABILITY_ENV]: scopedBrowserCapability } : {}
|
|
3603
3738
|
} : undefined;
|
|
3739
|
+
let vaultHook;
|
|
3740
|
+
try {
|
|
3741
|
+
vaultHook = await createCodexVaultHookBridge(opts.vaultUserId ?? opts.userId ?? "");
|
|
3742
|
+
} catch (err) {
|
|
3743
|
+
yield { type: "error", content: `Failed to initialize Codex Vault hooks: ${errMsg(err)}` };
|
|
3744
|
+
return;
|
|
3745
|
+
}
|
|
3604
3746
|
const codex = new Codex({
|
|
3747
|
+
codexPathOverride: vaultHook.codexPathOverride,
|
|
3605
3748
|
...codexEnvironment ? { env: codexEnvironment } : {},
|
|
3606
3749
|
config: {
|
|
3607
|
-
features: { multi_agent: false, multi_agent_v2: false, enable_fanout: false },
|
|
3750
|
+
features: { hooks: true, multi_agent: false, multi_agent_v2: false, enable_fanout: false },
|
|
3751
|
+
hooks: vaultHook.hooks,
|
|
3608
3752
|
model_catalog_json: codexModelCatalogPath,
|
|
3609
3753
|
mcp_servers: codexMcpServers,
|
|
3610
3754
|
...opts.toolPolicy ? { sandbox_permissions: [] } : {}
|
|
@@ -3708,7 +3852,7 @@ async function* codexProvider(opts) {
|
|
|
3708
3852
|
if (!item)
|
|
3709
3853
|
break;
|
|
3710
3854
|
if (item.type === "command_execution") {
|
|
3711
|
-
const command = String(item.command ?? "");
|
|
3855
|
+
const command = redactHostedSecrets(opts.vaultUserId ?? opts.userId ?? "", String(item.command ?? ""));
|
|
3712
3856
|
yield {
|
|
3713
3857
|
type: "tool_use",
|
|
3714
3858
|
name: "Bash",
|
|
@@ -3716,10 +3860,11 @@ async function* codexProvider(opts) {
|
|
|
3716
3860
|
toolUseId: String(item.id ?? "")
|
|
3717
3861
|
};
|
|
3718
3862
|
} else if (item.type === "mcp_tool_call") {
|
|
3863
|
+
const input = item.arguments && typeof item.arguments === "object" ? item.arguments : {};
|
|
3719
3864
|
yield {
|
|
3720
3865
|
type: "tool_use",
|
|
3721
3866
|
name: String(item.tool ?? "unknown"),
|
|
3722
|
-
input:
|
|
3867
|
+
input: deepMapStrings(input, (value) => redactHostedSecrets(opts.vaultUserId ?? opts.userId ?? "", value)),
|
|
3723
3868
|
toolUseId: String(item.id ?? "")
|
|
3724
3869
|
};
|
|
3725
3870
|
}
|
|
@@ -3762,7 +3907,7 @@ async function* codexProvider(opts) {
|
|
|
3762
3907
|
yield {
|
|
3763
3908
|
type: "tool_result",
|
|
3764
3909
|
toolUseId: String(item.id ?? ""),
|
|
3765
|
-
content: summarizeMcpToolCallResult(item),
|
|
3910
|
+
content: redactHostedSecrets(opts.vaultUserId ?? opts.userId ?? "", summarizeMcpToolCallResult(item)),
|
|
3766
3911
|
...isError ? { isError: true } : {}
|
|
3767
3912
|
};
|
|
3768
3913
|
} else if (item.type === "command_execution") {
|
|
@@ -3770,7 +3915,7 @@ async function* codexProvider(opts) {
|
|
|
3770
3915
|
yield {
|
|
3771
3916
|
type: "tool_result",
|
|
3772
3917
|
toolUseId: String(item.id ?? ""),
|
|
3773
|
-
content: String(item.aggregated_output ?? "").slice(0, 200),
|
|
3918
|
+
content: redactHostedSecrets(opts.vaultUserId ?? opts.userId ?? "", String(item.aggregated_output ?? "").slice(0, 200)),
|
|
3774
3919
|
...isError ? { isError: true } : {}
|
|
3775
3920
|
};
|
|
3776
3921
|
} else if (item.type === "file_change") {
|
|
@@ -3779,7 +3924,10 @@ async function* codexProvider(opts) {
|
|
|
3779
3924
|
yield fileEvent;
|
|
3780
3925
|
}
|
|
3781
3926
|
} else if (item.type === "error") {
|
|
3782
|
-
|
|
3927
|
+
const message = String(item.message ?? "");
|
|
3928
|
+
if (message !== CODEX_HOOK_TRUST_BYPASS_NOTICE) {
|
|
3929
|
+
yield { type: "error", content: message };
|
|
3930
|
+
}
|
|
3783
3931
|
}
|
|
3784
3932
|
break;
|
|
3785
3933
|
}
|
|
@@ -3867,6 +4015,7 @@ async function* codexProvider(opts) {
|
|
|
3867
4015
|
abortSignal?.removeEventListener("abort", onAbortKill);
|
|
3868
4016
|
if (trackedPids.pids.length > 0)
|
|
3869
4017
|
unregisterOwnedCodexPids(trackedPids.pids);
|
|
4018
|
+
await vaultHook.close();
|
|
3870
4019
|
}
|
|
3871
4020
|
}
|
|
3872
4021
|
|
|
@@ -3874,7 +4023,7 @@ async function* codexProvider(opts) {
|
|
|
3874
4023
|
process.env.MAESTRO_SDK_SILENT_BOOTSTRAP ??= "1";
|
|
3875
4024
|
|
|
3876
4025
|
// ../../packages/core/src/agents/maestro-provider.ts
|
|
3877
|
-
import { resolve as
|
|
4026
|
+
import { resolve as resolve8 } from "path";
|
|
3878
4027
|
import { maestroProvider as sdkMaestroProvider, setMcpResolver } from "maestro-agent-sdk";
|
|
3879
4028
|
var MAESTRO_DEFAULT_MAX_TOKENS = 32768;
|
|
3880
4029
|
var PROVIDER_ASK_USER_TOOL = "AskUserQuestion";
|
|
@@ -3973,7 +4122,7 @@ function buildProviderOwnedToolBlockHook() {
|
|
|
3973
4122
|
}
|
|
3974
4123
|
};
|
|
3975
4124
|
}
|
|
3976
|
-
var MAESTRO_TOOL_OUTPUT_DIR =
|
|
4125
|
+
var MAESTRO_TOOL_OUTPUT_DIR = resolve8(RUN_DIR, "maestro-tool-outputs");
|
|
3977
4126
|
function buildMaestroToolResultTruncation(opts) {
|
|
3978
4127
|
if (opts.toolResultTruncation)
|
|
3979
4128
|
return opts.toolResultTruncation;
|
|
@@ -4008,16 +4157,16 @@ function maestroProvider(opts) {
|
|
|
4008
4157
|
// ../../packages/core/src/agents/claude-runtime-inspection.ts
|
|
4009
4158
|
import { readFileSync as readFileSync7 } from "fs";
|
|
4010
4159
|
import { createRequire as createRequire3 } from "module";
|
|
4011
|
-
import { dirname as
|
|
4160
|
+
import { dirname as dirname9, join as join8 } from "path";
|
|
4012
4161
|
var cached;
|
|
4013
4162
|
function inspectBundledClaudeRuntime() {
|
|
4014
4163
|
if (cached)
|
|
4015
4164
|
return cached;
|
|
4016
4165
|
try {
|
|
4017
4166
|
const require2 = createRequire3(import.meta.url);
|
|
4018
|
-
const sdkDir =
|
|
4019
|
-
const sdkPackage = JSON.parse(readFileSync7(
|
|
4020
|
-
const manifest = JSON.parse(readFileSync7(
|
|
4167
|
+
const sdkDir = dirname9(require2.resolve("@anthropic-ai/claude-agent-sdk"));
|
|
4168
|
+
const sdkPackage = JSON.parse(readFileSync7(join8(sdkDir, "package.json"), "utf8"));
|
|
4169
|
+
const manifest = JSON.parse(readFileSync7(join8(sdkDir, "manifest.json"), "utf8"));
|
|
4021
4170
|
const sdkVersion = typeof sdkPackage.version === "string" ? sdkPackage.version : "";
|
|
4022
4171
|
const claudeCodeVersion = typeof manifest.version === "string" ? manifest.version : "";
|
|
4023
4172
|
if (!sdkVersion || !claudeCodeVersion) {
|
|
@@ -4090,4 +4239,4 @@ export {
|
|
|
4090
4239
|
buildClaudeDisallowedTools
|
|
4091
4240
|
};
|
|
4092
4241
|
|
|
4093
|
-
//# debugId=
|
|
4242
|
+
//# debugId=08FB62E75535D71964756E2164756E21
|