@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
@@ -1,10 +1,10 @@
1
- import { A as parseTranscriptPage, B as unwrapNodeInvokePayload, E as isInteractiveThreadSource, O as parseCatalogPage, S as catalogError, T as filterCatalogPageByTitle, b as NODE_INVOKE_TIMEOUT_MS, f as CODEX_APP_SERVER_THREADS_LIST_COMMAND, g as CatalogParamsError, p as CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND, x as boundedCatalogString } from "./session-catalog-native-projection-ChV3cCtm.mjs";
2
- import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-CrcyZk6O.mjs";
3
- import { n as withTimeout } from "./timeout-DZF05XrR.mjs";
4
- import { t as CODEX_CLI_SESSION_RESUME_COMMAND } from "./node-cli-sessions-Cl8b2ZF3.mjs";
5
- import { o as lookupNodeCodexCatalogRecord } from "./session-catalog-fUdWDx-U.mjs";
1
+ import { A as unwrapNodeInvokePayload, b as parseTranscriptPage, d as boundedCatalogString, f as catalogError, g as isInteractiveThreadSource, h as filterCatalogPageByTitle, n as CODEX_APP_SERVER_THREADS_LIST_COMMAND, o as CatalogParamsError, r as CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND, u as NODE_INVOKE_TIMEOUT_MS, v as parseCatalogPage } from "./session-catalog-parsing-CPGaPYr-.mjs";
2
+ import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-C746z5Pn.mjs";
3
+ import { r as CODEX_CLI_SESSION_SOURCE_UPGRADE_MESSAGE, t as CODEX_CLI_SESSION_RESUME_COMMAND } from "./node-cli-sessions-HC4W6FLI.mjs";
4
+ import { i as withTimeout } from "./timeout-CXOfNoaX.mjs";
5
+ import { t as lookupNodeCodexCatalogRecord } from "./session-catalog-node-lookup-CtAXI5W5.mjs";
6
6
  import { t as codexLastTerminalTurnId } from "./session-upstream-marker-D15C9NHp.mjs";
7
- import { createOrReuseNodeAdoptedSession, finalizeNodeAdoptedSession, findNodeAdoptedSessionEntry, nodeSessionMarker, runSessionActionExclusive } from "./session-catalog-node-adoption-BVRsYOSh.mjs";
7
+ import { catalogSessionActions, createOrReuseNodeAdoptedSession, finalizeNodeAdoptedSession, findNodeAdoptedSessionEntry, nodeAdoptedSourceKey, nodeSessionMarker } from "./session-catalog-node-adoption-DgXvSGu0.mjs";
8
8
  import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
9
9
  import { createSessionCatalogAdoptionCoordinator, publishSessionCatalogHost, sessionCatalogAdoptedSourceKey } from "openclaw/plugin-sdk/session-catalog";
10
10
  //#region extensions/codex/src/session-catalog-node-continue.ts
@@ -21,12 +21,10 @@ function nodeLabel(node) {
21
21
  function compareNodeLabels(left, right) {
22
22
  const leftLabel = nodeLabel(left);
23
23
  const rightLabel = nodeLabel(right);
24
- if (leftLabel < rightLabel) return -1;
25
- if (leftLabel > rightLabel) return 1;
26
- return 0;
24
+ return leftLabel < rightLabel ? -1 : leftLabel > rightLabel ? 1 : 0;
27
25
  }
28
26
  function canContinueCodexOnNode(node) {
29
- return node.connected === true && CODEX_NODE_CONTINUE_COMMANDS.every((command) => node.commands?.includes(command) === true && node.invocableCommands?.includes(command) === true);
27
+ return node.connected === true && node.caps?.includes("codex-cli-session-source") === true && CODEX_NODE_CONTINUE_COMMANDS.every((command) => node.commands?.includes(command) === true && node.invocableCommands?.includes(command) === true);
30
28
  }
31
29
  async function listPairedNode(params) {
32
30
  const hostId = `node:${params.node.nodeId}`;
@@ -79,10 +77,8 @@ async function listPairedNode(params) {
79
77
  ...common,
80
78
  connected: true,
81
79
  ...page,
82
- sessions: page.sessions.map((session) => {
83
- const adopted = params.adoptedSessions.get(sessionCatalogAdoptedSourceKey(hostId, session.threadId));
84
- return adopted ? Object.assign({}, session, { sessionKey: adopted.key }) : session;
85
- })
80
+ canContinueCodex: common.canContinueCodex && page.canContinueCodex === true && Boolean(page.sourceHomeId),
81
+ sessions: page.sessions.map((session) => Object.assign({}, session, page.sourceHomeId ? { sourceHomeId: page.sourceHomeId } : {}))
86
82
  };
87
83
  }).catch((error) => ({
88
84
  ...common,
@@ -106,7 +102,10 @@ async function requireNodeForCodexContinue(params) {
106
102
  const nodeId = params.hostId.slice(5).trim();
107
103
  if (!nodeId || params.hostId !== `node:${nodeId}`) throw new CatalogParamsError("Codex session catalog hostId is invalid");
108
104
  const node = (await params.runtime.nodes.list()).nodes.find((candidate) => candidate.nodeId === nodeId);
109
- if (!node || !canContinueCodexOnNode(node)) throw new CatalogParamsError("paired node does not permit Codex session continuation");
105
+ if (!node || !canContinueCodexOnNode(node)) {
106
+ if (node?.connected && !node.caps?.includes("codex-cli-session-source")) throw new CatalogParamsError(CODEX_CLI_SESSION_SOURCE_UPGRADE_MESSAGE);
107
+ throw new CatalogParamsError("paired node does not permit Codex session continuation");
108
+ }
110
109
  return {
111
110
  node,
112
111
  nodeId
@@ -125,6 +124,7 @@ async function readNodeCodexHistory(params) {
125
124
  command: CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND,
126
125
  params: {
127
126
  agentId: params.agentId,
127
+ sourceHomeId: params.sourceHomeId,
128
128
  threadId: params.record.threadId,
129
129
  limit: 50
130
130
  },
@@ -153,9 +153,12 @@ async function continueNodeCodexSessionInner(params) {
153
153
  agentId: params.agentId,
154
154
  runtime: params.api.runtime,
155
155
  nodeId,
156
- threadId: params.threadId
156
+ threadId: params.threadId,
157
+ sourceHomeId: params.sourceHomeId
157
158
  });
158
159
  if (lookup.kind !== "found") throw new CatalogParamsError(lookup.kind === "cursor-cycle" ? "Codex session eligibility could not be verified" : "Codex session is unavailable on the paired node");
160
+ if (lookup.canContinueCodex !== true || !lookup.sourceHomeId) throw new CatalogParamsError("Codex session source does not support Chat continuation; use a local stdio source or update the node.");
161
+ const sourceHomeId = lookup.sourceHomeId;
159
162
  const record = lookup.record;
160
163
  requireContinuableNodeRecord(record);
161
164
  const existing = findNodeAdoptedSessionEntry({
@@ -164,6 +167,7 @@ async function continueNodeCodexSessionInner(params) {
164
167
  runtime: params.api.runtime,
165
168
  hostId: params.hostId,
166
169
  threadId: params.threadId,
170
+ sourceHomeId,
167
171
  includeInitializing: true
168
172
  });
169
173
  let adopted;
@@ -176,6 +180,7 @@ async function continueNodeCodexSessionInner(params) {
176
180
  agentId: params.agentId,
177
181
  runtime: params.api.runtime,
178
182
  nodeId,
183
+ sourceHomeId,
179
184
  record
180
185
  });
181
186
  adopted = await createOrReuseNodeAdoptedSession({
@@ -184,6 +189,7 @@ async function continueNodeCodexSessionInner(params) {
184
189
  config: params.config,
185
190
  hostId: params.hostId,
186
191
  nodeId,
192
+ sourceHomeId,
187
193
  record,
188
194
  history
189
195
  });
@@ -192,6 +198,7 @@ async function continueNodeCodexSessionInner(params) {
192
198
  const marker = nodeSessionMarker({
193
199
  hostId: params.hostId,
194
200
  threadId: params.threadId,
201
+ sourceHomeId,
195
202
  nodeId
196
203
  });
197
204
  return {
@@ -223,11 +230,11 @@ async function continueNodeCodexSession(params) {
223
230
  agentId: params.agentId
224
231
  }).sessionAgentId;
225
232
  const sourceKey = sessionCatalogAdoptedSourceKey(`node:${nodeId}`, params.threadId);
226
- const operationKey = sessionCatalogAdoptedSourceKey(agentId, sourceKey);
233
+ const operationKey = sessionCatalogAdoptedSourceKey(agentId, params.sourceHomeId ? nodeAdoptedSourceKey(`node:${nodeId}`, params.threadId, params.sourceHomeId) : sourceKey);
227
234
  return await continueNodeAdoption({
228
235
  sourceKey: operationKey,
229
236
  findExisting: () => void 0,
230
- create: () => runSessionActionExclusive(sourceKey, async () => continueNodeCodexSessionInner({
237
+ create: () => catalogSessionActions.enqueue(sourceKey, async () => continueNodeCodexSessionInner({
231
238
  ...params,
232
239
  agentId
233
240
  })),
@@ -0,0 +1,56 @@
1
+ import { A as unwrapNodeInvokePayload, n as CODEX_APP_SERVER_THREADS_LIST_COMMAND, o as CatalogParamsError, u as NODE_INVOKE_TIMEOUT_MS, v as parseCatalogPage } from "./session-catalog-parsing-CPGaPYr-.mjs";
2
+ import "./session-catalog-limits-DDxOsQeC.mjs";
3
+ import { i as withTimeout } from "./timeout-CXOfNoaX.mjs";
4
+ //#region extensions/codex/src/session-catalog-node-lookup.ts
5
+ async function lookupNodeCodexCatalogRecord(params) {
6
+ const deadline = performance.now() + NODE_INVOKE_TIMEOUT_MS;
7
+ const unverified = () => new CatalogParamsError("Codex session eligibility could not be verified");
8
+ const remaining = () => {
9
+ const timeoutMs = Math.ceil(deadline - performance.now());
10
+ if (timeoutMs <= 0) throw unverified();
11
+ return timeoutMs;
12
+ };
13
+ let cursor;
14
+ let sourceHomeId = params.sourceHomeId;
15
+ let firstPage = true;
16
+ const seenCursors = /* @__PURE__ */ new Set();
17
+ for (;;) {
18
+ const timeoutMs = remaining();
19
+ const raw = await withTimeout(params.runtime.nodes.invoke({
20
+ nodeId: params.nodeId,
21
+ command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
22
+ params: {
23
+ agentId: params.agentId,
24
+ ...sourceHomeId ? { sourceHomeId } : {},
25
+ limit: 100,
26
+ ...cursor ? { cursor } : {}
27
+ },
28
+ timeoutMs,
29
+ scopes: ["operator.write"]
30
+ }), timeoutMs, "Codex session eligibility could not be verified", unverified);
31
+ remaining();
32
+ const page = parseCatalogPage(unwrapNodeInvokePayload(raw));
33
+ if ((!firstPage || sourceHomeId !== void 0) && page.sourceHomeId !== sourceHomeId) throw new CatalogParamsError("Codex session source home changed; refresh the catalog and retry");
34
+ sourceHomeId = page.sourceHomeId;
35
+ firstPage = false;
36
+ const record = page.sessions.find((candidate) => candidate.threadId === params.threadId);
37
+ if (record) return {
38
+ kind: "found",
39
+ record,
40
+ sourceHomeId,
41
+ canContinueCodex: page.canContinueCodex
42
+ };
43
+ const nextCursor = page.nextCursor?.trim();
44
+ if (!nextCursor) break;
45
+ if (seenCursors.has(nextCursor)) return { kind: "cursor-cycle" };
46
+ seenCursors.add(nextCursor);
47
+ if (seenCursors.size > 2e4) {
48
+ const oldest = seenCursors.values().next().value;
49
+ if (oldest !== void 0) seenCursors.delete(oldest);
50
+ }
51
+ cursor = nextCursor;
52
+ }
53
+ return { kind: "missing" };
54
+ }
55
+ //#endregion
56
+ export { lookupNodeCodexCatalogRecord as t };
@@ -1,24 +1,11 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { n as defineCodexBuildState } from "./build-state-Xx9ybZqa.mjs";
3
- import { m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
1
+ import "./protocol-CANUwXJ3.mjs";
2
+ import { n as detachCodexCatalogString } from "./session-catalog-limits-DDxOsQeC.mjs";
4
3
  import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
4
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
6
5
  //#region extensions/codex/src/app-server/protocol-session-source.ts
7
6
  const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
8
7
  const CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES = ["atlas", "chatgpt"];
9
8
  //#endregion
10
- //#region extensions/codex/src/session-catalog-limits.ts
11
- var session_catalog_limits_exports = /* @__PURE__ */ __exportAll({
12
- CODEX_CATALOG_MAX_ROWS: () => CODEX_CATALOG_MAX_ROWS,
13
- CODEX_CATALOG_MAX_STATE_KEY_BYTES: () => 512,
14
- detachCodexCatalogString: () => detachCodexCatalogString
15
- });
16
- const CODEX_CATALOG_MAX_ROWS = 2e4;
17
- /** Preserve UTF-16 code units without retaining an oversized source string. */
18
- function detachCodexCatalogString(value) {
19
- return Buffer.from(value, "utf16le").toString("utf16le");
20
- }
21
- //#endregion
22
9
  //#region extensions/codex/src/session-catalog-parsing.ts
23
10
  const DEFAULT_PAGE_LIMIT = 50;
24
11
  const CODEX_APP_SERVER_THREADS_CAPABILITY = "codex-app-server-threads";
@@ -67,8 +54,7 @@ function truncateCodexCatalogPreview(value, sanitize) {
67
54
  return Buffer.from(catalogPreview(value, sanitize) ?? "", "utf8").toString("utf8");
68
55
  }
69
56
  function normalizeInteractiveThreadSource(source) {
70
- if (CODEX_INTERACTIVE_THREAD_SOURCE_KINDS.some((kind) => kind === source) || CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source)) return source;
71
- if (isRecord(source) && CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source.custom)) return source.custom;
57
+ return CODEX_INTERACTIVE_THREAD_SOURCE_KINDS.find((kind) => kind === source) ?? CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.find((kind) => kind === source) ?? (isRecord(source) ? CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.find((kind) => kind === source.custom) : void 0);
72
58
  }
73
59
  function isInteractiveThreadSource(source) {
74
60
  return normalizeInteractiveThreadSource(source) !== void 0;
@@ -118,9 +104,9 @@ function toCatalogSession(thread, archived, sanitize, preparedPreview) {
118
104
  ...gitBranch ? { gitBranch } : {}
119
105
  };
120
106
  }
121
- function normalizeLimit(value, key) {
122
- if (value === void 0) return DEFAULT_PAGE_LIMIT;
123
- if (!Number.isInteger(value) || value < 1 || value > 100) throw new CatalogParamsError(`${key} must be an integer from 1 to 100`);
107
+ function normalizeLimit(value, key, fallback = DEFAULT_PAGE_LIMIT, max = 100) {
108
+ if (value === void 0) return fallback;
109
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > max) throw new CatalogParamsError(`${key} must be an integer from 1 to ${max}`);
124
110
  return value;
125
111
  }
126
112
  function readBoundedOptionalString(params, key, maxLength) {
@@ -157,7 +143,7 @@ function readPageParams(value) {
157
143
  }
158
144
  function readGatewayParams(value) {
159
145
  if (value !== void 0 && !isRecord(value)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
160
- const params = isRecord(value) ? value : {};
146
+ const params = value ?? {};
161
147
  requireOnlyKeys(params, /* @__PURE__ */ new Set([
162
148
  "search",
163
149
  "limitPerHost",
@@ -177,8 +163,7 @@ function readGatewayParams(value) {
177
163
  if (entries.length > MAX_CURSOR_COUNT) throw new CatalogParamsError(`cursors may contain at most ${MAX_CURSOR_COUNT} hosts`);
178
164
  cursors = {};
179
165
  for (const [hostId, cursor] of entries) {
180
- const normalizedHostId = hostId.trim();
181
- if (normalizedHostId.length === 0 || normalizedHostId.length > MAX_HOST_ID_LENGTH || !normalizedHostId.startsWith("gateway:") && !normalizedHostId.startsWith("node:")) throw new CatalogParamsError(`invalid Codex session catalog host id: ${hostId}`);
166
+ const normalizedHostId = readHostId(hostId);
182
167
  if (typeof cursor !== "string" || !cursor.trim() || cursor.trim().length > 4096) throw new CatalogParamsError(`invalid cursor for Codex session catalog host: ${hostId}`);
183
168
  cursors[normalizedHostId] = cursor.trim();
184
169
  }
@@ -254,9 +239,12 @@ function parseCatalogSession(value, options = {}) {
254
239
  function parseCatalogPage(value, options = {}) {
255
240
  if (!isRecord(value) || !Array.isArray(value.sessions) || value.sessions.length > 100) throw new Error("Codex session catalog returned an invalid page");
256
241
  const nextCursor = parseOptionalCatalogString(value.nextCursor, "next cursor", MAX_CURSOR_LENGTH);
242
+ const sourceHomeId = parseOptionalCatalogString(value.sourceHomeId, "source home id", 256);
257
243
  const backwardsCursor = parseOptionalCatalogString(value.backwardsCursor, "backwards cursor", MAX_CURSOR_LENGTH);
258
244
  return {
259
245
  sessions: value.sessions.map((session) => parseCatalogSession(session, options)),
246
+ ...sourceHomeId ? { sourceHomeId } : {},
247
+ ...typeof value.canContinueCodex === "boolean" ? { canContinueCodex: value.canContinueCodex } : {},
260
248
  ...nextCursor ? { nextCursor } : {},
261
249
  ...backwardsCursor ? { backwardsCursor } : {}
262
250
  };
@@ -268,12 +256,12 @@ function filterCatalogPageByTitle(page, searchTerm) {
268
256
  sessions: page.sessions.filter((session) => (session.name ?? session.fallbackName)?.toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase()))
269
257
  };
270
258
  }
271
- function unwrapNodeInvokePayload(value) {
259
+ function unwrapNodeInvokePayload(value, malformedMessage = "Codex node returned malformed session catalog JSON") {
272
260
  if (!isRecord(value)) return value;
273
261
  if (typeof value.payloadJSON === "string" && value.payloadJSON.trim()) try {
274
262
  return JSON.parse(value.payloadJSON);
275
263
  } catch (error) {
276
- throw new Error("Codex node returned malformed session catalog JSON", { cause: error });
264
+ throw new Error(malformedMessage, { cause: error });
277
265
  }
278
266
  return "payload" in value ? value.payload : value;
279
267
  }
@@ -315,158 +303,4 @@ function requireBoundThread(entry) {
315
303
  return entry.boundThreadId;
316
304
  }
317
305
  //#endregion
318
- //#region extensions/codex/src/session-catalog-source.ts
319
- const getSources = defineCodexBuildState("openclaw.codexCatalogSources", () => ({
320
- clients: /* @__PURE__ */ new WeakMap(),
321
- values: /* @__PURE__ */ new WeakMap()
322
- }));
323
- /** A passive lifetime fact; the token never retains its client or a lease. */
324
- function codexCatalogSourceForClient(client) {
325
- const { clients } = getSources();
326
- let source = clients.get(client);
327
- if (!source) {
328
- source = { closed: false };
329
- clients.set(client, source);
330
- }
331
- return source;
332
- }
333
- function closeCodexCatalogClientSource(client) {
334
- const { clients } = getSources();
335
- const source = clients.get(client);
336
- if (source) source.closed = true;
337
- else clients.set(client, { closed: true });
338
- }
339
- function getCodexCatalogSource(value) {
340
- return value !== null && typeof value === "object" ? getSources().values.get(value) : void 0;
341
- }
342
- function setCodexCatalogSource(value, source) {
343
- if (source) getSources().values.set(value, source);
344
- return value;
345
- }
346
- /** Source attribution survives projection without becoming serialized row data. */
347
- function copyCodexCatalogSource(from, to) {
348
- return setCodexCatalogSource(to, getCodexCatalogSource(from));
349
- }
350
- /** Stamp the final decoded objects, including any bounded catalog DTO replacement. */
351
- function recordCodexCatalogResponseSource(method, result, source) {
352
- if (result === null || typeof result !== "object") return;
353
- if (method === "thread/list" && "data" in result && Array.isArray(result.data)) {
354
- setCodexCatalogSource(result, source);
355
- for (const thread of result.data) if (thread !== null && typeof thread === "object") setCodexCatalogSource(thread, source);
356
- } else if ((method === "thread/read" || method === "thread/start" || method === "thread/fork" || method === "thread/resume") && "thread" in result && result.thread !== null && typeof result.thread === "object") {
357
- setCodexCatalogSource(result, source);
358
- setCodexCatalogSource(result.thread, source);
359
- }
360
- }
361
- //#endregion
362
- //#region extensions/codex/src/session-catalog-native-projection.ts
363
- var session_catalog_native_projection_exports = /* @__PURE__ */ __exportAll({
364
- CODEX_CATALOG_NATIVE_PAGE_LIMIT: () => 64,
365
- projectCodexCatalogNativeResponse: () => projectCodexCatalogNativeResponse,
366
- projectCodexCatalogNativeThread: () => projectCodexCatalogNativeThread
367
- });
368
- const CODEX_CATALOG_NATIVE_PAGE_LIMIT = 64;
369
- const STRING_FIELDS = [
370
- [
371
- "name",
372
- 500,
373
- "truncate"
374
- ],
375
- [
376
- "cwd",
377
- MAX_CWD_LENGTH,
378
- "omit"
379
- ],
380
- [
381
- "modelProvider",
382
- 500,
383
- "truncate"
384
- ],
385
- [
386
- "cliVersion",
387
- 500,
388
- "truncate"
389
- ]
390
- ];
391
- /** Drop unused native fields before catalog-owned asynchronous work can retain them. */
392
- function projectCodexCatalogNativeThread(thread, sanitize, cachedPreview) {
393
- if (!isJsonObject(thread)) throw new Error("Codex catalog response contains an invalid thread");
394
- const id = boundedCatalogString(thread.id, 256);
395
- if (!id) throw new Error("Codex catalog response contains an invalid thread id");
396
- const row = {
397
- id,
398
- projectId: boundedCatalogString(thread.projectId, 256, "omit") ?? null
399
- };
400
- const sessionId = boundedCatalogString(thread.sessionId, 256, "omit");
401
- if (sessionId) row.sessionId = sessionId;
402
- if (thread.ephemeral === true) return copyCodexCatalogSource(thread, {
403
- ...row,
404
- ephemeral: true
405
- });
406
- for (const [field, limit, overflow] of STRING_FIELDS) {
407
- const value = thread[field];
408
- const bounded = boundedCatalogString(value, limit, overflow);
409
- if (value === null || bounded !== void 0) row[field] = bounded ?? null;
410
- }
411
- if (typeof thread.path === "string") {
412
- if (thread.path.length > 4096) throw new Error("Codex catalog rollout path exceeds its length limit");
413
- row.path = detachCodexCatalogString(thread.path);
414
- } else if (thread.path === null) row.path = null;
415
- if (typeof thread.originator === "string") row.originator = detachCodexCatalogString(thread.originator.slice(0, 500));
416
- for (const field of [
417
- "createdAt",
418
- "updatedAt",
419
- "recencyAt"
420
- ]) {
421
- const value = thread[field];
422
- if (value === null || typeof value === "number" && Number.isFinite(value)) row[field] = value;
423
- }
424
- const preview = cachedPreview?.({
425
- id,
426
- path: typeof row.path === "string" ? row.path : null,
427
- updatedAt: typeof row.updatedAt === "number" ? row.updatedAt : null,
428
- recencyAt: typeof row.recencyAt === "number" ? row.recencyAt : null
429
- });
430
- const rawPreview = thread.preview;
431
- if (preview !== void 0 && preview.length <= 500 && !(typeof rawPreview === "string" && Boolean(rawPreview) !== Boolean(preview))) row.preview = preview;
432
- else if (typeof rawPreview === "string") row.preview = rawPreview ? truncateCodexCatalogPreview(selectCodexCatalogPreviewInput(rawPreview), sanitize) : "";
433
- else if (rawPreview === null) row.preview = null;
434
- const source = typeof thread.source === "string" ? detachCodexCatalogString(thread.source.slice(0, 500)) : void 0;
435
- if (source === "cli" || source === "vscode" || source === "exec" || source === "appServer" || source === "unknown") row.source = source;
436
- else if (isJsonObject(thread.source) && typeof thread.source.custom === "string" && thread.source.custom.length <= 500) row.source = { custom: detachCodexCatalogString(thread.source.custom) };
437
- if (isJsonObject(thread.gitInfo)) {
438
- const branch = boundedCatalogString(thread.gitInfo.branch, 500, "truncate");
439
- if (branch !== void 0) row.gitInfo = { branch };
440
- }
441
- if (isJsonObject(thread.status)) {
442
- const type = boundedCatalogString(thread.status.type, 64);
443
- if (type === "active" || type === "idle" || type === "notLoaded" || type === "systemError") {
444
- const activeFlags = type === "active" && Array.isArray(thread.status.activeFlags) ? thread.status.activeFlags.slice(0, 16).flatMap((flag) => {
445
- const bounded = boundedCatalogString(flag, 128, "omit");
446
- return bounded ? [bounded] : [];
447
- }) : void 0;
448
- row.status = type === "active" ? {
449
- type,
450
- ...activeFlags ? { activeFlags } : {}
451
- } : { type };
452
- }
453
- }
454
- return copyCodexCatalogSource(thread, row);
455
- }
456
- /** Keep only the admitted prefix before an RPC promise retains its response. */
457
- function projectCodexCatalogNativeResponse(response, sanitize, cachedPreview, remainingRows = 64) {
458
- if (!Array.isArray(response.data) || response.data.length > 64) throw new Error("Codex catalog response exceeds its native page limit");
459
- const limit = Number.isFinite(remainingRows) ? Math.max(0, Math.min(64, Math.floor(remainingRows))) : 0;
460
- const page = { data: response.data.slice(0, limit).map((thread) => projectCodexCatalogNativeThread(thread, sanitize, cachedPreview)) };
461
- for (const field of ["nextCursor", "backwardsCursor"]) {
462
- const value = response[field];
463
- if (value === null) page[field] = null;
464
- else if (value !== void 0) {
465
- if (typeof value !== "string" || value.length > 4096) throw new Error("Codex catalog response contains an invalid cursor");
466
- page[field] = detachCodexCatalogString(value);
467
- }
468
- }
469
- return page;
470
- }
471
- //#endregion
472
- export { parseTranscriptPage as A, unwrapNodeInvokePayload as B, codexCatalogThreadName as C, normalizeLimit as D, isInteractiveThreadSource as E, requireBoundThread as F, detachCodexCatalogString as H, requireOnlyKeys as I, selectCodexCatalogPreviewInput as L, readControlCursor as M, readGatewayParams as N, parseCatalogPage as O, readPageParams as P, toCatalogSession as R, catalogError as S, filterCatalogPageByTitle as T, session_catalog_limits_exports as U, CODEX_CATALOG_MAX_ROWS as V, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as W, MAX_CURSOR_LENGTH as _, closeCodexCatalogClientSource as a, NODE_INVOKE_TIMEOUT_MS as b, getCodexCatalogSource as c, CODEX_APP_SERVER_THREADS_CAPABILITY as d, CODEX_APP_SERVER_THREADS_LIST_COMMAND as f, CatalogParamsError as g, CODEX_LOCAL_SESSION_HOST_ID as h, session_catalog_native_projection_exports as i, readBoundedOptionalString as j, parseJsonParams as k, recordCodexCatalogResponseSource as l, CODEX_CATALOG_TRANSCRIPT_READ_COMMAND as m, projectCodexCatalogNativeResponse as n, codexCatalogSourceForClient as o, CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND as p, projectCodexCatalogNativeThread as r, copyCodexCatalogSource as s, CODEX_CATALOG_NATIVE_PAGE_LIMIT as t, setCodexCatalogSource as u, MAX_CWD_LENGTH as v, codexCatalogThreadStatus as w, boundedCatalogString as x, MAX_TRANSCRIPT_PAGE_BYTES as y, truncateCodexCatalogPreview as z };
306
+ export { unwrapNodeInvokePayload as A, readGatewayParams as C, selectCodexCatalogPreviewInput as D, requireOnlyKeys as E, toCatalogSession as O, readControlCursor as S, requireBoundThread as T, normalizeLimit as _, CODEX_LOCAL_SESSION_HOST_ID as a, parseTranscriptPage as b, MAX_CWD_LENGTH as c, boundedCatalogString as d, catalogError as f, isInteractiveThreadSource as g, filterCatalogPageByTitle as h, CODEX_CATALOG_TRANSCRIPT_READ_COMMAND as i, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as j, truncateCodexCatalogPreview as k, MAX_TRANSCRIPT_PAGE_BYTES as l, codexCatalogThreadStatus as m, CODEX_APP_SERVER_THREADS_LIST_COMMAND as n, CatalogParamsError as o, codexCatalogThreadName as p, CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND as r, MAX_CURSOR_LENGTH as s, CODEX_APP_SERVER_THREADS_CAPABILITY as t, NODE_INVOKE_TIMEOUT_MS as u, parseCatalogPage as v, readPageParams as w, readBoundedOptionalString as x, parseJsonParams as y };
@@ -1,12 +1,14 @@
1
- import { H as detachCodexCatalogString, L as selectCodexCatalogPreviewInput, M as readControlCursor, R as toCatalogSession, c as getCodexCatalogSource, r as projectCodexCatalogNativeThread, s as copyCodexCatalogSource, u as setCodexCatalogSource, x as boundedCatalogString, z as truncateCodexCatalogPreview } from "./session-catalog-native-projection-ChV3cCtm.mjs";
2
- import { n as codexCatalogRowRecency } from "./session-catalog-index-order-Cc5BzlQr.mjs";
3
- import { s as isOpenClawManagedCodexThread } from "./session-catalog-events-jMcYfQyd.mjs";
1
+ import { D as selectCodexCatalogPreviewInput, O as toCatalogSession, S as readControlCursor, d as boundedCatalogString, k as truncateCodexCatalogPreview } from "./session-catalog-parsing-CPGaPYr-.mjs";
2
+ import { n as detachCodexCatalogString } from "./session-catalog-limits-DDxOsQeC.mjs";
3
+ import { n as codexCatalogRowRecency } from "./session-catalog-index-order-BcQpHks3.mjs";
4
+ import { t as isOpenClawManagedCodexThread } from "./session-catalog-provenance-DoAvktcj.mjs";
5
+ import { c as copyCodexCatalogSource, l as getCodexCatalogSource, p as setCodexCatalogSource, r as projectCodexCatalogNativeThread } from "./session-catalog-native-projection-DjhwGL6x.mjs";
4
6
  import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
7
  import path from "node:path";
6
8
  import fs from "node:fs/promises";
7
9
  import { extractErrorCode, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
8
- import { constants, createZstdDecompress } from "node:zlib";
9
10
  import { root } from "openclaw/plugin-sdk/file-access-runtime";
11
+ import { constants, createZstdDecompress } from "node:zlib";
10
12
  import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
11
13
  //#region extensions/codex/src/session-catalog-rollouts.ts
12
14
  const WINDOW_BYTES = 131072;
@@ -74,6 +76,14 @@ var NewestRolloutCandidates = class {
74
76
  function codexCatalogRolloutLogicalPath(rolloutPath) {
75
77
  return rolloutPath.replace(/\.zst$/u, "");
76
78
  }
79
+ function resolveCodexCatalogRolloutFingerprint(rolloutPath, previous, files) {
80
+ const logicalPath = rolloutPath && codexCatalogRolloutLogicalPath(rolloutPath);
81
+ if (!logicalPath) return;
82
+ return files?.get(logicalPath) ?? files?.get(`${logicalPath}.zst`) ?? (previous?.rolloutPath && codexCatalogRolloutLogicalPath(previous.rolloutPath) === logicalPath ? previous.fingerprint : void 0);
83
+ }
84
+ function indexCodexCatalogRowsByRollout(rows) {
85
+ return new Map([...rows].flatMap((row) => row.rolloutPath ? [[codexCatalogRolloutLogicalPath(row.rolloutPath), row]] : []));
86
+ }
77
87
  /** Absence is meaningful only inside the layout visited by the currency scan. */
78
88
  function isCodexCatalogRolloutPathCovered(sessionsRoot, rolloutPath) {
79
89
  const directories = path.relative(sessionsRoot, rolloutPath).split(path.sep);
@@ -411,4 +421,4 @@ function mergeCodexCatalogRolloutRow(row, existing, fingerprint) {
411
421
  return merged;
412
422
  }
413
423
  //#endregion
414
- export { CodexCatalogProjectionCapacityError, CodexCatalogProjections, canReuseCodexCatalogPreview, scanCodexCatalogRollouts as i, mergeCodexCatalogRolloutRow, isCodexCatalogRolloutPathCovered as n, projectCodexCatalogDeltaPage, projectCodexCatalogPage, projectCodexCatalogThread, readCodexCatalogRollout as r, codexCatalogRolloutLogicalPath as t };
424
+ export { CodexCatalogProjectionCapacityError, CodexCatalogProjections, resolveCodexCatalogRolloutFingerprint as a, canReuseCodexCatalogPreview, readCodexCatalogRollout as i, mergeCodexCatalogRolloutRow, indexCodexCatalogRowsByRollout as n, scanCodexCatalogRollouts as o, projectCodexCatalogDeltaPage, projectCodexCatalogPage, projectCodexCatalogThread, isCodexCatalogRolloutPathCovered as r, codexCatalogRolloutLogicalPath as t };
@@ -0,0 +1,95 @@
1
+ import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
2
+ import path from "node:path";
3
+ import { root } from "openclaw/plugin-sdk/file-access-runtime";
4
+ import { createZstdDecompress } from "node:zlib";
5
+ //#region extensions/codex/src/session-catalog-provenance.ts
6
+ const MAX_SESSION_META_BYTES = 1048576;
7
+ const SESSION_META_READ_CHUNK_BYTES = 65536;
8
+ const MAX_PROVENANCE_CACHE_ENTRIES = 2e4;
9
+ const provenanceByPath = /* @__PURE__ */ new Map();
10
+ function cacheProvenance(key, value) {
11
+ provenanceByPath.delete(key);
12
+ provenanceByPath.set(key, value);
13
+ if (provenanceByPath.size > MAX_PROVENANCE_CACHE_ENTRIES) provenanceByPath.delete(provenanceByPath.keys().next().value);
14
+ }
15
+ /** Undefined means the metadata line is not durable enough to cache yet. */
16
+ async function readCodexSessionMeta(sessionsRoot, rolloutPath, threadId) {
17
+ let safeRoot;
18
+ try {
19
+ safeRoot = await root(sessionsRoot, {
20
+ hardlinks: "reject",
21
+ maxBytes: Number.MAX_SAFE_INTEGER,
22
+ symlinks: "reject"
23
+ });
24
+ } catch {
25
+ return;
26
+ }
27
+ const candidates = rolloutPath.endsWith(".zst") ? [rolloutPath, rolloutPath.slice(0, -4)] : [rolloutPath, `${rolloutPath}.zst`];
28
+ for (const candidate of candidates) {
29
+ let opened;
30
+ try {
31
+ opened = await safeRoot.open(path.relative(sessionsRoot, candidate));
32
+ } catch {
33
+ continue;
34
+ }
35
+ const input = opened.handle.createReadStream({
36
+ autoClose: false,
37
+ highWaterMark: SESSION_META_READ_CHUNK_BYTES
38
+ });
39
+ const reader = candidate.endsWith(".zst") ? input.pipe(createZstdDecompress()) : input;
40
+ try {
41
+ const chunks = [];
42
+ let bytesReadTotal = 0;
43
+ let line;
44
+ for await (const value of reader) {
45
+ const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
46
+ const remaining = MAX_SESSION_META_BYTES - bytesReadTotal;
47
+ if (remaining <= 0) break;
48
+ const bounded = chunk.subarray(0, remaining);
49
+ bytesReadTotal += bounded.length;
50
+ const newline = bounded.indexOf(10);
51
+ chunks.push(newline >= 0 ? bounded.subarray(0, newline) : bounded);
52
+ if (newline >= 0) {
53
+ line = Buffer.concat(chunks).toString("utf8");
54
+ break;
55
+ }
56
+ }
57
+ if (!line) continue;
58
+ const parsed = JSON.parse(line);
59
+ if (!isJsonObject(parsed) || parsed.type !== "session_meta" || !isJsonObject(parsed.payload)) return null;
60
+ const payload = parsed.payload;
61
+ return payload.id === threadId ? payload : null;
62
+ } catch {
63
+ continue;
64
+ } finally {
65
+ reader.destroy();
66
+ input.destroy();
67
+ await opened.handle.close().catch(() => void 0);
68
+ }
69
+ }
70
+ }
71
+ /** Passive local listing uses native creation provenance, with rollout fallback for older records. */
72
+ async function isOpenClawManagedCodexThread(thread, localSessionsRoot, diagnostics) {
73
+ const started = diagnostics ? performance.now() : 0;
74
+ if (diagnostics) diagnostics.fields.provenanceChecks++;
75
+ try {
76
+ const rolloutPath = typeof thread.path === "string" ? thread.path.trim() : "";
77
+ if (!localSessionsRoot || !rolloutPath) return false;
78
+ if (typeof thread.originator === "string" && thread.originator.length > 0) return thread.originator === "openclaw";
79
+ const cacheKey = `${localSessionsRoot}\0${rolloutPath}`;
80
+ const cached = provenanceByPath.get(cacheKey);
81
+ if (cached !== void 0) {
82
+ if (diagnostics) diagnostics.fields.provenanceCacheHits++;
83
+ return cached;
84
+ }
85
+ if (diagnostics) diagnostics.fields.provenanceReadCalls++;
86
+ const metadata = await readCodexSessionMeta(localSessionsRoot, rolloutPath, thread.id);
87
+ const managed = metadata === void 0 ? void 0 : metadata?.originator === "openclaw";
88
+ if (managed !== void 0) cacheProvenance(cacheKey, managed);
89
+ return managed ?? false;
90
+ } finally {
91
+ if (diagnostics) diagnostics.fields.provenanceMs = (diagnostics.fields.provenanceMs ?? 0) + performance.now() - started;
92
+ }
93
+ }
94
+ //#endregion
95
+ export { readCodexSessionMeta as n, isOpenClawManagedCodexThread as t };
@@ -1,10 +1,10 @@
1
- import "./session-catalog-native-projection-ChV3cCtm.mjs";
2
- import "./session-catalog-fUdWDx-U.mjs";
1
+ import "./session-catalog-parsing-CPGaPYr-.mjs";
2
+ import "./session-catalog-4sCdv5qx.mjs";
3
3
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
4
5
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
5
- import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
6
6
  import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
7
- import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
7
+ import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
8
8
  //#region extensions/codex/src/session-cli.ts
9
9
  const CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS = 75e3;
10
10
  function requestedAgentId(options) {
@@ -79,12 +79,6 @@ function writeHost(host) {
79
79
  }
80
80
  if (host.nextCursor) writeLine(` More sessions: repeat the same filters with --host ${quoteShellArgument(host.hostId)} --cursor ${quoteShellArgument(host.nextCursor)}`);
81
81
  }
82
- function filterHosts(result, selector) {
83
- return selector ? {
84
- ...result,
85
- hosts: result.hosts.filter((host) => host.hostId === selector)
86
- } : result;
87
- }
88
82
  async function listCodexSessions(options) {
89
83
  const agentId = requestedAgentId(options);
90
84
  const host = options.host?.trim() || void 0;
@@ -93,23 +87,22 @@ async function listCodexSessions(options) {
93
87
  const search = options.search?.trim() || void 0;
94
88
  const limitPerHost = parsePageLimit(options.limit);
95
89
  const params = {
90
+ catalogId: "codex",
96
91
  ...agentId ? { agentId } : {},
97
92
  ...search ? { search } : {},
98
93
  ...limitPerHost !== void 0 ? { limitPerHost } : {},
99
94
  ...host ? { hostIds: [host] } : {},
100
95
  ...cursor && host ? { cursors: { [host]: cursor } } : {}
101
96
  };
102
- const raw = await callGatewayFromCli("sessions.catalog.list", gatewayOptions(options), {
103
- catalogId: "codex",
104
- ...params
105
- }, {
97
+ const raw = await callGatewayFromCli("sessions.catalog.list", gatewayOptions(options), params, {
106
98
  mode: "cli",
107
99
  scopes: ["operator.write"]
108
100
  });
109
101
  if (!isRecord(raw) || !Array.isArray(raw.catalogs)) throw new Error("Codex session catalog returned an invalid result");
110
102
  const catalog = raw.catalogs.find((candidate) => isRecord(candidate) && candidate.id === "codex" && Array.isArray(candidate.hosts));
111
103
  if (!isRecord(catalog)) throw new Error("Codex session catalog is unavailable on this Gateway");
112
- const result = filterHosts({ hosts: catalog.hosts }, host);
104
+ const hosts = catalog.hosts;
105
+ const result = { hosts: host ? hosts.filter((entry) => entry.hostId === host) : hosts };
113
106
  if (options.json) {
114
107
  writeJson(result);
115
108
  return;
@@ -175,15 +168,9 @@ async function archiveCodexSession(threadIdValue, options) {
175
168
  /** Registers the plugin-owned Codex session supervision CLI. */
176
169
  function registerCodexSessionCli(program) {
177
170
  const codex = program.command("codex").description("Inspect and branch from Codex sessions through the Gateway");
178
- addGatewayClientOptions(codex.command("sessions").description("List non-archived Codex app-server sessions across connected hosts").option("--agent <id>", "Agent id that owns the Codex sessions").option("--search <text>", "Search session titles (case-insensitive)").option("--host <id>", "Filter by stable host id").option("--limit <count>", "Maximum sessions returned per host").option("--cursor <cursor>", "Continue one host page (requires --host)").option("--json", "Print the structured catalog response", false), { timeoutMs: CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS }).action(async (options) => {
179
- await listCodexSessions(options);
180
- });
181
- addGatewayClientOptions(codex.command("continue <thread-id>").description("Continue a Gateway-local Codex thread as an OpenClaw branch").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--json", "Print the structured response", false)).action(async (threadId, options) => {
182
- await continueCodexSession(threadId, options);
183
- });
184
- addGatewayClientOptions(codex.command("archive <thread-id>").description("Archive a stored or idle Gateway-local Codex thread").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--confirm-no-other-runner", "Confirm no other Codex client or OpenClaw runner is using this thread", false).option("--json", "Print the structured response", false)).action(async (threadId, options) => {
185
- await archiveCodexSession(threadId, options);
186
- });
171
+ addGatewayClientOptions(codex.command("sessions").description("List non-archived Codex app-server sessions across connected hosts").option("--agent <id>", "Agent id that owns the Codex sessions").option("--search <text>", "Search session titles (case-insensitive)").option("--host <id>", "Filter by stable host id").option("--limit <count>", "Maximum sessions returned per host").option("--cursor <cursor>", "Continue one host page (requires --host)").option("--json", "Print the structured catalog response", false), { timeoutMs: CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS }).action(listCodexSessions);
172
+ addGatewayClientOptions(codex.command("continue <thread-id>").description("Continue a Gateway-local Codex thread as an OpenClaw branch").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--json", "Print the structured response", false)).action(continueCodexSession);
173
+ addGatewayClientOptions(codex.command("archive <thread-id>").description("Archive a stored or idle Gateway-local Codex thread").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--confirm-no-other-runner", "Confirm no other Codex client or OpenClaw runner is using this thread", false).option("--json", "Print the structured response", false)).action(archiveCodexSession);
187
174
  }
188
175
  //#endregion
189
176
  export { registerCodexSessionCli };