@openclaw/codex 2026.8.1-beta.3 → 2026.9.1-beta.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 (54) hide show
  1. package/dist/api.js +3 -3
  2. package/dist/{attempt-client-cleanup-URjUlCHg.js → attempt-client-cleanup-bfsmcQ6m.js} +21 -2
  3. package/dist/{binding-connection-DAvZwp96.js → binding-connection-BMvPX73o.js} +2 -2
  4. package/dist/{bounded-turn-4BjrZEwW.js → bounded-turn-B7iBUcuP.js} +8 -8
  5. package/dist/{capabilities-CH3K57v4.js → capabilities-BRMh0aIq.js} +1 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-D0nZ3qtd.js → command-formatters-DEsIufkt.js} +2 -2
  8. package/dist/{command-handlers-DC86lgT4.js → command-handlers-D_-1_qRp.js} +43 -32
  9. package/dist/{command-rpc-xUIIonsO.js → command-rpc-CCeCkf_v.js} +4 -4
  10. package/dist/{compact-COqgBRny.js → compact-BglNFZrQ.js} +8 -8
  11. package/dist/{config-CpNeo5AE.js → config-giW8X0QA.js} +82 -28
  12. package/dist/doctor-contract-api.js +9 -8
  13. package/dist/{dynamic-tools-fJZhl4CE.js → dynamic-tools-Dnlfa--w.js} +108 -820
  14. package/dist/{effective-mcp-catalog-4YKn51aG.js → effective-mcp-catalog-CTeGrnfO.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-Bk1I90Bg.js} +3 -3
  17. package/dist/{harness-DoKQcF8n.js → harness-Csz0F-DK.js} +11 -11
  18. package/dist/harness.js +1 -1
  19. package/dist/index.js +130 -172
  20. package/dist/{isolated-completion-DPMtlH9r.js → isolated-completion-Cv6FqygM.js} +4 -4
  21. package/dist/{managed-binary-By4FZC6i.js → managed-binary-DFYK4DWq.js} +43 -7
  22. package/dist/media-understanding-provider.js +1 -1
  23. package/dist/{model-catalog-CmGoqVKB.js → model-catalog-i9rNBthX.js} +4 -4
  24. package/dist/{models-CZw1wClT.js → models-TS3HBU-q.js} +4 -3
  25. package/dist/{native-subagent-monitor-GGq3RnOo.js → native-subagent-monitor-4Mfq2HDs.js} +176 -19
  26. package/dist/{node-exec-server.runtime-Bsu1LdFZ.js → node-exec-server.runtime-BpWqJO1V.js} +2 -2
  27. package/dist/{plugin-app-cache-key-DMNQ8Zi8.js → plugin-app-cache-key-C1CAdfcP.js} +6 -3
  28. package/dist/{plugin-approval-roundtrip-C75Yiiwc.js → plugin-approval-roundtrip-bUm777tR.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-B9DvaAG-.js} +29 -38
  30. package/dist/{plugin-metadata-cache-BXH5NF-4.js → plugin-metadata-cache-CTCT3w5L.js} +162 -135
  31. package/dist/{protocol-validators-VAVyEnDp.js → protocol-validators-VeJxxJ0U.js} +25 -3
  32. package/dist/{rate-limits-BI1dMHDG.js → rate-limits-C5_D8Gmb.js} +1 -1
  33. package/dist/{request-DSK0W6YI.js → request-DXXGHko0.js} +2 -2
  34. package/dist/{run-attempt-BV3HzuCf.js → run-attempt-DYc0QCBF.js} +346 -267
  35. package/dist/{sandbox-guard-C1qEeZ5C.js → sandbox-guard-kuWTn9C5.js} +1 -1
  36. package/dist/{session-binding-BTrLf9Qm.js → session-binding-Bcynfd-_.js} +1 -1
  37. package/dist/{session-catalog-ezP_UcRM.js → session-catalog-DaLKVtpH.js} +17 -16
  38. package/dist/{session-cli-B1hKvfkI.js → session-cli-DMc4oS2w.js} +1 -1
  39. package/dist/session-permission-policy-BrNH1bjy.js +160 -0
  40. package/dist/{session-retirement-CE4iMiLh.js → session-retirement-CcNC3YSY.js} +3 -3
  41. package/dist/{session-upstream-marker-D_2npHlA.js → session-upstream-marker-BIkusb95.js} +1 -1
  42. package/dist/{settled-turn-finalizer-Dx1onIqg.js → settled-turn-finalizer-Dc3ApjU4.js} +4 -4
  43. package/dist/{shared-client-Dw-rzii0.js → shared-client-DKz23hHY.js} +1026 -248
  44. package/dist/{side-question-DbXkJZzg.js → side-question-DjA_jsNe.js} +65 -36
  45. package/dist/{thread-lifecycle-DKdrnTMX.js → thread-lifecycle-L7oEkTlq.js} +850 -35
  46. package/dist/{thread-ownership-i2NBwDUL.js → thread-ownership-DZeuKH1j.js} +2 -2
  47. package/dist/{thread-resume-CdJk2Ehf.js → thread-resume-BE9qNEW0.js} +3 -3
  48. package/dist/{transcript-mirror-BU0_LKAL.js → transcript-mirror-DsCMWBca.js} +91 -10
  49. package/dist/{upstream-session-fork-BDVJCLAD.js → upstream-session-fork-DlaHxSLC.js} +3 -3
  50. package/dist/{usage-9dKJCgcy.js → usage-ROIaW3wo.js} +3 -3
  51. package/dist/{web-search-provider.runtime-DCdx4DGu.js → web-search-provider.runtime-ClaNPV7N.js} +3 -3
  52. package/openclaw.plugin.json +18 -1
  53. package/package.json +8 -8
  54. package/dist/app-server-policy-bg5QPSVP.js +0 -25
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as resolveCodexAppServerStartOptionsForAgent, i as resolveCodexAppServerRuntimeOptions } from "./config-CpNeo5AE.js";
2
- import { a as CODEX_APP_SERVER_VERSION, n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-By4FZC6i.js";
1
+ import { a as resolveCodexAppServerStartOptionsForAgent, i as resolveCodexAppServerRuntimeOptions } from "./config-giW8X0QA.js";
2
+ import { a as CODEX_APP_SERVER_VERSION, n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-DFYK4DWq.js";
3
3
  import path from "node:path";
4
4
  import { resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
5
5
  import { listAgentIds as listAgentIds$1, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
@@ -117,7 +117,7 @@ function createCodexManagedAppServerHealthCheck(params) {
117
117
  })];
118
118
  }
119
119
  const detectedVersion = parseCodexVersion(`${output.stdout}\n${output.stderr}`);
120
- if (detectedVersion !== "0.149.1") return [managedCodexFinding({
120
+ if (detectedVersion !== "0.150.1") return [managedCodexFinding({
121
121
  message: detectedVersion ? `Managed Codex app-server version mismatch: expected ${CODEX_APP_SERVER_VERSION}, detected ${detectedVersion}.` : `Managed Codex app-server did not report a parseable version; expected ${CODEX_APP_SERVER_VERSION}.`,
122
122
  path: nativeCommand,
123
123
  requirement: `the exact OpenClaw-pinned Codex version ${CODEX_APP_SERVER_VERSION}`,
@@ -1,4 +1,4 @@
1
- import { B as CodexAppServerRpcError, X as unsubscribeCodexAppServerLiveThread, p as retireSharedCodexAppServerClientIfCurrent, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
1
+ import { G as CodexAppServerRpcError, _ as retireSharedCodexAppServerClientIfCurrent, tt as unsubscribeCodexAppServerLiveThread, vt as isJsonObject } from "./shared-client-DKz23hHY.js";
2
2
  import { asFiniteNumber, normalizeOptionalString, normalizeOptionalString as normalizeOptionalString$1, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
4
4
  import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -259,6 +259,7 @@ var CodexProjectionDiagnostics = class {
259
259
  //#region extensions/codex/src/app-server/turn-router.ts
260
260
  /** Keyed routing for all turn traffic on one shared Codex app-server client. */
261
261
  const DEFAULT_PREBIND_NOTIFICATION_LIMIT = 256;
262
+ const DEFAULT_GLOBAL_WARNING_LIMIT = 32;
262
263
  const CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS = 3e4;
263
264
  const routers = /* @__PURE__ */ new WeakMap();
264
265
  /** Returns the sole router installed on a physical app-server client. */
@@ -272,6 +273,7 @@ function getCodexAppServerTurnRouter(client) {
272
273
  var ClientTurnRouter = class {
273
274
  constructor(client) {
274
275
  this.routes = /* @__PURE__ */ new Map();
276
+ this.globalWarnings = [];
275
277
  this.nativeTurnCompletionWatchers = /* @__PURE__ */ new Map();
276
278
  this.disposed = false;
277
279
  client.addNotificationHandler((notification) => this.routeNotification(notification));
@@ -290,7 +292,11 @@ var ClientTurnRouter = class {
290
292
  ended: createDeferred(),
291
293
  activated: createDeferred(),
292
294
  gate: "open",
293
- pending: [],
295
+ pending: this.globalWarnings.map((notification) => ({
296
+ notification,
297
+ receivedAtMs: Date.now(),
298
+ scope: { threadId }
299
+ })),
294
300
  notificationTail: Promise.resolve(),
295
301
  completedNativeTurnIds: /* @__PURE__ */ new Set(),
296
302
  ignoredTurnNotificationKeys: /* @__PURE__ */ new Set()
@@ -412,6 +418,15 @@ var ClientTurnRouter = class {
412
418
  routeNotification(notification) {
413
419
  if (this.disposed) return;
414
420
  const scope = readScope(notification.params);
421
+ if (!scope.threadId && (notification.method === "configWarning" || notification.method === "warning")) {
422
+ if (this.globalWarnings.length === DEFAULT_GLOBAL_WARNING_LIMIT) this.globalWarnings.shift();
423
+ this.globalWarnings.push(notification);
424
+ for (const route of this.routes.values()) {
425
+ this.bufferNotification(route, notification, { threadId: route.threadId }, Date.now());
426
+ if (route.gate === "bound") this.flushNotifications(route);
427
+ }
428
+ return Promise.all([...this.routes.values()].map((route) => route.notificationTail)).then(() => void 0);
429
+ }
415
430
  const watchers = scope.threadId ? this.nativeTurnCompletionWatchers.get(scope.threadId) : void 0;
416
431
  const route = scope.threadId ? this.routes.get(scope.threadId) : void 0;
417
432
  if (!watchers && !route) return;
@@ -489,6 +504,10 @@ var ClientTurnRouter = class {
489
504
  const handler = route.handlers?.onNotification;
490
505
  if (!handler) return;
491
506
  for (const pending of route.pending.splice(0)) {
507
+ if (route.gate !== "bound" && (pending.notification.method === "configWarning" || pending.notification.method === "warning" && !readScope(pending.notification.params).threadId)) {
508
+ route.pending.push(pending);
509
+ continue;
510
+ }
492
511
  if (route.gate === "bound" && pending.scope.turnId && pending.scope.turnId !== route.turnId) {
493
512
  this.warnDroppedStaleTurnNotification(route, pending.notification, pending.scope);
494
513
  continue;
@@ -1,5 +1,5 @@
1
- import { h as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-CpNeo5AE.js";
2
- import { a as resolveCodexCatalogConnectionHome, t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-DMNQ8Zi8.js";
1
+ import { h as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-giW8X0QA.js";
2
+ import { a as resolveCodexCatalogConnectionHome, t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-C1CAdfcP.js";
3
3
  //#region extensions/codex/src/app-server/binding-connection.ts
4
4
  /** Requires the native model pair after a supervised pending branch has materialized. */
5
5
  function requireCodexSupervisionModelSelection(binding) {
@@ -1,10 +1,10 @@
1
- import { i as resolveCodexAppServerRuntimeOptions } from "./config-CpNeo5AE.js";
2
- import { V as createCodexElicitationResponse, s as isCodexAppServerStartSelectionChangedError, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
3
- import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, o as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-URjUlCHg.js";
4
- import { b as isTerminalTurnStatus, n as normalizeCodexResponseTokenUsage, x as readCodexNotificationItem, y as isRetryableErrorNotification } from "./event-projector-usage-CLwNEJqW.js";
5
- import { a as assertCodexThreadStartResponse, c as readCodexErrorNotification, o as assertCodexTurnStartResponse, u as readCodexTurnCompletedNotification } from "./protocol-validators-VAVyEnDp.js";
6
- import { r as readModelListResult } from "./models-CZw1wClT.js";
7
- import { Z as mergeCodexThreadConfigs, c as buildCodexRingZeroThreadConfigPatch, l as buildCodexRuntimeThreadConfig, o as assertCodexManagedRequirementsDoNotOverrideToolPolicy, s as attestCodexRestrictedToolSurfaceMcpServersDisabled, u as readCodexInheritedMcpServerNames } from "./thread-lifecycle-DKdrnTMX.js";
1
+ import { i as resolveCodexAppServerRuntimeOptions } from "./config-giW8X0QA.js";
2
+ import { K as createCodexElicitationResponse, c as isCodexAppServerStartSelectionChangedError, vt as isJsonObject } from "./shared-client-DKz23hHY.js";
3
+ import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, o as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-bfsmcQ6m.js";
4
+ import { b as isTerminalTurnStatus, n as normalizeCodexResponseTokenUsage, x as readCodexNotificationItem, y as isRetryableErrorNotification } from "./event-projector-usage-Bk1I90Bg.js";
5
+ import { a as assertCodexThreadStartResponse, c as readCodexErrorNotification, o as assertCodexTurnStartResponse, u as readCodexTurnCompletedNotification } from "./protocol-validators-VeJxxJ0U.js";
6
+ import { r as readModelListResult } from "./models-TS3HBU-q.js";
7
+ import { A as attestCodexRestrictedToolSurfaceMcpServersDisabled, M as buildCodexRuntimeThreadConfig, N as readCodexInheritedMcpServerNames, bt as mergeCodexThreadConfigs, j as buildCodexRingZeroThreadConfigPatch, k as assertCodexManagedRequirementsDoNotOverrideToolPolicy } from "./thread-lifecycle-L7oEkTlq.js";
8
8
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import fs from "node:fs/promises";
10
10
  import path from "node:path";
@@ -80,7 +80,7 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
80
80
  config: params.config,
81
81
  timeoutMs,
82
82
  ...params.signal ? { abandonSignal: params.signal } : {}
83
- }) : await import("./shared-client-Dw-rzii0.js").then((n) => n.m).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
83
+ }) : await import("./shared-client-DKz23hHY.js").then((n) => n.y).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
84
84
  startOptions,
85
85
  timeoutMs,
86
86
  ...authSelection,
@@ -1,4 +1,4 @@
1
- import { B as CodexAppServerRpcError } from "./shared-client-Dw-rzii0.js";
1
+ import { G as CodexAppServerRpcError } from "./shared-client-DKz23hHY.js";
2
2
  //#region extensions/codex/src/app-server/capabilities.ts
3
3
  /**
4
4
  * Capability helpers for optional Codex app-server control-plane methods.
@@ -2,7 +2,7 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
2
2
  //#region extensions/codex/cli-metadata.ts
3
3
  function registerCodexCliMetadata(api) {
4
4
  api.registerCli(async ({ program }) => {
5
- const { registerCodexSessionCli } = await import("./session-cli-B1hKvfkI.js");
5
+ const { registerCodexSessionCli } = await import("./session-cli-DMc4oS2w.js");
6
6
  registerCodexSessionCli(program);
7
7
  }, { descriptors: [{
8
8
  name: "codex",
@@ -1,5 +1,5 @@
1
- import { ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
2
- import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-BI1dMHDG.js";
1
+ import { vt as isJsonObject } from "./shared-client-DKz23hHY.js";
2
+ import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-C5_D8Gmb.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/codex/src/command-formatters.ts
5
5
  /**
@@ -1,22 +1,22 @@
1
- import { M as isCodexFastServiceTier, _ as CODEX_PLUGINS_MARKETPLACE_NAME, i as resolveCodexAppServerRuntimeOptions } from "./config-CpNeo5AE.js";
2
- import { U as consumeCodexAppServerLiveThread, a as getLeasedSharedCodexAppServerClient, et as resolveCodexAppServerAuthAccountCacheKey, l as releaseLeasedSharedCodexAppServerClient, nt as resolveCodexAppServerAuthProfileIdForAgent, rt as resolveCodexAppServerFallbackApiKeyCacheKey, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
3
- import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-BTrLf9Qm.js";
4
- import { i as assertCodexThreadResumeResponse } from "./protocol-validators-VAVyEnDp.js";
5
- import { t as listAllCodexAppServerModels } from "./models-CZw1wClT.js";
6
- import { o as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DMNQ8Zi8.js";
7
- import { et as refreshCodexPluginRuntimeState, nt as isOpenAiCuratedMarketplaceName } from "./thread-lifecycle-DKdrnTMX.js";
1
+ import { N as isCodexFastServiceTier, _ as CODEX_PLUGINS_MARKETPLACE_NAME, i as resolveCodexAppServerRuntimeOptions } from "./config-giW8X0QA.js";
2
+ import { J as consumeCodexAppServerLiveThread, ct as resolveCodexAppServerAuthAccountCacheKey, dt as resolveCodexAppServerFallbackApiKeyCacheKey, o as getLeasedSharedCodexAppServerClient, p as releaseLeasedSharedCodexAppServerClient, ut as resolveCodexAppServerAuthProfileIdForAgent, vt as isJsonObject } from "./shared-client-DKz23hHY.js";
3
+ import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-Bcynfd-_.js";
4
+ import { i as assertCodexThreadResumeResponse } from "./protocol-validators-VeJxxJ0U.js";
5
+ import { t as listAllCodexAppServerModels } from "./models-TS3HBU-q.js";
6
+ import { o as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-C1CAdfcP.js";
7
+ import { Ct as refreshCodexPluginRuntimeState, Tt as isOpenAiCuratedMarketplaceName } from "./thread-lifecycle-L7oEkTlq.js";
8
8
  import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
9
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-CH3K57v4.js";
10
- import { s as summarizeCodexAccountUsage } from "./rate-limits-BI1dMHDG.js";
11
- import { a as formatComputerUseStatus, c as formatSkills, i as formatCodexStatus, l as formatThreads, n as formatAccount, o as formatList, r as formatCodexDisplayText, s as formatModels, t as buildHelp } from "./command-formatters-D0nZ3qtd.js";
12
- import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-C1qEeZ5C.js";
13
- import { a as rollbackCodexAppServerBindingSubscription, i as retireCodexConversationThreadBinding, n as releaseCodexAppServerBindingSubscription, o as withCodexConversationThreadActivity, r as retainCodexAppServerBindingSubscription, s as withExclusiveCodexAppServerThread, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-i2NBwDUL.js";
14
- import { a as parseCodexPermissionsModeArg, c as setCodexConversationModel, d as stopCodexConversationTurn, g as hasCodexAdminScope, h as canMutateCodexHost, i as parseCodexFastModeArg, l as setCodexConversationPermissions, m as CODEX_NATIVE_EXECUTION_AUTH_ERROR, n as parseCodexPluginMarketplaceId, o as readCodexConversationActiveTurn, p as CODEX_FULL_PERMISSIONS_AUTH_ERROR, r as formatPermissionsMode, s as setCodexConversationFastMode, t as discoverCodexMarketplacePlugins, u as steerCodexConversationTurn } from "./plugin-marketplace-discovery-CSWDkMrP.js";
9
+ import { t as CODEX_CONTROL_METHODS } from "./capabilities-BRMh0aIq.js";
10
+ import { s as summarizeCodexAccountUsage } from "./rate-limits-C5_D8Gmb.js";
11
+ import { a as formatComputerUseStatus, c as formatSkills, i as formatCodexStatus, l as formatThreads, n as formatAccount, o as formatList, r as formatCodexDisplayText, s as formatModels, t as buildHelp } from "./command-formatters-DEsIufkt.js";
12
+ import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-kuWTn9C5.js";
13
+ import { a as rollbackCodexAppServerBindingSubscription, i as retireCodexConversationThreadBinding, n as releaseCodexAppServerBindingSubscription, o as withCodexConversationThreadActivity, r as retainCodexAppServerBindingSubscription, s as withExclusiveCodexAppServerThread, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-DZeuKH1j.js";
14
+ import { _ as hasCodexAdminScope, a as parseCodexPermissionsModeArg, c as setCodexConversationModel, d as stopCodexConversationTurn, g as canMutateCodexHost, h as CODEX_NATIVE_EXECUTION_AUTH_ERROR, i as parseCodexFastModeArg, l as setCodexConversationPermissions, m as CODEX_HOST_INSPECTION_AUTH_ERROR, n as parseCodexPluginMarketplaceId, o as readCodexConversationActiveTurn, p as CODEX_FULL_PERMISSIONS_AUTH_ERROR, r as formatPermissionsMode, s as setCodexConversationFastMode, t as discoverCodexMarketplacePlugins, u as steerCodexConversationTurn } from "./plugin-marketplace-discovery-B9DvaAG-.js";
15
15
  import { i as readCodexConversationBindingData, n as createCodexCliNodeConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-CW2GuupV.js";
16
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-DAvZwp96.js";
17
- import { l as formatCodexCliSessions } from "./session-catalog-ezP_UcRM.js";
18
- import { i as safeCodexControlRequest, n as readCodexStatusProbes, r as requestOptions, t as codexControlRequest } from "./command-rpc-xUIIonsO.js";
19
- import { i as readCodexComputerUseStatus, r as installCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BXH5NF-4.js";
16
+ import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-BMvPX73o.js";
17
+ import { l as formatCodexCliSessions } from "./session-catalog-DaLKVtpH.js";
18
+ import { i as safeCodexControlRequest, n as readCodexStatusProbes, r as requestOptions, t as codexControlRequest } from "./command-rpc-CCeCkf_v.js";
19
+ import { i as readCodexComputerUseStatus, r as installCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-CTCT3w5L.js";
20
20
  import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
21
21
  import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
22
22
  import crypto from "node:crypto";
@@ -51,8 +51,8 @@ async function readCodexAccountAuthOverview(params) {
51
51
  limits: params.limits,
52
52
  now
53
53
  });
54
- const subscriptionProfileId = order.find((profileId) => isChatGptSubscriptionProfile(store.profiles[profileId]));
55
54
  const activeIsSubscription = activeProfileId !== void 0 && isChatGptSubscriptionProfile(store.profiles[activeProfileId]);
55
+ const subscriptionProfileId = activeIsSubscription ? activeProfileId : order.find((profileId) => isChatGptSubscriptionProfile(store.profiles[profileId]));
56
56
  const activeUsage = activeIsSubscription && params.limits.ok ? summarizeCodexAccountUsage(params.limits.value, now) : void 0;
57
57
  const subscriptionUsage = subscriptionProfileId && (!activeIsSubscription || subscriptionProfileId !== activeProfileId) ? await readSubscriptionUsage({
58
58
  ...params,
@@ -157,13 +157,20 @@ function resolveLiveAccountProfileId(params) {
157
157
  const type = normalizeOptionalString(account.type)?.toLowerCase();
158
158
  if (type === "chatgpt") {
159
159
  const email = normalizeOptionalString(account.email)?.toLowerCase();
160
- const firstSubscription = params.order.find((profileId) => isChatGptSubscriptionProfile(params.store.profiles[profileId]));
161
- if (!email) return firstSubscription;
162
- return params.order.find((profileId) => {
163
- const credential = params.store.profiles[profileId];
164
- if (!credential || !isChatGptSubscriptionProfile(credential)) return false;
165
- return (credential.email?.trim().toLowerCase() ?? extractEmailFromProfileId(profileId))?.toLowerCase() === email;
166
- }) ?? firstSubscription;
160
+ const accountId = normalizeOptionalString(account.accountId ?? account.chatgptAccountId);
161
+ const subscriptionProfiles = params.order.filter((profileId) => isChatGptSubscriptionProfile(params.store.profiles[profileId]));
162
+ if (accountId) {
163
+ const exactWorkspace = subscriptionProfiles.find((profileId) => {
164
+ const credential = params.store.profiles[profileId];
165
+ return credential && "accountId" in credential && credential.accountId === accountId;
166
+ });
167
+ if (exactWorkspace) return exactWorkspace;
168
+ }
169
+ const matchingProfiles = email ? subscriptionProfiles.filter((profileId) => {
170
+ return (params.store.profiles[profileId]?.email?.trim().toLowerCase() ?? extractEmailFromProfileId(profileId))?.toLowerCase() === email;
171
+ }) : subscriptionProfiles;
172
+ const lastGood = params.store.lastGood?.[OPENAI_PROVIDER_ID];
173
+ return (lastGood && matchingProfiles.includes(lastGood) ? lastGood : void 0) ?? matchingProfiles[0] ?? subscriptionProfiles[0];
167
174
  }
168
175
  if (type === "apikey" || type === "api_key") return params.order.find((profileId) => params.store.profiles[profileId]?.type === "api_key");
169
176
  }
@@ -1834,7 +1841,7 @@ async function setConversationModel(deps, ctx, pluginConfig, args) {
1834
1841
  }) : void 0;
1835
1842
  const selectedModel = currentSession && currentSession.sessionId === ctx.sessionId ? currentSession.modelOverride ?? currentSession.model : void 0;
1836
1843
  const binding = await deps.bindingStore.read(target.identity);
1837
- const activeModel = selectedModel ?? binding?.model;
1844
+ const activeModel = target.identity.kind === "conversation" ? binding?.model : selectedModel ?? binding?.model;
1838
1845
  return activeModel ? `Codex model: ${formatCodexDisplayText(activeModel)}` : "Usage: /codex model <model>";
1839
1846
  }
1840
1847
  return await deps.setCodexConversationModel({
@@ -1843,12 +1850,7 @@ async function setConversationModel(deps, ctx, pluginConfig, args) {
1843
1850
  pluginConfig,
1844
1851
  model: normalized,
1845
1852
  agentDir: target.agentDir,
1846
- config: ctx.config,
1847
- ...ctx.sessionId && ctx.sessionKey ? { session: {
1848
- agentId: target.agentId,
1849
- sessionId: ctx.sessionId,
1850
- sessionKey: ctx.sessionKey
1851
- } } : {}
1853
+ config: ctx.config
1852
1854
  });
1853
1855
  }
1854
1856
  async function setConversationFastMode(deps, ctx, args) {
@@ -2293,6 +2295,14 @@ function formatPluginList(plugins, options = {}) {
2293
2295
  }
2294
2296
  //#endregion
2295
2297
  //#region extensions/codex/src/command-handlers.ts
2298
+ const CODEX_HOST_INSPECTION_SUBCOMMANDS = /* @__PURE__ */ new Set([
2299
+ "account",
2300
+ "mcp",
2301
+ "sessions",
2302
+ "skills",
2303
+ "status",
2304
+ "threads"
2305
+ ]);
2296
2306
  async function handleCodexSubcommand(ctx, options) {
2297
2307
  const deps = resolveCodexCommandDeps(options.deps);
2298
2308
  const args = splitArgs(ctx.args);
@@ -2300,6 +2310,7 @@ async function handleCodexSubcommand(ctx, options) {
2300
2310
  const [subcommand = "status", ...rest] = args;
2301
2311
  const normalized = subcommand.toLowerCase();
2302
2312
  if (normalized === "help") return { text: buildHelp() };
2313
+ if (CODEX_HOST_INSPECTION_SUBCOMMANDS.has(normalized) && !canMutateCodexHost(ctx)) return { text: CODEX_HOST_INSPECTION_AUTH_ERROR };
2303
2314
  if (CODEX_NATIVE_CONTROL_SUBCOMMANDS.has(normalized) && !returnsBeforeNativeCodexExecution(normalized, rest) && !isReadOnlyCodexGoalCommand(normalized, rest) && !canMutateCodexHost(ctx)) return { text: CODEX_NATIVE_EXECUTION_AUTH_ERROR };
2304
2315
  const sandboxBlock = resolveCodexNativeCommandSandboxBlock(ctx, normalized, rest);
2305
2316
  if (sandboxBlock) return { text: sandboxBlock };
@@ -1,7 +1,7 @@
1
- import { i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-CpNeo5AE.js";
2
- import { n as listCodexAppServerModels } from "./models-CZw1wClT.js";
3
- import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-CH3K57v4.js";
4
- import { i as withCodexAppServerJsonClient, r as requestCodexAppServerJson } from "./request-DSK0W6YI.js";
1
+ import { i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-giW8X0QA.js";
2
+ import { n as listCodexAppServerModels } from "./models-TS3HBU-q.js";
3
+ import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-BRMh0aIq.js";
4
+ import { i as withCodexAppServerJsonClient, r as requestCodexAppServerJson } from "./request-DXXGHko0.js";
5
5
  //#region extensions/codex/src/command-rpc.ts
6
6
  function requestOptions(pluginConfig, limit, config, agentDir) {
7
7
  const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig });
@@ -1,12 +1,12 @@
1
- import { B as CodexAppServerRpcError, U as consumeCodexAppServerLiveThread, Y as retainCodexAppServerLiveThread, a as getLeasedSharedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
2
- import { d as sessionBindingIdentity, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-BTrLf9Qm.js";
3
- import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, g as readCodexNotificationThreadId, r as CodexAppServerUnsafeSubscriptionError, s as isCodexAlreadyTerminalInterruptError } from "./attempt-client-cleanup-URjUlCHg.js";
4
- import { i as readCodexThreadContextSnapshot, x as readCodexNotificationItem } from "./event-projector-usage-CLwNEJqW.js";
1
+ import { G as CodexAppServerRpcError, J as consumeCodexAppServerLiveThread, et as retainCodexAppServerLiveThread, o as getLeasedSharedCodexAppServerClient, p as releaseLeasedSharedCodexAppServerClient, vt as isJsonObject } from "./shared-client-DKz23hHY.js";
2
+ import { d as sessionBindingIdentity, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-Bcynfd-_.js";
3
+ import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, g as readCodexNotificationThreadId, r as CodexAppServerUnsafeSubscriptionError, s as isCodexAlreadyTerminalInterruptError } from "./attempt-client-cleanup-bfsmcQ6m.js";
4
+ import { i as readCodexThreadContextSnapshot, x as readCodexNotificationItem } from "./event-projector-usage-Bk1I90Bg.js";
5
5
  import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
6
- import { t as resumeCodexAppServerThread } from "./thread-resume-CdJk2Ehf.js";
7
- import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-C1qEeZ5C.js";
8
- import { t as isSameCodexAppServerThreadOwner } from "./thread-ownership-i2NBwDUL.js";
9
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-DAvZwp96.js";
6
+ import { t as resumeCodexAppServerThread } from "./thread-resume-BE9qNEW0.js";
7
+ import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-kuWTn9C5.js";
8
+ import { t as isSameCodexAppServerThreadOwner } from "./thread-ownership-DZeuKH1j.js";
9
+ import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-BMvPX73o.js";
10
10
  import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-BOeJf7yo.js";
11
11
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
12
12
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
@@ -1,4 +1,4 @@
1
- import { asOptionalRecord as readRecord, normalizeOptionalString as readNonEmptyString, normalizeTrimmedStringList, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { asNullableRecord, asOptionalRecord as readRecord, normalizeOptionalString as readNonEmptyString, normalizeTrimmedStringList, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  import path from "node:path";
3
3
  import { resolvePositiveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { AgentHarnessPreflightError } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -118,8 +118,9 @@ function selectGuardianSandbox(allowedSandboxModes) {
118
118
  return "workspace-write";
119
119
  }
120
120
  function resolveApprovalPolicy(value) {
121
+ if (value === "untrusted") throw new Error("Codex app-server approval policy \"untrusted\" is retired; run \"openclaw doctor --fix\" and use \"on-request\".");
121
122
  if (value === "on-failure") return "on-request";
122
- return value === "on-request" || value === "untrusted" || value === "never" ? value : void 0;
123
+ return value === "on-request" || value === "never" ? value : void 0;
123
124
  }
124
125
  function resolveSandbox(value) {
125
126
  return value === "read-only" || value === "workspace-write" || value === "danger-full-access" ? value : void 0;
@@ -434,6 +435,7 @@ function globPatternMatches(value, pattern) {
434
435
  function normalizeRequirementsApprovalPolicy(value) {
435
436
  const normalized = value.trim().toLowerCase();
436
437
  if (normalized === "on-failure") return "on-request";
438
+ if (normalized === "untrusted") return normalized;
437
439
  return resolveApprovalPolicy(normalized);
438
440
  }
439
441
  function normalizeRequirementsApprovalsReviewer(value) {
@@ -441,8 +443,8 @@ function normalizeRequirementsApprovalsReviewer(value) {
441
443
  }
442
444
  function selectGuardianApprovalPolicy(allowedApprovalPolicies, execModeRequiringPromptingApprovals) {
443
445
  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
446
  if (allowedApprovalPolicies.has("untrusted")) return "untrusted";
447
+ if (execModeRequiringPromptingApprovals) throw new Error(`tools.exec.mode=${execModeRequiringPromptingApprovals} requires Codex app-server prompting approvals`);
446
448
  if (allowedApprovalPolicies.has("never")) return "never";
447
449
  return "on-request";
448
450
  }
@@ -461,6 +463,24 @@ function selectUserApprovalsReviewer(allowedApprovalsReviewers, execModeRequirin
461
463
  //#region extensions/codex/src/app-server/config-reviewer.ts
462
464
  const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
463
465
  const CODEX_CONFIG_TOML_FILENAME = "config.toml";
466
+ /** Cloud/system config can redirect reviews after local home/profile checks have passed. */
467
+ async function assertCodexModelBackedReviewerEffectiveConfig(params) {
468
+ 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");
474
+ const modelProvider = effectiveConfig.model_provider;
475
+ const providers = effectiveConfig.model_providers;
476
+ const providerRecords = providers == null ? void 0 : readRecord(providers);
477
+ const provider = providerRecords?.openai;
478
+ const openAIProvider = provider == null ? void 0 : readRecord(provider);
479
+ 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");
480
+ }
481
+ function isTrustedOptionalReviewerEndpoint(value, isTrusted) {
482
+ return value == null || typeof value === "string" && isTrusted(value);
483
+ }
464
484
  function canUseCodexModelBackedApprovalsReviewerForModel(params) {
465
485
  const explicitProvider = params.modelProvider?.trim().toLowerCase();
466
486
  const inferredProvider = inferProviderFromModelRef(params.model);
@@ -513,33 +533,60 @@ function isTrustedCodexModelBackedApprovalsReviewerProvider(provider, params) {
513
533
  model: params.model,
514
534
  agentDir: params.agentDir,
515
535
  codexConfigToml: params.codexConfigToml,
516
- homeScope: params.homeScope
536
+ homeScope: params.homeScope,
537
+ codexArgs: params.codexArgs
517
538
  });
518
539
  }
519
540
  function readCodexBaseUrlOverridesForModelBackedReview(params) {
520
541
  const configToml = readCodexAppServerConfigToml(params);
521
542
  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];
543
+ const configTomls = configToml === void 0 ? [] : [configToml];
544
+ const nativeOverrides = readNativeCodexReviewerConfigOverrides(params);
545
+ if (nativeOverrides === false) return false;
546
+ configTomls.push(...nativeOverrides);
547
+ const openAI = [];
548
+ const chatGPT = [];
549
+ for (const content of configTomls) {
550
+ const topLevelContent = stripTomlLineComments(content).slice(0, firstTomlTableOffset(content));
551
+ const modelProviderOpenAISection = parseTomlTableSection(content, "model_providers.openai");
552
+ const modelProvider = parseTomlStringValue(topLevelContent, "model_provider");
553
+ if (modelProvider === false || modelProvider && modelProvider !== "openai") return false;
554
+ openAI.push(parseTomlStringValue(topLevelContent, "openai_base_url"), parseTomlStringValue(topLevelContent, "model_providers.openai.base_url"), parseInlineOpenAIModelProviderBaseUrl(topLevelContent), modelProviderOpenAISection ? parseTomlStringValue(modelProviderOpenAISection, "base_url") : void 0);
555
+ chatGPT.push(parseTomlStringValue(topLevelContent, "chatgpt_base_url"));
556
+ }
537
557
  if ([...openAI, ...chatGPT].includes(false)) return false;
538
558
  return {
539
559
  openAI: openAI.filter((entry) => typeof entry === "string"),
540
560
  chatGPT: chatGPT.filter((entry) => typeof entry === "string")
541
561
  };
542
562
  }
563
+ function readNativeCodexReviewerConfigOverrides(params) {
564
+ const overrides = [];
565
+ 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`);
577
+ }
578
+ if (profile) {
579
+ if (path.basename(profile) !== profile || profile === "." || profile === "..") return false;
580
+ const configPath = resolveCodexAppServerConfigPath(params);
581
+ if (!configPath) return false;
582
+ try {
583
+ overrides.unshift(readFileSync(path.join(path.dirname(configPath), `${profile}.config.toml`), "utf8"));
584
+ } catch (error) {
585
+ if (readErrorCode(error) !== "ENOENT") return false;
586
+ }
587
+ }
588
+ return overrides;
589
+ }
543
590
  function readCodexAppServerConfigToml(params) {
544
591
  if (params.codexConfigToml !== void 0) return params.codexConfigToml ?? void 0;
545
592
  const configPath = resolveCodexAppServerConfigPath(params);
@@ -689,11 +736,7 @@ const codexAppServerTransportSchema = z.enum([
689
736
  const codexAppServerHomeScopeSchema = z.enum(["agent", "user"]);
690
737
  const SecretInputSchema = buildSecretInputSchema();
691
738
  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
- ]));
739
+ const codexAppServerApprovalPolicySchema = z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum(["never", "on-request"]));
697
740
  const codexAppServerSandboxSchema = z.enum([
698
741
  "read-only",
699
742
  "workspace-write",
@@ -821,6 +864,7 @@ const codexPluginConfigSchema = z.object({
821
864
  }).strict().optional()
822
865
  }).strict();
823
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\".");
824
868
  const parsed = codexPluginConfigSchema.safeParse(value);
825
869
  if (!parsed.success) return {};
826
870
  const { codexPlugins: rawCodexPlugins, ...config } = parsed.data;
@@ -951,6 +995,7 @@ function stableStringifyJson(value) {
951
995
  return JSON.stringify(value);
952
996
  }
953
997
  function withMcpElicitationsApprovalPolicy(policy) {
998
+ if (policy === "untrusted") return policy;
954
999
  if (typeof policy !== "string") return { granular: {
955
1000
  ...policy.granular,
956
1001
  mcp_elicitations: true
@@ -1034,7 +1079,7 @@ function resolveDefaultCodexAppServerPolicy(params) {
1034
1079
  const allowedApprovalPolicies = parseAllowedApprovalPoliciesFromCodexRequirements(content);
1035
1080
  const allowedApprovalsReviewers = parseAllowedApprovalsReviewersFromCodexRequirements(content);
1036
1081
  const yoloSandboxAllowed = allowedSandboxModes === void 0 || allowedSandboxModes.has("danger-full-access");
1037
- const yoloApprovalAllowed = allowedApprovalPolicies === void 0 || allowedApprovalPolicies.has("never");
1082
+ const yoloApprovalAllowed = allowedApprovalPolicies === void 0 || allowedApprovalPolicies.has("never") && !allowedApprovalPolicies.has("untrusted");
1038
1083
  const yoloReviewerAllowed = allowedApprovalsReviewers === void 0 || allowedApprovalsReviewers.has("user");
1039
1084
  if (!params.forceGuardian && yoloSandboxAllowed && yoloApprovalAllowed && yoloReviewerAllowed) return {
1040
1085
  mode: "yolo",
@@ -1114,6 +1159,15 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1114
1159
  const forceGuardianReviewer = execMode === "auto" && canUseModelBackedReviewer;
1115
1160
  const execModeRequiringPromptingApprovals = execMode === "auto" || execMode === "ask" ? execMode : forceUserReviewer ? "ask" : void 0;
1116
1161
  const forceDangerFullAccessSandbox = params.execPolicy?.touched === true && params.execPolicy.security === "full" && params.execPolicy.ask === "always";
1162
+ const forcePerCommandApprovals = params.execPolicy?.ask === "always";
1163
+ const requirementsToml = forcePerCommandApprovals ? readCodexRequirementsToml({
1164
+ env,
1165
+ requirementsToml: params.requirementsToml,
1166
+ requirementsPath: params.requirementsPath,
1167
+ readRequirementsFile: params.readRequirementsFile,
1168
+ platform: params.platform
1169
+ }) ?? null : params.requirementsToml;
1170
+ if (forcePerCommandApprovals && requirementsToml && parseAllowedApprovalPoliciesFromCodexRequirements(requirementsToml)?.has("untrusted") === false) throw new Error("tools.exec.ask=always requires Codex app-server per-command approvals");
1117
1171
  const forceRuntimePolicy = forceUserReviewer || forceGuardianReviewer || forceDangerFullAccessSandbox;
1118
1172
  const defaultPolicy = explicitPolicyMode && !forceRuntimePolicy && !ignoreLegacyYoloPolicyMode ? void 0 : resolveDefaultCodexAppServerPolicy({
1119
1173
  transport,
@@ -1121,7 +1175,7 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1121
1175
  forceGuardian: normalizedPolicyMode === "guardian",
1122
1176
  forceUserReviewer: forceUserReviewer || !canUseModelBackedReviewer,
1123
1177
  execModeRequiringPromptingApprovals,
1124
- requirementsToml: params.requirementsToml,
1178
+ requirementsToml,
1125
1179
  requirementsPath: params.requirementsPath,
1126
1180
  readRequirementsFile: params.readRequirementsFile,
1127
1181
  platform: params.platform,
@@ -1130,7 +1184,7 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
1130
1184
  });
1131
1185
  const preserveExplicitAutoSandbox = forceGuardianReviewer && configuredSandbox === "read-only";
1132
1186
  const forcedPolicy = forceRuntimePolicy ? {
1133
- approvalPolicy: defaultPolicy?.approvalPolicy ?? "on-request",
1187
+ approvalPolicy: forcePerCommandApprovals ? "untrusted" : defaultPolicy?.approvalPolicy ?? "on-request",
1134
1188
  sandbox: preserveExplicitAutoSandbox ? void 0 : forceDangerFullAccessSandbox ? selectForcedDangerFullAccessSandbox({
1135
1189
  configuredSandbox,
1136
1190
  defaultPolicy,
@@ -1332,4 +1386,4 @@ function resolveCodexSupervisionAppServerRuntimeOptions(params = {}) {
1332
1386
  });
1333
1387
  }
1334
1388
  //#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 };
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 };
@@ -293,7 +293,7 @@ async function migrateSource(source, candidates, params, store) {
293
293
  return await withFileLock(source.sidecarPath, LEGACY_BINDING_LOCK_OPTIONS, async () => {
294
294
  const [contents, stat] = await Promise.all([fs.readFile(source.sidecarPath, "utf8"), fs.stat(source.sidecarPath)]);
295
295
  const raw = JSON.parse(contents);
296
- const [{ bindingStoreKey, createStoredCodexAppServerBinding, normalizeStoredCodexAppServerBindingFingerprints, readStoredCodexAppServerBinding }, { legacyCodexConversationBindingId }] = await Promise.all([import("./session-binding-BTrLf9Qm.js").then((n) => n.f), import("./conversation-binding-data-CW2GuupV.js").then((n) => n.t)]);
296
+ const [{ bindingStoreKey, createStoredCodexAppServerBinding, normalizeStoredCodexAppServerBindingFingerprints, readStoredCodexAppServerBinding }, { legacyCodexConversationBindingId }] = await Promise.all([import("./session-binding-Bcynfd-_.js").then((n) => n.f), import("./conversation-binding-data-CW2GuupV.js").then((n) => n.t)]);
297
297
  const agentId = owner?.agentId ?? (source.agentIds.size === 1 ? [...source.agentIds][0] : void 0);
298
298
  const baseStored = createStoredCodexAppServerBinding(raw, {
299
299
  now: stat.mtime.toISOString(),
@@ -537,8 +537,9 @@ function hasLegacyPluginDestructivePolicy(value) {
537
537
  const plugins = asNullableRecord(codexPlugins.plugins);
538
538
  return Object.values(plugins ?? {}).some((plugin) => asNullableRecord(plugin)?.allow_destructive_actions === "on-request");
539
539
  }
540
- function hasRetiredOnFailureApprovalPolicy(value) {
541
- return asNullableRecord(value)?.approvalPolicy === "on-failure";
540
+ function hasRetiredApprovalPolicy(value) {
541
+ const approvalPolicy = asNullableRecord(value)?.approvalPolicy;
542
+ return approvalPolicy === "on-failure" || approvalPolicy === "untrusted";
542
543
  }
543
544
  /** Legacy Codex config keys that doctor should report or repair. */
544
545
  const legacyConfigRules = [
@@ -571,8 +572,8 @@ const legacyConfigRules = [
571
572
  "config",
572
573
  "appServer"
573
574
  ],
574
- message: "plugins.entries.codex.config.appServer.approvalPolicy=\"on-failure\" was retired by Codex 0.143; use \"on-request\". Run \"openclaw doctor --fix\".",
575
- match: hasRetiredOnFailureApprovalPolicy
575
+ message: "plugins.entries.codex.config.appServer.approvalPolicy values \"on-failure\" and \"untrusted\" are retired; use \"on-request\". Run \"openclaw doctor --fix\".",
576
+ match: hasRetiredApprovalPolicy
576
577
  }
577
578
  ];
578
579
  /**
@@ -584,7 +585,7 @@ function normalizeCompatibilityConfig({ cfg }) {
584
585
  const rawAppServer = asNullableRecord(rawPluginConfig?.appServer);
585
586
  const shouldRemoveDynamicToolsProfile = rawPluginConfig !== null && hasRetiredDynamicToolsProfile(rawPluginConfig);
586
587
  const shouldRewriteDestructivePolicy = hasLegacyPluginDestructivePolicy(rawCodexPlugins);
587
- const shouldRewriteApprovalPolicy = hasRetiredOnFailureApprovalPolicy(rawAppServer);
588
+ const shouldRewriteApprovalPolicy = hasRetiredApprovalPolicy(rawAppServer);
588
589
  if (!rawPluginConfig || !shouldRemoveDynamicToolsProfile && !shouldRewriteDestructivePolicy && !shouldRewriteApprovalPolicy) return {
589
590
  config: cfg,
590
591
  changes: []
@@ -612,8 +613,8 @@ function normalizeCompatibilityConfig({ cfg }) {
612
613
  }
613
614
  if (shouldRewriteApprovalPolicy) {
614
615
  const nextAppServer = asNullableRecord(nextPluginConfig.appServer);
615
- if (nextAppServer?.approvalPolicy === "on-failure") nextAppServer.approvalPolicy = "on-request";
616
- changes.push("Renamed plugins.entries.codex.config.appServer.approvalPolicy=\"on-failure\" to \"on-request\".");
616
+ if (nextAppServer?.approvalPolicy === "on-failure" || nextAppServer?.approvalPolicy === "untrusted") nextAppServer.approvalPolicy = "on-request";
617
+ changes.push("Renamed retired plugins.entries.codex.config.appServer.approvalPolicy to \"on-request\".");
617
618
  }
618
619
  return {
619
620
  config: nextConfig,