@openclaw/codex 2026.9.1-beta.1 → 2026.9.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 (73) hide show
  1. package/dist/api.js +5 -6
  2. package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-DYHcRQAa.js} +31 -45
  3. package/dist/attempt-context-DmQUNWwT.js +634 -0
  4. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  5. package/dist/{binding-connection-BMvPX73o.js → binding-connection-E6uDsPlx.js} +2 -2
  6. package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-wzJrwKKe.js} +15 -20
  7. package/dist/{capabilities-BRMh0aIq.js → capabilities-dIjNVCYH.js} +1 -1
  8. package/dist/cli-metadata.js +1 -1
  9. package/dist/{command-formatters-DEsIufkt.js → command-formatters-CLHhEB1Q.js} +5 -4
  10. package/dist/{command-handlers-D_-1_qRp.js → command-handlers-CTGb2csu.js} +124 -101
  11. package/dist/{compact-BglNFZrQ.js → compact-_t0HQrUS.js} +38 -29
  12. package/dist/{config-giW8X0QA.js → config-BhmfC1s6.js} +294 -282
  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 +143 -12
  16. package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BU9tmlYm.js} +599 -655
  17. package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
  18. package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
  19. package/dist/{event-projector-usage-Bk1I90Bg.js → event-projector-usage-C5mcrGjp.js} +15 -148
  20. package/dist/{harness-Csz0F-DK.js → harness-DXVZ5II5.js} +42 -52
  21. package/dist/harness.js +1 -1
  22. package/dist/index.js +458 -404
  23. package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-kg9kv4iH.js} +4 -4
  24. package/dist/launch-args-RXQwn8zV.js +90 -0
  25. package/dist/{managed-binary-DFYK4DWq.js → managed-binary-4-Vjz5GH.js} +14 -9
  26. package/dist/media-understanding-provider.js +1 -1
  27. package/dist/model-catalog-CUM68Hkl.js +101 -0
  28. package/dist/{models-TS3HBU-q.js → models-sYnEc0gd.js} +25 -28
  29. package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-CnH147jH.js} +55 -115
  30. package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-CstNHCmC.js} +9 -6
  31. package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-CNe-Xrjx.js} +30 -3
  32. package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-CfFlKqDl.js} +15 -14
  33. package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BFrPhb2c.js} +6 -6
  34. package/dist/provider-capabilities-DW5p4k9w.js +101 -0
  35. package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-CawQJfUS.js} +3 -2
  36. package/dist/{sandbox-guard-kuWTn9C5.js → request-DYAI5FQE.js} +195 -2
  37. package/dist/{run-attempt-DYc0QCBF.js → run-attempt-D1hJO4fX.js} +828 -2100
  38. package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-C3jVimFn.js} +21 -14
  39. package/dist/{session-binding-Bcynfd-_.js → session-binding-BHuTCRZQ.js} +198 -127
  40. package/dist/{session-catalog-DaLKVtpH.js → session-catalog-yyvTWFOw.js} +564 -408
  41. package/dist/{session-cli-DMc4oS2w.js → session-cli-CmFEXMAM.js} +1 -1
  42. package/dist/session-history-C5J1AKzG.js +87 -0
  43. package/dist/session-initialization-BeWzjGiR.js +74 -0
  44. package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-DeWVTCMj.js} +2 -2
  45. package/dist/session-retirement-BujDjXVF.js +97 -0
  46. package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-C351-5Qw.js} +19 -4
  47. package/dist/settled-turn-context-D3SNWtUn.js +268 -0
  48. package/dist/settled-turn-finalizer-BVJx4yoc.js +104 -0
  49. package/dist/{shared-client-DKz23hHY.js → shared-client-DxcfF9KX.js} +3480 -679
  50. package/dist/{side-question-DjA_jsNe.js → side-question-BTZAII4l.js} +108 -70
  51. package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DAcEJ_Om.js} +2188 -1915
  52. package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-zGokd8i1.js} +25 -14
  53. package/dist/thread-policy-g4KbJPzp.js +54 -0
  54. package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-C7pyVKeW.js} +59 -7
  55. package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-DTUxFWa_.js} +79 -17
  56. package/dist/transport-stdio-CyPldczm.js +726 -0
  57. package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
  58. package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
  59. package/dist/{usage-ROIaW3wo.js → usage-Bj-rrzkR.js} +3 -3
  60. package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
  61. package/openclaw.plugin.json +1 -30
  62. package/package.json +6 -6
  63. package/dist/command-rpc-CCeCkf_v.js +0 -90
  64. package/dist/incognito-session-ET_ufDH-.js +0 -2
  65. package/dist/model-catalog-i9rNBthX.js +0 -48
  66. package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
  67. package/dist/request-DXXGHko0.js +0 -157
  68. package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
  69. package/dist/session-retirement-CcNC3YSY.js +0 -36
  70. package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
  71. package/dist/thread-resume-BE9qNEW0.js +0 -30
  72. package/dist/transport-stdio-DhoGy33Z.js +0 -99
  73. package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
@@ -1,5 +1,5 @@
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";
1
+ import { E as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
2
+ import { n as buildCodexAppServerConnectionFingerprint, o as resolveCodexCatalogConnectionHome } from "./thread-resume-C7pyVKeW.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-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";
1
+ import { $t as isJsonObject, at as readCodexTurnCompletedNotification, et as assertCodexThreadStartResponse, ot as createCodexElicitationResponse, rt as readCodexErrorNotification, tt as assertCodexTurnStartResponse, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-DxcfF9KX.js";
2
+ import { r as readCodexAppServerConfigOptions } from "./launch-args-RXQwn8zV.js";
3
+ import { i as resolveCodexAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
4
+ import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, o as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-DYHcRQAa.js";
5
+ import { d as isTerminalTurnStatus, f as readCodexNotificationItem, n as normalizeCodexResponseTokenUsage, u as isRetryableErrorNotification } from "./event-projector-usage-C5mcrGjp.js";
6
+ import { r as readModelListResult } from "./models-sYnEc0gd.js";
7
+ import { Dt as mergeCodexThreadConfigs, G as attestCodexRestrictedToolSurfaceMcpServersDisabled, _ as buildCodexRingZeroThreadConfigPatch, b as readCodexInheritedMcpServerNames, g as assertCodexManagedRequirementsDoNotOverrideToolPolicy, v as buildCodexRuntimeThreadConfig } from "./thread-lifecycle-DAcEJ_Om.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";
@@ -65,11 +65,7 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
65
65
  const timeoutMs = deadline - Date.now();
66
66
  if (timeoutMs <= 0) throw timeoutError;
67
67
  const agentDir = params.agentDir?.trim() || void 0;
68
- const isolatedStartOptions = workspace.codexHome ? buildPrivateCodexAppServerStartOptions(appServer.start, workspace.codexHome) : appServer.start;
69
- const startOptions = workspace.codexHome && params.preparedAuth ? {
70
- ...isolatedStartOptions,
71
- homeScope: "agent"
72
- } : isolatedStartOptions;
68
+ const startOptions = workspace.codexHome ? buildPrivateCodexAppServerStartOptions(appServer.start, workspace.codexHome) : appServer.start;
73
69
  const ownsClient = !params.options.clientFactory;
74
70
  const authSelection = params.preparedAuth ? { preparedAuth: params.preparedAuth } : { authProfileId: params.profile };
75
71
  const client = params.options.clientFactory ? await params.options.clientFactory({
@@ -80,7 +76,7 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
80
76
  config: params.config,
81
77
  timeoutMs,
82
78
  ...params.signal ? { abandonSignal: params.signal } : {}
83
- }) : await import("./shared-client-DKz23hHY.js").then((n) => n.y).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
79
+ }) : await import("./shared-client-DxcfF9KX.js").then((n) => n.x).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
84
80
  startOptions,
85
81
  timeoutMs,
86
82
  ...authSelection,
@@ -204,10 +200,7 @@ function resolveBoundedThreadConfig(params, workspace, inheritedMcpServerNames)
204
200
  return mergeCodexThreadConfigs(privateConfig, CODEX_SETTLED_FINALIZER_THREAD_CONFIG, buildCodexRingZeroThreadConfigPatch({ toolsAllow: ["openclaw"] }, true, inheritedMcpServerNames)) ?? privateConfig;
205
201
  }
206
202
  function buildPrivateCodexAppServerStartOptions(start, codexHome) {
207
- const providerArgs = start.args.flatMap((arg, index) => {
208
- const override = arg === "-c" || arg === "--config" ? start.args[index + 1] : arg.startsWith("--config=") ? arg.slice(9) : void 0;
209
- return override && /^\s*(?:openai_base_url|model_catalog_json)\s*=/u.test(override) ? ["-c", override] : [];
210
- });
203
+ const providerArgs = readCodexAppServerConfigOptions(start.args).flatMap(({ name, value }) => (name === "-c" || name === "--config") && value && /^\s*(?:openai_base_url|model_catalog_json)\s*=/u.test(value) ? ["-c", value] : []);
211
204
  const privateEnv = Object.fromEntries(Object.entries(start.env ?? {}).filter(([name]) => name.trim().toUpperCase() !== CODEX_APP_SERVER_ARGS_ENV_KEY));
212
205
  const clearEnv = (start.clearEnv ?? []).filter((name) => {
213
206
  const normalized = name.trim().toUpperCase();
@@ -215,6 +208,7 @@ function buildPrivateCodexAppServerStartOptions(start, codexHome) {
215
208
  });
216
209
  return {
217
210
  ...start,
211
+ homeScope: "agent",
218
212
  args: [
219
213
  "app-server",
220
214
  ...providerArgs,
@@ -246,14 +240,15 @@ function createCodexBoundedApprovalHandler(taskLabel) {
246
240
  };
247
241
  }
248
242
  async function resolveCodexBoundedTurnModel(params) {
249
- const listed = readModelListResult(await params.client.request("model/list", {
243
+ const result = await params.client.request("model/list", {
250
244
  limit: null,
251
245
  cursor: null,
252
- includeHidden: false
246
+ includeHidden: params.selection.mode === "required"
253
247
  }, {
254
248
  timeoutMs: Math.min(params.timeoutMs, 5e3),
255
249
  signal: params.signal
256
- })).models;
250
+ });
251
+ const listed = readModelListResult(result).models;
257
252
  if (params.selection.mode === "live-default") {
258
253
  const supported = listed.filter((entry) => params.requiredModalities.every((modality) => entry.inputModalities.includes(modality)));
259
254
  const selected = supported.find((entry) => entry.isDefault) ?? supported[0];
@@ -1,4 +1,4 @@
1
- import { G as CodexAppServerRpcError } from "./shared-client-DKz23hHY.js";
1
+ import { q as CodexAppServerRpcError } from "./shared-client-DxcfF9KX.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-DMc4oS2w.js");
5
+ const { registerCodexSessionCli } = await import("./session-cli-CmFEXMAM.js");
6
6
  registerCodexSessionCli(program);
7
7
  }, { descriptors: [{
8
8
  name: "codex",
@@ -1,5 +1,5 @@
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";
1
+ import { $t as isJsonObject } from "./shared-client-DxcfF9KX.js";
2
+ import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-CawQJfUS.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/codex/src/command-formatters.ts
5
5
  /**
@@ -118,7 +118,8 @@ function formatSkills(response) {
118
118
  return lines.join("\n");
119
119
  }
120
120
  function formatCodexSkillEntry(entry) {
121
- return `\`${formatCodexDisplayText(normalizeOptionalString((isJsonObject(entry) ? entry : {}).name) ?? "<unknown>")}\``;
121
+ const record = isJsonObject(entry) ? entry : {};
122
+ return `\`${formatCodexDisplayText(normalizeOptionalString(record.name) ?? "<unknown>")}\``;
122
123
  }
123
124
  const CODEX_RESUME_SAFE_THREAD_ID_PATTERN = /^[A-Za-z0-9._:-]+$/;
124
125
  function formatCodexResumeHint(threadId) {
@@ -278,4 +279,4 @@ function extractArray(value) {
278
279
  return [];
279
280
  }
280
281
  //#endregion
281
- export { formatComputerUseStatus as a, formatSkills as c, formatCodexStatus as i, formatThreads as l, formatAccount as n, formatList as o, formatCodexDisplayText as r, formatModels as s, buildHelp as t };
282
+ export { formatCodexDisplayText as a, formatComputerUseStatus as c, formatSkills as d, formatThreads as f, formatAccount as i, formatList as l, buildHelp as n, formatCodexStatus as o, escapeCodexChatText as r, formatCodexTextForDisplay as s, CODEX_RESUME_SAFE_THREAD_ID_PATTERN as t, formatModels as u };
@@ -1,26 +1,28 @@
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
- import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.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
- 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-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";
1
+ import { $ as assertCodexThreadResumeResponse, $t as isJsonObject, Bt as resolveCodexAppServerAuthProfileIdForAgent, Ht as resolveCodexAppServerFallbackApiKeyCacheKey, Rt as resolveCodexAppServerAuthAccountCacheKey, St as consumeCodexAppServerLiveThread, X as assertCodexThreadAcceptsDirectInput, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, wt as hasCodexAppServerLiveThread } from "./shared-client-DxcfF9KX.js";
2
+ import { A as isCodexFastServiceTier, M as CODEX_PLUGINS_MARKETPLACE_NAME, i as resolveCodexAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
3
+ import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-BHuTCRZQ.js";
4
+ import { a as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-DYHcRQAa.js";
5
+ import { t as listAllCodexAppServerModels } from "./models-sYnEc0gd.js";
6
+ import { i as buildCodexPluginAppCacheKey, s as defaultCodexAppInventoryCache } from "./thread-resume-C7pyVKeW.js";
7
+ import { At as refreshCodexPluginRuntimeState, Mt as isOpenAiCuratedMarketplaceName } from "./thread-lifecycle-DAcEJ_Om.js";
8
+ import { a as rollbackCodexAppServerBindingSubscription, c as withExclusiveCodexAppServerThread, i as retireCodexConversationThreadBinding, l as isIncognitoSessionKey, n as releaseCodexAppServerBindingSubscription, r as retainCodexAppServerBindingSubscription, s as withCodexConversationThreadActivity, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-zGokd8i1.js";
9
+ import { c as resolveCodexNativeSandboxBlock, s as resolveCodexNativeExecutionBlock } from "./request-DYAI5FQE.js";
10
+ import { r as assertCodexSupervisionThreadLineage } from "./thread-policy-g4KbJPzp.js";
11
+ import { t as CODEX_CONTROL_METHODS } from "./capabilities-dIjNVCYH.js";
12
+ import { s as summarizeCodexAccountUsage } from "./rate-limits-CawQJfUS.js";
13
+ import { a as formatCodexDisplayText, c as formatComputerUseStatus, d as formatSkills, f as formatThreads, i as formatAccount, l as formatList, n as buildHelp, o as formatCodexStatus, r as escapeCodexChatText, s as formatCodexTextForDisplay, t as CODEX_RESUME_SAFE_THREAD_ID_PATTERN, u as formatModels } from "./command-formatters-CLHhEB1Q.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-CfFlKqDl.js";
15
+ import { i as readCodexConversationBindingData, n as createCodexCliNodeConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-BiodpIzq.js";
16
+ import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-E6uDsPlx.js";
17
+ import { c as readCodexStatusProbes, l as requestOptions, p as formatCodexCliSessions, s as codexControlRequest, u as safeCodexControlRequest } from "./session-catalog-yyvTWFOw.js";
18
+ import { i as readCodexComputerUseStatus, r as installCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BFrPhb2c.js";
20
19
  import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
21
20
  import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
22
21
  import crypto from "node:crypto";
23
- import { ensureAuthProfileStore, findNormalizedProviderValue, resolveAgentDir, resolveAuthProfileEligibility, resolveAuthProfileOrder, resolveProfileUnusableUntilForDisplay, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
22
+ import { isDeepStrictEqual } from "node:util";
23
+ import { ensureAuthProfileStore, resolveAgentDir, resolveAuthProfileEligibility, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
24
+ import { findNormalizedProviderValue, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
25
+ import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
24
26
  import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
25
27
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
26
28
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
@@ -591,7 +593,8 @@ function parseCodexCliSessionsArgs(args) {
591
593
  continue;
592
594
  }
593
595
  if (arg === "--limit") {
594
- const parsedLimit = parseStrictPositiveInteger(readRequiredOptionValue(args, index));
596
+ const value = readRequiredOptionValue(args, index);
597
+ const parsedLimit = parseStrictPositiveInteger(value);
595
598
  if (parsedLimit === void 0) {
596
599
  parsed.help = true;
597
600
  continue;
@@ -752,11 +755,10 @@ const CODEX_DIAGNOSTICS_COOLDOWN_MS = 6e4;
752
755
  const CODEX_DIAGNOSTICS_ERROR_MAX_CHARS = 500;
753
756
  const CODEX_DIAGNOSTICS_COOLDOWN_MAX_THREADS = 100;
754
757
  const CODEX_DIAGNOSTICS_COOLDOWN_MAX_SCOPES = 100;
755
- const CODEX_DIAGNOSTICS_CONFIRMATION_TTL_MS = 5 * 6e4;
758
+ const CODEX_DIAGNOSTICS_CONFIRMATION_TTL_MS = 3e5;
756
759
  const CODEX_DIAGNOSTICS_CONFIRMATION_MAX_REQUESTS_PER_SCOPE = 100;
757
760
  const CODEX_DIAGNOSTICS_CONFIRMATION_MAX_SCOPES = 100;
758
761
  const CODEX_DIAGNOSTICS_SCOPE_FIELD_MAX_CHARS = 128;
759
- const CODEX_RESUME_SAFE_THREAD_ID_PATTERN = /^[A-Za-z0-9._:-]+$/;
760
762
  const { lastUploadByThread: lastCodexDiagnosticsUploadByThread, lastUploadByScope: lastCodexDiagnosticsUploadByScope, pendingConfirmations: pendingCodexDiagnosticsConfirmations, pendingTokensByScope: pendingCodexDiagnosticsConfirmationTokensByScope } = codexDiagnosticsFeedbackState;
761
763
  function normalizeDiagnosticsReason(note) {
762
764
  const normalized = normalizeOptionalString(note);
@@ -909,7 +911,7 @@ function formatCodexDiagnosticsTargetLines(targets) {
909
911
  }
910
912
  function formatCodexDiagnosticsTargetBlock(target, index) {
911
913
  const lines = [`Session ${index + 1}`];
912
- if (target.channel) lines.push(`Channel: ${formatCodexValueForDisplay(target.channel)}`);
914
+ if (target.channel) lines.push(`Channel: ${formatCodexDisplayText(target.channel)}`);
913
915
  if (target.sessionKey) lines.push(`OpenClaw session key: ${formatCodexCopyableValueForDisplay(target.sessionKey)}`);
914
916
  if (target.sessionId) lines.push(`OpenClaw session id: ${formatCodexCopyableValueForDisplay(target.sessionId)}`);
915
917
  lines.push(`Codex thread id: ${formatCodexCopyableValueForDisplay(target.threadId)}`);
@@ -918,30 +920,18 @@ function formatCodexDiagnosticsTargetBlock(target, index) {
918
920
  }
919
921
  function formatCodexDiagnosticsTargetLine(target) {
920
922
  const parts = [];
921
- if (target.channel) parts.push(`channel ${formatCodexValueForDisplay(target.channel)}`);
923
+ if (target.channel) parts.push(`channel ${formatCodexDisplayText(target.channel)}`);
922
924
  const sessionLabel = target.sessionId || target.sessionKey;
923
- if (sessionLabel) parts.push(`OpenClaw session ${formatCodexValueForDisplay(sessionLabel)}`);
924
- parts.push(`Codex thread ${formatCodexThreadIdForDisplay(target.threadId)}`);
925
+ if (sessionLabel) parts.push(`OpenClaw session ${formatCodexDisplayText(sessionLabel)}`);
926
+ parts.push(`Codex thread ${formatCodexDisplayText(target.threadId)}`);
925
927
  return `- ${parts.join(", ")}`;
926
928
  }
927
- function escapeCodexChatText(value) {
928
- return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("@", "@").replaceAll("`", "`").replaceAll("[", "[").replaceAll("]", "]").replaceAll("(", "(").replaceAll(")", ")").replaceAll("*", "∗").replaceAll("_", "_").replaceAll("~", "~").replaceAll("|", "|");
929
- }
930
- function formatCodexTextForDisplay(value) {
931
- let safe = "";
932
- for (const character of value) {
933
- const codePoint = character.codePointAt(0);
934
- safe += codePoint != null && isUnsafeDisplayCodePoint(codePoint) ? "?" : character;
935
- }
936
- safe = safe.trim();
937
- return safe || "<unknown>";
938
- }
939
929
  function readCodexDiagnosticsTargetsCooldownMessage(targets, ctx, now, options = {}) {
940
930
  for (const target of targets) {
941
931
  const cooldownMs = readCodexDiagnosticsCooldownMs(target.threadId, now);
942
932
  if (cooldownMs > 0) {
943
933
  if (options.includeThreadId === false) return `Codex diagnostics were already sent for one of these Codex threads recently. Try again in ${Math.ceil(cooldownMs / 1e3)}s.`;
944
- return `Codex diagnostics were already sent for thread ${formatCodexThreadIdForDisplay(target.threadId)} recently. Try again in ${Math.ceil(cooldownMs / 1e3)}s.`;
934
+ return `Codex diagnostics were already sent for thread ${formatCodexDisplayText(target.threadId)} recently. Try again in ${Math.ceil(cooldownMs / 1e3)}s.`;
945
935
  }
946
936
  }
947
937
  const scopeCooldownMs = readCodexDiagnosticsScopeCooldownMs(options.cooldownScope ?? readCodexDiagnosticsCooldownScope(ctx), now);
@@ -973,12 +963,6 @@ function buildDiagnosticsTags(ctx) {
973
963
  function addTag(tags, key, value) {
974
964
  if (typeof value === "string" && value.trim()) tags[key] = value.trim();
975
965
  }
976
- function formatCodexThreadIdForDisplay(threadId) {
977
- return escapeCodexChatText(formatCodexTextForDisplay(threadId));
978
- }
979
- function formatCodexValueForDisplay(value) {
980
- return escapeCodexChatText(formatCodexTextForDisplay(value));
981
- }
982
966
  function formatCodexCopyableValueForDisplay(value) {
983
967
  const safe = formatCodexTextForDisplay(value);
984
968
  if (CODEX_RESUME_SAFE_THREAD_ID_PATTERN.test(safe)) return `\`${safe}\``;
@@ -1014,16 +998,14 @@ function pruneCodexDiagnosticsCooldownMap(map, now) {
1014
998
  for (const [key, lastSentAt] of map) if (now - lastSentAt >= CODEX_DIAGNOSTICS_COOLDOWN_MS) map.delete(key);
1015
999
  }
1016
1000
  function formatCodexErrorForDisplay(error) {
1017
- return escapeCodexChatText(truncateUtf16Safe(formatCodexTextForDisplay(error), CODEX_DIAGNOSTICS_ERROR_MAX_CHARS)) || "unknown error";
1001
+ const safe = truncateUtf16Safe(formatCodexTextForDisplay(error), CODEX_DIAGNOSTICS_ERROR_MAX_CHARS);
1002
+ return escapeCodexChatText(safe) || "unknown error";
1018
1003
  }
1019
1004
  function formatCodexResumeCommandForDisplay(threadId) {
1020
1005
  const safeThreadId = formatCodexTextForDisplay(threadId);
1021
1006
  if (!CODEX_RESUME_SAFE_THREAD_ID_PATTERN.test(safeThreadId)) return "run codex resume and paste the thread id shown above";
1022
1007
  return `\`codex resume ${safeThreadId}\``;
1023
1008
  }
1024
- function isUnsafeDisplayCodePoint(codePoint) {
1025
- return codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint === 173 || codePoint === 1564 || codePoint === 6158 || codePoint >= 8203 && codePoint <= 8207 || codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8288 && codePoint <= 8303 || codePoint === 65279 || codePoint >= 65529 && codePoint <= 65531 || codePoint >= 917504 && codePoint <= 917631;
1026
- }
1027
1009
  function normalizeCodexDiagnosticsScopeField(value) {
1028
1010
  const normalized = normalizeOptionalString(value);
1029
1011
  if (!normalized) return;
@@ -1063,7 +1045,8 @@ function resolveCodexCommandDeps(overrides) {
1063
1045
  //#endregion
1064
1046
  //#region extensions/codex/src/command-handler-scope.ts
1065
1047
  async function resolveControlTarget(ctx) {
1066
- const data = readCodexConversationBindingData(await ctx.getCurrentConversationBinding());
1048
+ const binding = await ctx.getCurrentConversationBinding();
1049
+ const data = readCodexConversationBindingData(binding);
1067
1050
  const scope = resolveCodexConversationControlScope(ctx);
1068
1051
  if (data?.kind === "codex-app-server-session") return {
1069
1052
  identity: conversationBindingIdentity(data.bindingId),
@@ -1087,13 +1070,14 @@ async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
1087
1070
  const fallback = resolveCodexConversationControlScope(ctx);
1088
1071
  const agentDir = target?.agentDir ?? fallback.agentDir;
1089
1072
  const binding = target ? await deps.bindingStore.read(target.identity) : void 0;
1073
+ const authProfileId = binding?.connectionScope === "supervision" ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
1074
+ authProfileId: binding?.authProfileId ?? target?.requestedAuthProfileId,
1075
+ agentDir,
1076
+ config: ctx.config
1077
+ });
1090
1078
  const connection = resolveCodexBindingAppServerConnection({
1091
1079
  binding,
1092
- authProfileId: binding?.connectionScope === "supervision" ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
1093
- authProfileId: binding?.authProfileId ?? target?.requestedAuthProfileId,
1094
- agentDir,
1095
- config: ctx.config
1096
- }),
1080
+ authProfileId,
1097
1081
  pluginConfig
1098
1082
  });
1099
1083
  return {
@@ -1112,7 +1096,7 @@ function conversationBindingIdentity(bindingId) {
1112
1096
  };
1113
1097
  }
1114
1098
  function resolveCodexConversationControlScope(ctx) {
1115
- const { sessionAgentId } = resolveSessionAgentIds({
1099
+ const { sessionAgentId } = resolveSessionAgentIdsStrict({
1116
1100
  sessionKey: ctx.sessionKey,
1117
1101
  agentId: ctx.agentId,
1118
1102
  config: ctx.config
@@ -1155,7 +1139,7 @@ async function requestCodexDiagnosticsFeedbackApproval(deps, ctx, note, commandP
1155
1139
  });
1156
1140
  const confirmCommand = `${commandPrefix} confirm ${token}`;
1157
1141
  const cancelCommand = `${commandPrefix} cancel ${token}`;
1158
- const displayReason = reason ? escapeCodexChatText(formatCodexTextForDisplay(reason)) : void 0;
1142
+ const displayReason = reason ? formatCodexDisplayText(reason) : void 0;
1159
1143
  return {
1160
1144
  text: [
1161
1145
  targets.length === 1 ? "Codex runtime thread detected." : "Codex runtime threads detected.",
@@ -1197,7 +1181,7 @@ async function previewCodexDiagnosticsFeedbackApproval(deps, ctx, note) {
1197
1181
  const cooldownMessage = readCodexDiagnosticsTargetsCooldownMessage(targets, ctx, Date.now(), { includeThreadId: false });
1198
1182
  if (cooldownMessage) return cooldownMessage;
1199
1183
  const reason = normalizeDiagnosticsReason(note);
1200
- const displayReason = reason ? escapeCodexChatText(formatCodexTextForDisplay(reason)) : void 0;
1184
+ const displayReason = reason ? formatCodexDisplayText(reason) : void 0;
1201
1185
  return [
1202
1186
  targets.length === 1 ? "Codex runtime thread detected." : "Codex runtime threads detected.",
1203
1187
  `Approving diagnostics will also send ${targets.length === 1 ? "this thread's feedback bundle" : "these threads' feedback bundles"} to OpenAI servers.`,
@@ -1392,8 +1376,9 @@ function isCurrentSessionModelSelectionLocked(ctx) {
1392
1376
  const sessionKey = ctx.sessionKey?.trim();
1393
1377
  if (!sessionKey) return false;
1394
1378
  const { agentId } = resolveCodexConversationControlScope(ctx);
1379
+ const storePath = resolveStorePath(ctx.config.session?.store, { agentId });
1395
1380
  return isModelSelectionLocked(getSessionEntry({
1396
- storePath: resolveStorePath(ctx.config.session?.store, { agentId }),
1381
+ storePath,
1397
1382
  sessionKey,
1398
1383
  hydrateSkillPromptRefs: false,
1399
1384
  readConsistency: "latest"
@@ -1450,7 +1435,8 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
1450
1435
  }
1451
1436
  async function detachConversation(deps, ctx) {
1452
1437
  if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
1453
- const data = readCodexConversationBindingData(await ctx.getCurrentConversationBinding());
1438
+ const current = await ctx.getCurrentConversationBinding();
1439
+ const data = readCodexConversationBindingData(current);
1454
1440
  const identity = data?.kind === "codex-app-server-session" ? conversationBindingIdentity(data.bindingId) : void 0;
1455
1441
  const sourceSessionKey = data?.kind === "codex-app-server-session" ? data.source?.sessionKey : void 0;
1456
1442
  let expectedThreadId;
@@ -1519,13 +1505,14 @@ async function describeConversationBinding(deps, ctx) {
1519
1505
  }
1520
1506
  async function buildThreads(deps, ctx, pluginConfig, filter) {
1521
1507
  const scope = await resolveCommandAppServerScope(deps, ctx, pluginConfig);
1522
- return formatThreads(await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.listThreads, {
1508
+ const response = await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.listThreads, {
1523
1509
  limit: 10,
1524
1510
  ...filter.trim() ? { searchTerm: filter.trim() } : {}
1525
1511
  }, {
1526
1512
  config: ctx.config,
1527
1513
  ...scope
1528
- }));
1514
+ });
1515
+ return formatThreads(response);
1529
1516
  }
1530
1517
  async function buildCodexCliSessions(deps, args) {
1531
1518
  const parsed = parseCodexCliSessionsArgs(args);
@@ -1563,13 +1550,8 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
1563
1550
  })) throw createCodexSessionGenerationSupersededError(identity.sessionId);
1564
1551
  const currentBinding = await deps.bindingStore.read(identity);
1565
1552
  assertCodexBindingMayBeReplaced(currentBinding, "attaching a different resumed thread");
1566
- const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
1567
- authProfileId: currentBinding?.authProfileId,
1568
- agentDir: scope.agentDir,
1569
- config: ctx.config
1570
- });
1571
- let committedResponse = false;
1572
- const commitResumedThread = async (value, client) => {
1553
+ let pendingResumeConfiguration = false;
1554
+ const commitResumedThread = async (value, client, { authProfileId, assertCurrent }) => {
1573
1555
  const response = assertCodexThreadResumeResponse(value);
1574
1556
  const effectiveThreadId = response.thread.id;
1575
1557
  if (effectiveThreadId !== normalizedThreadId) throw new Error(`Codex thread/resume returned ${effectiveThreadId} for ${normalizedThreadId}`);
@@ -1581,52 +1563,73 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
1581
1563
  agentDir: scope.agentDir,
1582
1564
  config: ctx.config
1583
1565
  });
1584
- const bindingBeforeCommit = await deps.bindingStore.read(identity);
1585
- assertCodexBindingMayBeReplaced(bindingBeforeCommit, "committing a different resumed thread");
1586
- const clientId = client?.getInstanceId();
1587
- const sameOwner = client ? isSameCodexAppServerThreadOwner(bindingBeforeCommit, {
1588
- threadId: effectiveThreadId,
1589
- clientId
1590
- }) : bindingBeforeCommit?.threadId === effectiveThreadId;
1566
+ const clientId = client.getInstanceId();
1591
1567
  let retained = false;
1568
+ let sameOwner = false;
1569
+ let knownOwnership;
1592
1570
  try {
1593
- if (client) {
1594
- retained = await retainCodexAppServerBindingSubscription(client, effectiveThreadId, sameOwner ? await consumeCodexAppServerLiveThread(client, effectiveThreadId) : void 0);
1595
- if (!retained) throw new Error("Codex resumed thread lost its native subscription owner.");
1596
- }
1571
+ const bindingBeforeCommit = await deps.bindingStore.read(identity);
1572
+ assertCodexBindingMayBeReplaced(bindingBeforeCommit, "committing a different resumed thread");
1573
+ sameOwner = isSameCodexAppServerThreadOwner(bindingBeforeCommit, {
1574
+ threadId: effectiveThreadId,
1575
+ clientId
1576
+ });
1577
+ const sameThreadBinding = bindingBeforeCommit?.threadId === effectiveThreadId ? bindingBeforeCommit : void 0;
1578
+ pendingResumeConfiguration = sameThreadBinding?.preserveNativeModel !== true && (!sameThreadBinding?.dynamicToolsFingerprint || !sameThreadBinding.webSearchThreadConfigFingerprint || sameThreadBinding.pendingResumeConfiguration === true);
1579
+ assertCurrent();
1580
+ assertCodexThreadAcceptsDirectInput(response.thread);
1581
+ knownOwnership = sameOwner ? await consumeCodexAppServerLiveThread(client, effectiveThreadId) : void 0;
1582
+ assertCurrent();
1583
+ retained = await retainCodexAppServerBindingSubscription(client, effectiveThreadId, knownOwnership);
1584
+ assertCurrent();
1585
+ if (!retained) throw new Error("Codex resumed thread lost its native subscription owner.");
1597
1586
  if (bindingBeforeCommit && !sameOwner) await releaseCodexAppServerBindingSubscription(bindingBeforeCommit);
1587
+ assertCurrent();
1598
1588
  if (!await deps.bindingStore.mutate(identity, {
1599
1589
  kind: "set",
1600
1590
  binding: {
1601
- ...bindingBeforeCommit?.threadId === effectiveThreadId ? bindingBeforeCommit : {},
1591
+ ...sameThreadBinding,
1602
1592
  threadId: effectiveThreadId,
1603
- ...clientId ? { clientId } : {},
1593
+ clientId,
1604
1594
  cwd: resumedCwd,
1595
+ rolloutPath: response.thread.path ?? sameThreadBinding?.rolloutPath,
1596
+ pendingResumeConfiguration: pendingResumeConfiguration ? true : void 0,
1605
1597
  authProfileId,
1606
1598
  model: response.model,
1607
1599
  modelProvider,
1608
1600
  historyCoveredThrough: (/* @__PURE__ */ new Date()).toISOString()
1609
1601
  }
1610
- })) throw new Error("Codex thread binding changed while attaching the resumed thread.");
1602
+ }, assertCurrent)) throw new Error("Codex thread binding changed while attaching the resumed thread.");
1611
1603
  } catch (error) {
1612
- if (client && !sameOwner) await rollbackCodexAppServerBindingSubscription(client, effectiveThreadId, retained);
1604
+ if (sameOwner && knownOwnership && !retained) {
1605
+ if (!await retainCodexAppServerBindingSubscription(client, effectiveThreadId, knownOwnership)) await closeCodexStartupClientBestEffort(client);
1606
+ } else if (retained && !sameOwner || !hasCodexAppServerLiveThread(client, effectiveThreadId)) await rollbackCodexAppServerBindingSubscription(client, effectiveThreadId, retained);
1613
1607
  throw error;
1614
1608
  }
1615
- committedResponse = true;
1616
1609
  };
1617
- const response = await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.resumeThread, {
1610
+ await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.resumeThread, {
1618
1611
  threadId: normalizedThreadId,
1619
1612
  excludeTurns: true
1620
1613
  }, {
1621
1614
  config: ctx.config,
1615
+ agentId: scope.agentId,
1622
1616
  agentDir: scope.agentDir,
1623
- authProfileId,
1617
+ authProfileId: currentBinding?.authProfileId,
1624
1618
  sessionKey: ctx.sessionKey,
1625
1619
  sessionId: ctx.sessionId,
1620
+ beforeRequest: async (request) => {
1621
+ const { thread } = await request({
1622
+ method: "thread/read",
1623
+ requestParams: {
1624
+ threadId: normalizedThreadId,
1625
+ includeTurns: false
1626
+ }
1627
+ });
1628
+ assertCodexThreadAcceptsDirectInput(thread);
1629
+ },
1626
1630
  onResponse: commitResumedThread
1627
1631
  });
1628
- if (!committedResponse) await commitResumedThread(response);
1629
- return `Attached this OpenClaw session to Codex thread ${formatCodexDisplayText(normalizedThreadId)}.`;
1632
+ return `Attached this OpenClaw session to Codex thread ${formatCodexDisplayText(normalizedThreadId)}.${pendingResumeConfiguration ? " The next turn will validate its tools and apply this session's configuration before continuing." : ""}`;
1630
1633
  })
1631
1634
  });
1632
1635
  }
@@ -1635,12 +1638,13 @@ async function bindCodexCliNodeSession(deps, ctx, parsed) {
1635
1638
  if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
1636
1639
  if (ctx.sessionId) {
1637
1640
  const scope = resolveCodexConversationControlScope(ctx);
1638
- assertCodexBindingMayBeReplaced(await deps.bindingStore.read(sessionBindingIdentity({
1641
+ const binding = await deps.bindingStore.read(sessionBindingIdentity({
1639
1642
  sessionId: ctx.sessionId,
1640
1643
  sessionKey: ctx.sessionKey,
1641
1644
  agentId: scope.agentId,
1642
1645
  config: ctx.config
1643
- })), "binding a Codex CLI node session");
1646
+ }));
1647
+ assertCodexBindingMayBeReplaced(binding, "binding a Codex CLI node session");
1644
1648
  }
1645
1649
  const resolved = await deps.resolveCodexCliSessionForBindingOnNode({
1646
1650
  requestedNode: parsed.host,
@@ -1783,11 +1787,14 @@ async function handleNativeGoal(deps, ctx, pluginConfig, args) {
1783
1787
  const isObjectiveUpdate = action === "set";
1784
1788
  if (!requestedStatus && !isObjectiveUpdate || isObjectiveUpdate && !objective) return "Usage: /codex goal [status|set <objective>|pause|resume|block|complete|clear]";
1785
1789
  if (requestedStatus && args.length > 1) return `Usage: /codex goal ${action}`;
1786
- return formatNativeGoal(await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.setThreadGoal, {
1790
+ return formatNativeGoal(await deps.bindingStore.withLease(target.identity, () => deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.setThreadGoal, {
1787
1791
  threadId: binding.threadId,
1788
1792
  ...objective ? { objective } : {},
1789
1793
  ...requestedStatus ? { status: requestedStatus } : {}
1790
- }, goalRequestOptions));
1794
+ }, {
1795
+ ...goalRequestOptions,
1796
+ ...(isObjectiveUpdate || requestedStatus === "active") && connection.usesSupervisionConnection ? { beforeRequest: supervisedCommandGuard(deps, target.identity, binding) } : {}
1797
+ })));
1791
1798
  }
1792
1799
  function formatNativeGoal(response) {
1793
1800
  const goal = isJsonObject(response) && isJsonObject(response.goal) ? response.goal : void 0;
@@ -1901,12 +1908,13 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
1901
1908
  });
1902
1909
  if (currentSession?.sessionId !== ctx.sessionId || resolvePersistedSessionRuntimeId(currentSession) !== "codex") return "Codex compaction is unavailable because the current OpenClaw session is not using the Codex runtime.";
1903
1910
  if (target.identity.kind === "conversation") {
1904
- if (!isSameCodexAppServerThreadOwner(binding, ctx.sessionId ? await deps.bindingStore.read(sessionBindingIdentity({
1911
+ const sessionBinding = ctx.sessionId ? await deps.bindingStore.read(sessionBindingIdentity({
1905
1912
  sessionId: ctx.sessionId,
1906
1913
  sessionKey: ctx.sessionKey,
1907
1914
  agentId: sessionTarget.agentId,
1908
1915
  config: ctx.config
1909
- })) : void 0)) return "Codex compaction is unavailable because the conversation-bound thread differs from the current session binding. Resume that thread into the session first.";
1916
+ })) : void 0;
1917
+ if (!isSameCodexAppServerThreadOwner(binding, sessionBinding)) return "Codex compaction is unavailable because the conversation-bound thread differs from the current session binding. Resume that thread into the session first.";
1910
1918
  }
1911
1919
  const compactCurrent = ctx.runtimeContext?.compactCurrent;
1912
1920
  if (!compactCurrent) return "Codex compaction is unavailable because this command is not bound to a session.";
@@ -1918,20 +1926,35 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
1918
1926
  authProfileId: binding.authProfileId,
1919
1927
  pluginConfig
1920
1928
  });
1921
- await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.review, {
1929
+ await deps.bindingStore.withLease(target.identity, () => deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.review, {
1922
1930
  threadId: binding.threadId,
1923
1931
  target: { type: "uncommittedChanges" }
1924
1932
  }, {
1925
1933
  agentDir: target.agentDir,
1926
1934
  authProfileId: connection.clientAuthProfileId,
1927
1935
  config: ctx.config,
1928
- ...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {}
1929
- });
1936
+ ...connection.usesSupervisionConnection ? {
1937
+ startOptions: connection.appServer.start,
1938
+ beforeRequest: supervisedCommandGuard(deps, target.identity, binding)
1939
+ } : {}
1940
+ }));
1930
1941
  return `Started Codex review for thread ${formatCodexDisplayText(binding.threadId)}.`;
1931
1942
  }
1943
+ function supervisedCommandGuard(deps, identity, binding) {
1944
+ return async (_request, client, scope) => {
1945
+ const { thread } = await client.request("thread/read", {
1946
+ threadId: binding.threadId,
1947
+ includeTurns: false
1948
+ });
1949
+ scope.assertCurrent();
1950
+ if (!isDeepStrictEqual(await deps.bindingStore.read(identity), binding)) throw new Error("Codex command binding changed before model execution");
1951
+ scope.assertCurrent();
1952
+ assertCodexSupervisionThreadLineage(binding, thread);
1953
+ };
1954
+ }
1932
1955
  //#endregion
1933
1956
  //#region extensions/codex/src/command-plugins-management.ts
1934
- const POLICY_REFRESH_HINT = "New Codex conversations pick this up automatically. Use /new or /reset to refresh the current one.";
1957
+ const POLICY_REFRESH_HINT = "Takes effect on your next message.";
1935
1958
  async function handleCodexPluginsSubcommand(ctx, rest, io, runtime) {
1936
1959
  const [verb = "list", ...args] = rest;
1937
1960
  const normalized = verb.toLowerCase();
@@ -2290,7 +2313,7 @@ function formatPluginList(plugins, options = {}) {
2290
2313
  ...rows.map((r) => ` ${r.state} ${r.displayKey.padEnd(keyW)} ${r.pluginName.padEnd(pluginW)} [${r.marketplace}]`),
2291
2314
  "",
2292
2315
  ...globalEnabled ? [] : ["Global codexPlugins.enabled is off; configured sub-plugins are inactive.", ""],
2293
- "New Codex conversations pick up policy changes automatically; /new or /reset to refresh the current one."
2316
+ POLICY_REFRESH_HINT
2294
2317
  ].join("\n");
2295
2318
  }
2296
2319
  //#endregion