@openclaw/codex 2026.9.1 → 2026.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/api.js +6 -6
  2. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-Bp1ZOnk2.js} +76 -32
  3. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-CSazkWns.js} +6 -6
  4. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-DxGJRYbY.js} +46 -45
  5. package/dist/{capabilities-dIjNVCYH.js → capabilities-B1mgvpP8.js} +2 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DSbGMXA0.js} +2 -2
  8. package/dist/{command-handlers-CTGb2csu.js → command-handlers-DOJvGv6-.js} +146 -74
  9. package/dist/{compact-_t0HQrUS.js → compact-Y_xBqrHN.js} +83 -48
  10. package/dist/{config-BhmfC1s6.js → config-CyapYSji.js} +47 -105
  11. package/dist/config-utils-C57JiJrU.js +69 -0
  12. package/dist/doctor-contract-api.js +4 -5
  13. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-BwpvTxaX.js} +678 -638
  14. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  15. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-B9kp6iGC.js} +11 -2
  16. package/dist/{event-projector-usage-C5mcrGjp.js → event-projector-usage-ZqEVbAEY.js} +30 -13
  17. package/dist/{harness-DXVZ5II5.js → harness-Czh2Sdoc.js} +36 -13
  18. package/dist/harness.js +1 -1
  19. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  20. package/dist/index.js +68 -84
  21. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-CRh-51AK.js} +9 -21
  22. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DcpnJF9x.js} +105 -73
  23. package/dist/media-understanding-provider.js +1 -1
  24. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-DT5vo6qo.js} +5 -5
  25. package/dist/{models-sYnEc0gd.js → models-CcrgSMQR.js} +4 -4
  26. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-B3bvQGcg.js} +12 -11
  27. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-nfbUOtUB.js} +3 -3
  28. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-aQVdyL5g.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → plugin-marketplace-discovery-B7gHXJ3d.js} +35 -22
  30. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-BwCLTY_U.js} +5 -5
  31. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-BpG9Ltc5.js} +2 -2
  32. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Fx_l4eNa.js} +1 -1
  33. package/dist/{request-DYAI5FQE.js → request-C8H22rPi.js} +2 -2
  34. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-BzthFQSM.js} +977 -723
  35. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-Bh_gf6-t.js} +3 -3
  36. package/dist/{session-binding-BHuTCRZQ.js → session-binding-4Ki04sW-.js} +94 -282
  37. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  38. package/dist/{session-catalog-yyvTWFOw.js → session-catalog-B47uwekb.js} +266 -114
  39. package/dist/{session-cli-CmFEXMAM.js → session-cli-BjLhpmS1.js} +1 -1
  40. package/dist/session-history-DWmMqiqW.js +93 -0
  41. package/dist/session-history-read-LHldwvyh.js +36 -0
  42. package/dist/session-history-worker-runtime.js +48 -0
  43. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-zZVcx0ME.js} +30 -31
  44. package/dist/session-history.worker.js +2 -0
  45. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-BCFVnLL4.js} +2 -1
  46. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-BaueHmSj.js} +1 -1
  47. package/dist/{session-retirement-BujDjXVF.js → session-retirement-DNdmYdFc.js} +7 -7
  48. package/dist/{session-upstream-marker-C351-5Qw.js → session-upstream-marker-DReTpGz6.js} +4 -3
  49. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  50. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BI-b1sry.js} +53 -42
  51. package/dist/{shared-client-DxcfF9KX.js → shared-client-CKhX2kFt.js} +279 -268
  52. package/dist/{side-question-BTZAII4l.js → side-question-B6DWAw1A.js} +85 -36
  53. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-DPK30jad.js} +382 -388
  54. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-CbucAmmp.js} +5 -5
  55. package/dist/thread-policy-CTalhWFy.js +105 -0
  56. package/dist/{thread-resume-C7pyVKeW.js → thread-resume-BLgqkUc1.js} +7 -7
  57. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-_njEB84z.js} +67 -125
  58. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  59. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-CzTngV0j.js} +10 -8
  60. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-1fwbNKzQ.js} +85 -165
  61. package/dist/{usage-Bj-rrzkR.js → usage-i9fv5-4m.js} +3 -3
  62. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  63. package/package.json +6 -6
  64. package/dist/binding-connection-E6uDsPlx.js +0 -45
  65. package/dist/launch-args-RXQwn8zV.js +0 -90
  66. package/dist/session-history-C5J1AKzG.js +0 -87
  67. package/dist/thread-policy-g4KbJPzp.js +0 -54
@@ -1,29 +1,30 @@
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";
1
+ import { m as CODEX_PLUGINS_MARKETPLACE_NAME, n as isCodexFastServiceTier } from "./config-utils-C57JiJrU.js";
2
+ import { l as sessionBindingIdentity, t as bindingStoreKey } from "./session-binding-record-CyaXZvTe.js";
3
+ import { B as isJsonObject, i as resolveCodexAppServerRuntimeOptions } from "./config-CyapYSji.js";
4
+ import { Bt as resolveCodexAppServerAuthAccountCacheKey, Et as hasCodexAppServerLiveThread, Ht as resolveCodexAppServerAuthProfileIdForAgent, Q as assertCodexThreadAcceptsDirectInput, Wt as resolveCodexAppServerFallbackApiKeyCacheKey, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, tt as assertCodexThreadResumeResponse, wt as consumeCodexAppServerLiveThread } from "./shared-client-CKhX2kFt.js";
5
+ import { l as resolveCodexSessionBinding, n as assertCodexBindingMayBeReplaced, o as normalizeCodexAppServerBindingModelProvider, r as createCodexSessionGenerationSupersededError } from "./session-binding-4Ki04sW-.js";
6
+ import { a as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-Bp1ZOnk2.js";
7
+ import { t as listAllCodexAppServerModels } from "./models-CcrgSMQR.js";
8
+ import { c as defaultCodexAppInventoryCache, i as buildCodexPluginAppCacheKey } from "./thread-resume-BLgqkUc1.js";
9
+ import { At as refreshCodexPluginRuntimeState, Mt as isOpenAiCuratedMarketplaceName } from "./thread-lifecycle-DPK30jad.js";
10
+ 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-CbucAmmp.js";
11
+ import { r as assertCodexSupervisionThreadLineage, s as resolveCodexBindingAppServerConnection } from "./thread-policy-CTalhWFy.js";
12
+ import { c as resolveCodexNativeSandboxBlock, s as resolveCodexNativeExecutionBlock } from "./request-C8H22rPi.js";
13
+ import { t as CODEX_CONTROL_METHODS } from "./capabilities-B1mgvpP8.js";
14
+ import { s as summarizeCodexAccountUsage } from "./rate-limits-Fx_l4eNa.js";
15
+ 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-DSbGMXA0.js";
16
+ 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-B7gHXJ3d.js";
15
17
  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";
18
+ import { c as readCodexStatusProbes, l as requestOptions, p as formatCodexCliSessions, s as codexControlRequest, u as safeCodexControlRequest } from "./session-catalog-B47uwekb.js";
19
+ import { i as readCodexComputerUseStatus, r as installCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BwCLTY_U.js";
19
20
  import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
20
- import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
21
21
  import crypto from "node:crypto";
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
22
  import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
26
23
  import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
24
+ import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
25
+ import { isDeepStrictEqual } from "node:util";
26
+ import { ensureAuthProfileStore, resolveAgentDir as resolveAgentDir$1, resolveAuthProfileEligibility, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
27
+ import { findNormalizedProviderValue, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
27
28
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
28
29
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
29
30
  import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
@@ -1065,11 +1066,56 @@ async function resolveControlTarget(ctx) {
1065
1066
  agentDir: scope.agentDir
1066
1067
  } : void 0;
1067
1068
  }
1068
- async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
1069
+ async function resolvePreparedCodexCommandAuthority(deps, ctx) {
1069
1070
  const target = await resolveControlTarget(ctx);
1070
1071
  const fallback = resolveCodexConversationControlScope(ctx);
1072
+ const sessionId = ctx.sessionId;
1073
+ const sessionKey = ctx.sessionKey;
1074
+ const sessionAgentId = ctx.sessionTarget?.agentId ?? fallback.agentId;
1075
+ const storePath = ctx.sessionTarget?.storePath ?? (sessionKey ? resolveStorePath(ctx.config.session?.store, { agentId: sessionAgentId }) : void 0);
1076
+ const sessionIdentity = sessionId ? sessionBindingIdentity({
1077
+ sessionId,
1078
+ sessionKey,
1079
+ agentId: sessionAgentId,
1080
+ config: ctx.config
1081
+ }) : void 0;
1082
+ const currentSession = sessionIdentity ? await resolveCodexSessionBinding({
1083
+ reclaimStale: true,
1084
+ bindingStore: deps.bindingStore,
1085
+ identity: sessionIdentity,
1086
+ config: ctx.config,
1087
+ storePath
1088
+ }) : void 0;
1089
+ const assertHostCurrent = currentSession?.assertCurrent ?? (() => {});
1090
+ const binding = (target && (!sessionIdentity || !isDeepStrictEqual(target.identity, sessionIdentity)) ? await resolveCodexSessionBinding({
1091
+ bindingStore: deps.bindingStore,
1092
+ identity: target.identity,
1093
+ config: ctx.config,
1094
+ storePath,
1095
+ assertCurrent: assertHostCurrent
1096
+ }) : currentSession)?.binding;
1097
+ const assertCurrent = () => {
1098
+ assertHostCurrent();
1099
+ if (target && !isDeepStrictEqual(deps.bindingStore.read(target.identity), binding)) throw new Error("Codex command binding changed before dispatch");
1100
+ assertHostCurrent();
1101
+ };
1102
+ assertCurrent();
1103
+ return {
1104
+ target,
1105
+ binding,
1106
+ currentSessionBinding: currentSession?.binding,
1107
+ sessionId,
1108
+ sessionKey,
1109
+ storePath,
1110
+ assertHostCurrent,
1111
+ assertCurrent
1112
+ };
1113
+ }
1114
+ async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
1115
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1116
+ const { target, binding } = authority;
1117
+ const fallback = resolveCodexConversationControlScope(ctx);
1071
1118
  const agentDir = target?.agentDir ?? fallback.agentDir;
1072
- const binding = target ? await deps.bindingStore.read(target.identity) : void 0;
1073
1119
  const authProfileId = binding?.connectionScope === "supervision" ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
1074
1120
  authProfileId: binding?.authProfileId ?? target?.requestedAuthProfileId,
1075
1121
  agentDir,
@@ -1085,8 +1131,10 @@ async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
1085
1131
  agentDir,
1086
1132
  ...connection.clientAuthProfileId !== void 0 ? { authProfileId: connection.clientAuthProfileId } : {},
1087
1133
  ...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {},
1088
- ...ctx.sessionKey ? { sessionKey: ctx.sessionKey } : {},
1089
- ...ctx.sessionId ? { sessionId: ctx.sessionId } : {}
1134
+ ...authority.sessionKey ? { sessionKey: authority.sessionKey } : {},
1135
+ ...authority.sessionId ? { sessionId: authority.sessionId } : {},
1136
+ ...authority.storePath ? { storePath: authority.storePath } : {},
1137
+ assertCurrent: authority.assertCurrent
1090
1138
  };
1091
1139
  }
1092
1140
  function conversationBindingIdentity(bindingId) {
@@ -1103,7 +1151,7 @@ function resolveCodexConversationControlScope(ctx) {
1103
1151
  });
1104
1152
  return {
1105
1153
  agentId: sessionAgentId,
1106
- agentDir: resolveAgentDir(ctx.config, sessionAgentId)
1154
+ agentDir: resolveAgentDir$1(ctx.config, sessionAgentId)
1107
1155
  };
1108
1156
  }
1109
1157
  //#endregion
@@ -1200,7 +1248,7 @@ async function confirmCodexDiagnosticsFeedback(deps, ctx, pluginConfig, token) {
1200
1248
  if (scopeMismatch) return scopeMismatch.confirmMessage;
1201
1249
  deletePendingCodexDiagnosticsConfirmation(token);
1202
1250
  if (!pending.privateRouted && !await hasAnyCodexDiagnosticsIdentity(ctx)) return "Cannot send Codex diagnostics because this command did not include a stable session identity.";
1203
- const currentTargets = pending.privateRouted ? await resolvePendingCodexDiagnosticsTargets(deps, pending.targets, ctx.config) : await resolveCodexDiagnosticsTargets(deps, ctx);
1251
+ const currentTargets = pending.privateRouted ? resolvePendingCodexDiagnosticsTargets(deps, pending.targets, ctx.config) : await resolveCodexDiagnosticsTargets(deps, ctx);
1204
1252
  if (!codexDiagnosticsTargetsMatch(pending.targets, currentTargets)) return "The Codex diagnostics sessions changed before confirmation. Run /diagnostics again for the current threads.";
1205
1253
  return await sendCodexDiagnosticsFeedbackForTargets(deps, ctx, pluginConfig, pending.note ?? "", currentTargets, { cooldownScope: pending.scopeKey });
1206
1254
  }
@@ -1307,7 +1355,7 @@ async function resolveCodexDiagnosticsTargets(deps, ctx) {
1307
1355
  });
1308
1356
  candidates.push({
1309
1357
  identity,
1310
- agentDir: resolveAgentDir(ctx.config, identity.agentId),
1358
+ agentDir: resolveAgentDir$1(ctx.config, identity.agentId),
1311
1359
  sessionKey: session.sessionKey,
1312
1360
  sessionId: session.sessionId,
1313
1361
  channel: session.channel,
@@ -1324,17 +1372,17 @@ async function resolveCodexDiagnosticsTargets(deps, ctx) {
1324
1372
  const key = bindingStoreKey(candidate.identity);
1325
1373
  if (seenBindingKeys.has(key)) continue;
1326
1374
  seenBindingKeys.add(key);
1327
- const binding = await deps.bindingStore.read(candidate.identity);
1375
+ const binding = deps.bindingStore.read(candidate.identity);
1328
1376
  if (!binding?.threadId || seenThreadIds.has(binding.threadId)) continue;
1329
1377
  seenThreadIds.add(binding.threadId);
1330
1378
  targets.push(resolveCodexDiagnosticsTarget(candidate, binding, ctx.config));
1331
1379
  }
1332
1380
  return targets;
1333
1381
  }
1334
- async function resolvePendingCodexDiagnosticsTargets(deps, targets, config) {
1382
+ function resolvePendingCodexDiagnosticsTargets(deps, targets, config) {
1335
1383
  const resolved = [];
1336
1384
  for (const target of targets) {
1337
- const binding = await deps.bindingStore.read(target.identity);
1385
+ const binding = deps.bindingStore.read(target.identity);
1338
1386
  if (!binding?.threadId) continue;
1339
1387
  resolved.push(resolveCodexDiagnosticsTarget(target, binding, config));
1340
1388
  }
@@ -1376,7 +1424,7 @@ function isCurrentSessionModelSelectionLocked(ctx) {
1376
1424
  const sessionKey = ctx.sessionKey?.trim();
1377
1425
  if (!sessionKey) return false;
1378
1426
  const { agentId } = resolveCodexConversationControlScope(ctx);
1379
- const storePath = resolveStorePath(ctx.config.session?.store, { agentId });
1427
+ const storePath = ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId });
1380
1428
  return isModelSelectionLocked(getSessionEntry({
1381
1429
  storePath,
1382
1430
  sessionKey,
@@ -1400,7 +1448,7 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
1400
1448
  config: ctx.config
1401
1449
  }) : void 0;
1402
1450
  const currentOwner = currentConversationData?.kind === "codex-app-server-session" ? conversationBindingIdentity(currentConversationData.bindingId) : sessionOwner;
1403
- const existingBinding = currentOwner ? await deps.bindingStore.read(currentOwner) : void 0;
1451
+ const existingBinding = currentOwner ? deps.bindingStore.read(currentOwner) : void 0;
1404
1452
  assertCodexBindingMayBeReplaced(existingBinding, "binding this conversation to another thread");
1405
1453
  const sessionSource = sessionOwner && existingBinding ? {
1406
1454
  agentId: sessionOwner.agentId,
@@ -1442,7 +1490,7 @@ async function detachConversation(deps, ctx) {
1442
1490
  let expectedThreadId;
1443
1491
  let expectedStartId;
1444
1492
  if (data?.kind === "codex-app-server-session") {
1445
- const binding = await deps.bindingStore.read(identity);
1493
+ const binding = deps.bindingStore.read(identity);
1446
1494
  assertCodexBindingMayBeReplaced(binding, "detaching its conversation binding");
1447
1495
  if (deps.readCodexConversationActiveTurn(identity)) return "This Codex conversation has an active run; use /codex stop before detaching it.";
1448
1496
  expectedThreadId = binding?.threadId;
@@ -1480,13 +1528,13 @@ async function describeConversationBinding(deps, ctx) {
1480
1528
  "- Active run: not tracked"
1481
1529
  ].join("\n");
1482
1530
  const identity = conversationBindingIdentity(data.bindingId);
1483
- const threadBinding = await deps.bindingStore.read(identity);
1531
+ const threadBinding = deps.bindingStore.read(identity);
1484
1532
  const active = deps.readCodexConversationActiveTurn(identity);
1485
1533
  const sessionKey = ctx.sessionKey?.trim();
1486
1534
  const { agentId } = resolveCodexConversationControlScope(ctx);
1487
1535
  const sessionEntry = sessionKey ? getSessionEntry({
1488
1536
  agentId,
1489
- storePath: resolveStorePath(ctx.config.session?.store, { agentId }),
1537
+ storePath: ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId }),
1490
1538
  sessionKey,
1491
1539
  hydrateSkillPromptRefs: false,
1492
1540
  readConsistency: "latest"
@@ -1538,17 +1586,22 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
1538
1586
  agentId: scope.agentId,
1539
1587
  config: ctx.config
1540
1588
  });
1589
+ const { assertCurrent: assertHostGeneration } = await resolveCodexSessionBinding({
1590
+ reclaimStale: true,
1591
+ bindingStore: deps.bindingStore,
1592
+ identity,
1593
+ config: ctx.config,
1594
+ storePath: ctx.sessionTarget?.storePath
1595
+ });
1541
1596
  return await withExclusiveCodexAppServerThread({
1542
1597
  bindingStore: deps.bindingStore,
1543
1598
  identity,
1544
1599
  threadId: normalizedThreadId,
1545
1600
  run: async () => await deps.bindingStore.withLease(identity, async () => {
1546
- if (!await reclaimCurrentCodexSessionGeneration({
1547
- bindingStore: deps.bindingStore,
1548
- identity,
1549
- config: ctx.config
1550
- })) throw createCodexSessionGenerationSupersededError(identity.sessionId);
1551
- const currentBinding = await deps.bindingStore.read(identity);
1601
+ const generation = await deps.bindingStore.prepareSessionGenerationReclaim(identity);
1602
+ assertHostGeneration();
1603
+ if (generation.kind !== "resolved" || !generation.result) throw createCodexSessionGenerationSupersededError(identity.sessionId);
1604
+ const currentBinding = deps.bindingStore.read(identity);
1552
1605
  assertCodexBindingMayBeReplaced(currentBinding, "attaching a different resumed thread");
1553
1606
  let pendingResumeConfiguration = false;
1554
1607
  const commitResumedThread = async (value, client, { authProfileId, assertCurrent }) => {
@@ -1568,7 +1621,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
1568
1621
  let sameOwner = false;
1569
1622
  let knownOwnership;
1570
1623
  try {
1571
- const bindingBeforeCommit = await deps.bindingStore.read(identity);
1624
+ const bindingBeforeCommit = deps.bindingStore.read(identity);
1572
1625
  assertCodexBindingMayBeReplaced(bindingBeforeCommit, "committing a different resumed thread");
1573
1626
  sameOwner = isSameCodexAppServerThreadOwner(bindingBeforeCommit, {
1574
1627
  threadId: effectiveThreadId,
@@ -1583,7 +1636,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
1583
1636
  retained = await retainCodexAppServerBindingSubscription(client, effectiveThreadId, knownOwnership);
1584
1637
  assertCurrent();
1585
1638
  if (!retained) throw new Error("Codex resumed thread lost its native subscription owner.");
1586
- if (bindingBeforeCommit && !sameOwner) await releaseCodexAppServerBindingSubscription(bindingBeforeCommit);
1639
+ if (bindingBeforeCommit && !sameOwner) await releaseCodexAppServerBindingSubscription(bindingBeforeCommit, { assertCurrent });
1587
1640
  assertCurrent();
1588
1641
  if (!await deps.bindingStore.mutate(identity, {
1589
1642
  kind: "set",
@@ -1617,6 +1670,8 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
1617
1670
  authProfileId: currentBinding?.authProfileId,
1618
1671
  sessionKey: ctx.sessionKey,
1619
1672
  sessionId: ctx.sessionId,
1673
+ storePath: ctx.sessionTarget?.storePath,
1674
+ assertCurrent: assertHostGeneration,
1620
1675
  beforeRequest: async (request) => {
1621
1676
  const { thread } = await request({
1622
1677
  method: "thread/read",
@@ -1638,7 +1693,7 @@ async function bindCodexCliNodeSession(deps, ctx, parsed) {
1638
1693
  if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
1639
1694
  if (ctx.sessionId) {
1640
1695
  const scope = resolveCodexConversationControlScope(ctx);
1641
- const binding = await deps.bindingStore.read(sessionBindingIdentity({
1696
+ const binding = deps.bindingStore.read(sessionBindingIdentity({
1642
1697
  sessionId: ctx.sessionId,
1643
1698
  sessionKey: ctx.sessionKey,
1644
1699
  agentId: scope.agentId,
@@ -1759,9 +1814,9 @@ async function handleComputerUseCommand(deps, ctx, pluginConfig, args) {
1759
1814
  async function handleNativeGoal(deps, ctx, pluginConfig, args) {
1760
1815
  const action = (args[0] ?? "status").toLowerCase();
1761
1816
  const objective = args.slice(1).join(" ").trim();
1762
- const target = await resolveControlTarget(ctx);
1817
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1818
+ const { target, binding } = authority;
1763
1819
  if (!target) return "Cannot manage the Codex goal because this command has no stable binding identity.";
1764
- const binding = await deps.bindingStore.read(target.identity);
1765
1820
  if (!binding?.threadId) return "No Codex thread is attached to this OpenClaw session yet.";
1766
1821
  const connection = resolveCodexBindingAppServerConnection({
1767
1822
  binding,
@@ -1772,6 +1827,10 @@ async function handleNativeGoal(deps, ctx, pluginConfig, args) {
1772
1827
  agentDir: target.agentDir,
1773
1828
  authProfileId: connection.clientAuthProfileId,
1774
1829
  config: ctx.config,
1830
+ sessionId: authority.sessionId,
1831
+ sessionKey: authority.sessionKey,
1832
+ storePath: authority.storePath,
1833
+ assertCurrent: authority.assertCurrent,
1775
1834
  ...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {}
1776
1835
  };
1777
1836
  if (action === "status" || action === "get") {
@@ -1810,26 +1869,30 @@ function formatNativeGoal(response) {
1810
1869
  ].join("\n");
1811
1870
  }
1812
1871
  async function stopConversationTurn(deps, ctx, pluginConfig) {
1813
- const target = await resolveControlTarget(ctx);
1872
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1873
+ const { target, binding } = authority;
1814
1874
  if (!target) return "Cannot stop Codex because this command did not include a stable binding identity.";
1815
1875
  return (await deps.stopCodexConversationTurn({
1816
1876
  identity: target.identity,
1817
- bindingStore: deps.bindingStore,
1877
+ binding,
1818
1878
  pluginConfig,
1819
1879
  agentDir: target.agentDir,
1820
- config: ctx.config
1880
+ config: ctx.config,
1881
+ assertCurrent: authority.assertCurrent
1821
1882
  })).message;
1822
1883
  }
1823
1884
  async function steerConversationTurn(deps, ctx, pluginConfig, message) {
1824
- const target = await resolveControlTarget(ctx);
1885
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1886
+ const { target, binding } = authority;
1825
1887
  if (!target) return "Cannot steer Codex because this command did not include a stable binding identity.";
1826
1888
  return (await deps.steerCodexConversationTurn({
1827
1889
  identity: target.identity,
1828
- bindingStore: deps.bindingStore,
1890
+ binding,
1829
1891
  message,
1830
1892
  pluginConfig,
1831
1893
  agentDir: target.agentDir,
1832
- config: ctx.config
1894
+ config: ctx.config,
1895
+ assertCurrent: authority.assertCurrent
1833
1896
  })).message;
1834
1897
  }
1835
1898
  async function setConversationModel(deps, ctx, pluginConfig, args) {
@@ -1837,17 +1900,18 @@ async function setConversationModel(deps, ctx, pluginConfig, args) {
1837
1900
  const [model = ""] = args;
1838
1901
  const normalized = model.trim();
1839
1902
  if (normalized && isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
1840
- const target = await resolveControlTarget(ctx);
1903
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1904
+ const { target, binding } = authority;
1841
1905
  if (!target) return "Cannot set Codex model because this command did not include a stable binding identity.";
1842
1906
  if (!normalized) {
1843
- const currentSession = ctx.sessionId && ctx.sessionKey ? getSessionEntry({
1844
- storePath: resolveStorePath(ctx.config.session?.store, { agentId: target.agentId }),
1845
- sessionKey: ctx.sessionKey,
1907
+ const currentSession = authority.sessionId && authority.sessionKey && authority.storePath ? getSessionEntry({
1908
+ storePath: authority.storePath,
1909
+ sessionKey: authority.sessionKey,
1846
1910
  hydrateSkillPromptRefs: false,
1847
1911
  readConsistency: "latest"
1848
1912
  }) : void 0;
1849
- const selectedModel = currentSession && currentSession.sessionId === ctx.sessionId ? currentSession.modelOverride ?? currentSession.model : void 0;
1850
- const binding = await deps.bindingStore.read(target.identity);
1913
+ const selectedModel = currentSession && currentSession.sessionId === authority.sessionId ? currentSession.modelOverride ?? currentSession.model : void 0;
1914
+ authority.assertCurrent();
1851
1915
  const activeModel = target.identity.kind === "conversation" ? binding?.model : selectedModel ?? binding?.model;
1852
1916
  return activeModel ? `Codex model: ${formatCodexDisplayText(activeModel)}` : "Usage: /codex model <model>";
1853
1917
  }
@@ -1857,12 +1921,16 @@ async function setConversationModel(deps, ctx, pluginConfig, args) {
1857
1921
  pluginConfig,
1858
1922
  model: normalized,
1859
1923
  agentDir: target.agentDir,
1860
- config: ctx.config
1924
+ config: ctx.config,
1925
+ binding,
1926
+ storePath: authority.storePath,
1927
+ assertCurrent: authority.assertCurrent
1861
1928
  });
1862
1929
  }
1863
1930
  async function setConversationFastMode(deps, ctx, args) {
1864
1931
  if (args.length > 1) return "Usage: /codex fast [on|off|status]";
1865
- const target = await resolveControlTarget(ctx);
1932
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1933
+ const { target, binding } = authority;
1866
1934
  if (!target) return "Cannot set Codex fast mode because this command did not include a stable binding identity.";
1867
1935
  const value = args[0];
1868
1936
  const parsed = parseCodexFastModeArg(value);
@@ -1870,12 +1938,15 @@ async function setConversationFastMode(deps, ctx, args) {
1870
1938
  return await deps.setCodexConversationFastMode({
1871
1939
  identity: target.identity,
1872
1940
  bindingStore: deps.bindingStore,
1873
- enabled: parsed
1941
+ binding,
1942
+ enabled: parsed,
1943
+ assertCurrent: authority.assertCurrent
1874
1944
  });
1875
1945
  }
1876
1946
  async function setConversationPermissions(deps, ctx, args) {
1877
1947
  if (args.length > 1) return "Usage: /codex permissions [default|yolo|status]";
1878
- const target = await resolveControlTarget(ctx);
1948
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1949
+ const { target } = authority;
1879
1950
  if (!target || !ctx.sessionId || !ctx.sessionKey) return "Cannot set Codex permissions because this command did not include a complete session identity.";
1880
1951
  const value = args[0];
1881
1952
  const parsed = parseCodexPermissionsModeArg(value);
@@ -1884,6 +1955,8 @@ async function setConversationPermissions(deps, ctx, args) {
1884
1955
  return await deps.setCodexConversationPermissions({
1885
1956
  mode: parsed,
1886
1957
  config: ctx.config,
1958
+ storePath: authority.storePath,
1959
+ assertCurrent: authority.assertHostCurrent,
1887
1960
  session: {
1888
1961
  agentId: target.agentId,
1889
1962
  sessionId: ctx.sessionId,
@@ -1893,31 +1966,26 @@ async function setConversationPermissions(deps, ctx, args) {
1893
1966
  }
1894
1967
  async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
1895
1968
  if (args.length > 0) return `Usage: /codex ${kind}`;
1896
- const target = await resolveControlTarget(ctx);
1969
+ const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
1970
+ const { target, binding } = authority;
1897
1971
  if (!target) return `Cannot start Codex ${kind === "compact" ? "compaction" : "review"} because this command did not include a stable binding identity.`;
1898
- const binding = await deps.bindingStore.read(target.identity);
1899
1972
  if (!binding?.threadId) return `No Codex thread is attached to this OpenClaw session yet.`;
1900
1973
  if (kind === "compact") {
1901
1974
  const sessionTarget = ctx.sessionTarget;
1902
1975
  if (!ctx.sessionId || !ctx.sessionKey || !sessionTarget || sessionTarget.sessionId !== ctx.sessionId || sessionTarget.sessionKey !== ctx.sessionKey) return "Codex compaction is unavailable because this command is not bound to a complete session identity.";
1903
1976
  const currentSession = getSessionEntry({
1904
- storePath: sessionTarget.storePath,
1977
+ storePath: authority.storePath ?? sessionTarget.storePath,
1905
1978
  sessionKey: ctx.sessionKey,
1906
1979
  hydrateSkillPromptRefs: false,
1907
1980
  readConsistency: "latest"
1908
1981
  });
1909
1982
  if (currentSession?.sessionId !== ctx.sessionId || resolvePersistedSessionRuntimeId(currentSession) !== "codex") return "Codex compaction is unavailable because the current OpenClaw session is not using the Codex runtime.";
1910
1983
  if (target.identity.kind === "conversation") {
1911
- const sessionBinding = ctx.sessionId ? await deps.bindingStore.read(sessionBindingIdentity({
1912
- sessionId: ctx.sessionId,
1913
- sessionKey: ctx.sessionKey,
1914
- agentId: sessionTarget.agentId,
1915
- config: ctx.config
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.";
1984
+ if (!isSameCodexAppServerThreadOwner(binding, authority.currentSessionBinding)) return "Codex compaction is unavailable because the conversation-bound thread differs from the current session binding. Resume that thread into the session first.";
1918
1985
  }
1919
1986
  const compactCurrent = ctx.runtimeContext?.compactCurrent;
1920
1987
  if (!compactCurrent) return "Codex compaction is unavailable because this command is not bound to a session.";
1988
+ authority.assertCurrent();
1921
1989
  const result = await compactCurrent();
1922
1990
  return result.compacted ? `Compacted Codex session (${result.tokensAfter ?? "unknown"} tokens after).` : `Codex compaction did not complete: ${formatCodexDisplayText(result.reason ?? "no reason returned")}.`;
1923
1991
  }
@@ -1933,6 +2001,10 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
1933
2001
  agentDir: target.agentDir,
1934
2002
  authProfileId: connection.clientAuthProfileId,
1935
2003
  config: ctx.config,
2004
+ sessionId: authority.sessionId,
2005
+ sessionKey: authority.sessionKey,
2006
+ storePath: authority.storePath,
2007
+ assertCurrent: authority.assertCurrent,
1936
2008
  ...connection.usesSupervisionConnection ? {
1937
2009
  startOptions: connection.appServer.start,
1938
2010
  beforeRequest: supervisedCommandGuard(deps, target.identity, binding)
@@ -1947,7 +2019,7 @@ function supervisedCommandGuard(deps, identity, binding) {
1947
2019
  includeTurns: false
1948
2020
  });
1949
2021
  scope.assertCurrent();
1950
- if (!isDeepStrictEqual(await deps.bindingStore.read(identity), binding)) throw new Error("Codex command binding changed before model execution");
2022
+ if (!isDeepStrictEqual(deps.bindingStore.read(identity), binding)) throw new Error("Codex command binding changed before model execution");
1951
2023
  scope.assertCurrent();
1952
2024
  assertCodexSupervisionThreadLineage(binding, thread);
1953
2025
  };