@openclaw/codex 2026.9.5 → 2026.9.7

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 (174) hide show
  1. package/README.md +2 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
  4. package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
  5. package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
  6. package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
  7. package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
  8. package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
  9. package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
  10. package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
  11. package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
  12. package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
  13. package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
  14. package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
  15. package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
  16. package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
  17. package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
  18. package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  19. package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
  20. package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
  21. package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
  22. package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
  23. package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
  24. package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
  25. package/dist/.setup/compact-C2WamavS.mjs +776 -0
  26. package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
  27. package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
  28. package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
  29. package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
  30. package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
  31. package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
  32. package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
  33. package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
  34. package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
  35. package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
  36. package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
  37. package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
  38. package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
  39. package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
  40. package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
  41. package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
  42. package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
  43. package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
  44. package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
  45. package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
  46. package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
  47. package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
  48. package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
  49. package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
  50. package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
  51. package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
  52. package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
  53. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  54. package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
  55. package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
  56. package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
  57. package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
  58. package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
  59. package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
  60. package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
  61. package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
  62. package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
  63. package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
  64. package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
  65. package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
  66. package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
  67. package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
  68. package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
  69. package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
  70. package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
  71. package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
  72. package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
  73. package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
  74. package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
  75. package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
  76. package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
  77. package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
  78. package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
  79. package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
  80. package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
  81. package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
  82. package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
  83. package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
  84. package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
  85. package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
  86. package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
  87. package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
  88. package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
  89. package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
  90. package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
  91. package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
  92. package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
  93. package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
  94. package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
  95. package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
  96. package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
  97. package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
  98. package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
  99. package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
  100. package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
  101. package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
  102. package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
  103. package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
  104. package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
  105. package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
  106. package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
  107. package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
  108. package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
  109. package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
  110. package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
  111. package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
  112. package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
  113. package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
  114. package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
  115. package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
  116. package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
  117. package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
  118. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  119. package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
  120. package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
  121. package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
  122. package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
  123. package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
  124. package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
  125. package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
  126. package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
  127. package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
  128. package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
  129. package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
  130. package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
  131. package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
  132. package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
  133. package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
  134. package/dist/api.js +25 -16
  135. package/dist/catalog-page-worker-entrypoint.js +12 -0
  136. package/dist/catalog-page.worker.js +9 -0
  137. package/dist/cli-metadata.js +1 -1
  138. package/dist/doctor-contract-api.js +50 -8
  139. package/dist/harness.js +344 -1
  140. package/dist/index.js +345 -346
  141. package/dist/media-understanding-provider.js +9 -22
  142. package/dist/migration-provider-api.js +1 -1
  143. package/dist/provider-discovery.js +1 -1
  144. package/dist/session-history-worker-runtime.js +16 -33
  145. package/dist/session-history.worker.js +1 -1
  146. package/openclaw.plugin.json +14 -2
  147. package/package.json +11 -7
  148. package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
  149. package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
  150. package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
  151. package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
  152. package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
  153. package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
  154. package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
  155. package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
  156. package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
  157. package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
  158. package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
  159. package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
  160. package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
  161. package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
  162. package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
  163. package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
  164. package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
  165. package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
  166. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
  167. package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
  168. package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
  169. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
  170. package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
  171. package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
  172. package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
  173. package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
  174. package/dist/.setup/version-CoqzXPgK.mjs +0 -12
package/dist/index.js CHANGED
@@ -1,38 +1,43 @@
1
1
  import { registerCodexCliMetadata } from "./cli-metadata.js";
2
- import { n as createCodexAppServerNativeCompaction, t as createCodexAppServerAgentHarness } from "./.setup/harness-rxaaoN-o.mjs";
3
- import { l as readCurrentCodexAppServerBinding, n as assertCodexBindingMayBeReplaced, p as sessionBindingIdentity, u as readCurrentCodexNativeSubagentSubmissions } from "./.setup/session-binding-record-TH3xA0zj.mjs";
4
- import { n as defineCodexBuildState } from "./.setup/build-state-Xx9ybZqa.mjs";
2
+ import { j as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS } from "./.setup/session-catalog-parsing-CPGaPYr-.mjs";
3
+ import { i as isJsonObject } from "./.setup/protocol-CANUwXJ3.mjs";
4
+ import { f as readCurrentCodexAppServerBinding, h as readCurrentNativePendingAssignments, m as readCurrentCodexNativeSubagentSubmissions, n as assertCodexBindingMayBeReplaced, p as readCurrentCodexAppServerBindings, v as sessionBindingIdentity } from "./.setup/session-binding-record-Oe9L-CNY.mjs";
5
+ import { n as defineCodexBuildState } from "./.setup/build-state-Da1_z0kd.mjs";
6
+ import { createCodexAppServerAgentHarness, createCodexAppServerNativeCompaction } from "./harness.js";
5
7
  import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
6
8
  import codexProviderDiscovery from "./provider-discovery.js";
7
9
  import { n as createCodexAuthProfileSelection } from "./.setup/auth-profile-selection-DFu9e167.mjs";
8
- import { m as isJsonObject, t as assertCodexAppServerConnectionSecurity } from "./.setup/config-security-BRQ2mgW9.mjs";
9
- import { d as readCodexPluginConfig } from "./.setup/config-parsing-CcB9iPoq.mjs";
10
- import { V as CODEX_CATALOG_MAX_ROWS, W as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS } from "./.setup/session-catalog-native-projection-ChV3cCtm.mjs";
11
- import { r as createCodexAppServerConfig, t as codexAppServerStartOptionsKey } from "./.setup/config-options-BsanJ8QG.mjs";
12
- import { o as setManagedCodexPluginRoot } from "./.setup/managed-binary-DP6Rib3P.mjs";
13
- import { g as createCodexDesktopGenerationService, h as retireSharedCodexAppServerClientsBeforeDesktopGeneration, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./.setup/auth-cache-key-QirmgiCo.mjs";
10
+ import { t as assertCodexAppServerConnectionSecurity } from "./.setup/config-security-CE-FcGw9.mjs";
11
+ import { d as readCodexPluginConfig } from "./.setup/config-parsing-b088LyhT.mjs";
12
+ import { r as createCodexAppServerConfig, t as codexAppServerStartOptionsKey } from "./.setup/config-options-CzyWLTJt.mjs";
13
+ import { o as setManagedCodexPluginRoot } from "./.setup/managed-binary-kiWRhNRE.mjs";
14
+ import { l as createCodexDesktopGenerationService, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./.setup/auth-cache-key-Dbvq-QgB.mjs";
14
15
  import { n as CODEX_MANAGED_THREAD_NAMESPACE, r as createCodexManagedThreadStore, t as CODEX_MANAGED_THREAD_MAX_ENTRIES } from "./.setup/managed-thread-store-BMqgThVL.mjs";
15
16
  import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./.setup/session-binding-meta-B7aEMU7g.mjs";
16
- import { o as createCodexAppServerProcessReaperService } from "./.setup/transport-stdio-Cmx94Oiy.mjs";
17
- import { r as withCodexConversationThreadActivity, t as isIncognitoSessionKey } from "./.setup/incognito-session-uhrBF6wJ.mjs";
18
- import { n as filterCodexMarketplacePlugins, o as CODEX_NATIVE_EXECUTION_AUTH_ERROR, s as canMutateCodexHost, t as discoverCodexMarketplacePlugins } from "./.setup/plugin-marketplace-discovery-P-Vndfqq.mjs";
19
- import { o as formatCodexDisplayText } from "./.setup/command-formatters-CGEkdawF.mjs";
20
- import { a as readCodexConversationBindingDataRecord, i as readCodexConversationBindingData, o as resolveCodexDefaultWorkspaceDir } from "./.setup/conversation-binding-data-CrcyZk6O.mjs";
21
- import { t as buildCodexMigrationProvider } from "./.setup/provider-fFh_-VR3.mjs";
22
- import { t as CODEX_CONTROL_METHODS } from "./.setup/capabilities-_vXcZGSx.mjs";
23
- import { t as assertCodexArchiveDescendantsUnowned } from "./.setup/thread-archive-guard-jmecf6OJ.mjs";
24
- import { a as listCodexCliSessionsOnNode, n as createCodexCliSessionNodeHostCommands, o as resolveCodexCliSessionForBindingOnNode, r as createCodexCliSessionNodeInvokePolicies, s as resumeCodexCliSessionOnNode } from "./.setup/node-cli-sessions-Cl8b2ZF3.mjs";
25
- import { t as CODEX_CATALOG_STATE_NAMESPACE } from "./.setup/session-catalog-index-state-BAuDztHN.mjs";
26
- import { i as createCodexSessionCatalogNodeHostCommands, n as createCodexSessionCatalogNodeInvokePolicies, r as createCodexSessionCatalogControl, t as codexSessionCatalogRuntime } from "./.setup/session-catalog-fUdWDx-U.mjs";
27
- import { i as requestCodexAppServerJson } from "./.setup/request-BioXJLYa.mjs";
17
+ import { f as retireSharedCodexAppServerClientsBeforeDesktopGeneration } from "./.setup/shared-client-lifecycle-DJIgqgMw.mjs";
18
+ import { s as createCodexAppServerProcessReaperService } from "./.setup/transport-stdio-Bdegpn2V.mjs";
19
+ import { n as codexNativeProfileRecoveryService } from "./.setup/auth-profile-health-oHizqgye.mjs";
20
+ import { n as withCodexConversationThreadActivity } from "./.setup/thread-ownership-queue-Dp24d7-F.mjs";
21
+ import { c as canMutateCodexHost, n as filterCodexMarketplacePlugins, o as CODEX_NATIVE_EXECUTION_AUTH_ERROR, t as discoverCodexMarketplacePlugins } from "./.setup/plugin-marketplace-discovery-D_dV9FXa.mjs";
22
+ import { o as formatCodexDisplayText } from "./.setup/command-formatters-R3ckE3Co.mjs";
23
+ import { a as readCodexConversationBindingDataRecord, i as readCodexConversationBindingData, o as resolveCodexDefaultWorkspaceDir } from "./.setup/conversation-binding-data-C746z5Pn.mjs";
24
+ import { t as isIncognitoSessionKey } from "./.setup/incognito-session-DWYapfwf.mjs";
25
+ import { t as buildCodexMigrationProvider } from "./.setup/provider-DH8NSzGt.mjs";
26
+ import { t as CODEX_CONTROL_METHODS } from "./.setup/capabilities-B3WEZl4e.mjs";
27
+ import { t as assertCodexArchiveDescendantsUnowned } from "./.setup/thread-archive-guard-C9frICzX.mjs";
28
+ import { a as createCodexCliSessionNodeInvokePolicies, c as resolveCodexCliSessionForBindingOnNode, i as createCodexCliSessionNodeHostCommands, l as resumeCodexCliSessionOnNode, s as listCodexCliSessionsOnNode } from "./.setup/node-cli-sessions-HC4W6FLI.mjs";
29
+ import { t as CODEX_CATALOG_MAX_ROWS } from "./.setup/session-catalog-limits-DDxOsQeC.mjs";
30
+ import { t as CODEX_CATALOG_STATE_NAMESPACE } from "./.setup/session-catalog-index-state-TeO7EyO-.mjs";
31
+ import { i as createCodexSessionCatalogNodeHostCommands, n as createCodexSessionCatalogNodeInvokePolicies, r as createCodexSessionCatalogControl, t as codexSessionCatalogRuntime } from "./.setup/session-catalog-4sCdv5qx.mjs";
32
+ import { i as requestCodexAppServerJson } from "./.setup/request-BHZ1nz8d.mjs";
28
33
  import { t as createCodexWebSearchProviderBase } from "./.setup/web-search-provider.shared-BrZmlqyR.mjs";
29
34
  import { normalizePluginsConfig, resolveEffectiveEnableState, resolveLivePluginConfigObject, resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
30
35
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
31
36
  import { asBoolean, asOptionalRecord, asSafeIntegerInRange, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
32
37
  import { isDeepStrictEqual } from "node:util";
33
38
  import { resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-harness-registration";
39
+ import { coerceErrorMessage, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
34
40
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
35
- import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
36
41
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
37
42
  import { jsonResult } from "openclaw/plugin-sdk/tool-results";
38
43
  import { Type } from "typebox";
@@ -41,7 +46,7 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
41
46
  //#region extensions/codex/src/account-usage.ts
42
47
  function registerCodexAccountUsage(api) {
43
48
  api.registerGatewayMethod("codex.accountUsage", async (options) => {
44
- const { handleCodexAccountUsage } = await import("./.setup/account-usage-runtime-C2MOIvfq.mjs");
49
+ const { handleCodexAccountUsage } = await import("./.setup/account-usage-runtime-DFhbh1zz.mjs");
45
50
  await handleCodexAccountUsage(options);
46
51
  }, { scope: "operator.admin" });
47
52
  }
@@ -53,7 +58,7 @@ function createCodexAppServerConnectionHealthService(options) {
53
58
  let abortController;
54
59
  let monitor;
55
60
  const run = async (ctx, signal) => {
56
- const { resolveCodexAppServerRuntimeOptions } = await import("./.setup/config-runtime-CeAhl_h4.mjs").then((n) => n.t);
61
+ const { resolveCodexAppServerRuntimeOptions } = await import("./.setup/config-runtime-C0NbLms1.mjs").then((n) => n.t);
57
62
  let consecutiveFailures = 0;
58
63
  while (!signal.aborted) {
59
64
  let pluginConfig;
@@ -69,8 +74,8 @@ function createCodexAppServerConnectionHealthService(options) {
69
74
  return;
70
75
  }
71
76
  if (runtime.start.transport !== "websocket") return;
72
- const { getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./.setup/shared-client-BpTtuLQ5.mjs").then((n) => n.y);
73
- const { isUnsupportedCodexAppServerVersionError } = await import("./.setup/client-vXs2929Q.mjs").then((n) => n.n);
77
+ const { getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./.setup/shared-client-DqyTMYug.mjs").then((n) => n.v);
78
+ const { isUnsupportedCodexAppServerVersionError } = await import("./.setup/client-N0JpgSzF.mjs").then((n) => n.n);
74
79
  if (signal.aborted) return;
75
80
  let leasedClient;
76
81
  try {
@@ -171,11 +176,15 @@ function waitForReconnect(delayMs, signal) {
171
176
  /** Keeps lifecycle/auth loading behind mutations while sharing the canonical read codec. */
172
177
  function createLazyCodexAppServerBindingStore(state, managedThreadState) {
173
178
  let resolved;
174
- const store = () => resolved ??= import("./.setup/session-binding-_0W_fHRr.mjs").then((n) => n.c).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
179
+ const store = () => resolved ??= import("./.setup/session-binding-DGCYAfvD.mjs").then((n) => n.s).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
175
180
  const managedThreads = managedThreadState ? createCodexManagedThreadStore(managedThreadState) : void 0;
176
181
  return {
177
182
  ...managedThreads ? { managedThreads } : {},
178
183
  read: (identity) => readCurrentCodexAppServerBinding(state, identity),
184
+ get readMany() {
185
+ return state.lookupMany ? (identities) => readCurrentCodexAppServerBindings(state, identities) : void 0;
186
+ },
187
+ readNativeSubagentAssignments: (identity, owner) => readCurrentNativePendingAssignments(state, identity, owner),
179
188
  readNativeSubagentSubmissions: (identity, owner) => readCurrentCodexNativeSubagentSubmissions(state, identity, owner),
180
189
  hasOtherThreadOwner: async (threadId, currentIdentity) => (await store()).hasOtherThreadOwner(threadId, currentIdentity),
181
190
  mutate: async (identity, mutation, assertCurrent) => (await store()).mutate(identity, mutation, assertCurrent),
@@ -213,14 +222,26 @@ function createCodexCommand(options) {
213
222
  acceptsArgs: true,
214
223
  requireAuth: true,
215
224
  handler: async (ctx) => {
216
- const { handleCodexCommand } = await import("./.setup/command-dispatch-naHIZwwF.mjs");
217
- return handleCodexCommand(ctx, options);
225
+ const commandContext = {
226
+ ...ctx,
227
+ gatewayClientScopes: ctx.gatewayClientScopes?.slice()
228
+ };
229
+ const { handleCodexCommand } = await import("./.setup/command-dispatch-BeAoaovI.mjs");
230
+ return handleCodexCommand(commandContext, options);
218
231
  }
219
232
  };
220
233
  }
221
234
  //#endregion
222
235
  //#region extensions/codex/src/conversation-binding-hooks.ts
223
236
  const getNodeConversationState = defineCodexBuildState("openclaw.codex.conversationBinding", () => ({ queue: new KeyedAsyncQueue() }));
237
+ function isCurrentPublicBinding(binding, service) {
238
+ return service.resolveByConversation({
239
+ channel: binding.channel,
240
+ accountId: binding.accountId,
241
+ conversationId: binding.conversationId,
242
+ ...binding.parentConversationId ? { parentConversationId: binding.parentConversationId } : {}
243
+ })?.bindingId === binding.bindingId;
244
+ }
224
245
  async function handleCodexConversationInboundClaim(event, ctx, options) {
225
246
  const publicBinding = ctx.pluginBinding;
226
247
  const data = readCodexConversationBindingData(publicBinding);
@@ -237,7 +258,7 @@ async function handleCodexConversationInboundClaim(event, ctx, options) {
237
258
  return {
238
259
  handled: true,
239
260
  reply: (await getNodeConversationState().queue.enqueue(`${data.nodeId}:${data.sessionId}`, async () => {
240
- const { resolveCodexNativeSandboxBlock } = await import("./.setup/sandbox-guard-BBP-RbTf.mjs").then((n) => n.r);
261
+ const { resolveCodexNativeSandboxBlock } = await import("./.setup/sandbox-guard-DjCz2eOw.mjs").then((n) => n.r);
241
262
  const blocked = resolveCodexNativeSandboxBlock({
242
263
  config: options.config,
243
264
  sessionKey,
@@ -246,9 +267,13 @@ async function handleCodexConversationInboundClaim(event, ctx, options) {
246
267
  if (blocked) return { reply: { text: blocked } };
247
268
  const resume = options.resumeCodexCliSessionOnNode;
248
269
  if (!resume) return { reply: { text: "Codex CLI node binding is unavailable because Gateway node runtime is not attached." } };
270
+ const { getSessionBindingService } = await import("openclaw/plugin-sdk/conversation-binding-runtime");
271
+ if (!isCurrentPublicBinding(publicBinding, getSessionBindingService())) return { reply: { text: "This Codex conversation was detached or changed before its message could run." } };
249
272
  return { reply: { text: (await resume({
250
273
  nodeId: data.nodeId,
251
274
  sessionId: data.sessionId,
275
+ agentId: data.agentId,
276
+ sessionKey,
252
277
  prompt,
253
278
  cwd: data.cwd,
254
279
  timeoutMs: options.timeoutMs
@@ -270,7 +295,7 @@ async function handleCodexConversationInboundClaim(event, ctx, options) {
270
295
  return {
271
296
  handled: true,
272
297
  reply: (await withCodexConversationThreadActivity(data.bindingId, async () => {
273
- const { resolveCodexNativeExecutionBlock } = await import("./.setup/sandbox-guard-BBP-RbTf.mjs").then((n) => n.r);
298
+ const { resolveCodexNativeExecutionBlock } = await import("./.setup/sandbox-guard-DjCz2eOw.mjs").then((n) => n.r);
274
299
  const nativeExecutionBlock = resolveCodexNativeExecutionBlock({
275
300
  config: options.config,
276
301
  sessionKey,
@@ -279,15 +304,9 @@ async function handleCodexConversationInboundClaim(event, ctx, options) {
279
304
  });
280
305
  if (nativeExecutionBlock) return { reply: { text: nativeExecutionBlock } };
281
306
  const { getSessionBindingService } = await import("openclaw/plugin-sdk/conversation-binding-runtime");
282
- const { runBoundTurnWithMissingThreadRecovery } = await import("./.setup/conversation-binding-DhzrpTM6.mjs");
283
- const currentPublicBinding = getSessionBindingService().resolveByConversation({
284
- channel: publicBinding.channel,
285
- accountId: publicBinding.accountId,
286
- conversationId: publicBinding.conversationId,
287
- ...publicBinding.parentConversationId ? { parentConversationId: publicBinding.parentConversationId } : {}
288
- });
307
+ const { runBoundTurnWithMissingThreadRecovery } = await import("./.setup/conversation-binding-3Min8qvP.mjs");
289
308
  const current = options.bindingStore.read(identity);
290
- if (currentPublicBinding?.bindingId !== publicBinding.bindingId || expected && (!current || current.threadId !== expected.threadId || current.conversationStartId !== expected.conversationStartId) || !expected && current && data.start?.id && current.conversationStartId !== data.start.id) return { reply: { text: "This Codex conversation was detached or changed before its message could run." } };
309
+ if (!isCurrentPublicBinding(publicBinding, getSessionBindingService()) || expected && (!current || current.threadId !== expected.threadId || current.conversationStartId !== expected.conversationStartId) || !expected && current && data.start?.id && current.conversationStartId !== data.start.id) return { reply: { text: "This Codex conversation was detached or changed before its message could run." } };
291
310
  return await runBoundTurnWithMissingThreadRecovery({
292
311
  bindingStore: options.bindingStore,
293
312
  data,
@@ -319,7 +338,7 @@ async function handleCodexConversationBindingResolved(event, options) {
319
338
  const binding = options.bindingStore.read(identity);
320
339
  assertCodexBindingMayBeReplaced(binding, "clearing a denied conversation binding");
321
340
  if (binding && (!data.start?.id || binding.conversationStartId === data.start.id)) await withCodexConversationThreadActivity(identity.bindingId, async () => {
322
- const { retireCodexConversationThreadBinding } = await import("./.setup/thread-ownership-skomxnIt.mjs").then((n) => n.o);
341
+ const { retireCodexConversationThreadBinding } = await import("./.setup/thread-ownership-roNP0l1c.mjs").then((n) => n.o);
323
342
  return retireCodexConversationThreadBinding({
324
343
  bindingStore: options.bindingStore,
325
344
  identity,
@@ -354,7 +373,7 @@ function createCodexPluginsTool(options) {
354
373
  const query = typeof params.query === "string" ? params.query : "";
355
374
  const marketplace = typeof params.marketplace === "string" ? params.marketplace.trim() : void 0;
356
375
  const limit = typeof params.limit === "number" && Number.isInteger(params.limit) ? Math.max(1, Math.min(params.limit, 20)) : 12;
357
- const { codexBindingConnectionSelection, resolveCodexBindingAppServerConnection } = await import("./.setup/binding-connection-Bm38niE8.mjs").then((n) => n.n);
376
+ const { codexBindingConnectionSelection, resolveCodexBindingAppServerConnection } = await import("./.setup/binding-connection-DTtN1KrX.mjs").then((n) => n.n);
358
377
  const pluginConfig = options.getPluginConfig();
359
378
  const config = runtimeConfig();
360
379
  const identity = options.context.sessionId ? sessionBindingIdentity({
@@ -367,10 +386,11 @@ function createCodexPluginsTool(options) {
367
386
  const binding = readBinding();
368
387
  const selection = codexBindingConnectionSelection(binding);
369
388
  const assertCurrent = () => {
389
+ options.context.assertInvocationCurrent?.();
370
390
  if (runtimeConfig() !== config || !isDeepStrictEqual(options.getPluginConfig(), pluginConfig) || !isDeepStrictEqual(codexBindingConnectionSelection(readBinding()), selection)) throw new Error("Codex plugin discovery ownership changed; retry the request.");
371
391
  };
372
392
  const workspaceDir = binding?.cwd?.trim() || options.context.workspaceDir?.trim() || resolveCodexDefaultWorkspaceDir(pluginConfig);
373
- const request = options.request ?? (await import("./.setup/command-rpc-DHFpn4le.mjs").then((n) => n.n)).codexControlRequest;
393
+ const request = options.request ?? (await import("./.setup/command-rpc-CGJGUQ6Y.mjs").then((n) => n.n)).codexControlRequest;
374
394
  const connection = await resolveCodexBindingAppServerConnection({
375
395
  binding,
376
396
  pluginConfig,
@@ -403,7 +423,7 @@ function createCodexPluginsTool(options) {
403
423
  };
404
424
  }
405
425
  function projectAvailablePlugin(plugin) {
406
- const projected = {
426
+ return {
407
427
  id: plugin.id,
408
428
  pluginName: plugin.pluginName,
409
429
  marketplaceName: plugin.marketplaceName,
@@ -411,13 +431,12 @@ function projectAvailablePlugin(plugin) {
411
431
  untrustedDeveloperName: plugin.developerName,
412
432
  installed: plugin.installed,
413
433
  enabled: plugin.enabled,
414
- available: plugin.available
434
+ available: plugin.available,
435
+ ...plugin.description ? { untrustedDescription: plugin.description } : {},
436
+ ...plugin.installPolicy ? { installPolicy: plugin.installPolicy } : {},
437
+ ...plugin.authPolicy ? { authPolicy: plugin.authPolicy } : {},
438
+ ...plugin.mustShowInstallationInterstitial !== void 0 ? { mustShowInstallationInterstitial: plugin.mustShowInstallationInterstitial } : {}
415
439
  };
416
- if (plugin.description) projected.untrustedDescription = plugin.description;
417
- if (plugin.installPolicy) projected.installPolicy = plugin.installPolicy;
418
- if (plugin.authPolicy) projected.authPolicy = plugin.authPolicy;
419
- if (plugin.mustShowInstallationInterstitial !== void 0) projected.mustShowInstallationInterstitial = plugin.mustShowInstallationInterstitial;
420
- return projected;
421
440
  }
422
441
  //#endregion
423
442
  //#region extensions/codex/src/native-thread-tool.ts
@@ -475,22 +494,12 @@ function readThreadId(params) {
475
494
  label: "thread_id"
476
495
  });
477
496
  }
478
- function readThreadStatusType(value) {
479
- if (!isJsonObject(value) || !isJsonObject(value.thread) || !isJsonObject(value.thread.status)) return;
480
- return typeof value.thread.status.type === "string" ? value.thread.status.type : void 0;
481
- }
482
- function assertThreadMayBeArchived(value, expectedThreadId) {
497
+ function assertThreadIdle(value, expectedThreadId, action) {
483
498
  if (!isJsonObject(value) || !isJsonObject(value.thread)) throw new Error("Codex app-server returned an invalid thread/read response");
484
499
  if (value.thread.id !== expectedThreadId) throw new Error("Codex app-server returned a different thread than requested");
485
- const status = readThreadStatusType(value);
486
- if (status === "active") throw new Error("cannot archive an active Codex thread; wait for its turn to finish");
487
- if (status !== "idle" && status !== "notLoaded") throw new Error("cannot verify that the Codex thread is idle; refusing to archive");
488
- }
489
- function assertThreadMayBeForked(value, expectedThreadId) {
490
- if (!isJsonObject(value) || !isJsonObject(value.thread)) throw new Error("Codex app-server returned an invalid thread/read response");
491
- if (value.thread.id !== expectedThreadId) throw new Error("Codex app-server returned a different thread than requested");
492
- const status = readThreadStatusType(value);
493
- if (status !== "idle" && status !== "notLoaded") throw new Error("cannot fork a Codex thread unless it is idle or not loaded");
500
+ const status = isJsonObject(value.thread.status) ? value.thread.status.type : void 0;
501
+ if (action === "archive" && status === "active") throw new Error("cannot archive an active Codex thread; wait for its turn to finish");
502
+ if (status !== "idle" && status !== "notLoaded") throw new Error(action === "archive" ? "cannot verify that the Codex thread is idle; refusing to archive" : "cannot fork a Codex thread unless it is idle or not loaded");
494
503
  }
495
504
  function redactNativeThreadTranscriptFields(value) {
496
505
  if (!isJsonObject(value)) return value;
@@ -558,11 +567,12 @@ function createCodexThreadsTool(options) {
558
567
  const mayReadRawTranscripts = supervision?.enabled !== true || supervision.allowRawTranscripts === true;
559
568
  if ((action === "fork" || action === "rename" || action === "archive" || action === "unarchive") && supervision?.enabled === true && supervision.allowWriteControls !== true) throw new Error("Codex native thread mutations are disabled for this codex plugin supervision config.");
560
569
  const run = async (archiveAdmission) => {
561
- const request = options.request ?? (await import("./.setup/command-rpc-DHFpn4le.mjs").then((n) => n.n)).codexControlRequest;
570
+ const request = options.request ?? (await import("./.setup/command-rpc-CGJGUQ6Y.mjs").then((n) => n.n)).codexControlRequest;
562
571
  const { isModelSelectionLocked, ModelSelectionLockedError } = await import("openclaw/plugin-sdk/model-session-runtime");
563
- const { codexBindingConnectionSelection, resolveCodexBindingAppServerConnection } = await import("./.setup/binding-connection-Bm38niE8.mjs").then((n) => n.n);
564
- const { resolveCodexSupervisionAppServerRuntimeOptions } = await import("./.setup/config-runtime-CeAhl_h4.mjs").then((n) => n.t);
565
- const requestOptions = async (pluginConfig) => {
572
+ const { codexBindingConnectionSelection, resolveCodexBindingAppServerConnection } = await import("./.setup/binding-connection-DTtN1KrX.mjs").then((n) => n.n);
573
+ const { resolveCodexSupervisionAppServerRuntimeOptions } = await import("./.setup/config-runtime-C0NbLms1.mjs").then((n) => n.t);
574
+ const requestOptions = async () => {
575
+ const pluginConfig = admissionConfig;
566
576
  const plugin = readCodexPluginConfig(pluginConfig);
567
577
  const base = baseRequestOptions();
568
578
  const session = currentSession();
@@ -571,6 +581,7 @@ function createCodexThreadsTool(options) {
571
581
  const binding = readBinding();
572
582
  const selection = codexBindingConnectionSelection(binding);
573
583
  const assertCurrent = () => {
584
+ options.context.assertInvocationCurrent?.();
574
585
  const current = currentSession();
575
586
  if (runtimeConfig() !== base.config || !isDeepStrictEqual(options.getPluginConfig(), pluginConfig) || current?.sessionId !== session?.sessionId || current?.entry?.sessionId !== session?.entry?.sessionId || isModelSelectionLocked(current?.entry) !== isModelSelectionLocked(session?.entry) || !isDeepStrictEqual(codexBindingConnectionSelection(readBinding()), selection)) throw new Error("Codex native thread ownership changed; retry the request.");
576
587
  };
@@ -597,11 +608,12 @@ function createCodexThreadsTool(options) {
597
608
  assertCurrent
598
609
  };
599
610
  };
611
+ const scopedRequest = async (method, requestParams) => request(admissionConfig, method, requestParams, await requestOptions());
600
612
  if (action === "list") {
601
613
  const cursor = readStringParam(params, "cursor");
602
614
  const searchTerm = readStringParam(params, "search");
603
615
  if (searchTerm && !mayReadRawTranscripts) throw new Error("Codex native thread search is disabled while raw transcript access is disabled.");
604
- const response = await request(admissionConfig, CODEX_CONTROL_METHODS.listThreads, {
616
+ const response = await scopedRequest(CODEX_CONTROL_METHODS.listThreads, {
605
617
  archived: asBoolean(params.archived) ?? false,
606
618
  limit: asSafeIntegerInRange(params.limit, {
607
619
  min: 1,
@@ -613,17 +625,17 @@ function createCodexThreadsTool(options) {
613
625
  sourceKinds: [...CODEX_INTERACTIVE_THREAD_SOURCE_KINDS],
614
626
  ...cursor ? { cursor } : {},
615
627
  ...searchTerm ? { searchTerm } : {}
616
- }, await requestOptions(admissionConfig));
628
+ });
617
629
  return jsonResult(mayReadRawTranscripts ? response : redactNativeThreadResponse(response));
618
630
  }
619
631
  const threadId = archiveAdmission?.threadId ?? readThreadId(params);
620
632
  if (action === "read") {
621
633
  const includeTurns = asBoolean(params.include_turns) ?? false;
622
634
  if (includeTurns && !mayReadRawTranscripts) throw new Error("Codex raw transcript reads are disabled for this codex plugin supervision config.");
623
- const response = await request(admissionConfig, CODEX_CONTROL_METHODS.readThread, {
635
+ const response = await scopedRequest(CODEX_CONTROL_METHODS.readThread, {
624
636
  threadId,
625
637
  includeTurns
626
- }, await requestOptions(admissionConfig));
638
+ });
627
639
  return jsonResult(mayReadRawTranscripts ? response : redactNativeThreadResponse(response));
628
640
  }
629
641
  if (action === "rename") {
@@ -631,10 +643,10 @@ function createCodexThreadsTool(options) {
631
643
  required: true,
632
644
  label: "name"
633
645
  });
634
- await request(admissionConfig, CODEX_CONTROL_METHODS.renameThread, {
646
+ await scopedRequest(CODEX_CONTROL_METHODS.renameThread, {
635
647
  threadId,
636
648
  name
637
- }, await requestOptions(admissionConfig));
649
+ });
638
650
  return jsonResult({
639
651
  action,
640
652
  threadId,
@@ -642,7 +654,7 @@ function createCodexThreadsTool(options) {
642
654
  });
643
655
  }
644
656
  if (action === "unarchive") {
645
- const response = await request(admissionConfig, CODEX_CONTROL_METHODS.unarchiveThread, { threadId }, await requestOptions(admissionConfig));
657
+ const response = await scopedRequest(CODEX_CONTROL_METHODS.unarchiveThread, { threadId });
646
658
  return jsonResult(mayReadRawTranscripts ? response : redactNativeThreadResponse(response));
647
659
  }
648
660
  const session = archiveAdmission?.session ?? currentSession();
@@ -654,27 +666,27 @@ function createCodexThreadsTool(options) {
654
666
  if (isModelSelectionLocked(admittedSession.entry)) throw new ModelSelectionLockedError();
655
667
  assertCodexBindingMayBeReplaced(archivedBinding, "archiving its bound native thread");
656
668
  }
657
- assertThreadMayBeArchived(await request(admissionConfig, CODEX_CONTROL_METHODS.readThread, {
669
+ assertThreadIdle(await scopedRequest(CODEX_CONTROL_METHODS.readThread, {
658
670
  threadId,
659
671
  includeTurns: false
660
- }, await requestOptions(admissionConfig)), threadId);
672
+ }), threadId, "archive");
661
673
  if (await options.bindingStore.hasOtherThreadOwner(threadId, identity)) throw new Error("cannot archive a native Codex thread owned by another OpenClaw session");
662
674
  await assertCodexArchiveDescendantsUnowned({
663
675
  bindingStore: options.bindingStore,
664
676
  threadId,
665
- listPage: async (listParams) => await request(admissionConfig, CODEX_CONTROL_METHODS.listThreads, listParams, await requestOptions(admissionConfig)),
677
+ listPage: async (listParams) => await scopedRequest(CODEX_CONTROL_METHODS.listThreads, listParams),
666
678
  assertDescendantIdle: async (descendantThreadId) => {
667
- assertThreadMayBeArchived(await request(admissionConfig, CODEX_CONTROL_METHODS.readThread, {
679
+ assertThreadIdle(await scopedRequest(CODEX_CONTROL_METHODS.readThread, {
668
680
  threadId: descendantThreadId,
669
681
  includeTurns: false
670
- }, await requestOptions(admissionConfig)), descendantThreadId);
682
+ }), descendantThreadId, "archive");
671
683
  }
672
684
  });
673
- await request(admissionConfig, CODEX_CONTROL_METHODS.archiveThread, { threadId }, await requestOptions(admissionConfig));
685
+ await scopedRequest(CODEX_CONTROL_METHODS.archiveThread, { threadId });
674
686
  if (archivedBinding?.threadId === threadId) await options.bindingStore.mutate(identity, {
675
687
  kind: "clear",
676
688
  threadId
677
- });
689
+ }, options.context.assertInvocationCurrent);
678
690
  return jsonResult({
679
691
  action,
680
692
  threadId
@@ -686,33 +698,65 @@ function createCodexThreadsTool(options) {
686
698
  if (attach && isModelSelectionLocked(session?.entry)) throw new ModelSelectionLockedError();
687
699
  const usesSupervisionConnection = binding?.connectionScope === "supervision" || admissionPlugin.appServer?.homeScope !== "user" && supervision?.enabled === true;
688
700
  if (attach && usesSupervisionConnection) throw new Error("Supervised Codex forks must stay detached; set attach=false.");
701
+ const forkOptions = await requestOptions();
702
+ const { retainCodexAppServerBindingSubscription, rollbackCodexAppServerBindingSubscription } = await import("./.setup/thread-ownership-roNP0l1c.mjs").then((n) => n.o);
703
+ const { closeCodexStartupClientBestEffort } = await import("./.setup/attempt-client-cleanup-DOP-cW5j.mjs").then((n) => n.a);
689
704
  if (attach) {
690
705
  assertCodexBindingMayBeReplaced(binding, "attaching a different native fork");
691
- assertThreadMayBeForked(await request(admissionConfig, CODEX_CONTROL_METHODS.readThread, {
706
+ assertThreadIdle(await request(admissionConfig, CODEX_CONTROL_METHODS.readThread, {
692
707
  threadId,
693
708
  includeTurns: false
694
- }, await requestOptions(admissionConfig)), threadId);
709
+ }, forkOptions), threadId, "fork");
695
710
  }
696
711
  const response = await request(admissionConfig, CODEX_CONTROL_METHODS.forkThread, {
697
712
  threadId,
698
713
  threadSource: "user",
699
714
  excludeTurns: true
700
- }, await requestOptions(admissionConfig));
701
- if (!isJsonObject(response) || !isJsonObject(response.thread)) throw new Error("Codex app-server returned an invalid thread/fork response");
702
- const forkThreadId = typeof response.thread.id === "string" && response.thread.id.trim() ? response.thread.id : void 0;
703
- if (!forkThreadId) throw new Error("Codex app-server thread/fork response did not include a thread id");
704
- if (attach && session) {
705
- if (!await options.bindingStore.mutate(currentIdentity(session.sessionId), {
706
- kind: "set",
707
- binding: {
708
- threadId: forkThreadId,
709
- cwd: typeof response.thread.cwd === "string" ? response.thread.cwd : options.context.workspaceDir ?? "",
710
- model: typeof response.model === "string" ? response.model : void 0,
711
- modelProvider: typeof response.modelProvider === "string" ? response.modelProvider : void 0,
712
- historyCoveredThrough: (/* @__PURE__ */ new Date()).toISOString()
715
+ }, {
716
+ ...forkOptions,
717
+ onResponse: async (value, client, { assertCurrent }) => {
718
+ if (!isJsonObject(value) || !isJsonObject(value.thread)) {
719
+ await closeCodexStartupClientBestEffort(client);
720
+ throw new Error("Codex app-server returned an invalid thread/fork response");
713
721
  }
714
- })) throw new Error("Codex session binding changed before the fork could be attached");
715
- }
722
+ const forkThread = value.thread;
723
+ const forkThreadId = typeof forkThread.id === "string" && forkThread.id.trim() ? forkThread.id : void 0;
724
+ if (!forkThreadId) {
725
+ await closeCodexStartupClientBestEffort(client);
726
+ throw new Error("Codex app-server thread/fork response did not include a thread id");
727
+ }
728
+ let retained = false;
729
+ let attached = false;
730
+ try {
731
+ assertCurrent();
732
+ if (attach && session) {
733
+ const identity = currentIdentity(session.sessionId);
734
+ await options.bindingStore.withLease(identity, async () => {
735
+ assertCurrent();
736
+ if (currentSession()?.entry?.sessionId !== session.sessionId) throw new Error("Codex native thread ownership changed; retry the request.");
737
+ assertCodexBindingMayBeReplaced(currentBinding(session), "attaching a different native fork");
738
+ retained = await retainCodexAppServerBindingSubscription(client, forkThreadId);
739
+ if (!retained) throw new Error("Codex fork lost its native subscription owner.");
740
+ const nextBinding = {
741
+ threadId: forkThreadId,
742
+ clientId: client.getInstanceId(),
743
+ cwd: typeof forkThread.cwd === "string" ? forkThread.cwd : options.context.workspaceDir ?? "",
744
+ model: typeof value.model === "string" ? value.model : void 0,
745
+ modelProvider: typeof value.modelProvider === "string" ? value.modelProvider : void 0,
746
+ historyCoveredThrough: (/* @__PURE__ */ new Date()).toISOString()
747
+ };
748
+ attached = await options.bindingStore.mutate(identity, {
749
+ kind: "set",
750
+ binding: nextBinding
751
+ }, assertCurrent);
752
+ if (!attached) throw new Error("Codex session binding changed before the fork could be attached");
753
+ });
754
+ }
755
+ } finally {
756
+ if (!attached) await rollbackCodexAppServerBindingSubscription(client, forkThreadId, retained);
757
+ }
758
+ }
759
+ });
716
760
  const result = {
717
761
  action,
718
762
  sourceThreadId: threadId,
@@ -759,6 +803,7 @@ function createCodexNodeExecServerCommand() {
759
803
  cap: CODEX_NODE_EXEC_SERVER_CAPABILITY,
760
804
  dangerous: true,
761
805
  duplex: true,
806
+ hasActiveWork: () => activeProcesses.size > 0,
762
807
  onDisconnect: async () => {
763
808
  await Promise.all([...activeProcesses].map(async (terminate) => await terminate()));
764
809
  },
@@ -772,37 +817,34 @@ function createCodexNodeExecServerCommand() {
772
817
  }
773
818
  if (!isRecord(request) || Object.keys(request).length !== 2 || request.authorization !== "human-approved" && request.authorization !== "session-full") throw new Error("Codex node exec-server requires an authorized managed placement workspace launch.");
774
819
  const placement = parseCodexNodePlacementWorkspace(request.placement);
775
- if (!context?.acquireManagedWorkspace || context.sessionKey !== placement.sessionKey || io.signal.aborted) throw new Error("Codex node exec-server requires active managed placement authority.");
776
- const workspace = context.acquireManagedWorkspace({
820
+ if (!context?.acquireManagedWorkspaceAsync || context.sessionKey !== placement.sessionKey || io.signal.aborted) throw new Error("Codex node exec-server requires active managed placement authority.");
821
+ if (!context.prepareExecAuthorization) throw new Error("Codex node execution requires node-local exec policy support; update the node.");
822
+ const runtimeIo = context.signal ? {
823
+ ...io,
824
+ signal: AbortSignal.any([io.signal, context.signal])
825
+ } : io;
826
+ const assertExecAuthorized = context.prepareExecAuthorization(request.authorization);
827
+ const { runCodexNodeExecServer } = await import("./.setup/node-exec-server.runtime-BgBfWQqo.mjs");
828
+ runtimeIo.signal.throwIfAborted();
829
+ const workspace = await context.acquireManagedWorkspaceAsync({
777
830
  workspaceDir: placement.cwd,
778
831
  environmentId: placement.environmentId,
779
832
  sessionId: placement.sessionId,
780
833
  ownerEpoch: placement.ownerEpoch,
781
834
  sessionKey: placement.sessionKey
782
835
  });
783
- const frames = io.frames;
784
- let unsubscribe;
785
836
  try {
786
- if (!context.prepareExecAuthorization) throw new Error("Codex node execution requires node-local exec policy support; update the node.");
787
- const assertExecAuthorized = context.prepareExecAuthorization(request.authorization);
788
- const { runCodexNodeExecServer } = await import("./.setup/node-exec-server.runtime-BaViBKNz.mjs");
789
- return await runCodexNodeExecServer({
790
- workspaceDir: workspace.workspaceDir,
791
- homeDir: workspace.homeDir,
792
- io,
793
- activeProcesses,
794
- assertExecAuthorized,
795
- onFrameReceiver: (receiver) => {
796
- unsubscribe = frames.onMessage(receiver);
797
- }
798
- });
799
- } finally {
800
- try {
801
- unsubscribe?.();
802
- } finally {
803
- workspace.release();
804
- }
837
+ runtimeIo.signal.throwIfAborted();
838
+ } catch (error) {
839
+ workspace.release();
840
+ throw error;
805
841
  }
842
+ return await runCodexNodeExecServer({
843
+ workspace,
844
+ io: runtimeIo,
845
+ activeProcesses,
846
+ assertExecAuthorized
847
+ });
806
848
  }
807
849
  };
808
850
  }
@@ -885,6 +927,29 @@ function createCodexNodeExecServerInvokePolicy() {
885
927
  };
886
928
  }
887
929
  //#endregion
930
+ //#region extensions/codex/src/supervision-tool-policy.ts
931
+ var CodexSupervisionPolicyError = class extends Error {};
932
+ function requireSupervisionEnabled(pluginConfig) {
933
+ if (readCodexPluginConfig(pluginConfig).supervision?.enabled !== true) throw new CodexSupervisionPolicyError("Codex supervision is disabled in the codex plugin config.");
934
+ }
935
+ function requireOwnerAccess(options) {
936
+ options.assertInvocationCurrent?.();
937
+ if (!options.senderIsOwner) throw new CodexSupervisionPolicyError("Codex supervision compatibility tools require an owner-authorized sender.");
938
+ }
939
+ function resolveToolPolicy(pluginConfig) {
940
+ const config = readCodexPluginConfig(pluginConfig).supervision;
941
+ return {
942
+ allowRawTranscripts: config?.allowRawTranscripts === true,
943
+ allowWriteControls: config?.allowWriteControls === true
944
+ };
945
+ }
946
+ function requireRawTranscriptAccess(pluginConfig) {
947
+ if (!resolveToolPolicy(pluginConfig).allowRawTranscripts) throw new CodexSupervisionPolicyError("Codex session reads are disabled for this codex plugin supervision config.");
948
+ }
949
+ function requireWriteAccess(pluginConfig) {
950
+ if (!resolveToolPolicy(pluginConfig).allowWriteControls) throw new CodexSupervisionPolicyError("Codex write controls are disabled for this codex plugin supervision config.");
951
+ }
952
+ //#endregion
888
953
  //#region extensions/codex/src/supervision-tools.ts
889
954
  /**
890
955
  * Compatibility tools for the retired Codex Supervisor plugin.
@@ -896,10 +961,6 @@ function createCodexNodeExecServerInvokePolicy() {
896
961
  */
897
962
  /** Legacy endpoint env retained for the shipped Supervisor tool contract. */
898
963
  const LEGACY_CODEX_SUPERVISOR_ENDPOINTS_ENV = "OPENCLAW_CODEX_SUPERVISOR_ENDPOINTS";
899
- /** Legacy standalone-MCP transcript gate. Agent tools use canonical config. */
900
- const LEGACY_CODEX_SUPERVISOR_RAW_TRANSCRIPTS_ENV = "OPENCLAW_CODEX_SUPERVISOR_ALLOW_RAW_TRANSCRIPTS";
901
- /** Legacy standalone-MCP write gate. Agent tools use canonical config. */
902
- const LEGACY_CODEX_SUPERVISOR_WRITE_CONTROLS_ENV = "OPENCLAW_CODEX_SUPERVISOR_ALLOW_WRITE_CONTROLS";
903
964
  const CODEX_SUPERVISION_COMPAT_TOOL_NAMES = [
904
965
  "codex_endpoint_probe",
905
966
  "codex_sessions_list",
@@ -952,7 +1013,6 @@ const PAGE_LIMIT = 100;
952
1013
  const MAX_COMPAT_PAGINATION_PAGES = 100;
953
1014
  const MAX_COMPAT_CURSOR_LENGTH = 4096;
954
1015
  const MAX_COMPAT_THREAD_ID_LENGTH = 4096;
955
- var CodexSupervisionPolicyError = class extends Error {};
956
1016
  function asRecordArray(value) {
957
1017
  return Array.isArray(value) ? value.filter(isRecord) : [];
958
1018
  }
@@ -977,9 +1037,6 @@ function readStoredThreads(data, maxEntries) {
977
1037
  return entry;
978
1038
  });
979
1039
  }
980
- function readBooleanParam(params, key) {
981
- return params[key] === true;
982
- }
983
1040
  function readIntegerParam(params, key) {
984
1041
  const value = params[key];
985
1042
  if (value === void 0) return;
@@ -1071,25 +1128,23 @@ function readLegacyEnvEndpoints(env) {
1071
1128
  function resolveEndpoints(pluginConfig, env, runtimeConfig, resolveAuthProfileId, resolveRuntimeOptions) {
1072
1129
  const configured = readCodexPluginConfig(pluginConfig).supervision?.endpoints;
1073
1130
  const endpoints = configured?.length ? configured : readLegacyEnvEndpoints(env);
1074
- return (endpoints ? requireUniqueEndpointIds(endpoints.map(normalizeConfiguredEndpoint)) : [{
1131
+ const normalized = endpoints ? requireUniqueEndpointIds(endpoints.map(normalizeConfiguredEndpoint)) : [{
1075
1132
  id: "local",
1076
1133
  label: "local Codex app-server"
1077
- }]).map((endpoint) => {
1078
- const resolved = {
1079
- id: endpoint.id,
1080
- connectionKey: supervisionEndpointConnectionKey({
1081
- endpoint,
1082
- pluginConfig,
1083
- env,
1084
- runtimeConfig,
1085
- resolveAuthProfileId,
1086
- resolveRuntimeOptions
1087
- })
1088
- };
1089
- if (endpoint.label !== void 0) resolved.label = endpoint.label;
1090
- if (endpoint.configured !== void 0) resolved.configured = endpoint.configured;
1091
- return resolved;
1134
+ }];
1135
+ const resolved = [];
1136
+ for (const endpoint of normalized) resolved.push({
1137
+ ...endpoint,
1138
+ connectionKey: supervisionEndpointConnectionKey({
1139
+ endpoint,
1140
+ pluginConfig,
1141
+ env,
1142
+ runtimeConfig,
1143
+ resolveAuthProfileId,
1144
+ resolveRuntimeOptions
1145
+ })
1092
1146
  });
1147
+ return resolved;
1093
1148
  }
1094
1149
  function resolveEndpointStartOptions(params) {
1095
1150
  const base = params.resolveRuntimeOptions({
@@ -1148,8 +1203,10 @@ function supervisionEndpointConnectionKey(params) {
1148
1203
  })
1149
1204
  });
1150
1205
  }
1151
- function createCanonicalEndpointRequest(options) {
1206
+ function createPolicyGuardedRequest(options, policy) {
1152
1207
  return async (endpoint, method, requestParams) => {
1208
+ const currentEndpoint = requireCurrentEndpoint(options, policy, endpoint);
1209
+ if (options.request) return await options.request(currentEndpoint, method, requestParams);
1153
1210
  const pluginConfig = options.getPluginConfig();
1154
1211
  const env = options.env ?? process.env;
1155
1212
  const runtime = options.resolveRuntimeOptions({
@@ -1158,7 +1215,7 @@ function createCanonicalEndpointRequest(options) {
1158
1215
  });
1159
1216
  const config = options.getRuntimeConfig?.();
1160
1217
  const startOptions = resolveEndpointStartOptions({
1161
- endpoint,
1218
+ endpoint: currentEndpoint,
1162
1219
  pluginConfig,
1163
1220
  env,
1164
1221
  resolveRuntimeOptions: options.resolveRuntimeOptions
@@ -1168,6 +1225,9 @@ function createCanonicalEndpointRequest(options) {
1168
1225
  requestParams,
1169
1226
  timeoutMs: runtime.requestTimeoutMs,
1170
1227
  startOptions,
1228
+ assertCurrent: () => {
1229
+ requireCurrentEndpoint(options, policy, currentEndpoint);
1230
+ },
1171
1231
  ...endpoint.configured || startOptions.homeScope === "user" ? { authProfileId: null } : {},
1172
1232
  ...config ? { config } : {}
1173
1233
  });
@@ -1203,7 +1263,7 @@ function threadFromRead(value) {
1203
1263
  return isRecord(value) && isRecord(value.thread) ? value.thread : void 0;
1204
1264
  }
1205
1265
  function isLoadedThreadReadMiss(error) {
1206
- const message = error instanceof Error ? error.message : String(error);
1266
+ const message = coerceErrorMessage(error);
1207
1267
  return message.includes("thread not found") || message.includes("thread not loaded");
1208
1268
  }
1209
1269
  async function readThread(params) {
@@ -1224,86 +1284,63 @@ async function readThread(params) {
1224
1284
  return thread;
1225
1285
  }
1226
1286
  }
1227
- async function listLoadedSessions(request, endpoint) {
1287
+ async function listSessions(request, endpoint, storedLimit) {
1288
+ const loaded = storedLimit === void 0;
1289
+ const method = loaded ? "thread/loaded/list" : "thread/list";
1290
+ const limit = storedLimit ?? Infinity;
1228
1291
  const sessions = [];
1229
1292
  const seenCursors = /* @__PURE__ */ new Set();
1230
1293
  let cursor;
1231
1294
  for (let pageIndex = 0; pageIndex < MAX_COMPAT_PAGINATION_PAGES; pageIndex += 1) {
1232
- const listed = await request(endpoint, "thread/loaded/list", {
1233
- limit: PAGE_LIMIT,
1295
+ const remaining = limit - sessions.length;
1296
+ if (remaining <= 0) break;
1297
+ const pageLimit = Math.min(PAGE_LIMIT, remaining);
1298
+ const listed = await request(endpoint, method, {
1299
+ ...loaded ? {} : {
1300
+ archived: false,
1301
+ sourceKinds: [...ALL_CODEX_THREAD_SOURCE_KINDS],
1302
+ modelProviders: [],
1303
+ sortKey: "recency_at",
1304
+ sortDirection: "desc",
1305
+ useStateDbOnly: true
1306
+ },
1307
+ limit: pageLimit,
1234
1308
  ...cursor ? { cursor } : {}
1235
1309
  });
1236
- if (!isRecord(listed) || !Array.isArray(listed.data)) throw new Error("Codex thread/loaded/list returned an invalid response");
1237
- const threadIds = readLoadedThreadIds(listed.data);
1238
- for (const threadId of threadIds) {
1239
- if (sessions.some((entry) => entry.threadId === threadId)) continue;
1310
+ if (!isRecord(listed) || !Array.isArray(listed.data)) throw new Error(`Codex ${method} returned an invalid response`);
1311
+ const entries = loaded ? readLoadedThreadIds(listed.data) : readStoredThreads(listed.data, pageLimit);
1312
+ for (const entry of entries) {
1313
+ if (typeof entry === "string" && sessions.some((session) => session.threadId === entry)) continue;
1240
1314
  try {
1241
- const thread = await readThread({
1315
+ const thread = typeof entry === "string" ? await readThread({
1242
1316
  request,
1243
1317
  endpoint,
1244
- threadId,
1318
+ threadId: entry,
1245
1319
  includeTurns: false
1246
- });
1247
- const session = toSession(endpoint.id, thread, true);
1248
- if (session) sessions.push(session);
1320
+ }) : entry;
1321
+ const session = toSession(endpoint.id, thread, loaded ? true : void 0);
1322
+ if (session && (loaded || !sessions.some((existing) => existing.threadId === session.threadId))) sessions.push(session);
1249
1323
  } catch (error) {
1250
- if (!isLoadedThreadReadMiss(error)) throw error;
1324
+ if (!loaded || !isLoadedThreadReadMiss(error)) throw error;
1251
1325
  }
1252
1326
  }
1253
- const nextCursor = readCompatNextCursor(listed.nextCursor, "thread/loaded/list");
1254
- if (nextCursor && seenCursors.has(nextCursor)) throw new Error(`Codex thread/loaded/list returned repeated cursor ${nextCursor}`);
1327
+ const nextCursor = readCompatNextCursor(listed.nextCursor, method);
1328
+ if (nextCursor && sessions.length < limit && seenCursors.has(nextCursor)) throw new Error(`Codex ${method} returned repeated cursor ${nextCursor}`);
1255
1329
  if (nextCursor) seenCursors.add(nextCursor);
1256
1330
  cursor = nextCursor;
1257
- if (!cursor) break;
1331
+ if (!cursor || sessions.length >= limit) break;
1258
1332
  }
1259
- if (cursor) throw new Error(`Codex thread/loaded/list exceeded ${MAX_COMPAT_PAGINATION_PAGES} pages with a continuation cursor`);
1260
- return sessions;
1261
- }
1262
- async function listStoredSessions(params) {
1263
- const sessions = [];
1264
- const seenCursors = /* @__PURE__ */ new Set();
1265
- let cursor;
1266
- for (let pageIndex = 0; pageIndex < MAX_COMPAT_PAGINATION_PAGES; pageIndex += 1) {
1267
- const remaining = params.limit - sessions.length;
1268
- if (remaining <= 0) break;
1269
- const pageLimit = Math.min(PAGE_LIMIT, remaining);
1270
- const listed = await params.request(params.endpoint, "thread/list", {
1271
- archived: false,
1272
- limit: pageLimit,
1273
- sourceKinds: [...ALL_CODEX_THREAD_SOURCE_KINDS],
1274
- modelProviders: [],
1275
- sortKey: "recency_at",
1276
- sortDirection: "desc",
1277
- useStateDbOnly: true,
1278
- ...cursor ? { cursor } : {}
1279
- });
1280
- if (!isRecord(listed) || !Array.isArray(listed.data)) throw new Error("Codex thread/list returned an invalid response");
1281
- for (const thread of readStoredThreads(listed.data, pageLimit)) {
1282
- if (sessions.length >= params.limit) break;
1283
- const session = toSession(params.endpoint.id, thread);
1284
- if (session && !sessions.some((entry) => entry.threadId === session.threadId)) sessions.push(session);
1285
- }
1286
- const nextCursor = readCompatNextCursor(listed.nextCursor, "thread/list");
1287
- if (nextCursor && sessions.length < params.limit && seenCursors.has(nextCursor)) throw new Error(`Codex thread/list returned repeated cursor ${nextCursor}`);
1288
- if (nextCursor) seenCursors.add(nextCursor);
1289
- cursor = nextCursor;
1290
- if (!cursor || sessions.length >= params.limit) break;
1291
- }
1292
- if (cursor && sessions.length < params.limit) throw new Error(`Codex thread/list exceeded ${MAX_COMPAT_PAGINATION_PAGES} pages with a continuation cursor`);
1333
+ if (cursor && sessions.length < limit) throw new Error(`Codex ${method} exceeded ${MAX_COMPAT_PAGINATION_PAGES} pages with a continuation cursor`);
1293
1334
  return sessions;
1294
1335
  }
1295
1336
  async function listSessionSnapshot(params) {
1296
1337
  const sessions = [];
1297
1338
  const errors = [];
1298
1339
  for (const endpoint of params.endpoints) try {
1299
- const loaded = await listLoadedSessions(params.request, endpoint);
1340
+ const loaded = await listSessions(params.request, endpoint);
1300
1341
  sessions.push(...loaded);
1301
1342
  if (params.includeStored) {
1302
- const stored = await listStoredSessions({
1303
- request: params.request,
1304
- endpoint,
1305
- limit: params.maxStoredSessions ?? DEFAULT_MAX_STORED_SESSIONS
1306
- });
1343
+ const stored = await listSessions(params.request, endpoint, params.maxStoredSessions ?? DEFAULT_MAX_STORED_SESSIONS);
1307
1344
  for (const session of stored) if (!sessions.some((entry) => entry.endpointId === endpoint.id && entry.threadId === session.threadId)) sessions.push(session);
1308
1345
  }
1309
1346
  } catch (error) {
@@ -1311,7 +1348,7 @@ async function listSessionSnapshot(params) {
1311
1348
  errors.push({
1312
1349
  endpointId: endpoint.id,
1313
1350
  ok: false,
1314
- detail: error instanceof Error ? error.message : String(error)
1351
+ detail: coerceErrorMessage(error)
1315
1352
  });
1316
1353
  }
1317
1354
  return {
@@ -1335,7 +1372,6 @@ async function resolveEndpointForThread(params) {
1335
1372
  })).id === params.threadId) matches.push(endpoint);
1336
1373
  } catch (error) {
1337
1374
  if (error instanceof CodexSupervisionPolicyError) throw error;
1338
- if (!isLoadedThreadReadMiss(error)) continue;
1339
1375
  }
1340
1376
  if (matches.length === 1) return expectDefined(matches[0], "single matching Codex supervision endpoint");
1341
1377
  if (matches.length > 1) throw new Error(`Codex thread id is ambiguous across endpoints: ${params.threadId}`);
@@ -1384,27 +1420,16 @@ function redactEndpointUrl(value) {
1384
1420
  }
1385
1421
  }
1386
1422
  function endpointResult(endpoint, pluginConfig, env, resolveRuntimeOptions) {
1387
- const configured = endpoint.configured;
1388
- if (configured && (configured.transport === "stdio-proxy" || configured.transport === void 0)) return {
1389
- id: endpoint.id,
1390
- transport: "stdio-proxy",
1391
- ...endpoint.label ? { label: endpoint.label } : {}
1392
- };
1393
- if (configured?.transport === "websocket") return {
1394
- id: endpoint.id,
1395
- transport: "websocket",
1396
- ...endpoint.label ? { label: endpoint.label } : {},
1397
- url: redactEndpointUrl(configured.url)
1398
- };
1399
- const start = resolveRuntimeOptions({
1423
+ const start = endpoint.configured ?? resolveRuntimeOptions({
1400
1424
  pluginConfig,
1401
1425
  env
1402
1426
  }).start;
1427
+ const remote = start.transport === "websocket" || start.transport === "unix" ? { url: redactEndpointUrl(start.url ?? (start.transport === "unix" ? "unix://" : "")) } : void 0;
1403
1428
  return {
1404
1429
  id: endpoint.id,
1405
- transport: start.transport === "stdio" ? "stdio-proxy" : "websocket",
1430
+ transport: remote ? "websocket" : "stdio-proxy",
1406
1431
  ...endpoint.label ? { label: endpoint.label } : {},
1407
- ...start.transport === "stdio" ? {} : { url: redactEndpointUrl(start.transport === "unix" ? start.url ?? "unix://" : start.url ?? "") }
1432
+ ...remote
1408
1433
  };
1409
1434
  }
1410
1435
  function sanitizeSessionListResult(result, includeTranscriptDerivedFields) {
@@ -1423,32 +1448,12 @@ function sanitizeSessionListResult(result, includeTranscriptDerivedFields) {
1423
1448
  }))
1424
1449
  };
1425
1450
  }
1426
- function requireSupervisionEnabled(pluginConfig) {
1427
- if (readCodexPluginConfig(pluginConfig).supervision?.enabled !== true) throw new CodexSupervisionPolicyError("Codex supervision is disabled in the codex plugin config.");
1428
- }
1429
- function requireOwnerAccess(options) {
1430
- if (!options.senderIsOwner) throw new CodexSupervisionPolicyError("Codex supervision compatibility tools require an owner-authorized sender.");
1431
- }
1432
- function resolveToolPolicy(options, pluginConfig) {
1433
- const config = readCodexPluginConfig(pluginConfig).supervision;
1434
- const env = options.env ?? process.env;
1435
- return {
1436
- allowRawTranscripts: config?.allowRawTranscripts === true || options.useLegacyMcpPolicyEnv === true && env[LEGACY_CODEX_SUPERVISOR_RAW_TRANSCRIPTS_ENV] === "1",
1437
- allowWriteControls: config?.allowWriteControls === true || options.useLegacyMcpPolicyEnv === true && env[LEGACY_CODEX_SUPERVISOR_WRITE_CONTROLS_ENV] === "1"
1438
- };
1439
- }
1440
- function requireRawTranscriptAccess(options, pluginConfig) {
1441
- if (!resolveToolPolicy(options, pluginConfig).allowRawTranscripts) throw new CodexSupervisionPolicyError("Codex session reads are disabled for this codex plugin supervision config.");
1442
- }
1443
- function requireWriteAccess(options, pluginConfig) {
1444
- if (!resolveToolPolicy(options, pluginConfig).allowWriteControls) throw new CodexSupervisionPolicyError("Codex write controls are disabled for this codex plugin supervision config.");
1445
- }
1446
1451
  function requireLiveToolPolicy(options, policy) {
1447
1452
  requireOwnerAccess(options);
1448
1453
  const pluginConfig = options.getPluginConfig();
1449
1454
  requireSupervisionEnabled(pluginConfig);
1450
- if (policy === "raw-transcripts") requireRawTranscriptAccess(options, pluginConfig);
1451
- else if (policy === "write-controls") requireWriteAccess(options, pluginConfig);
1455
+ if (policy === "raw-transcripts") requireRawTranscriptAccess(pluginConfig);
1456
+ else if (policy === "write-controls") requireWriteAccess(pluginConfig);
1452
1457
  return {
1453
1458
  pluginConfig,
1454
1459
  endpoints: resolveEndpoints(pluginConfig, options.env ?? process.env, options.getRuntimeConfig?.(), options.resolveAuthProfileId, options.resolveRuntimeOptions)
@@ -1465,22 +1470,34 @@ function requireCurrentEndpointSet(options, expected) {
1465
1470
  if (!(current.endpoints.length === expected.length && expected.every((endpoint) => current.endpoints.some((candidate) => candidate.id === endpoint.id && candidate.connectionKey === endpoint.connectionKey)))) throw new CodexSupervisionPolicyError("Codex supervision endpoint configuration changed during the request.");
1466
1471
  return { pluginConfig: current.pluginConfig };
1467
1472
  }
1468
- function createPolicyGuardedRequest(options, request, policy) {
1469
- return async (endpoint, method, params) => {
1470
- return await request(requireCurrentEndpoint(options, policy, endpoint), method, params);
1471
- };
1472
- }
1473
1473
  function idleContinuationError(threadId) {
1474
1474
  return /* @__PURE__ */ new Error(`Codex thread ${threadId} is idle. Continue it from Codex Sessions so OpenClaw can install the Codex harness approval and tool handlers before resume.`);
1475
1475
  }
1476
1476
  /** Builds the five shipped Codex Supervisor compatibility tools. */
1477
1477
  function createCodexSupervisionTools(options) {
1478
- const baseRequest = options.request ?? createCanonicalEndpointRequest(options);
1479
- const request = createPolicyGuardedRequest(options, baseRequest, "enabled");
1480
- const rawTranscriptRequest = createPolicyGuardedRequest(options, baseRequest, "raw-transcripts");
1481
- const writeRequest = createPolicyGuardedRequest(options, baseRequest, "write-controls");
1482
- const current = () => {
1483
- return requireLiveToolPolicy(options, "enabled");
1478
+ const request = createPolicyGuardedRequest(options, "enabled");
1479
+ const rawTranscriptRequest = createPolicyGuardedRequest(options, "raw-transcripts");
1480
+ const writeRequest = createPolicyGuardedRequest(options, "write-controls");
1481
+ const current = () => requireLiveToolPolicy(options, "enabled");
1482
+ const readActiveThread = async (endpoints, params, threadId, idleError) => {
1483
+ const endpoint = await resolveEndpointForThread({
1484
+ endpoints,
1485
+ request: writeRequest,
1486
+ endpointId: readStringParam(params, "endpoint_id"),
1487
+ threadId
1488
+ });
1489
+ const thread = await readThread({
1490
+ request: writeRequest,
1491
+ endpoint,
1492
+ threadId,
1493
+ includeTurns: true
1494
+ });
1495
+ requireCurrentEndpoint(options, "write-controls", endpoint);
1496
+ if (statusType(thread) !== "active") throw idleError();
1497
+ return {
1498
+ endpoint,
1499
+ thread
1500
+ };
1484
1501
  };
1485
1502
  return [
1486
1503
  {
@@ -1523,13 +1540,13 @@ function createCodexSupervisionTools(options) {
1523
1540
  const result = await listSessionSnapshot({
1524
1541
  endpoints,
1525
1542
  request,
1526
- includeStored: readBooleanParam(params, "include_stored"),
1543
+ includeStored: params.include_stored === true,
1527
1544
  maxStoredSessions: readIntegerParam(params, "max_stored_sessions")
1528
1545
  });
1529
1546
  const { pluginConfig } = requireCurrentEndpointSet(options, endpoints);
1530
1547
  return jsonResult({
1531
1548
  summary: `codex sessions: ${result.sessions.length}`,
1532
- ...sanitizeSessionListResult(result, resolveToolPolicy(options, pluginConfig).allowRawTranscripts)
1549
+ ...sanitizeSessionListResult(result, resolveToolPolicy(pluginConfig).allowRawTranscripts)
1533
1550
  });
1534
1551
  }
1535
1552
  },
@@ -1540,7 +1557,7 @@ function createCodexSupervisionTools(options) {
1540
1557
  parameters: SessionReadParamsSchema,
1541
1558
  execute: async (_toolCallId, rawParams) => {
1542
1559
  const { endpoints, pluginConfig } = current();
1543
- requireRawTranscriptAccess(options, pluginConfig);
1560
+ requireRawTranscriptAccess(pluginConfig);
1544
1561
  const params = isRecord(rawParams) ? rawParams : {};
1545
1562
  const threadId = readStringParam(params, "thread_id", { required: true });
1546
1563
  const endpoint = await resolveEndpointForThread({
@@ -1553,7 +1570,7 @@ function createCodexSupervisionTools(options) {
1553
1570
  request: rawTranscriptRequest,
1554
1571
  endpoint,
1555
1572
  threadId,
1556
- includeTurns: readBooleanParam(params, "include_turns")
1573
+ includeTurns: params.include_turns === true
1557
1574
  });
1558
1575
  requireCurrentEndpoint(options, "raw-transcripts", endpoint);
1559
1576
  return jsonResult({
@@ -1569,7 +1586,7 @@ function createCodexSupervisionTools(options) {
1569
1586
  parameters: SessionSendParamsSchema,
1570
1587
  execute: async (_toolCallId, rawParams) => {
1571
1588
  const { endpoints, pluginConfig } = current();
1572
- requireWriteAccess(options, pluginConfig);
1589
+ requireWriteAccess(pluginConfig);
1573
1590
  const params = isRecord(rawParams) ? rawParams : {};
1574
1591
  const threadId = readStringParam(params, "thread_id", { required: true });
1575
1592
  const text = readStringParam(params, "text", {
@@ -1577,20 +1594,7 @@ function createCodexSupervisionTools(options) {
1577
1594
  allowEmpty: false
1578
1595
  });
1579
1596
  if ((readModeParam(params) ?? "auto") === "start") throw idleContinuationError(threadId);
1580
- const endpoint = await resolveEndpointForThread({
1581
- endpoints,
1582
- request: writeRequest,
1583
- endpointId: readStringParam(params, "endpoint_id"),
1584
- threadId
1585
- });
1586
- const thread = await readThread({
1587
- request: writeRequest,
1588
- endpoint,
1589
- threadId,
1590
- includeTurns: true
1591
- });
1592
- requireCurrentEndpoint(options, "write-controls", endpoint);
1593
- if (statusType(thread) !== "active") throw idleContinuationError(threadId);
1597
+ const { endpoint, thread } = await readActiveThread(endpoints, params, threadId, () => idleContinuationError(threadId));
1594
1598
  const turnId = await resolveInProgressTurnId({
1595
1599
  request: writeRequest,
1596
1600
  endpoint,
@@ -1626,23 +1630,10 @@ function createCodexSupervisionTools(options) {
1626
1630
  parameters: SessionInterruptParamsSchema,
1627
1631
  execute: async (_toolCallId, rawParams) => {
1628
1632
  const { endpoints, pluginConfig } = current();
1629
- requireWriteAccess(options, pluginConfig);
1633
+ requireWriteAccess(pluginConfig);
1630
1634
  const params = isRecord(rawParams) ? rawParams : {};
1631
1635
  const threadId = readStringParam(params, "thread_id", { required: true });
1632
- const endpoint = await resolveEndpointForThread({
1633
- endpoints,
1634
- request: writeRequest,
1635
- endpointId: readStringParam(params, "endpoint_id"),
1636
- threadId
1637
- });
1638
- const thread = await readThread({
1639
- request: writeRequest,
1640
- endpoint,
1641
- threadId,
1642
- includeTurns: true
1643
- });
1644
- requireCurrentEndpoint(options, "write-controls", endpoint);
1645
- if (statusType(thread) !== "active") throw new Error(`Codex thread ${threadId} has no active turn to interrupt`);
1636
+ const { endpoint, thread } = await readActiveThread(endpoints, params, threadId, () => /* @__PURE__ */ new Error(`Codex thread ${threadId} has no active turn to interrupt`));
1646
1637
  const turnId = readStringParam(params, "turn_id") ?? await resolveInProgressTurnId({
1647
1638
  request: writeRequest,
1648
1639
  endpoint,
@@ -1669,7 +1660,7 @@ function createCodexSupervisionTools(options) {
1669
1660
  }
1670
1661
  //#endregion
1671
1662
  //#region extensions/codex/src/web-search-provider.ts
1672
- const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./.setup/web-search-provider.runtime-CTGuJt6i.mjs"));
1663
+ const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./.setup/web-search-provider.runtime-P77OUeoo.mjs"));
1673
1664
  const CodexWebSearchSchema = {
1674
1665
  type: "object",
1675
1666
  properties: { query: {
@@ -1714,6 +1705,7 @@ var codex_default = definePluginEntry({
1714
1705
  reload: { noopPrefixes: ["plugins.entries.codex.config.codexPlugins"] },
1715
1706
  register(api) {
1716
1707
  registerCodexAccountUsage(api);
1708
+ api.registerService(codexNativeProfileRecoveryService);
1717
1709
  setManagedCodexPluginRoot(api.rootDir);
1718
1710
  api.registerProvider(codexProviderDiscovery);
1719
1711
  const resolveCurrentConfig = () => api.runtime.config?.current ? api.runtime.config.current() : void 0;
@@ -1739,20 +1731,28 @@ var codex_default = definePluginEntry({
1739
1731
  getRuntimeConfig: resolveCurrentConfig
1740
1732
  }));
1741
1733
  let bindingStateStore;
1734
+ let bindingMutationStore;
1742
1735
  let managedThreadStateStore;
1743
- const openBindingStateStore = () => bindingStateStore ??= api.runtime.state.openSyncKeyedStore({
1736
+ const bindingStateOptions = {
1744
1737
  namespace: CODEX_APP_SERVER_BINDING_NAMESPACE,
1745
1738
  maxEntries: CODEX_APP_SERVER_BINDING_MAX_ENTRIES,
1746
1739
  overflowPolicy: "reject-new"
1747
- });
1740
+ };
1741
+ const openBindingStateStore = () => bindingStateStore ??= api.runtime.state.openSyncKeyedStore(bindingStateOptions);
1742
+ const openBindingMutationStore = () => bindingMutationStore ??= api.runtime.state.openKeyedStore(bindingStateOptions);
1748
1743
  const lazyBindingStateStore = {
1749
1744
  deleteIf: (key, predicate) => openBindingStateStore().deleteIf(key, predicate),
1750
1745
  entries: () => openBindingStateStore().entries(),
1751
1746
  lookup: (key) => openBindingStateStore().lookup(key),
1752
- registerIfAbsent: (key, value, options) => openBindingStateStore().registerIfAbsent(key, value, options),
1753
- get update() {
1747
+ get lookupMany() {
1754
1748
  const store = openBindingStateStore();
1755
- return store.update?.bind(store);
1749
+ return store.lookupMany?.bind(store);
1750
+ },
1751
+ registerIfAbsent: (key, value, options) => openBindingStateStore().registerIfAbsent(key, value, options),
1752
+ withCurrent: (authority) => {
1753
+ const store = openBindingMutationStore();
1754
+ if (!store.withCurrent) throw new Error("Codex bindings require action-bound plugin-state mutations");
1755
+ return store.withCurrent(authority);
1756
1756
  }
1757
1757
  };
1758
1758
  const openManagedThreadStateStore = () => managedThreadStateStore ??= api.runtime.state.openKeyedStore({
@@ -1799,16 +1799,20 @@ var codex_default = definePluginEntry({
1799
1799
  for (const policy of createCodexSessionCatalogNodeInvokePolicies()) api.registerNodeInvokePolicy(policy);
1800
1800
  if (readCodexPluginConfig(resolveCurrentPluginConfig()).supervision?.enabled === true) {
1801
1801
  const { resolveCodexAppServerAuthProfileIdForAgent } = createCodexAuthProfileSelection(api.runtime.modelAuth);
1802
- api.registerTool((context) => {
1803
- if (context.senderIsOwner !== true) return [];
1804
- const resolveToolRuntimeConfig = () => context.getRuntimeConfig?.() ?? context.runtimeConfig ?? context.config ?? resolveCurrentConfig();
1805
- return createCodexSupervisionTools({
1806
- getPluginConfig: () => resolvePluginConfig(resolveToolRuntimeConfig),
1807
- getRuntimeConfig: resolveToolRuntimeConfig,
1808
- resolveAuthProfileId: resolveCodexAppServerAuthProfileIdForAgent,
1809
- resolveRuntimeOptions: resolveCodexSupervisionAppServerRuntimeOptions,
1810
- senderIsOwner: context.senderIsOwner
1811
- });
1802
+ api.registerTool({
1803
+ contextVersion: 2,
1804
+ create: (context) => {
1805
+ if (context.senderIsOwner !== true) return [];
1806
+ const resolveToolRuntimeConfig = () => context.getRuntimeConfig?.() ?? context.runtimeConfig ?? context.config ?? resolveCurrentConfig();
1807
+ return createCodexSupervisionTools({
1808
+ getPluginConfig: () => resolvePluginConfig(resolveToolRuntimeConfig),
1809
+ getRuntimeConfig: resolveToolRuntimeConfig,
1810
+ resolveAuthProfileId: resolveCodexAppServerAuthProfileIdForAgent,
1811
+ resolveRuntimeOptions: resolveCodexSupervisionAppServerRuntimeOptions,
1812
+ senderIsOwner: context.senderIsOwner,
1813
+ assertInvocationCurrent: context.assertInvocationCurrent
1814
+ });
1815
+ }
1812
1816
  }, { names: [...CODEX_SUPERVISION_COMPAT_TOOL_NAMES] });
1813
1817
  }
1814
1818
  const agentHarnessOptions = {
@@ -1822,12 +1826,15 @@ var codex_default = definePluginEntry({
1822
1826
  api.registerMediaUnderstandingProvider(buildCodexMediaUnderstandingProvider({ pluginConfig: api.pluginConfig }));
1823
1827
  api.registerWebSearchProvider(createCodexWebSearchProvider({ resolvePluginConfig: resolveCurrentPluginConfig }));
1824
1828
  api.registerMigrationProvider(buildCodexMigrationProvider({ runtime: api.runtime }));
1825
- api.registerTool((context) => createCodexThreadsTool({
1826
- bindingStore,
1827
- context,
1828
- runtime: api.runtime,
1829
- getPluginConfig: resolveCurrentPluginConfig
1830
- }), { name: "codex_threads" });
1829
+ api.registerTool({
1830
+ contextVersion: 2,
1831
+ create: (context) => createCodexThreadsTool({
1832
+ bindingStore,
1833
+ context,
1834
+ runtime: api.runtime,
1835
+ getPluginConfig: resolveCurrentPluginConfig
1836
+ })
1837
+ }, { name: "codex_threads" });
1831
1838
  api.registerToolMetadata({
1832
1839
  toolName: "codex_threads",
1833
1840
  displayName: "Codex Threads",
@@ -1835,11 +1842,14 @@ var codex_default = definePluginEntry({
1835
1842
  risk: "high",
1836
1843
  tags: ["codex", "sessions"]
1837
1844
  });
1838
- api.registerTool((context) => createCodexPluginsTool({
1839
- bindingStore,
1840
- context,
1841
- getPluginConfig: resolveCurrentPluginConfig
1842
- }), { name: "codex_plugins" });
1845
+ api.registerTool({
1846
+ contextVersion: 2,
1847
+ create: (context) => createCodexPluginsTool({
1848
+ bindingStore,
1849
+ context,
1850
+ getPluginConfig: resolveCurrentPluginConfig
1851
+ })
1852
+ }, { name: "codex_plugins" });
1843
1853
  api.registerToolMetadata({
1844
1854
  toolName: "codex_plugins",
1845
1855
  displayName: "Codex Plugins",
@@ -1851,7 +1861,7 @@ var codex_default = definePluginEntry({
1851
1861
  "discovery"
1852
1862
  ]
1853
1863
  });
1854
- for (const command of createCodexCliSessionNodeHostCommands()) api.registerNodeHostCommand(command);
1864
+ for (const command of createCodexCliSessionNodeHostCommands((agentId) => sessionCatalogControlFactory.forNode(agentId))) api.registerNodeHostCommand(command);
1855
1865
  for (const policy of createCodexCliSessionNodeInvokePolicies()) api.registerNodeInvokePolicy(policy);
1856
1866
  api.registerNodeHostCommand(createCodexNodeExecServerCommand());
1857
1867
  api.registerNodeInvokePolicy(createCodexNodeExecServerInvokePolicy());
@@ -1870,40 +1880,29 @@ var codex_default = definePluginEntry({
1870
1880
  }),
1871
1881
  codexPluginsManagementIo: {
1872
1882
  readConfig: () => {
1873
- const plugins = (api.runtime.config?.current?.() ?? {}).plugins;
1874
- if (!plugins || typeof plugins !== "object") return Promise.resolve({});
1875
- const entries = plugins.entries;
1876
- if (!entries || typeof entries !== "object") return Promise.resolve({});
1877
- const codexEntry = entries.codex;
1878
- if (!codexEntry || typeof codexEntry !== "object") return Promise.resolve({});
1879
- const config = codexEntry.config;
1880
- if (!config || typeof config !== "object") return Promise.resolve({});
1881
- const codexPlugins = config.codexPlugins;
1883
+ const codexPlugins = resolveCurrentConfig()?.plugins?.entries?.codex?.config?.codexPlugins;
1882
1884
  if (!codexPlugins || typeof codexPlugins !== "object") return Promise.resolve({});
1883
- const declared = codexPlugins.plugins;
1884
- if (!declared || typeof declared !== "object") return Promise.resolve({ enabled: codexPlugins.enabled === true });
1885
+ const enabled = "enabled" in codexPlugins && codexPlugins.enabled === true;
1886
+ const declared = "plugins" in codexPlugins ? codexPlugins.plugins : void 0;
1885
1887
  return Promise.resolve({
1886
- enabled: codexPlugins.enabled === true,
1887
- plugins: declared
1888
+ enabled,
1889
+ ...declared && typeof declared === "object" ? { plugins: declared } : {}
1888
1890
  });
1889
1891
  },
1890
- mutate: async (update) => {
1892
+ mutate: async (update, assertCurrent) => {
1891
1893
  const { mutateConfigFile } = await import("openclaw/plugin-sdk/config-mutation");
1892
- await mutateConfigFile({ mutate: (draft) => {
1893
- const root = draft;
1894
- root.plugins = root.plugins ?? {};
1895
- const pluginsBlock = root.plugins;
1896
- pluginsBlock.entries = pluginsBlock.entries ?? {};
1897
- const entries = pluginsBlock.entries;
1898
- entries.codex = entries.codex ?? {};
1899
- const codexEntry = entries.codex;
1900
- codexEntry.config = codexEntry.config ?? {};
1901
- const config = codexEntry.config;
1902
- config.codexPlugins = config.codexPlugins ?? {};
1903
- const codexPlugins = config.codexPlugins;
1904
- codexPlugins.plugins = codexPlugins.plugins ?? {};
1905
- update(codexPlugins);
1906
- } });
1894
+ await mutateConfigFile({
1895
+ writeOptions: { assertCurrent },
1896
+ mutate: (draft) => {
1897
+ draft.plugins ??= {};
1898
+ draft.plugins.entries ??= {};
1899
+ const entry = draft.plugins.entries.codex ??= {};
1900
+ const config = entry.config ??= {};
1901
+ const codexPlugins = config.codexPlugins ??= {};
1902
+ codexPlugins.plugins ??= {};
1903
+ update(codexPlugins);
1904
+ }
1905
+ });
1907
1906
  }
1908
1907
  }
1909
1908
  }
@@ -1926,7 +1925,7 @@ var codex_default = definePluginEntry({
1926
1925
  if (endedSessionKey && nextSessionKey && nextSessionKey !== endedSessionKey) return;
1927
1926
  if (event.nextSessionId?.trim() === event.sessionId.trim()) return;
1928
1927
  const config = resolveCurrentConfig();
1929
- const [{ sessionBindingIdentity }, { retireCodexAppServerSessionGeneration }] = await Promise.all([import("./.setup/session-binding-_0W_fHRr.mjs").then((n) => n.c), import("./.setup/session-retirement-CU87AOg9.mjs")]);
1928
+ const [{ sessionBindingIdentity }, { retireCodexAppServerSessionGeneration }] = await Promise.all([import("./.setup/session-binding-DGCYAfvD.mjs").then((n) => n.s), import("./.setup/session-retirement-qMTxkNx2.mjs")]);
1930
1929
  await retireCodexAppServerSessionGeneration({
1931
1930
  bindingStore,
1932
1931
  identity: sessionBindingIdentity({