@openclaw/codex 2026.8.1-beta.3 → 2026.8.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 (64) hide show
  1. package/dist/api.js +4 -5
  2. package/dist/{attempt-client-cleanup-URjUlCHg.js → attempt-client-cleanup-CVPvp9dL.js} +47 -5
  3. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  4. package/dist/{binding-connection-DAvZwp96.js → binding-connection-CCQFs8lf.js} +2 -2
  5. package/dist/{bounded-turn-4BjrZEwW.js → bounded-turn-rq5tiSXk.js} +13 -18
  6. package/dist/{capabilities-CH3K57v4.js → capabilities-CGm_94eL.js} +1 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-D0nZ3qtd.js → command-formatters-C54Yg3eA.js} +2 -2
  9. package/dist/{command-handlers-DC86lgT4.js → command-handlers-BvOAHTrA.js} +89 -62
  10. package/dist/{compact-COqgBRny.js → compact-Hd7SAc0N.js} +8 -9
  11. package/dist/{config-CpNeo5AE.js → config-Cxw3Cl3k.js} +346 -286
  12. package/dist/doctor-contract-api.js +115 -14
  13. package/dist/{dynamic-tools-fJZhl4CE.js → dynamic-tools-BFoUcRdx.js} +147 -903
  14. package/dist/{effective-mcp-catalog-4YKn51aG.js → effective-mcp-catalog-BTJHnDSx.js} +2 -2
  15. package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
  16. package/dist/{event-projector-usage-CLwNEJqW.js → event-projector-usage-D3PHFFXh.js} +3 -3
  17. package/dist/{harness-DoKQcF8n.js → harness-DVfUQBlQ.js} +42 -52
  18. package/dist/harness.js +1 -1
  19. package/dist/index.js +278 -295
  20. package/dist/{isolated-completion-DPMtlH9r.js → isolated-completion-Cbbx_5Ed.js} +4 -4
  21. package/dist/launch-args-sXOAg0SX.js +84 -0
  22. package/dist/{managed-binary-By4FZC6i.js → managed-binary-ZkGodW19.js} +43 -7
  23. package/dist/media-understanding-provider.js +1 -1
  24. package/dist/model-catalog-o6Cgjoss.js +101 -0
  25. package/dist/{models-CZw1wClT.js → models-DgFWSuxA.js} +25 -28
  26. package/dist/{native-subagent-monitor-GGq3RnOo.js → native-subagent-monitor-CwFyoylz.js} +207 -30
  27. package/dist/{node-exec-server.runtime-Bsu1LdFZ.js → node-exec-server.runtime-DXrqpw1c.js} +8 -5
  28. package/dist/{plugin-approval-roundtrip-C75Yiiwc.js → plugin-approval-roundtrip-D80UZiJ_.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-mdmScYOj.js} +30 -39
  30. package/dist/{plugin-metadata-cache-BXH5NF-4.js → plugin-metadata-cache-CulOABwu.js} +162 -135
  31. package/dist/{protocol-validators-VAVyEnDp.js → protocol-validators-Bg5rpNxk.js} +148 -5
  32. package/dist/{rate-limits-BI1dMHDG.js → rate-limits-hFtzt2Up.js} +1 -1
  33. package/dist/{sandbox-guard-C1qEeZ5C.js → request-CCm4LaED.js} +183 -2
  34. package/dist/{run-attempt-BV3HzuCf.js → run-attempt-BwNQDH2u.js} +599 -361
  35. package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-DeBvleJw.js} +1 -1
  36. package/dist/{session-binding-BTrLf9Qm.js → session-binding-q2WSTVmC.js} +195 -122
  37. package/dist/{session-catalog-ezP_UcRM.js → session-catalog-C2Tae4rI.js} +229 -122
  38. package/dist/session-catalog-home-id-DAKUrm3C.js +112 -0
  39. package/dist/{session-cli-B1hKvfkI.js → session-cli-BuDjm5Ou.js} +1 -1
  40. package/dist/session-permission-policy-gLm40Vtq.js +160 -0
  41. package/dist/session-retirement-CdkI0bvb.js +90 -0
  42. package/dist/{session-upstream-marker-D_2npHlA.js → session-upstream-marker-Bcy33kam.js} +2 -3
  43. package/dist/{settled-turn-finalizer-Dx1onIqg.js → settled-turn-finalizer-B8JJcxCi.js} +7 -6
  44. package/dist/{shared-client-Dw-rzii0.js → shared-client-kNkljY-R.js} +1720 -786
  45. package/dist/{side-question-DbXkJZzg.js → side-question-GwD73tX6.js} +69 -39
  46. package/dist/{thread-lifecycle-DKdrnTMX.js → thread-lifecycle-Ss-uwnC4.js} +852 -359
  47. package/dist/{thread-ownership-i2NBwDUL.js → thread-ownership-CeYBqg_4.js} +18 -8
  48. package/dist/{plugin-app-cache-key-DMNQ8Zi8.js → thread-resume-DF54hagX.js} +52 -6
  49. package/dist/{transcript-mirror-BU0_LKAL.js → transcript-mirror-CkEQIna-.js} +112 -13
  50. package/dist/transport-stdio-C7-s9TLG.js +708 -0
  51. package/dist/{upstream-session-fork-BDVJCLAD.js → upstream-session-fork-BACGlOFa.js} +78 -86
  52. package/dist/{usage-9dKJCgcy.js → usage-C2l8Mils.js} +3 -3
  53. package/dist/{web-search-provider.runtime-DCdx4DGu.js → web-search-provider.runtime-B2XgRdFv.js} +3 -3
  54. package/openclaw.plugin.json +19 -1
  55. package/package.json +8 -8
  56. package/dist/app-server-policy-bg5QPSVP.js +0 -25
  57. package/dist/command-rpc-xUIIonsO.js +0 -90
  58. package/dist/incognito-session-ET_ufDH-.js +0 -2
  59. package/dist/model-catalog-CmGoqVKB.js +0 -48
  60. package/dist/request-DSK0W6YI.js +0 -157
  61. package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
  62. package/dist/session-retirement-CE4iMiLh.js +0 -36
  63. package/dist/thread-resume-CdJk2Ehf.js +0 -30
  64. package/dist/transport-stdio-DhoGy33Z.js +0 -99
@@ -1,4 +1,5 @@
1
- import { asOptionalRecord as readRecord, normalizeOptionalString as readNonEmptyString, normalizeTrimmedStringList, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { n as readCodexAppServerConfigOptions, t as normalizeCodexAppServerArgs } from "./launch-args-sXOAg0SX.js";
2
+ import { asNullableRecord, asOptionalRecord as readRecord, normalizeOptionalString, normalizeOptionalString as readNonEmptyString, normalizeTrimmedStringList, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
2
3
  import path from "node:path";
3
4
  import { resolvePositiveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
4
5
  import { AgentHarnessPreflightError } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -6,13 +7,46 @@ import { createHash, createHmac, randomBytes } from "node:crypto";
6
7
  import { readFileSync } from "node:fs";
7
8
  import { homedir, hostname } from "node:os";
8
9
  import { resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
9
- import { parse } from "smol-toml";
10
10
  import { resolveAgentConfig as resolveAgentConfig$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
11
11
  import { resolveExecApprovalsFromFile } from "openclaw/plugin-sdk/exec-approvals-runtime";
12
12
  import { buildSecretInputSchema, normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
13
13
  import { detectWindowsSpawnCommandInlineArgs } from "openclaw/plugin-sdk/windows-spawn";
14
14
  import { z } from "zod";
15
+ import { parse } from "smol-toml";
15
16
  import { isLoopbackHost } from "openclaw/plugin-sdk/ssrf-runtime";
17
+ //#region extensions/codex/src/app-server/auth-start-options.ts
18
+ const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
19
+ const CODEX_EPHEMERAL_AUTH_STORE_OVERRIDE = "cli_auth_credentials_store=\"ephemeral\"";
20
+ function resolveCodexAppServerHomeDir(agentDir) {
21
+ return path.join(path.resolve(agentDir), CODEX_APP_SERVER_HOME_DIRNAME);
22
+ }
23
+ /** Resolves the native user Codex home used by Desktop and the CLI. */
24
+ function resolveCodexAppServerUserHomeDir(env = process.env, homedir$1 = homedir) {
25
+ const configured = normalizeOptionalString(env.CODEX_HOME);
26
+ return path.resolve(configured ?? path.join(homedir$1(), ".codex"));
27
+ }
28
+ /** Resolves the local CODEX_HOME used when starting one app-server connection. */
29
+ function resolveCodexAppServerLocalHomeDir(startOptions, agentDir, env = process.env) {
30
+ const configured = startOptions.env?.CODEX_HOME;
31
+ if (configured?.trim()) return configured;
32
+ return startOptions.homeScope === "user" ? resolveCodexAppServerUserHomeDir(env) : resolveCodexAppServerHomeDir(agentDir);
33
+ }
34
+ /** Forces OpenClaw-owned Codex auth to remain process-local. */
35
+ function withEphemeralCodexAuthStore(params) {
36
+ const { startOptions } = params;
37
+ if (!params.preparedAuth && params.authProfileId === null) return startOptions;
38
+ const args = normalizeCodexAppServerArgs(startOptions.args, CODEX_EPHEMERAL_AUTH_STORE_OVERRIDE);
39
+ return args === startOptions.args ? startOptions : {
40
+ ...startOptions,
41
+ args
42
+ };
43
+ }
44
+ //#endregion
45
+ //#region extensions/codex/src/app-server/config-contracts.ts
46
+ const CODEX_PLUGINS_MARKETPLACE_NAME = "openai-curated";
47
+ const CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME = "workspace-directory";
48
+ const CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN = /^[A-Za-z0-9_-]+$/;
49
+ //#endregion
16
50
  //#region extensions/codex/src/app-server/config-utils.ts
17
51
  const START_OPTIONS_KEY_SECRET_SYMBOL = Symbol.for("openclaw.codexAppServerStartOptionsKeySecret");
18
52
  const START_OPTIONS_KEY_SECRET = getStartOptionsKeySecret();
@@ -118,8 +152,9 @@ function selectGuardianSandbox(allowedSandboxModes) {
118
152
  return "workspace-write";
119
153
  }
120
154
  function resolveApprovalPolicy(value) {
155
+ if (value === "untrusted") throw new Error("Codex app-server approval policy \"untrusted\" is retired; run \"openclaw doctor --fix\" and use \"on-request\".");
121
156
  if (value === "on-failure") return "on-request";
122
- return value === "on-request" || value === "untrusted" || value === "never" ? value : void 0;
157
+ return value === "on-request" || value === "never" ? value : void 0;
123
158
  }
124
159
  function resolveSandbox(value) {
125
160
  return value === "read-only" || value === "workspace-write" || value === "danger-full-access" ? value : void 0;
@@ -265,6 +300,229 @@ function readExecMode(value) {
265
300
  return value === "deny" || value === "allowlist" || value === "ask" || value === "auto" || value === "full" ? value : void 0;
266
301
  }
267
302
  //#endregion
303
+ //#region extensions/codex/src/app-server/session-discovery-config.ts
304
+ const codexSessionCatalogHomeSchema = z.union([z.string().trim().min(1), z.object({
305
+ path: z.string().trim().min(1),
306
+ label: z.string().trim().min(1).optional()
307
+ }).strict()]);
308
+ const codexSessionCatalogConfigSchema = z.object({
309
+ enabled: z.boolean().optional(),
310
+ homes: z.array(codexSessionCatalogHomeSchema).optional()
311
+ }).strict();
312
+ const codexDiscoveryConfigSchema = z.object({
313
+ enabled: z.boolean().optional(),
314
+ timeoutMs: z.number().positive().optional()
315
+ }).strict();
316
+ //#endregion
317
+ //#region extensions/codex/src/app-server/config-parsing.ts
318
+ const DEFAULT_CODEX_COMPUTER_USE_PLUGIN_NAME = "computer-use";
319
+ const DEFAULT_CODEX_COMPUTER_USE_MARKETPLACE_DISCOVERY_TIMEOUT_MS = 6e4;
320
+ const DEFAULT_CODEX_COMPUTER_USE_LIVE_TEST_TIMEOUT_MS = 6e4;
321
+ const DEFAULT_CODEX_COMPUTER_USE_TOOL_CALL_TIMEOUT_MS = 6e4;
322
+ const DEFAULT_CODEX_APP_SERVER_NETWORK_PROXY_PROFILE_PREFIX = "openclaw-network";
323
+ const codexAppServerTransportSchema = z.enum([
324
+ "stdio",
325
+ "websocket",
326
+ "unix"
327
+ ]);
328
+ const codexAppServerHomeScopeSchema = z.enum(["agent", "user"]);
329
+ const SecretInputSchema = buildSecretInputSchema();
330
+ const codexAppServerPolicyModeSchema = z.enum(["yolo", "guardian"]);
331
+ const codexAppServerApprovalPolicySchema = z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum(["never", "on-request"]));
332
+ const codexAppServerSandboxSchema = z.enum([
333
+ "read-only",
334
+ "workspace-write",
335
+ "danger-full-access"
336
+ ]);
337
+ const codexAppServerApprovalsReviewerSchema = z.enum([
338
+ "user",
339
+ "auto_review",
340
+ "guardian_subagent"
341
+ ]);
342
+ const codexDynamicToolsLoadingSchema = z.enum(["searchable", "direct"]);
343
+ const codexComputerUseHealthIntervalSchema = z.union([
344
+ z.literal(30),
345
+ z.literal(60),
346
+ z.literal(120),
347
+ z.literal(240)
348
+ ]);
349
+ const codexComputerUsePluginCacheModeSchema = z.enum(["shared", "independent"]);
350
+ const codexPluginDestructivePolicySchema = z.union([
351
+ z.boolean(),
352
+ z.literal("auto"),
353
+ z.literal("ask")
354
+ ]);
355
+ const codexAppServerServiceTierSchema = z.preprocess((value) => value === null ? null : normalizeCodexServiceTier(value), z.string().trim().min(1).nullable().optional()).optional();
356
+ const codexAppServerExperimentalSchema = z.object({ sandboxExecServer: z.boolean().optional() }).strict();
357
+ const codexAppServerRemoteWorkspaceRootSchema = z.string().trim().min(1);
358
+ const codexAppServerNetworkProxyDomainPermissionSchema = z.enum(["allow", "deny"]);
359
+ const codexAppServerNetworkProxyUnixSocketPermissionSchema = z.enum(["allow", "none"]);
360
+ const codexAppServerNetworkProxySchema = z.object({
361
+ enabled: z.boolean().optional(),
362
+ profileName: z.string().trim().min(1).optional(),
363
+ baseProfile: z.enum(["read-only", "workspace"]).optional(),
364
+ mode: z.enum(["limited", "full"]).optional(),
365
+ domains: z.record(z.string(), codexAppServerNetworkProxyDomainPermissionSchema).optional(),
366
+ unixSockets: z.record(z.string(), codexAppServerNetworkProxyUnixSocketPermissionSchema).optional(),
367
+ proxyUrl: z.string().trim().min(1).optional(),
368
+ socksUrl: z.string().trim().min(1).optional(),
369
+ enableSocks5: z.boolean().optional(),
370
+ enableSocks5Udp: z.boolean().optional(),
371
+ allowUpstreamProxy: z.boolean().optional(),
372
+ allowLocalBinding: z.boolean().optional(),
373
+ dangerouslyAllowNonLoopbackProxy: z.boolean().optional(),
374
+ dangerouslyAllowAllUnixSockets: z.boolean().optional()
375
+ }).strict();
376
+ const codexPluginEntryConfigSchema = z.object({
377
+ enabled: z.boolean().optional(),
378
+ marketplaceName: z.string().regex(CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN).optional(),
379
+ pluginName: z.string().trim().min(1).optional(),
380
+ allow_destructive_actions: codexPluginDestructivePolicySchema.optional()
381
+ }).strict();
382
+ const codexPluginsConfigSchema = z.object({
383
+ enabled: z.boolean().optional(),
384
+ allow_all_plugins: z.boolean().optional(),
385
+ allow_destructive_actions: codexPluginDestructivePolicySchema.optional(),
386
+ plugins: z.record(z.string(), codexPluginEntryConfigSchema).optional()
387
+ }).strict();
388
+ const codexSupervisionEndpointSchema = z.union([z.object({
389
+ id: z.string().optional(),
390
+ label: z.string().optional(),
391
+ transport: z.literal("stdio-proxy").optional(),
392
+ command: z.string().optional(),
393
+ args: z.array(z.string()).optional(),
394
+ cwd: z.string().optional()
395
+ }).strict(), z.object({
396
+ id: z.string().optional(),
397
+ label: z.string().optional(),
398
+ transport: z.literal("websocket"),
399
+ url: z.string(),
400
+ authTokenEnv: z.string().optional()
401
+ }).strict()]);
402
+ const codexSupervisionConfigSchema = z.object({
403
+ enabled: z.boolean().optional(),
404
+ endpoints: z.array(codexSupervisionEndpointSchema).optional(),
405
+ allowRawTranscripts: z.boolean().optional(),
406
+ allowWriteControls: z.boolean().optional()
407
+ }).strict();
408
+ const codexPluginConfigSchema = z.object({
409
+ codexDynamicToolsLoading: codexDynamicToolsLoadingSchema.optional(),
410
+ codexDynamicToolsExclude: z.array(z.string()).optional(),
411
+ sessionCatalog: codexSessionCatalogConfigSchema.optional(),
412
+ discovery: codexDiscoveryConfigSchema.optional(),
413
+ computerUse: z.object({
414
+ enabled: z.boolean().optional(),
415
+ autoInstall: z.boolean().optional(),
416
+ marketplaceDiscoveryTimeoutMs: z.number().positive().optional(),
417
+ liveTestTimeoutMs: z.number().positive().optional(),
418
+ toolCallTimeoutMs: z.number().positive().optional(),
419
+ healthCheckEnabled: z.boolean().optional(),
420
+ healthCheckIntervalMinutes: codexComputerUseHealthIntervalSchema.optional(),
421
+ pluginCacheMode: codexComputerUsePluginCacheModeSchema.optional(),
422
+ strictReadiness: z.boolean().optional(),
423
+ autoRepair: z.boolean().optional(),
424
+ marketplaceSource: z.string().optional(),
425
+ marketplacePath: z.string().optional(),
426
+ marketplaceName: z.string().optional(),
427
+ pluginName: z.string().optional(),
428
+ mcpServerName: z.string().optional()
429
+ }).strict().optional(),
430
+ codexPlugins: z.unknown().optional(),
431
+ supervision: codexSupervisionConfigSchema.optional(),
432
+ appServer: z.object({
433
+ mode: codexAppServerPolicyModeSchema.optional(),
434
+ transport: codexAppServerTransportSchema.optional(),
435
+ homeScope: codexAppServerHomeScopeSchema.optional(),
436
+ command: z.string().optional(),
437
+ args: z.union([z.array(z.string()), z.string()]).optional(),
438
+ url: z.string().optional(),
439
+ authToken: SecretInputSchema.optional(),
440
+ headers: z.record(z.string(), SecretInputSchema).optional(),
441
+ clearEnv: z.array(z.string()).optional(),
442
+ remoteWorkspaceRoot: codexAppServerRemoteWorkspaceRootSchema.optional(),
443
+ codeModeOnly: z.boolean().optional(),
444
+ loopDetectionPreToolUseRelay: z.boolean().optional(),
445
+ requestTimeoutMs: z.number().positive().optional(),
446
+ turnCompletionIdleTimeoutMs: z.number().positive().optional(),
447
+ turnAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
448
+ postToolRawAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
449
+ approvalPolicy: codexAppServerApprovalPolicySchema.optional(),
450
+ sandbox: codexAppServerSandboxSchema.optional(),
451
+ approvalsReviewer: codexAppServerApprovalsReviewerSchema.optional(),
452
+ serviceTier: codexAppServerServiceTierSchema,
453
+ networkProxy: codexAppServerNetworkProxySchema.optional(),
454
+ defaultWorkspaceDir: z.string().optional(),
455
+ experimental: codexAppServerExperimentalSchema.optional()
456
+ }).strict().optional()
457
+ }).strict();
458
+ function readCodexPluginConfig(value) {
459
+ if (asNullableRecord(asNullableRecord(value)?.appServer)?.approvalPolicy === "untrusted") throw new Error("plugins.entries.codex.config.appServer.approvalPolicy=\"untrusted\" is retired; run \"openclaw doctor --fix\" to migrate it to \"on-request\".");
460
+ const parsed = codexPluginConfigSchema.safeParse(value);
461
+ if (!parsed.success) return {};
462
+ const { codexPlugins: rawCodexPlugins, ...config } = parsed.data;
463
+ const plugins = codexPluginsConfigSchema.safeParse(rawCodexPlugins);
464
+ if (!plugins.success) return config;
465
+ return {
466
+ ...config,
467
+ ...plugins.data ? { codexPlugins: plugins.data } : {}
468
+ };
469
+ }
470
+ function isCodexSandboxExecServerEnabled(pluginConfig, sandbox) {
471
+ return isCodexRemoteExecPlacementSandbox(sandbox) || readCodexPluginConfig(pluginConfig).appServer?.experimental?.sandboxExecServer === true;
472
+ }
473
+ function isCodexRemoteExecPlacementSandbox(sandbox) {
474
+ return typeof sandbox === "object" && sandbox !== null && "placementExecutionMode" in sandbox && sandbox.placementExecutionMode === "remote-exec";
475
+ }
476
+ function isCodexPairedNodeRemoteExecPlacementSandbox(sandbox) {
477
+ return isCodexRemoteExecPlacementSandbox(sandbox) && typeof sandbox === "object" && sandbox !== null && "placementNodeId" in sandbox && typeof sandbox.placementNodeId === "string" && sandbox.placementNodeId.length > 0;
478
+ }
479
+ function assertCodexAppServerCommandHasNoInlineArgs(params) {
480
+ const inlineArgs = detectWindowsSpawnCommandInlineArgs(params.command);
481
+ if (!inlineArgs) return;
482
+ const sourceLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_BIN" : "plugins.entries.codex.config.appServer.command";
483
+ const argsLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_ARGS" : "plugins.entries.codex.config.appServer.args";
484
+ throw new Error(`${sourceLabel} must be only the Codex app-server executable path; "${inlineArgs.executable}" was configured with inline arguments "${inlineArgs.arguments}". Move those arguments to ${argsLabel}, or remove the override to use the managed Codex startup path.`);
485
+ }
486
+ function resolveCodexPluginsPolicy(pluginConfig) {
487
+ const config = readCodexPluginConfig(pluginConfig).codexPlugins;
488
+ const configured = config !== void 0;
489
+ const enabled = config?.enabled === true;
490
+ const destructivePolicy = resolveCodexPluginDestructivePolicy(config?.allow_destructive_actions ?? true);
491
+ const pluginPolicies = Object.entries(config?.plugins ?? {}).flatMap(([configKey, entry]) => {
492
+ if (!isCodexPluginMarketplaceName(entry.marketplaceName) || !entry.pluginName) return [];
493
+ const entryDestructivePolicy = resolveCodexPluginDestructivePolicy(entry.allow_destructive_actions ?? config?.allow_destructive_actions ?? true);
494
+ return [{
495
+ configKey,
496
+ marketplaceName: entry.marketplaceName,
497
+ pluginName: entry.pluginName,
498
+ enabled: enabled && entry.enabled !== false,
499
+ allowDestructiveActions: entryDestructivePolicy.allowDestructiveActions,
500
+ destructiveApprovalMode: entryDestructivePolicy.destructiveApprovalMode
501
+ }];
502
+ }).toSorted((left, right) => left.configKey.localeCompare(right.configKey));
503
+ return {
504
+ configured,
505
+ enabled,
506
+ allowAllPlugins: enabled && config?.allow_all_plugins === true,
507
+ allowDestructiveActions: destructivePolicy.allowDestructiveActions,
508
+ destructiveApprovalMode: destructivePolicy.destructiveApprovalMode,
509
+ pluginPolicies
510
+ };
511
+ }
512
+ function isCodexPluginMarketplaceName(value) {
513
+ return typeof value === "string" && CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN.test(value);
514
+ }
515
+ function resolveCodexPluginDestructivePolicy(policy) {
516
+ if (policy === "auto" || policy === "ask") return {
517
+ allowDestructiveActions: true,
518
+ destructiveApprovalMode: policy
519
+ };
520
+ return {
521
+ allowDestructiveActions: policy,
522
+ destructiveApprovalMode: policy ? "allow" : "deny"
523
+ };
524
+ }
525
+ //#endregion
268
526
  //#region extensions/codex/src/app-server/config-requirements.ts
269
527
  const UNIX_CODEX_REQUIREMENTS_PATH = "/etc/codex/requirements.toml";
270
528
  const WINDOWS_CODEX_REQUIREMENTS_SUFFIX = "\\OpenAI\\Codex\\requirements.toml";
@@ -434,6 +692,7 @@ function globPatternMatches(value, pattern) {
434
692
  function normalizeRequirementsApprovalPolicy(value) {
435
693
  const normalized = value.trim().toLowerCase();
436
694
  if (normalized === "on-failure") return "on-request";
695
+ if (normalized === "untrusted") return normalized;
437
696
  return resolveApprovalPolicy(normalized);
438
697
  }
439
698
  function normalizeRequirementsApprovalsReviewer(value) {
@@ -441,8 +700,8 @@ function normalizeRequirementsApprovalsReviewer(value) {
441
700
  }
442
701
  function selectGuardianApprovalPolicy(allowedApprovalPolicies, execModeRequiringPromptingApprovals) {
443
702
  if (allowedApprovalPolicies === void 0 || allowedApprovalPolicies.has("on-request")) return "on-request";
444
- if (execModeRequiringPromptingApprovals) throw new Error(`tools.exec.mode=${execModeRequiringPromptingApprovals} requires Codex app-server prompting approvals`);
445
703
  if (allowedApprovalPolicies.has("untrusted")) return "untrusted";
704
+ if (execModeRequiringPromptingApprovals) throw new Error(`tools.exec.mode=${execModeRequiringPromptingApprovals} requires Codex app-server prompting approvals`);
446
705
  if (allowedApprovalPolicies.has("never")) return "never";
447
706
  return "on-request";
448
707
  }
@@ -459,14 +718,30 @@ function selectUserApprovalsReviewer(allowedApprovalsReviewers, execModeRequirin
459
718
  }
460
719
  //#endregion
461
720
  //#region extensions/codex/src/app-server/config-reviewer.ts
462
- const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
463
721
  const CODEX_CONFIG_TOML_FILENAME = "config.toml";
722
+ /** Cloud/system config can redirect reviews after local home/profile checks have passed. */
723
+ async function assertCodexModelBackedReviewerEffectiveConfig(params) {
724
+ if (params.approvalsReviewer !== "auto_review" && params.approvalsReviewer !== "guardian_subagent") return;
725
+ const effectiveConfig = readRecord(readRecord(await params.client.request("config/read", {
726
+ cwd: path.resolve(params.cwd),
727
+ includeLayers: false
728
+ }, { signal: params.signal }))?.config);
729
+ if (!effectiveConfig) throw new Error("Codex config/read returned an invalid model-backed reviewer config");
730
+ const modelProvider = effectiveConfig.model_provider;
731
+ const providers = effectiveConfig.model_providers;
732
+ const providerRecords = providers == null ? void 0 : readRecord(providers);
733
+ const provider = providerRecords?.openai;
734
+ const openAIProvider = provider == null ? void 0 : readRecord(provider);
735
+ if (modelProvider != null && modelProvider !== "openai" || providers != null && !providerRecords || provider != null && !openAIProvider || !isTrustedOptionalReviewerEndpoint(effectiveConfig.openai_base_url, isNativeOpenAIBaseUrl) || !isTrustedOptionalReviewerEndpoint(effectiveConfig.chatgpt_base_url, isNativeChatGPTBaseUrl) || !isTrustedOptionalReviewerEndpoint(openAIProvider?.base_url, isNativeOpenAIBaseUrl)) throw new Error("Codex model-backed approval reviewer requires the running server to use a trusted OpenAI endpoint");
736
+ }
737
+ function isTrustedOptionalReviewerEndpoint(value, isTrusted) {
738
+ return value == null || typeof value === "string" && isTrusted(value);
739
+ }
464
740
  function canUseCodexModelBackedApprovalsReviewerForModel(params) {
465
741
  const explicitProvider = params.modelProvider?.trim().toLowerCase();
466
742
  const inferredProvider = inferProviderFromModelRef(params.model);
467
- if (explicitProvider && explicitProvider !== "codex") return isTrustedCodexModelBackedApprovalsReviewerProvider(explicitProvider, params) && (inferredProvider === void 0 || isTrustedCodexModelBackedApprovalsReviewerProvider(inferredProvider, params));
468
- if (inferredProvider !== void 0) return isTrustedCodexModelBackedApprovalsReviewerProvider(inferredProvider, params);
469
- return isTrustedCodexModelBackedApprovalsReviewerProvider(explicitProvider, params);
743
+ if (explicitProvider && explicitProvider !== "codex" && explicitProvider !== "openai") return false;
744
+ return (inferredProvider ?? explicitProvider) === "openai" && isTrustedCodexModelBackedOpenAIProvider(params);
470
745
  }
471
746
  function isTrustedCodexModelBackedOpenAIProvider(params) {
472
747
  if (!openAIBaseUrlEnvOverridesAreTrustedForModelBackedReview(params.env)) return false;
@@ -503,43 +778,50 @@ function resolveCodexModelBackedReviewerPolicyContext(params) {
503
778
  model: params.model ?? params.bindingModel
504
779
  };
505
780
  }
506
- function isCodexModelBackedApprovalsReviewerProvider(provider) {
507
- return provider?.trim().toLowerCase() === "openai";
508
- }
509
- function isTrustedCodexModelBackedApprovalsReviewerProvider(provider, params) {
510
- return isCodexModelBackedApprovalsReviewerProvider(provider) && isTrustedCodexModelBackedOpenAIProvider({
511
- config: params.config,
512
- env: params.env,
513
- model: params.model,
514
- agentDir: params.agentDir,
515
- codexConfigToml: params.codexConfigToml,
516
- homeScope: params.homeScope
517
- });
518
- }
519
781
  function readCodexBaseUrlOverridesForModelBackedReview(params) {
520
782
  const configToml = readCodexAppServerConfigToml(params);
521
783
  if (configToml === false) return false;
522
- if (configToml === void 0) return {
523
- openAI: [],
524
- chatGPT: []
525
- };
526
- const topLevelContent = stripTomlLineComments(configToml).slice(0, firstTomlTableOffset(configToml));
527
- const modelProviderOpenAISection = parseTomlTableSection(configToml, "model_providers.openai");
528
- const openAIBaseUrl = parseTomlStringValue(topLevelContent, "openai_base_url");
529
- const chatGPTBaseUrl = parseTomlStringValue(topLevelContent, "chatgpt_base_url");
530
- const openAI = [
531
- openAIBaseUrl,
532
- parseTomlStringValue(topLevelContent, "model_providers.openai.base_url"),
533
- parseInlineOpenAIModelProviderBaseUrl(topLevelContent),
534
- modelProviderOpenAISection ? parseTomlStringValue(modelProviderOpenAISection, "base_url") : void 0
535
- ];
536
- const chatGPT = [chatGPTBaseUrl];
784
+ const configTomls = configToml === void 0 ? [] : [configToml];
785
+ const nativeOverrides = readNativeCodexReviewerConfigOverrides(params);
786
+ if (nativeOverrides === false) return false;
787
+ configTomls.push(...nativeOverrides);
788
+ const openAI = [];
789
+ const chatGPT = [];
790
+ for (const content of configTomls) {
791
+ const topLevelContent = stripTomlLineComments(content).slice(0, firstTomlTableOffset(content));
792
+ const modelProviderOpenAISection = parseTomlTableSection(content, "model_providers.openai");
793
+ const modelProvider = parseTomlStringValue(topLevelContent, "model_provider");
794
+ if (modelProvider === false || modelProvider && modelProvider !== "openai") return false;
795
+ openAI.push(parseTomlStringValue(topLevelContent, "openai_base_url"), parseTomlStringValue(topLevelContent, "model_providers.openai.base_url"), parseInlineOpenAIModelProviderBaseUrl(topLevelContent), modelProviderOpenAISection ? parseTomlStringValue(modelProviderOpenAISection, "base_url") : void 0);
796
+ chatGPT.push(parseTomlStringValue(topLevelContent, "chatgpt_base_url"));
797
+ }
537
798
  if ([...openAI, ...chatGPT].includes(false)) return false;
538
799
  return {
539
800
  openAI: openAI.filter((entry) => typeof entry === "string"),
540
801
  chatGPT: chatGPT.filter((entry) => typeof entry === "string")
541
802
  };
542
803
  }
804
+ function readNativeCodexReviewerConfigOverrides(params) {
805
+ if (params.codexArgs?.some((arg) => !arg)) return false;
806
+ const overrides = [];
807
+ let profile;
808
+ for (const { name, value } of readCodexAppServerConfigOptions(params.codexArgs ?? [])) {
809
+ if (!value) return false;
810
+ if (name === "--profile" || name === "-p") profile = value;
811
+ else overrides.push(`${value}\n`);
812
+ }
813
+ if (profile) {
814
+ if (path.basename(profile) !== profile || profile === "." || profile === "..") return false;
815
+ const configPath = resolveCodexAppServerConfigPath(params);
816
+ if (!configPath) return false;
817
+ try {
818
+ overrides.unshift(readFileSync(path.join(path.dirname(configPath), `${profile}.config.toml`), "utf8"));
819
+ } catch (error) {
820
+ if (readErrorCode(error) !== "ENOENT") return false;
821
+ }
822
+ }
823
+ return overrides;
824
+ }
543
825
  function readCodexAppServerConfigToml(params) {
544
826
  if (params.codexConfigToml !== void 0) return params.codexConfigToml ?? void 0;
545
827
  const configPath = resolveCodexAppServerConfigPath(params);
@@ -576,13 +858,7 @@ function codexConfigEnablesNativeComputerUse(params) {
576
858
  function resolveCodexAppServerConfigPath(params) {
577
859
  if (params.homeScope === "user") return path.join(resolveCodexAppServerUserHomeDir(params.env), CODEX_CONFIG_TOML_FILENAME);
578
860
  const agentDir = readNonEmptyString(params.agentDir);
579
- const codexHome = agentDir ? path.join(path.resolve(agentDir), CODEX_APP_SERVER_HOME_DIRNAME) : void 0;
580
- return codexHome ? path.join(codexHome, CODEX_CONFIG_TOML_FILENAME) : void 0;
581
- }
582
- /** Resolves the native user Codex home used by Desktop and the CLI. */
583
- function resolveCodexAppServerUserHomeDir(env = process.env, homedir$1 = homedir) {
584
- const configured = readNonEmptyString(env.CODEX_HOME);
585
- return path.resolve(configured ?? path.join(homedir$1(), ".codex"));
861
+ return agentDir ? path.join(resolveCodexAppServerHomeDir(agentDir), CODEX_CONFIG_TOML_FILENAME) : void 0;
586
862
  }
587
863
  function readErrorCode(error) {
588
864
  return error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
@@ -656,237 +932,6 @@ function inferProviderFromModelRef(model) {
656
932
  return slashIndex > 0 ? normalized?.slice(0, slashIndex) : void 0;
657
933
  }
658
934
  //#endregion
659
- //#region extensions/codex/src/app-server/config-contracts.ts
660
- const CODEX_PLUGINS_MARKETPLACE_NAME = "openai-curated";
661
- const CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME = "workspace-directory";
662
- const CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN = /^[A-Za-z0-9_-]+$/;
663
- //#endregion
664
- //#region extensions/codex/src/app-server/session-discovery-config.ts
665
- const codexSessionCatalogHomeSchema = z.union([z.string().trim().min(1), z.object({
666
- path: z.string().trim().min(1),
667
- label: z.string().trim().min(1).optional()
668
- }).strict()]);
669
- const codexSessionCatalogConfigSchema = z.object({
670
- enabled: z.boolean().optional(),
671
- homes: z.array(codexSessionCatalogHomeSchema).optional()
672
- }).strict();
673
- const codexDiscoveryConfigSchema = z.object({
674
- enabled: z.boolean().optional(),
675
- timeoutMs: z.number().positive().optional()
676
- }).strict();
677
- //#endregion
678
- //#region extensions/codex/src/app-server/config-parsing.ts
679
- const DEFAULT_CODEX_COMPUTER_USE_PLUGIN_NAME = "computer-use";
680
- const DEFAULT_CODEX_COMPUTER_USE_MARKETPLACE_DISCOVERY_TIMEOUT_MS = 6e4;
681
- const DEFAULT_CODEX_COMPUTER_USE_LIVE_TEST_TIMEOUT_MS = 6e4;
682
- const DEFAULT_CODEX_COMPUTER_USE_TOOL_CALL_TIMEOUT_MS = 6e4;
683
- const DEFAULT_CODEX_APP_SERVER_NETWORK_PROXY_PROFILE_PREFIX = "openclaw-network";
684
- const codexAppServerTransportSchema = z.enum([
685
- "stdio",
686
- "websocket",
687
- "unix"
688
- ]);
689
- const codexAppServerHomeScopeSchema = z.enum(["agent", "user"]);
690
- const SecretInputSchema = buildSecretInputSchema();
691
- const codexAppServerPolicyModeSchema = z.enum(["yolo", "guardian"]);
692
- const codexAppServerApprovalPolicySchema = z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum([
693
- "never",
694
- "on-request",
695
- "untrusted"
696
- ]));
697
- const codexAppServerSandboxSchema = z.enum([
698
- "read-only",
699
- "workspace-write",
700
- "danger-full-access"
701
- ]);
702
- const codexAppServerApprovalsReviewerSchema = z.enum([
703
- "user",
704
- "auto_review",
705
- "guardian_subagent"
706
- ]);
707
- const codexDynamicToolsLoadingSchema = z.enum(["searchable", "direct"]);
708
- const codexComputerUseHealthIntervalSchema = z.union([
709
- z.literal(30),
710
- z.literal(60),
711
- z.literal(120),
712
- z.literal(240)
713
- ]);
714
- const codexComputerUsePluginCacheModeSchema = z.enum(["shared", "independent"]);
715
- const codexPluginDestructivePolicySchema = z.union([
716
- z.boolean(),
717
- z.literal("auto"),
718
- z.literal("ask")
719
- ]);
720
- const codexAppServerServiceTierSchema = z.preprocess((value) => value === null ? null : normalizeCodexServiceTier(value), z.string().trim().min(1).nullable().optional()).optional();
721
- const codexAppServerExperimentalSchema = z.object({ sandboxExecServer: z.boolean().optional() }).strict();
722
- const codexAppServerRemoteWorkspaceRootSchema = z.string().trim().min(1);
723
- const codexAppServerNetworkProxyDomainPermissionSchema = z.enum(["allow", "deny"]);
724
- const codexAppServerNetworkProxyUnixSocketPermissionSchema = z.enum(["allow", "none"]);
725
- const codexAppServerNetworkProxySchema = z.object({
726
- enabled: z.boolean().optional(),
727
- profileName: z.string().trim().min(1).optional(),
728
- baseProfile: z.enum(["read-only", "workspace"]).optional(),
729
- mode: z.enum(["limited", "full"]).optional(),
730
- domains: z.record(z.string(), codexAppServerNetworkProxyDomainPermissionSchema).optional(),
731
- unixSockets: z.record(z.string(), codexAppServerNetworkProxyUnixSocketPermissionSchema).optional(),
732
- proxyUrl: z.string().trim().min(1).optional(),
733
- socksUrl: z.string().trim().min(1).optional(),
734
- enableSocks5: z.boolean().optional(),
735
- enableSocks5Udp: z.boolean().optional(),
736
- allowUpstreamProxy: z.boolean().optional(),
737
- allowLocalBinding: z.boolean().optional(),
738
- dangerouslyAllowNonLoopbackProxy: z.boolean().optional(),
739
- dangerouslyAllowAllUnixSockets: z.boolean().optional()
740
- }).strict();
741
- const codexPluginEntryConfigSchema = z.object({
742
- enabled: z.boolean().optional(),
743
- marketplaceName: z.string().regex(CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN).optional(),
744
- pluginName: z.string().trim().min(1).optional(),
745
- allow_destructive_actions: codexPluginDestructivePolicySchema.optional()
746
- }).strict();
747
- const codexPluginsConfigSchema = z.object({
748
- enabled: z.boolean().optional(),
749
- allow_all_plugins: z.boolean().optional(),
750
- allow_destructive_actions: codexPluginDestructivePolicySchema.optional(),
751
- plugins: z.record(z.string(), codexPluginEntryConfigSchema).optional()
752
- }).strict();
753
- const codexSupervisionEndpointSchema = z.union([z.object({
754
- id: z.string().optional(),
755
- label: z.string().optional(),
756
- transport: z.literal("stdio-proxy").optional(),
757
- command: z.string().optional(),
758
- args: z.array(z.string()).optional(),
759
- cwd: z.string().optional()
760
- }).strict(), z.object({
761
- id: z.string().optional(),
762
- label: z.string().optional(),
763
- transport: z.literal("websocket"),
764
- url: z.string(),
765
- authTokenEnv: z.string().optional()
766
- }).strict()]);
767
- const codexSupervisionConfigSchema = z.object({
768
- enabled: z.boolean().optional(),
769
- endpoints: z.array(codexSupervisionEndpointSchema).optional(),
770
- allowRawTranscripts: z.boolean().optional(),
771
- allowWriteControls: z.boolean().optional()
772
- }).strict();
773
- const codexPluginConfigSchema = z.object({
774
- codexDynamicToolsLoading: codexDynamicToolsLoadingSchema.optional(),
775
- codexDynamicToolsExclude: z.array(z.string()).optional(),
776
- sessionCatalog: codexSessionCatalogConfigSchema.optional(),
777
- discovery: codexDiscoveryConfigSchema.optional(),
778
- computerUse: z.object({
779
- enabled: z.boolean().optional(),
780
- autoInstall: z.boolean().optional(),
781
- marketplaceDiscoveryTimeoutMs: z.number().positive().optional(),
782
- liveTestTimeoutMs: z.number().positive().optional(),
783
- toolCallTimeoutMs: z.number().positive().optional(),
784
- healthCheckEnabled: z.boolean().optional(),
785
- healthCheckIntervalMinutes: codexComputerUseHealthIntervalSchema.optional(),
786
- pluginCacheMode: codexComputerUsePluginCacheModeSchema.optional(),
787
- strictReadiness: z.boolean().optional(),
788
- autoRepair: z.boolean().optional(),
789
- marketplaceSource: z.string().optional(),
790
- marketplacePath: z.string().optional(),
791
- marketplaceName: z.string().optional(),
792
- pluginName: z.string().optional(),
793
- mcpServerName: z.string().optional()
794
- }).strict().optional(),
795
- codexPlugins: z.unknown().optional(),
796
- supervision: codexSupervisionConfigSchema.optional(),
797
- appServer: z.object({
798
- mode: codexAppServerPolicyModeSchema.optional(),
799
- transport: codexAppServerTransportSchema.optional(),
800
- homeScope: codexAppServerHomeScopeSchema.optional(),
801
- command: z.string().optional(),
802
- args: z.union([z.array(z.string()), z.string()]).optional(),
803
- url: z.string().optional(),
804
- authToken: SecretInputSchema.optional(),
805
- headers: z.record(z.string(), SecretInputSchema).optional(),
806
- clearEnv: z.array(z.string()).optional(),
807
- remoteWorkspaceRoot: codexAppServerRemoteWorkspaceRootSchema.optional(),
808
- codeModeOnly: z.boolean().optional(),
809
- loopDetectionPreToolUseRelay: z.boolean().optional(),
810
- requestTimeoutMs: z.number().positive().optional(),
811
- turnCompletionIdleTimeoutMs: z.number().positive().optional(),
812
- turnAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
813
- postToolRawAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
814
- approvalPolicy: codexAppServerApprovalPolicySchema.optional(),
815
- sandbox: codexAppServerSandboxSchema.optional(),
816
- approvalsReviewer: codexAppServerApprovalsReviewerSchema.optional(),
817
- serviceTier: codexAppServerServiceTierSchema,
818
- networkProxy: codexAppServerNetworkProxySchema.optional(),
819
- defaultWorkspaceDir: z.string().optional(),
820
- experimental: codexAppServerExperimentalSchema.optional()
821
- }).strict().optional()
822
- }).strict();
823
- function readCodexPluginConfig(value) {
824
- const parsed = codexPluginConfigSchema.safeParse(value);
825
- if (!parsed.success) return {};
826
- const { codexPlugins: rawCodexPlugins, ...config } = parsed.data;
827
- const plugins = codexPluginsConfigSchema.safeParse(rawCodexPlugins);
828
- if (!plugins.success) return config;
829
- return {
830
- ...config,
831
- ...plugins.data ? { codexPlugins: plugins.data } : {}
832
- };
833
- }
834
- function isCodexSandboxExecServerEnabled(pluginConfig, sandbox) {
835
- return isCodexRemoteExecPlacementSandbox(sandbox) || readCodexPluginConfig(pluginConfig).appServer?.experimental?.sandboxExecServer === true;
836
- }
837
- function isCodexRemoteExecPlacementSandbox(sandbox) {
838
- return typeof sandbox === "object" && sandbox !== null && "placementExecutionMode" in sandbox && sandbox.placementExecutionMode === "remote-exec";
839
- }
840
- function isCodexPairedNodeRemoteExecPlacementSandbox(sandbox) {
841
- return isCodexRemoteExecPlacementSandbox(sandbox) && typeof sandbox === "object" && sandbox !== null && "placementNodeId" in sandbox && typeof sandbox.placementNodeId === "string" && sandbox.placementNodeId.length > 0;
842
- }
843
- function assertCodexAppServerCommandHasNoInlineArgs(params) {
844
- const inlineArgs = detectWindowsSpawnCommandInlineArgs(params.command);
845
- if (!inlineArgs) return;
846
- const sourceLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_BIN" : "plugins.entries.codex.config.appServer.command";
847
- const argsLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_ARGS" : "plugins.entries.codex.config.appServer.args";
848
- throw new Error(`${sourceLabel} must be only the Codex app-server executable path; "${inlineArgs.executable}" was configured with inline arguments "${inlineArgs.arguments}". Move those arguments to ${argsLabel}, or remove the override to use the managed Codex startup path.`);
849
- }
850
- function resolveCodexPluginsPolicy(pluginConfig) {
851
- const config = readCodexPluginConfig(pluginConfig).codexPlugins;
852
- const configured = config !== void 0;
853
- const enabled = config?.enabled === true;
854
- const destructivePolicy = resolveCodexPluginDestructivePolicy(config?.allow_destructive_actions ?? true);
855
- const pluginPolicies = Object.entries(config?.plugins ?? {}).flatMap(([configKey, entry]) => {
856
- if (!isCodexPluginMarketplaceName(entry.marketplaceName) || !entry.pluginName) return [];
857
- const entryDestructivePolicy = resolveCodexPluginDestructivePolicy(entry.allow_destructive_actions ?? config?.allow_destructive_actions ?? true);
858
- return [{
859
- configKey,
860
- marketplaceName: entry.marketplaceName,
861
- pluginName: entry.pluginName,
862
- enabled: enabled && entry.enabled !== false,
863
- allowDestructiveActions: entryDestructivePolicy.allowDestructiveActions,
864
- destructiveApprovalMode: entryDestructivePolicy.destructiveApprovalMode
865
- }];
866
- }).toSorted((left, right) => left.configKey.localeCompare(right.configKey));
867
- return {
868
- configured,
869
- enabled,
870
- allowAllPlugins: enabled && config?.allow_all_plugins === true,
871
- allowDestructiveActions: destructivePolicy.allowDestructiveActions,
872
- destructiveApprovalMode: destructivePolicy.destructiveApprovalMode,
873
- pluginPolicies
874
- };
875
- }
876
- function isCodexPluginMarketplaceName(value) {
877
- return typeof value === "string" && CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN.test(value);
878
- }
879
- function resolveCodexPluginDestructivePolicy(policy) {
880
- if (policy === "auto" || policy === "ask") return {
881
- allowDestructiveActions: true,
882
- destructiveApprovalMode: policy
883
- };
884
- return {
885
- allowDestructiveActions: policy,
886
- destructiveApprovalMode: policy ? "allow" : "deny"
887
- };
888
- }
889
- //#endregion
890
935
  //#region extensions/codex/src/app-server/config-security.ts
891
936
  function shouldAutoApproveCodexAppServerApprovals(appServer) {
892
937
  return appServer.networkProxy === void 0 && appServer.approvalPolicy === "never" && appServer.sandbox === "danger-full-access";
@@ -951,6 +996,7 @@ function stableStringifyJson(value) {
951
996
  return JSON.stringify(value);
952
997
  }
953
998
  function withMcpElicitationsApprovalPolicy(policy) {
999
+ if (policy === "untrusted") return policy;
954
1000
  if (typeof policy !== "string") return { granular: {
955
1001
  ...policy.granular,
956
1002
  mcp_elicitations: true
@@ -1034,7 +1080,7 @@ function resolveDefaultCodexAppServerPolicy(params) {
1034
1080
  const allowedApprovalPolicies = parseAllowedApprovalPoliciesFromCodexRequirements(content);
1035
1081
  const allowedApprovalsReviewers = parseAllowedApprovalsReviewersFromCodexRequirements(content);
1036
1082
  const yoloSandboxAllowed = allowedSandboxModes === void 0 || allowedSandboxModes.has("danger-full-access");
1037
- const yoloApprovalAllowed = allowedApprovalPolicies === void 0 || allowedApprovalPolicies.has("never");
1083
+ const yoloApprovalAllowed = allowedApprovalPolicies === void 0 || allowedApprovalPolicies.has("never") && !allowedApprovalPolicies.has("untrusted");
1038
1084
  const yoloReviewerAllowed = allowedApprovalsReviewers === void 0 || allowedApprovalsReviewers.has("user");
1039
1085
  if (!params.forceGuardian && yoloSandboxAllowed && yoloApprovalAllowed && yoloReviewerAllowed) return {
1040
1086
  mode: "yolo",
@@ -1114,6 +1160,15 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1114
1160
  const forceGuardianReviewer = execMode === "auto" && canUseModelBackedReviewer;
1115
1161
  const execModeRequiringPromptingApprovals = execMode === "auto" || execMode === "ask" ? execMode : forceUserReviewer ? "ask" : void 0;
1116
1162
  const forceDangerFullAccessSandbox = params.execPolicy?.touched === true && params.execPolicy.security === "full" && params.execPolicy.ask === "always";
1163
+ const forcePerCommandApprovals = params.execPolicy?.ask === "always";
1164
+ const requirementsToml = forcePerCommandApprovals ? readCodexRequirementsToml({
1165
+ env,
1166
+ requirementsToml: params.requirementsToml,
1167
+ requirementsPath: params.requirementsPath,
1168
+ readRequirementsFile: params.readRequirementsFile,
1169
+ platform: params.platform
1170
+ }) ?? null : params.requirementsToml;
1171
+ if (forcePerCommandApprovals && requirementsToml && parseAllowedApprovalPoliciesFromCodexRequirements(requirementsToml)?.has("untrusted") === false) throw new Error("tools.exec.ask=always requires Codex app-server per-command approvals");
1117
1172
  const forceRuntimePolicy = forceUserReviewer || forceGuardianReviewer || forceDangerFullAccessSandbox;
1118
1173
  const defaultPolicy = explicitPolicyMode && !forceRuntimePolicy && !ignoreLegacyYoloPolicyMode ? void 0 : resolveDefaultCodexAppServerPolicy({
1119
1174
  transport,
@@ -1121,7 +1176,7 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1121
1176
  forceGuardian: normalizedPolicyMode === "guardian",
1122
1177
  forceUserReviewer: forceUserReviewer || !canUseModelBackedReviewer,
1123
1178
  execModeRequiringPromptingApprovals,
1124
- requirementsToml: params.requirementsToml,
1179
+ requirementsToml,
1125
1180
  requirementsPath: params.requirementsPath,
1126
1181
  readRequirementsFile: params.readRequirementsFile,
1127
1182
  platform: params.platform,
@@ -1130,7 +1185,7 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1130
1185
  });
1131
1186
  const preserveExplicitAutoSandbox = forceGuardianReviewer && configuredSandbox === "read-only";
1132
1187
  const forcedPolicy = forceRuntimePolicy ? {
1133
- approvalPolicy: defaultPolicy?.approvalPolicy ?? "on-request",
1188
+ approvalPolicy: forcePerCommandApprovals ? "untrusted" : defaultPolicy?.approvalPolicy ?? "on-request",
1134
1189
  sandbox: preserveExplicitAutoSandbox ? void 0 : forceDangerFullAccessSandbox ? selectForcedDangerFullAccessSandbox({
1135
1190
  configuredSandbox,
1136
1191
  defaultPolicy,
@@ -1292,17 +1347,22 @@ function codexSandboxPolicyForTurn(mode, cwd, nativeArgs = []) {
1292
1347
  };
1293
1348
  let excludeTmpdirEnvVar = false;
1294
1349
  let excludeSlashTmp = false;
1295
- for (let index = 0; index < nativeArgs.length; index += 1) {
1296
- const arg = nativeArgs[index];
1297
- const override = arg === "-c" || arg === "--config" ? nativeArgs[++index] : arg?.startsWith("--config=") ? arg.slice(9) : void 0;
1298
- if (!override) continue;
1350
+ for (const { name, value: override } of readCodexAppServerConfigOptions(nativeArgs)) {
1351
+ if (name !== "-c" && name !== "--config" || !override) continue;
1299
1352
  const separator = override.indexOf("=");
1300
1353
  if (separator < 0) continue;
1301
1354
  const key = override.slice(0, separator).trim();
1302
- const value = override.slice(separator + 1).trim();
1303
- if (value !== "true" && value !== "false") continue;
1304
- if (key === "sandbox_workspace_write.exclude_tmpdir_env_var") excludeTmpdirEnvVar = value === "true";
1305
- else if (key === "sandbox_workspace_write.exclude_slash_tmp") excludeSlashTmp = value === "true";
1355
+ const isTmpdirExclusion = key === "sandbox_workspace_write.exclude_tmpdir_env_var";
1356
+ if (!isTmpdirExclusion && key !== "sandbox_workspace_write.exclude_slash_tmp") continue;
1357
+ let value;
1358
+ try {
1359
+ value = parse(`_x_ = ${override.slice(separator + 1).trim()}`)["_x_"];
1360
+ } catch {
1361
+ continue;
1362
+ }
1363
+ if (typeof value !== "boolean") continue;
1364
+ if (isTmpdirExclusion) excludeTmpdirEnvVar = value;
1365
+ else excludeSlashTmp = value;
1306
1366
  }
1307
1367
  return {
1308
1368
  type: "workspaceWrite",
@@ -1332,4 +1392,4 @@ function resolveCodexSupervisionAppServerRuntimeOptions(params = {}) {
1332
1392
  });
1333
1393
  }
1334
1394
  //#endregion
1335
- export { resolveOpenClawExecPolicyForCodexAppServer as A, parseAllowedApprovalPoliciesFromCodexRequirements as C, selectGuardianApprovalPolicy as D, readCodexRequirementsToml as E, isCodexFastServiceTier as M, normalizeCodexServiceTier as N, selectGuardianApprovalsReviewer as O, resolveCodexModelBackedReviewerPolicyContext as S, parseAllowedSandboxModesFromCodexRequirements as T, CODEX_PLUGINS_MARKETPLACE_NAME as _, resolveCodexAppServerStartOptionsForAgent as a, canUseCodexModelBackedApprovalsReviewerForModel as b, assertCodexAppServerConnectionSecurity as c, withMcpElicitationsApprovalPolicy as d, isCodexPairedNodeRemoteExecPlacementSandbox as f, resolveCodexPluginsPolicy as g, readCodexPluginConfig as h, resolveCodexAppServerRuntimeOptions as i, selectGuardianSandbox as j, selectUserApprovalsReviewer as k, resolveCodexAppServerNetworkProxy as l, isCodexSandboxExecServerEnabled as m, codexSandboxPolicyForTurn as n, resolveCodexComputerUseConfig as o, isCodexRemoteExecPlacementSandbox as p, resolveCodexAppServerHomeScope as r, resolveCodexSupervisionAppServerRuntimeOptions as s, codexAppServerStartOptionsKey as t, shouldAutoApproveCodexAppServerApprovals as u, CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME as v, parseAllowedApprovalsReviewersFromCodexRequirements as w, resolveCodexAppServerUserHomeDir as x, CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN as y };
1395
+ export { normalizeCodexServiceTier as A, isCodexRemoteExecPlacementSandbox as C, resolveOpenClawExecPolicyForCodexAppServer as D, resolveCodexPluginsPolicy as E, resolveCodexAppServerLocalHomeDir as F, resolveCodexAppServerUserHomeDir as I, withEphemeralCodexAuthStore as L, CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME as M, CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN as N, selectGuardianSandbox as O, resolveCodexAppServerHomeDir as P, isCodexPairedNodeRemoteExecPlacementSandbox as S, readCodexPluginConfig as T, parseAllowedSandboxModesFromCodexRequirements as _, resolveCodexAppServerStartOptionsForAgent as a, selectGuardianApprovalsReviewer as b, assertCodexAppServerConnectionSecurity as c, withMcpElicitationsApprovalPolicy as d, assertCodexModelBackedReviewerEffectiveConfig as f, parseAllowedApprovalsReviewersFromCodexRequirements as g, parseAllowedApprovalPoliciesFromCodexRequirements as h, resolveCodexAppServerRuntimeOptions as i, CODEX_PLUGINS_MARKETPLACE_NAME as j, isCodexFastServiceTier as k, resolveCodexAppServerNetworkProxy as l, resolveCodexModelBackedReviewerPolicyContext as m, codexSandboxPolicyForTurn as n, resolveCodexComputerUseConfig as o, canUseCodexModelBackedApprovalsReviewerForModel as p, resolveCodexAppServerHomeScope as r, resolveCodexSupervisionAppServerRuntimeOptions as s, codexAppServerStartOptionsKey as t, shouldAutoApproveCodexAppServerApprovals as u, readCodexRequirementsToml as v, isCodexSandboxExecServerEnabled as w, selectUserApprovalsReviewer as x, selectGuardianApprovalPolicy as y };