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.
Files changed (39) hide show
  1. package/README.md +2 -6
  2. package/dist/agent-helpers.js +333 -187
  3. package/dist/agent-helpers.js.map +9 -8
  4. package/dist/{chunk-0ynjwr50.js → chunk-zq2tcq4k.js} +12 -29
  5. package/dist/{chunk-0ynjwr50.js.map → chunk-zq2tcq4k.js.map} +4 -4
  6. package/dist/hosted-agent.js +214 -65
  7. package/dist/hosted-agent.js.map +8 -7
  8. package/dist/main.js +712 -895
  9. package/dist/main.js.map +10 -11
  10. package/dist/mcp-factories.js +305 -470
  11. package/dist/mcp-factories.js.map +9 -10
  12. package/dist/registry.js +3 -3
  13. package/dist/registry.js.map +2 -2
  14. package/dist/rollout.js +1 -1
  15. package/dist/runtime/src/agents/codex-provider.ts +40 -9
  16. package/dist/runtime/src/agents/codex-vault-hook-bridge.ts +198 -0
  17. package/dist/runtime/src/agents/codex-vault-hook.mjs +50 -0
  18. package/dist/runtime/src/agents/execution-host.ts +1 -14
  19. package/dist/runtime/src/agents/public-helpers.ts +0 -9
  20. package/dist/runtime/src/agents/vault-tool-policy.ts +9 -51
  21. package/dist/runtime/src/mcp/factories/index.ts +1 -8
  22. package/dist/runtime/src/mcp/factories/vault.ts +6 -104
  23. package/dist/runtime/src/mcp/vault-server.ts +4 -20
  24. package/dist/runtime/src/prompts/sessions/_shared-tools.md +1 -1
  25. package/dist/runtime/src/version.ts +1 -1
  26. package/dist/types/packages/core/src/agents/codex-vault-hook-bridge.d.ts +28 -0
  27. package/dist/types/packages/core/src/agents/execution-host.d.ts +0 -2
  28. package/dist/types/packages/core/src/agents/public-helpers.d.ts +0 -1
  29. package/dist/types/packages/core/src/agents/vault-tool-policy.d.ts +1 -14
  30. package/dist/types/packages/core/src/mcp/factories/index.d.ts +1 -3
  31. package/dist/types/packages/core/src/mcp/factories/vault.d.ts +4 -13
  32. package/dist/types/packages/core/src/version.d.ts +1 -1
  33. package/package.json +2 -2
  34. package/dist/runtime/src/mcp/factories/vault-host.ts +0 -8
  35. package/dist/runtime/src/mcp/vault-http.ts +0 -235
  36. package/dist/runtime/src/mcp/vault-run.ts +0 -154
  37. package/dist/types/packages/core/src/mcp/factories/vault-host.d.ts +0 -7
  38. package/dist/types/packages/core/src/mcp/vault-http.d.ts +0 -23
  39. package/dist/types/packages/core/src/mcp/vault-run.d.ts +0 -19
@@ -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 createVaultToolPolicy(host) {
507
- function isVaultBrokerTool(toolName) {
508
- return toolName.includes("vault_run") || toolName.includes("vault_http_request");
509
- }
510
- function referencesRuntimeSecretStorage(value) {
511
- if (typeof value === "string") {
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
- function shouldRedirectVaultTool(userId, toolName, input) {
525
- return false;
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 { isVaultBrokerTool, referencesRuntimeSecretStorage, shouldRedirectVaultTool };
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 existsSync5, readFileSync as readFileSync6, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
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 dirname7, isAbsolute, join as join6, relative, resolve as resolve6 } from "path";
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.3.14";
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 existsSync4, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync4 } from "fs";
2832
- import { basename, dirname as dirname6, join as join5, resolve as resolve5 } from "path";
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 join5(hostedCodexHomePath(), "sessions");
2968
+ return join6(hostedCodexHomePath(), "sessions");
2835
2969
  }
2836
2970
  function canonicalFilePath(path) {
2837
- const absolute = resolve5(path);
2971
+ const absolute = resolve6(path);
2838
2972
  try {
2839
2973
  return realpathSync2(absolute);
2840
2974
  } catch {
2841
2975
  try {
2842
- return join5(realpathSync2(dirname6(absolute)), basename(absolute));
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 = join5(sessionsDir, bucket);
3073
- if (!existsSync4(dir))
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(join5(dir, rel));
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(join5(sessionsDir, rel));
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 = join6(dirname7(authFilePath), "config.toml");
3237
- if (!existsSync5(configPath))
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(resolve6(path));
3470
+ return realpathSync3(resolve7(path));
3336
3471
  } catch {
3337
- return resolve6(path);
3472
+ return resolve7(path);
3338
3473
  }
3339
3474
  }
3340
3475
  function textFile(path, maxBytes = CODEX_DIFF_FILE_LIMIT) {
3341
- if (!existsSync5(path))
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(resolve6(this.#root, path), remainingBytes) : undefined;
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 : resolve6(this.#cwd, 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 : resolve6(cwd, 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 (!existsSync5(codexAuthPath)) {
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: existsSync5(opts.cwd),
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 || join6(homedir3(), ".codex");
3599
- const codexEnvironment = scopedBrowserCapability || resolve6(hostedCodexHome) !== resolve6(inheritedCodexHome) ? {
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: item.arguments && typeof item.arguments === "object" ? item.arguments : {},
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
- yield { type: "error", content: String(item.message ?? "") };
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 resolve7 } from "path";
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 = resolve7(RUN_DIR, "maestro-tool-outputs");
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 dirname8, join as join7 } from "path";
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 = dirname8(require2.resolve("@anthropic-ai/claude-agent-sdk"));
4019
- const sdkPackage = JSON.parse(readFileSync7(join7(sdkDir, "package.json"), "utf8"));
4020
- const manifest = JSON.parse(readFileSync7(join7(sdkDir, "manifest.json"), "utf8"));
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=781205E1C0740CD564756E2164756E21
4242
+ //# debugId=08FB62E75535D71964756E2164756E21