@openclaw/codex 2026.9.1-beta.1 → 2026.9.2

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 (81) hide show
  1. package/dist/api.js +8 -9
  2. package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-Bp1ZOnk2.js} +105 -75
  3. package/dist/attempt-context-CSazkWns.js +634 -0
  4. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  5. package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-DxGJRYbY.js} +53 -57
  6. package/dist/{capabilities-BRMh0aIq.js → capabilities-B1mgvpP8.js} +2 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-DEsIufkt.js → command-formatters-DSbGMXA0.js} +5 -4
  9. package/dist/{command-handlers-D_-1_qRp.js → command-handlers-DOJvGv6-.js} +243 -148
  10. package/dist/{compact-BglNFZrQ.js → compact-Y_xBqrHN.js} +109 -65
  11. package/dist/{config-giW8X0QA.js → config-CyapYSji.js} +328 -374
  12. package/dist/config-utils-C57JiJrU.js +69 -0
  13. package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
  14. package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
  15. package/dist/doctor-contract-api.js +144 -14
  16. package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BwpvTxaX.js} +1119 -1135
  17. package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  18. package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-B9kp6iGC.js} +15 -6
  19. package/dist/event-projector-usage-ZqEVbAEY.js +212 -0
  20. package/dist/{harness-Csz0F-DK.js → harness-Czh2Sdoc.js} +65 -52
  21. package/dist/harness.js +1 -1
  22. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  23. package/dist/index.js +495 -457
  24. package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-CRh-51AK.js} +9 -21
  25. package/dist/{managed-binary-DFYK4DWq.js → managed-binary-DcpnJF9x.js} +117 -80
  26. package/dist/media-understanding-provider.js +1 -1
  27. package/dist/model-catalog-DT5vo6qo.js +101 -0
  28. package/dist/{models-TS3HBU-q.js → models-CcrgSMQR.js} +26 -29
  29. package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-B3bvQGcg.js} +63 -122
  30. package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-nfbUOtUB.js} +10 -7
  31. package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-aQVdyL5g.js} +30 -3
  32. package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-B7gHXJ3d.js} +44 -30
  33. package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BwCLTY_U.js} +6 -6
  34. package/dist/provider-capabilities-BpG9Ltc5.js +101 -0
  35. package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-Fx_l4eNa.js} +3 -2
  36. package/dist/{sandbox-guard-kuWTn9C5.js → request-C8H22rPi.js} +195 -2
  37. package/dist/{run-attempt-DYc0QCBF.js → run-attempt-BzthFQSM.js} +1616 -2634
  38. package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-Bh_gf6-t.js} +22 -15
  39. package/dist/{session-binding-Bcynfd-_.js → session-binding-4Ki04sW-.js} +282 -399
  40. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  41. package/dist/{session-catalog-DaLKVtpH.js → session-catalog-B47uwekb.js} +812 -504
  42. package/dist/{session-cli-DMc4oS2w.js → session-cli-BjLhpmS1.js} +1 -1
  43. package/dist/session-history-DWmMqiqW.js +93 -0
  44. package/dist/session-history-read-LHldwvyh.js +36 -0
  45. package/dist/session-history-worker-runtime.js +48 -0
  46. package/dist/session-history.worker-zZVcx0ME.js +267 -0
  47. package/dist/session-history.worker.js +2 -0
  48. package/dist/session-initialization-BCFVnLL4.js +75 -0
  49. package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-BaueHmSj.js} +2 -2
  50. package/dist/session-retirement-DNdmYdFc.js +97 -0
  51. package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-DReTpGz6.js} +20 -4
  52. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  53. package/dist/settled-turn-finalizer-BI-b1sry.js +115 -0
  54. package/dist/{shared-client-DKz23hHY.js → shared-client-CKhX2kFt.js} +3659 -847
  55. package/dist/{side-question-DjA_jsNe.js → side-question-B6DWAw1A.js} +168 -81
  56. package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DPK30jad.js} +2412 -2145
  57. package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-CbucAmmp.js} +27 -16
  58. package/dist/thread-policy-CTalhWFy.js +105 -0
  59. package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-BLgqkUc1.js} +61 -9
  60. package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-_njEB84z.js} +114 -110
  61. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  62. package/dist/transport-stdio-CzTngV0j.js +728 -0
  63. package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
  64. package/dist/upstream-session-fork-1fwbNKzQ.js +886 -0
  65. package/dist/{usage-ROIaW3wo.js → usage-i9fv5-4m.js} +3 -3
  66. package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  67. package/openclaw.plugin.json +1 -30
  68. package/package.json +6 -6
  69. package/dist/binding-connection-BMvPX73o.js +0 -45
  70. package/dist/command-rpc-CCeCkf_v.js +0 -90
  71. package/dist/event-projector-usage-Bk1I90Bg.js +0 -328
  72. package/dist/incognito-session-ET_ufDH-.js +0 -2
  73. package/dist/model-catalog-i9rNBthX.js +0 -48
  74. package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
  75. package/dist/request-DXXGHko0.js +0 -157
  76. package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
  77. package/dist/session-retirement-CcNC3YSY.js +0 -36
  78. package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
  79. package/dist/thread-resume-BE9qNEW0.js +0 -30
  80. package/dist/transport-stdio-DhoGy33Z.js +0 -99
  81. package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
@@ -1,101 +1,60 @@
1
- import { asNullableRecord, asOptionalRecord as readRecord, normalizeOptionalString as readNonEmptyString, normalizeTrimmedStringList, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { a as normalizeHeaders, c as readExecAsk, d as readNumberEnv, f as readRecord, g as CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN, i as normalizeCodexServiceTier, l as readExecSecurity, o as normalizePositiveNumber, p as resolveArgs, r as normalizeCodexAppServerSecretInput, s as readBooleanEnv, t as hashSecretForKey, u as readNonEmptyString } from "./config-utils-C57JiJrU.js";
2
+ import { m as readCodexAppServerConfigOptions, p as normalizeCodexAppServerArgs } from "./managed-binary-DcpnJF9x.js";
3
+ import { asNullableRecord, isRecord, normalizeOptionalString, normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { createHash } from "node:crypto";
5
+ import { resolveAgentConfig } from "openclaw/plugin-sdk/agent-scope-runtime";
6
+ import { z } from "zod";
7
+ import { buildSecretInputSchema } from "openclaw/plugin-sdk/secret-input";
2
8
  import path from "node:path";
3
- import { resolvePositiveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
4
9
  import { AgentHarnessPreflightError } from "openclaw/plugin-sdk/agent-harness-runtime";
5
- import { createHash, createHmac, randomBytes } from "node:crypto";
6
10
  import { readFileSync } from "node:fs";
7
11
  import { homedir, hostname } from "node:os";
8
12
  import { resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
9
- import { parse } from "smol-toml";
10
- import { resolveAgentConfig as resolveAgentConfig$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
11
13
  import { resolveExecApprovalsFromFile } from "openclaw/plugin-sdk/exec-approvals-runtime";
12
- import { buildSecretInputSchema, normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
13
14
  import { detectWindowsSpawnCommandInlineArgs } from "openclaw/plugin-sdk/windows-spawn";
14
- import { z } from "zod";
15
+ import { parse } from "smol-toml";
15
16
  import { isLoopbackHost } from "openclaw/plugin-sdk/ssrf-runtime";
16
- //#region extensions/codex/src/app-server/config-utils.ts
17
- const START_OPTIONS_KEY_SECRET_SYMBOL = Symbol.for("openclaw.codexAppServerStartOptionsKeySecret");
18
- const START_OPTIONS_KEY_SECRET = getStartOptionsKeySecret();
19
- const PLAIN_DECIMAL_NUMBER_RE = /^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))$/;
20
- function normalizeCodexServiceTier(value) {
21
- if (typeof value !== "string") return;
22
- const trimmed = value.trim();
23
- if (!trimmed) return;
24
- const normalized = trimmed.toLowerCase();
25
- if (normalized === "fast" || normalized === "priority") return "priority";
26
- if (normalized === "flex") return "flex";
27
- return trimmed;
28
- }
29
- function isCodexFastServiceTier(value) {
30
- return normalizeCodexServiceTier(value) === "priority";
31
- }
32
- function normalizePositiveNumber(value, fallback) {
33
- return resolvePositiveTimerTimeoutMs(value, fallback);
34
- }
35
- function normalizeHeaders(value) {
36
- if (!value || typeof value !== "object" || Array.isArray(value)) return {};
37
- return Object.fromEntries(Object.entries(value).map(([key, child]) => [key.trim(), normalizeCodexAppServerSecretInput({
38
- value: child,
39
- path: `plugins.entries.codex.config.appServer.headers.${key}`
40
- })]).filter((entry) => Boolean(entry[0] && entry[1])));
41
- }
42
- function normalizeCodexAppServerSecretInput(params) {
43
- return normalizeResolvedSecretInputString(params);
44
- }
45
- function readBooleanEnv(value) {
46
- return parseBooleanValue(value);
47
- }
48
- function readExecSecurity(value) {
49
- return value === "deny" || value === "allowlist" || value === "full" ? value : void 0;
50
- }
51
- function readExecAsk(value) {
52
- return value === "off" || value === "on-miss" || value === "always" ? value : void 0;
53
- }
54
- function readNumberEnv(value) {
55
- const trimmed = value?.trim();
56
- if (!trimmed || !PLAIN_DECIMAL_NUMBER_RE.test(trimmed)) return;
57
- const parsed = Number(trimmed);
58
- return Number.isFinite(parsed) ? parsed : void 0;
59
- }
60
- function resolveArgs(configArgs, envArgs) {
61
- if (Array.isArray(configArgs)) return configArgs.map((entry) => readNonEmptyString(entry)).filter((entry) => entry !== void 0);
62
- if (typeof configArgs === "string") return splitShellWords(configArgs);
63
- return splitShellWords(envArgs ?? "");
64
- }
65
- function hashSecretForKey(value, label) {
66
- if (!value) return null;
67
- return createHmac("sha256", START_OPTIONS_KEY_SECRET).update(label).update("\0").update(value).digest("hex");
68
- }
69
- function getStartOptionsKeySecret() {
70
- const globalState = globalThis;
71
- globalState[START_OPTIONS_KEY_SECRET_SYMBOL] ??= randomBytes(32);
72
- return globalState[START_OPTIONS_KEY_SECRET_SYMBOL];
73
- }
74
- function splitShellWords(value) {
75
- const words = [];
76
- let current = "";
77
- let quote = null;
78
- for (const char of value) {
79
- if (quote) {
80
- if (char === quote) quote = null;
81
- else current += char;
82
- continue;
83
- }
84
- if (char === "\"" || char === "'") {
85
- quote = char;
86
- continue;
87
- }
88
- if (/\s/.test(char)) {
89
- if (current) {
90
- words.push(current);
91
- current = "";
92
- }
93
- continue;
94
- }
95
- current += char;
96
- }
97
- if (current) words.push(current);
98
- return words;
17
+ //#region extensions/codex/src/app-server/protocol.ts
18
+ /** Namespace Codex keeps directly model-visible without exposing it to Code Mode guests. */
19
+ const CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE = "openclaw_direct";
20
+ function flattenCodexDynamicToolFunctions(tools) {
21
+ return (tools ?? []).flatMap((tool) => tool.type === "namespace" ? tool.tools : [tool]);
22
+ }
23
+ const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
24
+ const CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES = ["atlas", "chatgpt"];
25
+ function isJsonObject(value) {
26
+ return isRecord(value);
27
+ }
28
+ function isRpcResponse(message) {
29
+ return "id" in message && !("method" in message);
30
+ }
31
+ //#endregion
32
+ //#region extensions/codex/src/app-server/auth-start-options.ts
33
+ const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
34
+ const CODEX_EPHEMERAL_AUTH_STORE_OVERRIDE = "cli_auth_credentials_store=\"ephemeral\"";
35
+ function resolveCodexAppServerHomeDir(agentDir) {
36
+ return path.join(path.resolve(agentDir), CODEX_APP_SERVER_HOME_DIRNAME);
37
+ }
38
+ /** Resolves the native user Codex home used by Desktop and the CLI. */
39
+ function resolveCodexAppServerUserHomeDir(env = process.env, homedir$1 = homedir) {
40
+ const configured = normalizeOptionalString(env.CODEX_HOME);
41
+ return path.resolve(configured ?? path.join(homedir$1(), ".codex"));
42
+ }
43
+ /** Resolves the local CODEX_HOME used when starting one app-server connection. */
44
+ function resolveCodexAppServerLocalHomeDir(startOptions, agentDir, env = process.env) {
45
+ const configured = startOptions.env?.CODEX_HOME;
46
+ if (configured?.trim()) return configured;
47
+ return startOptions.homeScope === "user" ? resolveCodexAppServerUserHomeDir(env) : resolveCodexAppServerHomeDir(agentDir);
48
+ }
49
+ /** Forces OpenClaw-owned Codex auth to remain process-local. */
50
+ function withEphemeralCodexAuthStore(params) {
51
+ const { startOptions } = params;
52
+ if (!params.preparedAuth && params.authProfileId === null) return startOptions;
53
+ const args = normalizeCodexAppServerArgs(startOptions.args, CODEX_EPHEMERAL_AUTH_STORE_OVERRIDE);
54
+ return args === startOptions.args ? startOptions : {
55
+ ...startOptions,
56
+ args
57
+ };
99
58
  }
100
59
  //#endregion
101
60
  //#region extensions/codex/src/app-server/config-exec-policy.ts
@@ -132,7 +91,7 @@ function resolveOpenClawExecPolicyFromConfig(params) {
132
91
  const globalExec = readRecord(params.config?.tools?.exec);
133
92
  const globalPolicy = applyOpenClawExecPolicyLayer(createDefaultOpenClawExecPolicy(), globalExec);
134
93
  const agentId = params.agentId?.trim();
135
- return applyOpenClawExecPolicyLayer(globalPolicy, agentId ? readRecord(resolveAgentConfig$1(params.config ?? {}, agentId)?.tools?.exec) : void 0);
94
+ return applyOpenClawExecPolicyLayer(globalPolicy, agentId ? readRecord(resolveAgentConfig(params.config ?? {}, agentId)?.tools?.exec) : void 0);
136
95
  }
137
96
  function resolveOpenClawExecPolicyForCodexAppServer(params) {
138
97
  if (params.permissionMode === "full") return {
@@ -266,6 +225,246 @@ function readExecMode(value) {
266
225
  return value === "deny" || value === "allowlist" || value === "ask" || value === "auto" || value === "full" ? value : void 0;
267
226
  }
268
227
  //#endregion
228
+ //#region extensions/codex/src/app-server/session-discovery-config.ts
229
+ const codexSessionCatalogHomeSchema = z.union([z.string().trim().min(1), z.object({
230
+ path: z.string().trim().min(1),
231
+ label: z.string().trim().min(1).optional()
232
+ }).strict()]);
233
+ const codexSessionCatalogConfigSchema = z.object({
234
+ enabled: z.boolean().optional(),
235
+ homes: z.array(codexSessionCatalogHomeSchema).optional()
236
+ }).strict();
237
+ const codexDiscoveryConfigSchema = z.object({
238
+ enabled: z.boolean().optional(),
239
+ timeoutMs: z.number().positive().optional()
240
+ }).strict();
241
+ //#endregion
242
+ //#region extensions/codex/src/app-server/config-parsing.ts
243
+ const DEFAULT_CODEX_COMPUTER_USE_PLUGIN_NAME = "computer-use";
244
+ const DEFAULT_CODEX_COMPUTER_USE_MARKETPLACE_DISCOVERY_TIMEOUT_MS = 6e4;
245
+ const DEFAULT_CODEX_COMPUTER_USE_LIVE_TEST_TIMEOUT_MS = 6e4;
246
+ const DEFAULT_CODEX_COMPUTER_USE_TOOL_CALL_TIMEOUT_MS = 6e4;
247
+ const DEFAULT_CODEX_APP_SERVER_NETWORK_PROXY_PROFILE_PREFIX = "openclaw-network";
248
+ const codexAppServerTransportSchema = z.enum([
249
+ "stdio",
250
+ "websocket",
251
+ "unix"
252
+ ]);
253
+ const codexAppServerHomeScopeSchema = z.enum(["agent", "user"]);
254
+ const SecretInputSchema = buildSecretInputSchema();
255
+ const codexAppServerPolicyModeSchema = z.enum(["yolo", "guardian"]);
256
+ const codexAppServerApprovalPolicySchema = z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum(["never", "on-request"]));
257
+ const codexAppServerSandboxSchema = z.enum([
258
+ "read-only",
259
+ "workspace-write",
260
+ "danger-full-access"
261
+ ]);
262
+ const codexAppServerApprovalsReviewerSchema = z.enum([
263
+ "user",
264
+ "auto_review",
265
+ "guardian_subagent"
266
+ ]);
267
+ const codexDynamicToolsLoadingSchema = z.enum(["searchable", "direct"]);
268
+ const codexComputerUseHealthIntervalSchema = z.union([
269
+ z.literal(30),
270
+ z.literal(60),
271
+ z.literal(120),
272
+ z.literal(240)
273
+ ]);
274
+ const codexComputerUsePluginCacheModeSchema = z.enum(["shared", "independent"]);
275
+ const codexPluginDestructivePolicySchema = z.union([
276
+ z.boolean(),
277
+ z.literal("auto"),
278
+ z.literal("ask")
279
+ ]);
280
+ const codexAppServerServiceTierSchema = z.preprocess((value) => value === null ? null : normalizeCodexServiceTier(value), z.string().trim().min(1).nullable().optional()).optional();
281
+ const codexAppServerExperimentalSchema = z.object({ sandboxExecServer: z.boolean().optional() }).strict();
282
+ const codexAppServerRemoteWorkspaceRootSchema = z.string().trim().min(1);
283
+ const codexAppServerNetworkProxyDomainPermissionSchema = z.enum(["allow", "deny"]);
284
+ const codexAppServerNetworkProxyUnixSocketPermissionSchema = z.enum(["allow", "none"]);
285
+ const codexAppServerNetworkProxySchema = z.object({
286
+ enabled: z.boolean().optional(),
287
+ profileName: z.string().trim().min(1).optional(),
288
+ baseProfile: z.enum(["read-only", "workspace"]).optional(),
289
+ mode: z.enum(["limited", "full"]).optional(),
290
+ domains: z.record(z.string(), codexAppServerNetworkProxyDomainPermissionSchema).optional(),
291
+ unixSockets: z.record(z.string(), codexAppServerNetworkProxyUnixSocketPermissionSchema).optional(),
292
+ proxyUrl: z.string().trim().min(1).optional(),
293
+ socksUrl: z.string().trim().min(1).optional(),
294
+ enableSocks5: z.boolean().optional(),
295
+ enableSocks5Udp: z.boolean().optional(),
296
+ allowUpstreamProxy: z.boolean().optional(),
297
+ allowLocalBinding: z.boolean().optional(),
298
+ dangerouslyAllowNonLoopbackProxy: z.boolean().optional(),
299
+ dangerouslyAllowAllUnixSockets: z.boolean().optional()
300
+ }).strict();
301
+ const codexPluginEntryConfigSchema = z.object({
302
+ enabled: z.boolean().optional(),
303
+ marketplaceName: z.string().regex(CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN).optional(),
304
+ pluginName: z.string().trim().min(1).optional(),
305
+ allow_destructive_actions: codexPluginDestructivePolicySchema.optional()
306
+ }).strict();
307
+ const codexPluginsConfigSchema = z.object({
308
+ enabled: z.boolean().optional(),
309
+ allow_all_plugins: z.boolean().optional(),
310
+ allow_destructive_actions: codexPluginDestructivePolicySchema.optional(),
311
+ plugins: z.record(z.string(), codexPluginEntryConfigSchema).optional()
312
+ }).strict();
313
+ const codexSupervisionEndpointSchema = z.union([z.object({
314
+ id: z.string().optional(),
315
+ label: z.string().optional(),
316
+ transport: z.literal("stdio-proxy").optional(),
317
+ command: z.string().optional(),
318
+ args: z.array(z.string()).optional(),
319
+ cwd: z.string().optional()
320
+ }).strict(), z.object({
321
+ id: z.string().optional(),
322
+ label: z.string().optional(),
323
+ transport: z.literal("websocket"),
324
+ url: z.string(),
325
+ authTokenEnv: z.string().optional()
326
+ }).strict()]);
327
+ const codexSupervisionConfigSchema = z.object({
328
+ enabled: z.boolean().optional(),
329
+ endpoints: z.array(codexSupervisionEndpointSchema).optional(),
330
+ allowRawTranscripts: z.boolean().optional(),
331
+ allowWriteControls: z.boolean().optional()
332
+ }).strict();
333
+ const codexPluginConfigSchema = z.object({
334
+ codexDynamicToolsLoading: codexDynamicToolsLoadingSchema.optional(),
335
+ codexDynamicToolsExclude: z.array(z.string()).optional(),
336
+ sessionCatalog: codexSessionCatalogConfigSchema.optional(),
337
+ discovery: codexDiscoveryConfigSchema.optional(),
338
+ computerUse: z.object({
339
+ enabled: z.boolean().optional(),
340
+ autoInstall: z.boolean().optional(),
341
+ marketplaceDiscoveryTimeoutMs: z.number().positive().optional(),
342
+ liveTestTimeoutMs: z.number().positive().optional(),
343
+ toolCallTimeoutMs: z.number().positive().optional(),
344
+ healthCheckEnabled: z.boolean().optional(),
345
+ healthCheckIntervalMinutes: codexComputerUseHealthIntervalSchema.optional(),
346
+ pluginCacheMode: codexComputerUsePluginCacheModeSchema.optional(),
347
+ strictReadiness: z.boolean().optional(),
348
+ autoRepair: z.boolean().optional(),
349
+ marketplaceSource: z.string().optional(),
350
+ marketplacePath: z.string().optional(),
351
+ marketplaceName: z.string().optional(),
352
+ pluginName: z.string().optional(),
353
+ mcpServerName: z.string().optional()
354
+ }).strict().optional(),
355
+ codexPlugins: z.unknown().optional(),
356
+ supervision: codexSupervisionConfigSchema.optional(),
357
+ appServer: z.object({
358
+ mode: codexAppServerPolicyModeSchema.optional(),
359
+ transport: codexAppServerTransportSchema.optional(),
360
+ homeScope: codexAppServerHomeScopeSchema.optional(),
361
+ command: z.string().optional(),
362
+ args: z.union([z.array(z.string()), z.string()]).optional(),
363
+ url: z.string().optional(),
364
+ authToken: SecretInputSchema.optional(),
365
+ headers: z.record(z.string(), SecretInputSchema).optional(),
366
+ clearEnv: z.array(z.string()).optional(),
367
+ remoteWorkspaceRoot: codexAppServerRemoteWorkspaceRootSchema.optional(),
368
+ codeModeOnly: z.boolean().optional(),
369
+ loopDetectionPreToolUseRelay: z.boolean().optional(),
370
+ requestTimeoutMs: z.number().positive().optional(),
371
+ approvalPolicy: codexAppServerApprovalPolicySchema.optional(),
372
+ sandbox: codexAppServerSandboxSchema.optional(),
373
+ approvalsReviewer: codexAppServerApprovalsReviewerSchema.optional(),
374
+ serviceTier: codexAppServerServiceTierSchema,
375
+ networkProxy: codexAppServerNetworkProxySchema.optional(),
376
+ defaultWorkspaceDir: z.string().optional(),
377
+ experimental: codexAppServerExperimentalSchema.optional()
378
+ }).strict().optional()
379
+ }).strict();
380
+ function readCodexPluginConfig(value) {
381
+ 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\".");
382
+ const parsed = codexPluginConfigSchema.safeParse(value);
383
+ if (!parsed.success) return {};
384
+ const { codexPlugins: rawCodexPlugins, ...config } = parsed.data;
385
+ const plugins = codexPluginsConfigSchema.safeParse(rawCodexPlugins);
386
+ if (!plugins.success) return config;
387
+ return {
388
+ ...config,
389
+ ...plugins.data ? { codexPlugins: plugins.data } : {}
390
+ };
391
+ }
392
+ function isCodexSandboxExecServerEnabled(pluginConfig, sandbox) {
393
+ return isCodexRemoteExecPlacementSandbox(sandbox) || readCodexPluginConfig(pluginConfig).appServer?.experimental?.sandboxExecServer === true;
394
+ }
395
+ function isCodexRemoteExecPlacementSandbox(sandbox) {
396
+ return typeof sandbox === "object" && sandbox !== null && "placementExecutionMode" in sandbox && sandbox.placementExecutionMode === "remote-exec";
397
+ }
398
+ function isCodexPairedNodeRemoteExecPlacementSandbox(sandbox) {
399
+ return isCodexRemoteExecPlacementSandbox(sandbox) && typeof sandbox === "object" && sandbox !== null && "placementNodeId" in sandbox && typeof sandbox.placementNodeId === "string" && sandbox.placementNodeId.length > 0;
400
+ }
401
+ function assertCodexAppServerCommandHasNoInlineArgs(params) {
402
+ const inlineArgs = detectWindowsSpawnCommandInlineArgs(params.command);
403
+ if (!inlineArgs) return;
404
+ const sourceLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_BIN" : "plugins.entries.codex.config.appServer.command";
405
+ const argsLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_ARGS" : "plugins.entries.codex.config.appServer.args";
406
+ 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.`);
407
+ }
408
+ function resolveCodexPluginsPolicy(pluginConfig) {
409
+ const config = readCodexPluginConfig(pluginConfig).codexPlugins;
410
+ const configured = config !== void 0;
411
+ const enabled = config?.enabled === true;
412
+ const destructivePolicy = resolveCodexPluginDestructivePolicy(config?.allow_destructive_actions ?? true);
413
+ const pluginPolicies = Object.entries(config?.plugins ?? {}).flatMap(([configKey, entry]) => {
414
+ if (!isCodexPluginMarketplaceName(entry.marketplaceName) || !entry.pluginName) return [];
415
+ const entryDestructivePolicy = resolveCodexPluginDestructivePolicy(entry.allow_destructive_actions ?? config?.allow_destructive_actions ?? true);
416
+ return [{
417
+ configKey,
418
+ marketplaceName: entry.marketplaceName,
419
+ pluginName: entry.pluginName,
420
+ enabled: enabled && entry.enabled !== false,
421
+ allowDestructiveActions: entryDestructivePolicy.allowDestructiveActions,
422
+ destructiveApprovalMode: entryDestructivePolicy.destructiveApprovalMode
423
+ }];
424
+ }).toSorted((left, right) => left.configKey.localeCompare(right.configKey));
425
+ return {
426
+ configured,
427
+ enabled,
428
+ allowAllPlugins: enabled && config?.allow_all_plugins === true,
429
+ allowDestructiveActions: destructivePolicy.allowDestructiveActions,
430
+ destructiveApprovalMode: destructivePolicy.destructiveApprovalMode,
431
+ pluginPolicies
432
+ };
433
+ }
434
+ function isCodexPluginMarketplaceName(value) {
435
+ return typeof value === "string" && CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN.test(value);
436
+ }
437
+ function resolveCodexPluginDestructivePolicy(policy) {
438
+ if (policy === "auto" || policy === "ask") return {
439
+ allowDestructiveActions: true,
440
+ destructiveApprovalMode: policy
441
+ };
442
+ return {
443
+ allowDestructiveActions: policy,
444
+ destructiveApprovalMode: policy ? "allow" : "deny"
445
+ };
446
+ }
447
+ //#endregion
448
+ //#region extensions/codex/src/app-server/config-layer-policy.ts
449
+ const CODEX_SESSION_OVERRIDABLE_LAYER_TYPES = /* @__PURE__ */ new Set([
450
+ "packagedDefaults",
451
+ "mdm",
452
+ "system",
453
+ "enterpriseManaged",
454
+ "user",
455
+ "project",
456
+ "sessionFlags"
457
+ ]);
458
+ /** Read one effective snapshot for the current boundary's reviewer and tool-policy checks. */
459
+ async function readCodexEffectiveConfig(client, cwd, signal) {
460
+ const response = await client.request("config/read", {
461
+ cwd: path.resolve(cwd),
462
+ includeLayers: true
463
+ }, { signal });
464
+ if (!isJsonObject(response) || !isJsonObject(response.config)) throw new Error("Codex config/read returned an invalid effective config");
465
+ return response;
466
+ }
467
+ //#endregion
269
468
  //#region extensions/codex/src/app-server/config-requirements.ts
270
469
  const UNIX_CODEX_REQUIREMENTS_PATH = "/etc/codex/requirements.toml";
271
470
  const WINDOWS_CODEX_REQUIREMENTS_SUFFIX = "\\OpenAI\\Codex\\requirements.toml";
@@ -461,22 +660,19 @@ function selectUserApprovalsReviewer(allowedApprovalsReviewers, execModeRequirin
461
660
  }
462
661
  //#endregion
463
662
  //#region extensions/codex/src/app-server/config-reviewer.ts
464
- const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
465
663
  const CODEX_CONFIG_TOML_FILENAME = "config.toml";
466
664
  /** Cloud/system config can redirect reviews after local home/profile checks have passed. */
467
665
  async function assertCodexModelBackedReviewerEffectiveConfig(params) {
468
666
  if (params.approvalsReviewer !== "auto_review" && params.approvalsReviewer !== "guardian_subagent") return;
469
- const effectiveConfig = readRecord(readRecord(await params.client.request("config/read", {
470
- cwd: path.resolve(params.cwd),
471
- includeLayers: false
472
- }, { signal: params.signal }))?.config);
473
- if (!effectiveConfig) throw new Error("Codex config/read returned an invalid model-backed reviewer config");
667
+ const response = await readCodexEffectiveConfig(params.client, params.cwd, params.signal);
668
+ const effectiveConfig = response.config;
474
669
  const modelProvider = effectiveConfig.model_provider;
475
670
  const providers = effectiveConfig.model_providers;
476
671
  const providerRecords = providers == null ? void 0 : readRecord(providers);
477
672
  const provider = providerRecords?.openai;
478
673
  const openAIProvider = provider == null ? void 0 : readRecord(provider);
479
674
  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");
675
+ return response;
480
676
  }
481
677
  function isTrustedOptionalReviewerEndpoint(value, isTrusted) {
482
678
  return value == null || typeof value === "string" && isTrusted(value);
@@ -484,9 +680,8 @@ function isTrustedOptionalReviewerEndpoint(value, isTrusted) {
484
680
  function canUseCodexModelBackedApprovalsReviewerForModel(params) {
485
681
  const explicitProvider = params.modelProvider?.trim().toLowerCase();
486
682
  const inferredProvider = inferProviderFromModelRef(params.model);
487
- if (explicitProvider && explicitProvider !== "codex") return isTrustedCodexModelBackedApprovalsReviewerProvider(explicitProvider, params) && (inferredProvider === void 0 || isTrustedCodexModelBackedApprovalsReviewerProvider(inferredProvider, params));
488
- if (inferredProvider !== void 0) return isTrustedCodexModelBackedApprovalsReviewerProvider(inferredProvider, params);
489
- return isTrustedCodexModelBackedApprovalsReviewerProvider(explicitProvider, params);
683
+ if (explicitProvider && explicitProvider !== "codex" && explicitProvider !== "openai") return false;
684
+ return (inferredProvider ?? explicitProvider) === "openai" && isTrustedCodexModelBackedOpenAIProvider(params);
490
685
  }
491
686
  function isTrustedCodexModelBackedOpenAIProvider(params) {
492
687
  if (!openAIBaseUrlEnvOverridesAreTrustedForModelBackedReview(params.env)) return false;
@@ -523,20 +718,6 @@ function resolveCodexModelBackedReviewerPolicyContext(params) {
523
718
  model: params.model ?? params.bindingModel
524
719
  };
525
720
  }
526
- function isCodexModelBackedApprovalsReviewerProvider(provider) {
527
- return provider?.trim().toLowerCase() === "openai";
528
- }
529
- function isTrustedCodexModelBackedApprovalsReviewerProvider(provider, params) {
530
- return isCodexModelBackedApprovalsReviewerProvider(provider) && isTrustedCodexModelBackedOpenAIProvider({
531
- config: params.config,
532
- env: params.env,
533
- model: params.model,
534
- agentDir: params.agentDir,
535
- codexConfigToml: params.codexConfigToml,
536
- homeScope: params.homeScope,
537
- codexArgs: params.codexArgs
538
- });
539
- }
540
721
  function readCodexBaseUrlOverridesForModelBackedReview(params) {
541
722
  const configToml = readCodexAppServerConfigToml(params);
542
723
  if (configToml === false) return false;
@@ -561,19 +742,13 @@ function readCodexBaseUrlOverridesForModelBackedReview(params) {
561
742
  };
562
743
  }
563
744
  function readNativeCodexReviewerConfigOverrides(params) {
745
+ if (params.codexArgs?.some((arg) => !arg)) return false;
564
746
  const overrides = [];
565
747
  let profile;
566
- const args = params.codexArgs ?? [];
567
- for (let index = 0; index < args.length; index += 1) {
568
- const arg = args[index];
569
- if (!arg) return false;
570
- if (arg === "--profile" || arg === "-p") profile = args[++index];
571
- else if (arg.startsWith("--profile=")) profile = arg.slice(10);
572
- else if (arg === "-c" || arg === "--config") {
573
- const override = args[++index];
574
- if (!override) return false;
575
- overrides.push(`${override}\n`);
576
- } else if (arg.startsWith("--config=")) overrides.push(`${arg.slice(9)}\n`);
748
+ for (const { name, value } of readCodexAppServerConfigOptions(params.codexArgs ?? [])) {
749
+ if (!value) return false;
750
+ if (name === "--profile" || name === "-p") profile = value;
751
+ else overrides.push(`${value}\n`);
577
752
  }
578
753
  if (profile) {
579
754
  if (path.basename(profile) !== profile || profile === "." || profile === "..") return false;
@@ -623,13 +798,7 @@ function codexConfigEnablesNativeComputerUse(params) {
623
798
  function resolveCodexAppServerConfigPath(params) {
624
799
  if (params.homeScope === "user") return path.join(resolveCodexAppServerUserHomeDir(params.env), CODEX_CONFIG_TOML_FILENAME);
625
800
  const agentDir = readNonEmptyString(params.agentDir);
626
- const codexHome = agentDir ? path.join(path.resolve(agentDir), CODEX_APP_SERVER_HOME_DIRNAME) : void 0;
627
- return codexHome ? path.join(codexHome, CODEX_CONFIG_TOML_FILENAME) : void 0;
628
- }
629
- /** Resolves the native user Codex home used by Desktop and the CLI. */
630
- function resolveCodexAppServerUserHomeDir(env = process.env, homedir$1 = homedir) {
631
- const configured = readNonEmptyString(env.CODEX_HOME);
632
- return path.resolve(configured ?? path.join(homedir$1(), ".codex"));
801
+ return agentDir ? path.join(resolveCodexAppServerHomeDir(agentDir), CODEX_CONFIG_TOML_FILENAME) : void 0;
633
802
  }
634
803
  function readErrorCode(error) {
635
804
  return error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
@@ -703,234 +872,6 @@ function inferProviderFromModelRef(model) {
703
872
  return slashIndex > 0 ? normalized?.slice(0, slashIndex) : void 0;
704
873
  }
705
874
  //#endregion
706
- //#region extensions/codex/src/app-server/config-contracts.ts
707
- const CODEX_PLUGINS_MARKETPLACE_NAME = "openai-curated";
708
- const CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME = "workspace-directory";
709
- const CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN = /^[A-Za-z0-9_-]+$/;
710
- //#endregion
711
- //#region extensions/codex/src/app-server/session-discovery-config.ts
712
- const codexSessionCatalogHomeSchema = z.union([z.string().trim().min(1), z.object({
713
- path: z.string().trim().min(1),
714
- label: z.string().trim().min(1).optional()
715
- }).strict()]);
716
- const codexSessionCatalogConfigSchema = z.object({
717
- enabled: z.boolean().optional(),
718
- homes: z.array(codexSessionCatalogHomeSchema).optional()
719
- }).strict();
720
- const codexDiscoveryConfigSchema = z.object({
721
- enabled: z.boolean().optional(),
722
- timeoutMs: z.number().positive().optional()
723
- }).strict();
724
- //#endregion
725
- //#region extensions/codex/src/app-server/config-parsing.ts
726
- const DEFAULT_CODEX_COMPUTER_USE_PLUGIN_NAME = "computer-use";
727
- const DEFAULT_CODEX_COMPUTER_USE_MARKETPLACE_DISCOVERY_TIMEOUT_MS = 6e4;
728
- const DEFAULT_CODEX_COMPUTER_USE_LIVE_TEST_TIMEOUT_MS = 6e4;
729
- const DEFAULT_CODEX_COMPUTER_USE_TOOL_CALL_TIMEOUT_MS = 6e4;
730
- const DEFAULT_CODEX_APP_SERVER_NETWORK_PROXY_PROFILE_PREFIX = "openclaw-network";
731
- const codexAppServerTransportSchema = z.enum([
732
- "stdio",
733
- "websocket",
734
- "unix"
735
- ]);
736
- const codexAppServerHomeScopeSchema = z.enum(["agent", "user"]);
737
- const SecretInputSchema = buildSecretInputSchema();
738
- const codexAppServerPolicyModeSchema = z.enum(["yolo", "guardian"]);
739
- const codexAppServerApprovalPolicySchema = z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum(["never", "on-request"]));
740
- const codexAppServerSandboxSchema = z.enum([
741
- "read-only",
742
- "workspace-write",
743
- "danger-full-access"
744
- ]);
745
- const codexAppServerApprovalsReviewerSchema = z.enum([
746
- "user",
747
- "auto_review",
748
- "guardian_subagent"
749
- ]);
750
- const codexDynamicToolsLoadingSchema = z.enum(["searchable", "direct"]);
751
- const codexComputerUseHealthIntervalSchema = z.union([
752
- z.literal(30),
753
- z.literal(60),
754
- z.literal(120),
755
- z.literal(240)
756
- ]);
757
- const codexComputerUsePluginCacheModeSchema = z.enum(["shared", "independent"]);
758
- const codexPluginDestructivePolicySchema = z.union([
759
- z.boolean(),
760
- z.literal("auto"),
761
- z.literal("ask")
762
- ]);
763
- const codexAppServerServiceTierSchema = z.preprocess((value) => value === null ? null : normalizeCodexServiceTier(value), z.string().trim().min(1).nullable().optional()).optional();
764
- const codexAppServerExperimentalSchema = z.object({ sandboxExecServer: z.boolean().optional() }).strict();
765
- const codexAppServerRemoteWorkspaceRootSchema = z.string().trim().min(1);
766
- const codexAppServerNetworkProxyDomainPermissionSchema = z.enum(["allow", "deny"]);
767
- const codexAppServerNetworkProxyUnixSocketPermissionSchema = z.enum(["allow", "none"]);
768
- const codexAppServerNetworkProxySchema = z.object({
769
- enabled: z.boolean().optional(),
770
- profileName: z.string().trim().min(1).optional(),
771
- baseProfile: z.enum(["read-only", "workspace"]).optional(),
772
- mode: z.enum(["limited", "full"]).optional(),
773
- domains: z.record(z.string(), codexAppServerNetworkProxyDomainPermissionSchema).optional(),
774
- unixSockets: z.record(z.string(), codexAppServerNetworkProxyUnixSocketPermissionSchema).optional(),
775
- proxyUrl: z.string().trim().min(1).optional(),
776
- socksUrl: z.string().trim().min(1).optional(),
777
- enableSocks5: z.boolean().optional(),
778
- enableSocks5Udp: z.boolean().optional(),
779
- allowUpstreamProxy: z.boolean().optional(),
780
- allowLocalBinding: z.boolean().optional(),
781
- dangerouslyAllowNonLoopbackProxy: z.boolean().optional(),
782
- dangerouslyAllowAllUnixSockets: z.boolean().optional()
783
- }).strict();
784
- const codexPluginEntryConfigSchema = z.object({
785
- enabled: z.boolean().optional(),
786
- marketplaceName: z.string().regex(CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN).optional(),
787
- pluginName: z.string().trim().min(1).optional(),
788
- allow_destructive_actions: codexPluginDestructivePolicySchema.optional()
789
- }).strict();
790
- const codexPluginsConfigSchema = z.object({
791
- enabled: z.boolean().optional(),
792
- allow_all_plugins: z.boolean().optional(),
793
- allow_destructive_actions: codexPluginDestructivePolicySchema.optional(),
794
- plugins: z.record(z.string(), codexPluginEntryConfigSchema).optional()
795
- }).strict();
796
- const codexSupervisionEndpointSchema = z.union([z.object({
797
- id: z.string().optional(),
798
- label: z.string().optional(),
799
- transport: z.literal("stdio-proxy").optional(),
800
- command: z.string().optional(),
801
- args: z.array(z.string()).optional(),
802
- cwd: z.string().optional()
803
- }).strict(), z.object({
804
- id: z.string().optional(),
805
- label: z.string().optional(),
806
- transport: z.literal("websocket"),
807
- url: z.string(),
808
- authTokenEnv: z.string().optional()
809
- }).strict()]);
810
- const codexSupervisionConfigSchema = z.object({
811
- enabled: z.boolean().optional(),
812
- endpoints: z.array(codexSupervisionEndpointSchema).optional(),
813
- allowRawTranscripts: z.boolean().optional(),
814
- allowWriteControls: z.boolean().optional()
815
- }).strict();
816
- const codexPluginConfigSchema = z.object({
817
- codexDynamicToolsLoading: codexDynamicToolsLoadingSchema.optional(),
818
- codexDynamicToolsExclude: z.array(z.string()).optional(),
819
- sessionCatalog: codexSessionCatalogConfigSchema.optional(),
820
- discovery: codexDiscoveryConfigSchema.optional(),
821
- computerUse: z.object({
822
- enabled: z.boolean().optional(),
823
- autoInstall: z.boolean().optional(),
824
- marketplaceDiscoveryTimeoutMs: z.number().positive().optional(),
825
- liveTestTimeoutMs: z.number().positive().optional(),
826
- toolCallTimeoutMs: z.number().positive().optional(),
827
- healthCheckEnabled: z.boolean().optional(),
828
- healthCheckIntervalMinutes: codexComputerUseHealthIntervalSchema.optional(),
829
- pluginCacheMode: codexComputerUsePluginCacheModeSchema.optional(),
830
- strictReadiness: z.boolean().optional(),
831
- autoRepair: z.boolean().optional(),
832
- marketplaceSource: z.string().optional(),
833
- marketplacePath: z.string().optional(),
834
- marketplaceName: z.string().optional(),
835
- pluginName: z.string().optional(),
836
- mcpServerName: z.string().optional()
837
- }).strict().optional(),
838
- codexPlugins: z.unknown().optional(),
839
- supervision: codexSupervisionConfigSchema.optional(),
840
- appServer: z.object({
841
- mode: codexAppServerPolicyModeSchema.optional(),
842
- transport: codexAppServerTransportSchema.optional(),
843
- homeScope: codexAppServerHomeScopeSchema.optional(),
844
- command: z.string().optional(),
845
- args: z.union([z.array(z.string()), z.string()]).optional(),
846
- url: z.string().optional(),
847
- authToken: SecretInputSchema.optional(),
848
- headers: z.record(z.string(), SecretInputSchema).optional(),
849
- clearEnv: z.array(z.string()).optional(),
850
- remoteWorkspaceRoot: codexAppServerRemoteWorkspaceRootSchema.optional(),
851
- codeModeOnly: z.boolean().optional(),
852
- loopDetectionPreToolUseRelay: z.boolean().optional(),
853
- requestTimeoutMs: z.number().positive().optional(),
854
- turnCompletionIdleTimeoutMs: z.number().positive().optional(),
855
- turnAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
856
- postToolRawAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
857
- approvalPolicy: codexAppServerApprovalPolicySchema.optional(),
858
- sandbox: codexAppServerSandboxSchema.optional(),
859
- approvalsReviewer: codexAppServerApprovalsReviewerSchema.optional(),
860
- serviceTier: codexAppServerServiceTierSchema,
861
- networkProxy: codexAppServerNetworkProxySchema.optional(),
862
- defaultWorkspaceDir: z.string().optional(),
863
- experimental: codexAppServerExperimentalSchema.optional()
864
- }).strict().optional()
865
- }).strict();
866
- function readCodexPluginConfig(value) {
867
- 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\".");
868
- const parsed = codexPluginConfigSchema.safeParse(value);
869
- if (!parsed.success) return {};
870
- const { codexPlugins: rawCodexPlugins, ...config } = parsed.data;
871
- const plugins = codexPluginsConfigSchema.safeParse(rawCodexPlugins);
872
- if (!plugins.success) return config;
873
- return {
874
- ...config,
875
- ...plugins.data ? { codexPlugins: plugins.data } : {}
876
- };
877
- }
878
- function isCodexSandboxExecServerEnabled(pluginConfig, sandbox) {
879
- return isCodexRemoteExecPlacementSandbox(sandbox) || readCodexPluginConfig(pluginConfig).appServer?.experimental?.sandboxExecServer === true;
880
- }
881
- function isCodexRemoteExecPlacementSandbox(sandbox) {
882
- return typeof sandbox === "object" && sandbox !== null && "placementExecutionMode" in sandbox && sandbox.placementExecutionMode === "remote-exec";
883
- }
884
- function isCodexPairedNodeRemoteExecPlacementSandbox(sandbox) {
885
- return isCodexRemoteExecPlacementSandbox(sandbox) && typeof sandbox === "object" && sandbox !== null && "placementNodeId" in sandbox && typeof sandbox.placementNodeId === "string" && sandbox.placementNodeId.length > 0;
886
- }
887
- function assertCodexAppServerCommandHasNoInlineArgs(params) {
888
- const inlineArgs = detectWindowsSpawnCommandInlineArgs(params.command);
889
- if (!inlineArgs) return;
890
- const sourceLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_BIN" : "plugins.entries.codex.config.appServer.command";
891
- const argsLabel = params.source === "env" ? "OPENCLAW_CODEX_APP_SERVER_ARGS" : "plugins.entries.codex.config.appServer.args";
892
- 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.`);
893
- }
894
- function resolveCodexPluginsPolicy(pluginConfig) {
895
- const config = readCodexPluginConfig(pluginConfig).codexPlugins;
896
- const configured = config !== void 0;
897
- const enabled = config?.enabled === true;
898
- const destructivePolicy = resolveCodexPluginDestructivePolicy(config?.allow_destructive_actions ?? true);
899
- const pluginPolicies = Object.entries(config?.plugins ?? {}).flatMap(([configKey, entry]) => {
900
- if (!isCodexPluginMarketplaceName(entry.marketplaceName) || !entry.pluginName) return [];
901
- const entryDestructivePolicy = resolveCodexPluginDestructivePolicy(entry.allow_destructive_actions ?? config?.allow_destructive_actions ?? true);
902
- return [{
903
- configKey,
904
- marketplaceName: entry.marketplaceName,
905
- pluginName: entry.pluginName,
906
- enabled: enabled && entry.enabled !== false,
907
- allowDestructiveActions: entryDestructivePolicy.allowDestructiveActions,
908
- destructiveApprovalMode: entryDestructivePolicy.destructiveApprovalMode
909
- }];
910
- }).toSorted((left, right) => left.configKey.localeCompare(right.configKey));
911
- return {
912
- configured,
913
- enabled,
914
- allowAllPlugins: enabled && config?.allow_all_plugins === true,
915
- allowDestructiveActions: destructivePolicy.allowDestructiveActions,
916
- destructiveApprovalMode: destructivePolicy.destructiveApprovalMode,
917
- pluginPolicies
918
- };
919
- }
920
- function isCodexPluginMarketplaceName(value) {
921
- return typeof value === "string" && CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN.test(value);
922
- }
923
- function resolveCodexPluginDestructivePolicy(policy) {
924
- if (policy === "auto" || policy === "ask") return {
925
- allowDestructiveActions: true,
926
- destructiveApprovalMode: policy
927
- };
928
- return {
929
- allowDestructiveActions: policy,
930
- destructiveApprovalMode: policy ? "allow" : "deny"
931
- };
932
- }
933
- //#endregion
934
875
  //#region extensions/codex/src/app-server/config-security.ts
935
876
  function shouldAutoApproveCodexAppServerApprovals(appServer) {
936
877
  return appServer.networkProxy === void 0 && appServer.approvalPolicy === "never" && appServer.sandbox === "danger-full-access";
@@ -974,10 +915,11 @@ function resolveCodexAppServerNetworkProxy(config, sandbox) {
974
915
  function resolveNetworkProxyPermissionProfileName(config, profile) {
975
916
  const explicitProfileName = readNonEmptyString(config.profileName);
976
917
  if (explicitProfileName) return explicitProfileName;
977
- return `${DEFAULT_CODEX_APP_SERVER_NETWORK_PROXY_PROFILE_PREFIX}-${createHash("sha256").update(stableStringifyJson({
918
+ const suffix = createHash("sha256").update(stableStringifyJson({
978
919
  version: 1,
979
920
  profile
980
- })).digest("hex").slice(0, 16)}`;
921
+ })).digest("hex").slice(0, 16);
922
+ return `${DEFAULT_CODEX_APP_SERVER_NETWORK_PROXY_PROFILE_PREFIX}-${suffix}`;
981
923
  }
982
924
  function fingerprintCodexAppServerNetworkProxyConfigPatch(configPatch) {
983
925
  return createHash("sha256").update(stableStringifyJson(configPatch)).digest("hex");
@@ -994,6 +936,16 @@ function stableStringifyJson(value) {
994
936
  if (value && typeof value === "object") return `{${Object.entries(value).toSorted(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableStringifyJson(item)}`).join(",")}}`;
995
937
  return JSON.stringify(value);
996
938
  }
939
+ /** Explicit MCP prompting must bypass Codex's unconditional Never-policy approval. */
940
+ function hasCodexMcpToolApprovalOverrides(servers, serverNames, projectedMcpServers) {
941
+ const modes = new Map(Object.entries(projectedMcpServers ?? {}).map(([name, server]) => [name, server.default_tools_approval_mode]));
942
+ for (const name of serverNames ?? Object.keys(servers ?? {})) {
943
+ const server = servers?.[name];
944
+ const mode = server?.codex?.defaultToolsApprovalMode;
945
+ if (mode !== void 0 && (serverNames !== void 0 || server?.enabled !== false)) modes.set(name, mode);
946
+ }
947
+ return [...modes.values()].some((mode) => mode === "auto" || mode === "prompt");
948
+ }
997
949
  function withMcpElicitationsApprovalPolicy(policy) {
998
950
  if (policy === "untrusted") return policy;
999
951
  if (typeof policy !== "string") return { granular: {
@@ -1243,9 +1195,6 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1243
1195
  codeModeOnly: config.codeModeOnly === true,
1244
1196
  loopDetectionPreToolUseRelay: config.loopDetectionPreToolUseRelay !== false,
1245
1197
  requestTimeoutMs: normalizePositiveNumber(config.requestTimeoutMs, 6e4),
1246
- turnCompletionIdleTimeoutMs: normalizePositiveNumber(config.turnCompletionIdleTimeoutMs, 6e4),
1247
- turnAssistantCompletionIdleTimeoutMs: normalizePositiveNumber(config.turnAssistantCompletionIdleTimeoutMs, 1e4),
1248
- ...config.postToolRawAssistantCompletionIdleTimeoutMs !== void 0 ? { postToolRawAssistantCompletionIdleTimeoutMs: normalizePositiveNumber(config.postToolRawAssistantCompletionIdleTimeoutMs, 6e4) } : {},
1249
1198
  approvalPolicy: forcedPolicy?.approvalPolicy ?? approvalPolicy,
1250
1199
  approvalPolicySource,
1251
1200
  sandbox: resolvedSandbox,
@@ -1346,17 +1295,22 @@ function codexSandboxPolicyForTurn(mode, cwd, nativeArgs = []) {
1346
1295
  };
1347
1296
  let excludeTmpdirEnvVar = false;
1348
1297
  let excludeSlashTmp = false;
1349
- for (let index = 0; index < nativeArgs.length; index += 1) {
1350
- const arg = nativeArgs[index];
1351
- const override = arg === "-c" || arg === "--config" ? nativeArgs[++index] : arg?.startsWith("--config=") ? arg.slice(9) : void 0;
1352
- if (!override) continue;
1298
+ for (const { name, value: override } of readCodexAppServerConfigOptions(nativeArgs)) {
1299
+ if (name !== "-c" && name !== "--config" || !override) continue;
1353
1300
  const separator = override.indexOf("=");
1354
1301
  if (separator < 0) continue;
1355
1302
  const key = override.slice(0, separator).trim();
1356
- const value = override.slice(separator + 1).trim();
1357
- if (value !== "true" && value !== "false") continue;
1358
- if (key === "sandbox_workspace_write.exclude_tmpdir_env_var") excludeTmpdirEnvVar = value === "true";
1359
- else if (key === "sandbox_workspace_write.exclude_slash_tmp") excludeSlashTmp = value === "true";
1303
+ const isTmpdirExclusion = key === "sandbox_workspace_write.exclude_tmpdir_env_var";
1304
+ if (!isTmpdirExclusion && key !== "sandbox_workspace_write.exclude_slash_tmp") continue;
1305
+ let value;
1306
+ try {
1307
+ value = parse(`_x_ = ${override.slice(separator + 1).trim()}`)["_x_"];
1308
+ } catch {
1309
+ continue;
1310
+ }
1311
+ if (typeof value !== "boolean") continue;
1312
+ if (isTmpdirExclusion) excludeTmpdirEnvVar = value;
1313
+ else excludeSlashTmp = value;
1360
1314
  }
1361
1315
  return {
1362
1316
  type: "workspaceWrite",
@@ -1386,4 +1340,4 @@ function resolveCodexSupervisionAppServerRuntimeOptions(params = {}) {
1386
1340
  });
1387
1341
  }
1388
1342
  //#endregion
1389
- export { selectUserApprovalsReviewer as A, resolveCodexModelBackedReviewerPolicyContext as C, readCodexRequirementsToml as D, parseAllowedSandboxModesFromCodexRequirements as E, selectGuardianSandbox as M, isCodexFastServiceTier as N, selectGuardianApprovalPolicy as O, normalizeCodexServiceTier as P, resolveCodexAppServerUserHomeDir as S, parseAllowedApprovalsReviewersFromCodexRequirements as T, CODEX_PLUGINS_MARKETPLACE_NAME as _, resolveCodexAppServerStartOptionsForAgent as a, assertCodexModelBackedReviewerEffectiveConfig as b, assertCodexAppServerConnectionSecurity as c, withMcpElicitationsApprovalPolicy as d, isCodexPairedNodeRemoteExecPlacementSandbox as f, resolveCodexPluginsPolicy as g, readCodexPluginConfig as h, resolveCodexAppServerRuntimeOptions as i, resolveOpenClawExecPolicyForCodexAppServer as j, selectGuardianApprovalsReviewer 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, parseAllowedApprovalPoliciesFromCodexRequirements as w, canUseCodexModelBackedApprovalsReviewerForModel as x, CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN as y };
1343
+ export { resolveOpenClawExecPolicyForCodexAppServer as A, isJsonObject as B, CODEX_SESSION_OVERRIDABLE_LAYER_TYPES as C, isCodexSandboxExecServerEnabled as D, isCodexRemoteExecPlacementSandbox as E, withEphemeralCodexAuthStore as F, CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES as I, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as L, resolveCodexAppServerHomeDir as M, resolveCodexAppServerLocalHomeDir as N, readCodexPluginConfig as O, resolveCodexAppServerUserHomeDir as P, CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE as R, selectUserApprovalsReviewer as S, isCodexPairedNodeRemoteExecPlacementSandbox as T, isRpcResponse as V, parseAllowedApprovalsReviewersFromCodexRequirements as _, resolveCodexAppServerStartOptionsForAgent as a, selectGuardianApprovalPolicy as b, assertCodexAppServerConnectionSecurity as c, shouldAutoApproveCodexAppServerApprovals as d, withMcpElicitationsApprovalPolicy as f, parseAllowedApprovalPoliciesFromCodexRequirements as g, resolveCodexModelBackedReviewerPolicyContext as h, resolveCodexAppServerRuntimeOptions as i, selectGuardianSandbox as j, resolveCodexPluginsPolicy as k, hasCodexMcpToolApprovalOverrides as l, canUseCodexModelBackedApprovalsReviewerForModel as m, codexSandboxPolicyForTurn as n, resolveCodexComputerUseConfig as o, assertCodexModelBackedReviewerEffectiveConfig as p, resolveCodexAppServerHomeScope as r, resolveCodexSupervisionAppServerRuntimeOptions as s, codexAppServerStartOptionsKey as t, resolveCodexAppServerNetworkProxy as u, parseAllowedSandboxModesFromCodexRequirements as v, readCodexEffectiveConfig as w, selectGuardianApprovalsReviewer as x, readCodexRequirementsToml as y, flattenCodexDynamicToolFunctions as z };