@openclaw/codex 2026.9.4 → 2026.9.5

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 (148) hide show
  1. package/assets/activity.svg +30 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/account-usage-runtime-C2MOIvfq.mjs +75 -0
  4. package/dist/{apply-CvT8tW5i.js → .setup/apply-CJ0ZfmBG.mjs} +11 -11
  5. package/dist/.setup/async-questions-DdhOCwGi.mjs +27 -0
  6. package/dist/{attempt-client-cleanup-DKHzbwt5.js → .setup/attempt-client-cleanup-BpYKdTA0.mjs} +29 -14
  7. package/dist/{attempt-context-D44yeDII.js → .setup/attempt-context-VXVwTCfS.mjs} +5 -5
  8. package/dist/.setup/attempt-terminal-gZrxQ35N.mjs +5 -0
  9. package/dist/{auth-binding-CWlKVccJ.js → .setup/auth-binding-DhLWa_7K.mjs} +1 -1
  10. package/dist/{auth-cache-key-7orQae_j.js → .setup/auth-cache-key-QirmgiCo.mjs} +3 -3
  11. package/dist/{auth-profile-CwzO4_RG.js → .setup/auth-profile-WqZtZfXN.mjs} +1 -1
  12. package/dist/.setup/binding-connection-Bm38niE8.mjs +50 -0
  13. package/dist/.setup/binding-connection.runtime-CnRMC0ta.mjs +48 -0
  14. package/dist/{bounded-turn-C_Hneydj.js → .setup/bounded-turn-BtlZcivC.mjs} +16 -11
  15. package/dist/{build-state-BCmg9-5p.js → .setup/build-state-Xx9ybZqa.mjs} +1 -1
  16. package/dist/{capabilities-8vx68WLH.js → .setup/capabilities-_vXcZGSx.mjs} +1 -1
  17. package/dist/{client-B57KWPQx.js → .setup/client-vXs2929Q.mjs} +332 -163
  18. package/dist/{command-dispatch-BpduNGVf.js → .setup/command-dispatch-naHIZwwF.mjs} +3 -3
  19. package/dist/{command-formatters-lxlkNZgU.js → .setup/command-formatters-CGEkdawF.mjs} +2 -2
  20. package/dist/{command-handlers-tiL9iWj7.js → .setup/command-handlers-BtAJEW1X.mjs} +59 -42
  21. package/dist/{command-rpc-CR5EOEZX.js → .setup/command-rpc-DHFpn4le.mjs} +22 -13
  22. package/dist/{compact-B_H3AOd7.js → .setup/compact-C3i3qlzj.mjs} +28 -43
  23. package/dist/{config-oIORaQ5T.js → .setup/config-CedDWjM-.mjs} +5 -4
  24. package/dist/{config-options-CXMq1T-C.js → .setup/config-options-BsanJ8QG.mjs} +6 -418
  25. package/dist/{protocol-5bh1G-H7.js → .setup/config-parsing-CcB9iPoq.mjs} +9 -51
  26. package/dist/{config-runtime-D0zGNIHu.js → .setup/config-runtime-CeAhl_h4.mjs} +2 -2
  27. package/dist/.setup/config-security-BRQ2mgW9.mjs +465 -0
  28. package/dist/{conversation-binding-DsB4-O7U.js → .setup/conversation-binding-DhzrpTM6.mjs} +23 -21
  29. package/dist/{conversation-binding-data-BiodpIzq.js → .setup/conversation-binding-data-CrcyZk6O.mjs} +1 -1
  30. package/dist/{conversation-control-CtUu1b3m.js → .setup/conversation-control-DN53ns41.mjs} +17 -13
  31. package/dist/.setup/cyber-failover-DYwbmf1o.mjs +123 -0
  32. package/dist/.setup/cyber-failover-notice-e9G3J9-e.mjs +17 -0
  33. package/dist/{dynamic-tools-CmN5RAip.js → .setup/dynamic-tools-D16lOp67.mjs} +101 -55
  34. package/dist/{effective-mcp-catalog-Bd73bqA8.js → .setup/effective-mcp-catalog-K6kLCN8X.mjs} +3 -3
  35. package/dist/{ephemeral-turn-D78_VmzO.js → .setup/ephemeral-turn-R1gA8Sn6.mjs} +4 -5
  36. package/dist/{event-projector-assistant-message-BmBM4qBV.js → .setup/event-projector-assistant-message-DNUR1s0A.mjs} +6 -3
  37. package/dist/{event-projector-items-5VhsECCO.js → .setup/event-projector-items-DyTQ_XqL.mjs} +1 -1
  38. package/dist/{attempt-notifications-C9XufG6l.js → .setup/event-projector-usage-C7Ntzs-f.mjs} +102 -9
  39. package/dist/{harness-C7rRa7bm.js → .setup/harness-rxaaoN-o.mjs} +74 -20
  40. package/dist/{inference-context-Dr_mzvk4.js → .setup/inference-context-fulhZuz8.mjs} +1 -1
  41. package/dist/{inference-proxy-HGXKUIre.js → .setup/inference-proxy-CC15HuSi.mjs} +4 -4
  42. package/dist/{isolated-completion-DWVb5U2J.js → .setup/isolated-completion-B6srt48J.mjs} +7 -7
  43. package/dist/{launch-args-RXQwn8zV.js → .setup/launch-args-DnMak49W.mjs} +22 -1
  44. package/dist/{managed-binary-D22rNEcR.js → .setup/managed-binary-DP6Rib3P.mjs} +2 -2
  45. package/dist/{managed-thread-store-D1t5jh3G.js → .setup/managed-thread-store-BMqgThVL.mjs} +48 -14
  46. package/dist/{model-catalog-Dq2n8f_p.js → .setup/model-catalog-DkvUuBey.mjs} +35 -10
  47. package/dist/{models-PCKOim-h.js → .setup/models-BDFgm_G-.mjs} +3 -3
  48. package/dist/.setup/native-auth-BLZGqFjw.mjs +57 -0
  49. package/dist/{native-subagent-history-DjtPloaU.js → .setup/native-subagent-history-YXaL6dMd.mjs} +24 -29
  50. package/dist/.setup/native-subagent-monitor-B1hxzIOy.mjs +5031 -0
  51. package/dist/{native-subagent-task-ids-BzTdT0Uw.js → .setup/native-subagent-task-ids-DsuOonKv.mjs} +32 -8
  52. package/dist/{node-cli-sessions-DKaOmVUh.js → .setup/node-cli-sessions-Cl8b2ZF3.mjs} +1 -1
  53. package/dist/{node-exec-server.runtime-Cl2vapEi.js → .setup/node-exec-server.runtime-BaViBKNz.mjs} +3 -3
  54. package/dist/{plan-7uG-Fp36.js → .setup/plan-xD7WKYTM.mjs} +64 -48
  55. package/dist/{plugin-activation-BYQculil.js → .setup/plugin-activation-r8nq5Jzp.mjs} +3 -3
  56. package/dist/{plugin-app-cache-key-d0eKxy7b.js → .setup/plugin-app-cache-key-BOxKP7db.mjs} +29 -25
  57. package/dist/{plugin-approval-roundtrip-Bz3FT8W5.js → .setup/plugin-approval-roundtrip-CjfzafAZ.mjs} +1 -1
  58. package/dist/{plugin-inventory-oL4Na1ZG.js → .setup/plugin-inventory-DUle8DLz.mjs} +7 -6
  59. package/dist/{plugin-metadata-cache-ClPJpRio.js → .setup/plugin-metadata-cache-DsS5buNa.mjs} +29 -14
  60. package/dist/{provider-capabilities-BvCUL69A.js → .setup/provider-capabilities-B8J4Dy-O.mjs} +2 -2
  61. package/dist/{provider-MQ8PVkuE.js → .setup/provider-fFh_-VR3.mjs} +4 -4
  62. package/dist/{rate-limits-CBMmWBr9.js → .setup/rate-limits-DOEGYRNs.mjs} +90 -46
  63. package/dist/{request-B7hEkBGq.js → .setup/request-BioXJLYa.mjs} +113 -33
  64. package/dist/.setup/run-attempt-lifecycle-B7JbY4-F.mjs +71 -0
  65. package/dist/{run-attempt-CvsAAGa0.js → .setup/run-attempt-rlA07pUv.mjs} +580 -498
  66. package/dist/{runtime-artifact-BJ0rXBZ_.js → .setup/runtime-artifact-Dy38Z5iU.mjs} +2 -2
  67. package/dist/{sandbox-guard-BxgyoM8M.js → .setup/sandbox-guard-BBP-RbTf.mjs} +3 -3
  68. package/dist/{session-binding-CI8UuilT.js → .setup/session-binding-_0W_fHRr.mjs} +46 -64
  69. package/dist/{session-binding-record-Bcvslnhf.js → .setup/session-binding-record-TH3xA0zj.mjs} +181 -3
  70. package/dist/.setup/session-binding-sidecars-CKYEcfNn.mjs +543 -0
  71. package/dist/{session-catalog-adoption-tcZi1IfX.js → .setup/session-catalog-adoption-CR_whkEW.mjs} +6 -6
  72. package/dist/{session-catalog-archive-CwKg8Xz2.js → .setup/session-catalog-archive-CwZaPacf.mjs} +6 -6
  73. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +250 -0
  74. package/dist/.setup/session-catalog-fUdWDx-U.mjs +2464 -0
  75. package/dist/.setup/session-catalog-index-B141u15s.mjs +1070 -0
  76. package/dist/.setup/session-catalog-index-order-Cc5BzlQr.mjs +48 -0
  77. package/dist/.setup/session-catalog-index-state-BAuDztHN.mjs +180 -0
  78. package/dist/{thread-history-page-D0JIp48V.js → .setup/session-catalog-native-projection-ChV3cCtm.mjs} +206 -95
  79. package/dist/{session-catalog-node-adoption-B1tgDW-m.js → .setup/session-catalog-node-adoption-BVRsYOSh.mjs} +3 -3
  80. package/dist/{session-catalog-node-continue-Ci-DXyJP.js → .setup/session-catalog-node-continue-Dowv8osw.mjs} +7 -7
  81. package/dist/.setup/session-catalog-projection-C1Bj9Jl-.mjs +414 -0
  82. package/dist/{session-cli-DNN_jhGc.js → .setup/session-cli-DIj-IE-E.mjs} +4 -4
  83. package/dist/{session-history-Cz-tOOYj.js → .setup/session-history-C--SrLI8.mjs} +10 -5
  84. package/dist/{session-history-import-DwyijFI6.js → .setup/session-history-import-JHXT5Xfi.mjs} +4 -4
  85. package/dist/{session-history-read-cxPUxyVV.js → .setup/session-history-read-B3ZfSUbF.mjs} +2 -2
  86. package/dist/{session-history.worker-BeK1YOyT.js → .setup/session-history.worker-CpNj7H_P.mjs} +5 -6
  87. package/dist/{session-initialization-Ct0_Hzmg.js → .setup/session-initialization-DH1z6fXn.mjs} +2 -2
  88. package/dist/{session-permission-policy-BBmXA8Eg.js → .setup/session-permission-policy-DhurXY0l.mjs} +2 -2
  89. package/dist/{session-retirement-B2YfbAAT.js → .setup/session-retirement-CU87AOg9.mjs} +6 -6
  90. package/dist/{settled-turn-context-Du6gdUDd.js → .setup/settled-turn-context-fmwouT5I.mjs} +2 -2
  91. package/dist/{settled-turn-finalizer-Dn91stmc.js → .setup/settled-turn-finalizer-CiY2bLFK.mjs} +9 -9
  92. package/dist/{shared-client-CscigXXL.js → .setup/shared-client-BpTtuLQ5.mjs} +286 -145
  93. package/dist/{side-question-BGMJQf4U.js → .setup/side-question-DSCZyoBD.mjs} +64 -47
  94. package/dist/{source-CElXU0Oy.js → .setup/source-Bjp4UQij.mjs} +7 -6
  95. package/dist/{thread-archive-guard-DfpBr-Sz.js → .setup/thread-archive-guard-jmecf6OJ.mjs} +1 -1
  96. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +83 -0
  97. package/dist/{thread-lifecycle-DXl1-I6b.js → .setup/thread-lifecycle-Cik28qWn.mjs} +256 -128
  98. package/dist/{thread-ownership-BsDRTsyp.js → .setup/thread-ownership-skomxnIt.mjs} +4 -4
  99. package/dist/{thread-policy-BuEQfE0g.js → .setup/thread-policy-Cjs4B8xf.mjs} +2 -2
  100. package/dist/{thread-resume-DsDOZpFg.js → .setup/thread-resume-BkNpj9Pz.mjs} +8 -5
  101. package/dist/.setup/timeout-DZF05XrR.mjs +63 -0
  102. package/dist/{transcript-history-projection-v17wXgdK.js → .setup/transcript-history-projection-DHNBDhCU.mjs} +8 -3
  103. package/dist/{transcript-mirror-C5CKgNy6.js → .setup/transcript-mirror-D4qp_leP.mjs} +15 -6
  104. package/dist/{transcript-mirror-attestation-DibE0krH.js → .setup/transcript-mirror-attestation-CzM-94NC.mjs} +4 -1
  105. package/dist/{transport-stdio-BGjHoYLr.js → .setup/transport-stdio-Cmx94Oiy.mjs} +149 -44
  106. package/dist/{upstream-session-fork-BZerMte_.js → .setup/upstream-session-fork-D3UKxgVD.mjs} +27 -26
  107. package/dist/{usage-tCk-mg_x.js → .setup/usage-BOgBEKso.mjs} +4 -4
  108. package/dist/.setup/usage-limit-error-C0ow7DOc.mjs +166 -0
  109. package/dist/{version-omm6IPI3.js → .setup/version-CoqzXPgK.mjs} +1 -1
  110. package/dist/{web-search-provider.runtime-B7bGbGWq.js → .setup/web-search-provider.runtime-CTGuJt6i.mjs} +3 -3
  111. package/dist/api.js +6 -6
  112. package/dist/cli-metadata.js +1 -1
  113. package/dist/doctor-contract-api.js +8 -528
  114. package/dist/harness.js +1 -1
  115. package/dist/index.js +123 -83
  116. package/dist/media-understanding-provider.js +3 -3
  117. package/dist/migration-provider-api.js +1 -1
  118. package/dist/native-tool-policy.js +12 -0
  119. package/dist/provider-discovery.js +18 -0
  120. package/dist/session-history-worker-runtime.js +23 -5
  121. package/dist/session-history.worker.js +2 -2
  122. package/dist/web-search-contract-api.js +1 -1
  123. package/openclaw.plugin.json +354 -69
  124. package/package.json +11 -8
  125. package/dist/binding-connection-D3udKbIE.js +0 -60
  126. package/dist/event-projector-usage-BfXmpOec.js +0 -102
  127. package/dist/native-subagent-history-owner-Pcp7JuVF.js +0 -34
  128. package/dist/native-subagent-monitor-fQ7eIXEf.js +0 -2978
  129. package/dist/rpc-error-ttN_QjEm.js +0 -30
  130. package/dist/session-catalog-ct-AH01I.js +0 -1477
  131. package/dist/session-catalog-home-id-CwhLdC03.js +0 -18
  132. package/dist/session-catalog-provenance-D-dIfRAH.js +0 -96
  133. package/dist/timeout-BVw8aaM1.js +0 -33
  134. package/dist/{auth-profile-selection-DFu9e167.js → .setup/auth-profile-selection-DFu9e167.mjs} +0 -0
  135. package/dist/{config-utils-DujwEnhg.js → .setup/config-utils-DujwEnhg.mjs} +0 -0
  136. package/dist/{context-compaction-activity-CMla5FPJ.js → .setup/context-compaction-activity-CMla5FPJ.mjs} +0 -0
  137. package/dist/{elicitation-input-DPoK8F7w.js → .setup/elicitation-input-DPoK8F7w.mjs} +0 -0
  138. package/dist/{history-rejection-B4nOXNXF.js → .setup/history-rejection-B4nOXNXF.mjs} +0 -0
  139. package/dist/{image-payload-sanitizer-tupAr-2o.js → .setup/image-payload-sanitizer-tupAr-2o.mjs} +0 -0
  140. package/dist/{incognito-session-uhrBF6wJ.js → .setup/incognito-session-uhrBF6wJ.mjs} +0 -0
  141. package/dist/{local-runtime-attribution-B_2mnqhb.js → .setup/local-runtime-attribution-B_2mnqhb.mjs} +0 -0
  142. package/dist/{native-execution-policy-umd0tgh4.js → .setup/native-execution-policy-YBMHSzC4.mjs} +1 -1
  143. /package/dist/{plugin-marketplace-discovery-P-Vndfqq.js → .setup/plugin-marketplace-discovery-P-Vndfqq.mjs} +0 -0
  144. /package/dist/{rolldown-runtime-8H4AJuhK.js → .setup/rolldown-runtime-8H4AJuhK.mjs} +0 -0
  145. /package/dist/{session-binding-meta-B7aEMU7g.js → .setup/session-binding-meta-B7aEMU7g.mjs} +0 -0
  146. /package/dist/{session-upstream-marker-D15C9NHp.js → .setup/session-upstream-marker-D15C9NHp.mjs} +0 -0
  147. /package/dist/{upstream-prompt-provenance-LphB8slG.js → .setup/upstream-prompt-provenance-LphB8slG.mjs} +0 -0
  148. /package/dist/{web-search-provider.shared-BrZmlqyR.js → .setup/web-search-provider.shared-BrZmlqyR.mjs} +0 -0
@@ -0,0 +1,48 @@
1
+ import { V as CODEX_CATALOG_MAX_ROWS } from "./session-catalog-native-projection-ChV3cCtm.mjs";
2
+ //#region extensions/codex/src/session-catalog-index-order.ts
3
+ function codexCatalogRowRecency(row) {
4
+ return row.recencyAt ?? row.updatedAt ?? 0;
5
+ }
6
+ function compareCodexCatalogRows(a, b) {
7
+ return codexCatalogRowRecency(b) - codexCatalogRowRecency(a) || (a.sourceOrder ?? 0) - (b.sourceOrder ?? 0) || (a.threadId < b.threadId ? 1 : a.threadId > b.threadId ? -1 : 0);
8
+ }
9
+ /** Admission and restoration share the archived-oldest eviction policy. */
10
+ function retainCodexCatalogRow(rows, candidate) {
11
+ rows.set(candidate.threadId, candidate);
12
+ if (rows.size <= 2e4) return;
13
+ let oldest;
14
+ for (const row of rows.values()) if (!oldest || (row.archived !== oldest.archived ? row.archived : compareCodexCatalogRows(row, oldest) > 0)) oldest = row;
15
+ if (oldest) rows.delete(oldest.threadId);
16
+ return oldest;
17
+ }
18
+ /** Stable positions keep issued cursors independent of later native page offsets. */
19
+ var CodexCatalogOrdering = class {
20
+ constructor() {
21
+ this.nextEventOrder = -1;
22
+ }
23
+ read(rows) {
24
+ return this.ordered ??= [...rows.values()].toSorted(compareCodexCatalogRows);
25
+ }
26
+ invalidate() {
27
+ this.ordered = void 0;
28
+ }
29
+ restore(row) {
30
+ this.nextEventOrder = Math.min(this.nextEventOrder, (row.sourceOrder ?? 0) - 1);
31
+ }
32
+ reserveEvent() {
33
+ return this.nextEventOrder--;
34
+ }
35
+ unchangedPosition(row, previous) {
36
+ return previous && codexCatalogRowRecency(row) <= codexCatalogRowRecency(previous) ? previous.sourceOrder : void 0;
37
+ }
38
+ position(row, previous) {
39
+ return row.sourceOrder ?? this.unchangedPosition(row, previous) ?? this.reserveEvent();
40
+ }
41
+ captureBatch(hasCompleteSnapshot) {
42
+ const base = hasCompleteSnapshot ? this.nextEventOrder - CODEX_CATALOG_MAX_ROWS : 0;
43
+ if (hasCompleteSnapshot) this.nextEventOrder = base - 1;
44
+ return (row, previous, position) => this.unchangedPosition(row, previous) ?? base + position;
45
+ }
46
+ };
47
+ //#endregion
48
+ export { retainCodexCatalogRow as i, codexCatalogRowRecency as n, compareCodexCatalogRows as r, CodexCatalogOrdering as t };
@@ -0,0 +1,180 @@
1
+ import { H as detachCodexCatalogString, O as parseCatalogPage } from "./session-catalog-native-projection-ChV3cCtm.mjs";
2
+ import { i as retainCodexCatalogRow } from "./session-catalog-index-order-Cc5BzlQr.mjs";
3
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { createHash } from "node:crypto";
5
+ import { setImmediate } from "node:timers/promises";
6
+ //#region extensions/codex/src/session-catalog-index-state.ts
7
+ const CODEX_CATALOG_STATE_NAMESPACE = "session-catalog-resident";
8
+ /** Durable metadata never asserts that a native process is still running. */
9
+ function codexCatalogMetadataPage(page) {
10
+ return { sessions: page.sessions.map(({ status: _status, activeFlags: _flags, ...session }) => ({
11
+ ...session,
12
+ status: "notLoaded"
13
+ })) };
14
+ }
15
+ function readStoredCodexCatalogRow(value) {
16
+ if (!isRecord(value) || value.version !== 1 || value.kind !== "row" || !isRecord(value.row)) return;
17
+ const row = value.row;
18
+ if (typeof row.threadId !== "string" || !row.threadId || row.threadId.length > 256 || typeof row.archived !== "boolean" || typeof row.nativeMetadata !== "boolean" || row.preview !== void 0 && (typeof row.preview !== "string" || row.preview.length > 500) || row.sourceOrder !== void 0 && (typeof row.sourceOrder !== "number" || !Number.isSafeInteger(row.sourceOrder)) || row.rolloutPath !== void 0 && (typeof row.rolloutPath !== "string" || row.rolloutPath.length > 4096) || !(row.updatedAt === null || typeof row.updatedAt === "number" && Number.isFinite(row.updatedAt)) || !(row.recencyAt === null || typeof row.recencyAt === "number" && Number.isFinite(row.recencyAt))) return;
19
+ try {
20
+ const page = parseCatalogPage(row.page);
21
+ if (page.sessions.length > 1 || page.sessions.some((session) => session.threadId !== row.threadId)) return;
22
+ const fingerprint = isRecord(row.fingerprint) && typeof row.fingerprint.mtimeMs === "number" && Number.isFinite(row.fingerprint.mtimeMs) && typeof row.fingerprint.size === "number" && Number.isFinite(row.fingerprint.size) ? {
23
+ mtimeMs: row.fingerprint.mtimeMs,
24
+ size: row.fingerprint.size
25
+ } : void 0;
26
+ return {
27
+ threadId: detachCodexCatalogString(row.threadId),
28
+ updatedAt: row.updatedAt,
29
+ recencyAt: row.recencyAt,
30
+ archived: row.archived,
31
+ nativeMetadata: row.nativeMetadata,
32
+ page: codexCatalogMetadataPage(page),
33
+ ...typeof row.preview === "string" ? { preview: detachCodexCatalogString(row.preview) } : {},
34
+ ...typeof row.sourceOrder === "number" ? { sourceOrder: row.sourceOrder } : {},
35
+ ...typeof row.rolloutPath === "string" ? { rolloutPath: detachCodexCatalogString(row.rolloutPath) } : {},
36
+ ...fingerprint ? { fingerprint } : {}
37
+ };
38
+ } catch {
39
+ return;
40
+ }
41
+ }
42
+ /** An incomplete cache cannot prove which native rows precede an issued cursor. */
43
+ async function readCodexCatalogSnapshot(state) {
44
+ const entries = await state?.entries() ?? [];
45
+ const rows = /* @__PURE__ */ new Map();
46
+ const keys = /* @__PURE__ */ new Map();
47
+ const obsolete = /* @__PURE__ */ new Set();
48
+ let cleanupIncomplete = false;
49
+ let valid = true;
50
+ const discard = (key) => {
51
+ if (obsolete.has(key)) return;
52
+ if ((key === "complete" || obsolete.size - Number(obsolete.has("complete")) < 2e4) && Buffer.byteLength(key) <= 512) obsolete.add(detachCodexCatalogString(key));
53
+ else {
54
+ cleanupIncomplete = true;
55
+ obsolete.add("complete");
56
+ }
57
+ };
58
+ let complete = false;
59
+ let overflow = false;
60
+ for (const entry of entries) {
61
+ if (Buffer.byteLength(entry.key) > 512) {
62
+ valid = false;
63
+ discard(entry.key);
64
+ continue;
65
+ }
66
+ if (entry.value?.version === 1 && entry.value.kind === "complete") {
67
+ complete = true;
68
+ overflow ||= entry.value.overflow === true;
69
+ continue;
70
+ }
71
+ const row = readStoredCodexCatalogRow(entry.value);
72
+ if (row) {
73
+ const evicted = retainCodexCatalogRow(rows, row);
74
+ if (evicted) {
75
+ discard(evicted === row ? entry.key : keys.get(evicted.threadId));
76
+ keys.delete(evicted.threadId);
77
+ }
78
+ if (evicted !== row) keys.set(row.threadId, detachCodexCatalogString(entry.key));
79
+ } else {
80
+ valid = false;
81
+ discard(entry.key);
82
+ }
83
+ }
84
+ complete &&= valid;
85
+ if (!complete) {
86
+ rows.clear();
87
+ for (const entry of entries) discard(entry.key);
88
+ if (entries.length) obsolete.add("complete");
89
+ }
90
+ return {
91
+ rows: [...rows.values()],
92
+ complete,
93
+ overflow,
94
+ obsolete,
95
+ cleanupIncomplete
96
+ };
97
+ }
98
+ /** Serializes reconstructible cache writes without blocking resident queries. */
99
+ var CodexCatalogPersistence = class {
100
+ invalidate(error) {
101
+ if (!this.failed) this.report(error);
102
+ this.failed = true;
103
+ this.queue("complete", void 0);
104
+ }
105
+ constructor(state, report) {
106
+ this.state = state;
107
+ this.report = report;
108
+ this.pending = /* @__PURE__ */ new Map();
109
+ this.failed = false;
110
+ this.retired = false;
111
+ }
112
+ async readSnapshot() {
113
+ await this.drain();
114
+ return await readCodexCatalogSnapshot(this.state);
115
+ }
116
+ key(threadId) {
117
+ return `thread:${createHash("sha256").update(threadId).digest("hex")}`;
118
+ }
119
+ put(row) {
120
+ if (!this.state || this.retired) return;
121
+ this.queue(this.key(row.threadId), {
122
+ version: 1,
123
+ kind: "row",
124
+ row
125
+ });
126
+ }
127
+ remove(threadId) {
128
+ this.queue(this.key(threadId), void 0);
129
+ }
130
+ async pruneObsolete(keys, currentRows) {
131
+ const currentKeys = new Set(Array.from(currentRows, (row) => this.key(row.threadId)));
132
+ for (const key of keys) if (!currentKeys.has(key)) this.queue(key, void 0);
133
+ await this.drain();
134
+ }
135
+ async finishHydration(overflow = false) {
136
+ await this.drain();
137
+ if (!this.failed) {
138
+ this.queue("complete", {
139
+ version: 1,
140
+ kind: "complete",
141
+ ...overflow ? { overflow: true } : {}
142
+ });
143
+ await this.drain();
144
+ }
145
+ }
146
+ async drain() {
147
+ while (this.writing) await this.writing;
148
+ }
149
+ retire() {
150
+ this.retired = true;
151
+ return this.drain();
152
+ }
153
+ queue(key, value) {
154
+ if (!this.state || this.retired && (!this.writing || key !== "complete" || value !== void 0)) return;
155
+ if (key !== "complete" && !this.pending.has(key) && this.pending.size - Number(this.pending.has("complete")) >= 2e4) {
156
+ this.invalidate(/* @__PURE__ */ new Error("Codex catalog persistence queue reached its resident row limit"));
157
+ return;
158
+ }
159
+ this.pending.set(key, value);
160
+ this.writing ??= this.writePending();
161
+ }
162
+ async writePending() {
163
+ try {
164
+ await setImmediate();
165
+ for (const [key, value] of this.pending) {
166
+ this.pending.delete(key);
167
+ try {
168
+ if (value) await this.state.register(key, value);
169
+ else await this.state.delete(key);
170
+ } catch (error) {
171
+ if (!this.failed) this.invalidate(error);
172
+ }
173
+ }
174
+ } finally {
175
+ this.writing = void 0;
176
+ }
177
+ }
178
+ };
179
+ //#endregion
180
+ export { CodexCatalogPersistence as n, codexCatalogMetadataPage as r, CODEX_CATALOG_STATE_NAMESPACE as t };
@@ -1,6 +1,24 @@
1
- import { n as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, t as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES } from "./protocol-5bh1G-H7.js";
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";
2
4
  import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
5
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
6
+ //#region extensions/codex/src/app-server/protocol-session-source.ts
7
+ const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
8
+ const CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES = ["atlas", "chatgpt"];
9
+ //#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
4
22
  //#region extensions/codex/src/session-catalog-parsing.ts
5
23
  const DEFAULT_PAGE_LIMIT = 50;
6
24
  const CODEX_APP_SERVER_THREADS_CAPABILITY = "codex-app-server-threads";
@@ -16,6 +34,7 @@ const MAX_HOST_ID_LENGTH = 256;
16
34
  const MAX_CWD_LENGTH = 4096;
17
35
  const MAX_SESSION_NAME_LENGTH = 500;
18
36
  const MAX_SESSION_PREVIEW_LENGTH = 500;
37
+ const SESSION_PREVIEW_PREFIX_LENGTH = 2048;
19
38
  const MAX_SESSION_KEY_LENGTH = 1024;
20
39
  const MAX_METADATA_LENGTH = 500;
21
40
  const MAX_ACTIVE_FLAGS = 16;
@@ -24,19 +43,29 @@ var CatalogParamsError = class extends Error {};
24
43
  function readControlCursor(value, label) {
25
44
  if (value === void 0 || value === null) return;
26
45
  if (typeof value !== "string" || !value.trim() || value.length > 4096) throw new CatalogParamsError(`invalid Codex session catalog ${label} cursor`);
27
- return value;
46
+ return detachCodexCatalogString(value);
28
47
  }
29
48
  function boundedCatalogString(value, maxLength, overflow = "omit") {
30
49
  if (typeof value !== "string") return;
31
50
  const normalized = value.trim();
32
51
  if (!normalized) return;
33
- if (normalized.length <= maxLength) return normalized;
34
- return overflow === "truncate" ? truncateUtf16Safe(normalized, maxLength) : void 0;
52
+ if (normalized.length <= maxLength) return detachCodexCatalogString(normalized);
53
+ return overflow === "truncate" ? detachCodexCatalogString(truncateUtf16Safe(normalized, maxLength)) : void 0;
35
54
  }
36
55
  function catalogPreview(value, sanitize) {
37
56
  if (typeof value !== "string") return;
38
57
  return boundedCatalogString(sanitize(value.replace(/\s+/g, " ")), MAX_SESSION_PREVIEW_LENGTH, "truncate");
39
58
  }
59
+ /** Select a bounded input only for the canonical terminal sanitizer. */
60
+ function selectCodexCatalogPreviewInput(value) {
61
+ if (value.length <= SESSION_PREVIEW_PREFIX_LENGTH) return value;
62
+ const prefix = value.slice(0, SESSION_PREVIEW_PREFIX_LENGTH).replace(/\s+/g, " ").trim();
63
+ return prefix.length > MAX_SESSION_PREVIEW_LENGTH && !/\p{Cc}/u.test(prefix) ? prefix : value;
64
+ }
65
+ /** Detach the small preview from V8's potentially large sliced-string backing store. */
66
+ function truncateCodexCatalogPreview(value, sanitize) {
67
+ return Buffer.from(catalogPreview(value, sanitize) ?? "", "utf8").toString("utf8");
68
+ }
40
69
  function normalizeInteractiveThreadSource(source) {
41
70
  if (CODEX_INTERACTIVE_THREAD_SOURCE_KINDS.some((kind) => kind === source) || CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source)) return source;
42
71
  if (isRecord(source) && CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source.custom)) return source.custom;
@@ -44,36 +73,45 @@ function normalizeInteractiveThreadSource(source) {
44
73
  function isInteractiveThreadSource(source) {
45
74
  return normalizeInteractiveThreadSource(source) !== void 0;
46
75
  }
47
- function toCatalogSession(thread, archived, sanitize) {
76
+ function codexCatalogThreadName(value) {
77
+ return value === null ? null : boundedCatalogString(value, MAX_SESSION_NAME_LENGTH, "truncate");
78
+ }
79
+ function codexCatalogThreadStatus(status) {
80
+ const activeFlags = [];
81
+ if (status?.type === "active" && Array.isArray(status.activeFlags)) for (const flag of status.activeFlags) {
82
+ const normalized = boundedCatalogString(flag, 128);
83
+ if (normalized) activeFlags.push(normalized);
84
+ if (activeFlags.length === MAX_ACTIVE_FLAGS) break;
85
+ }
86
+ return {
87
+ status: boundedCatalogString(status?.type, 64) ?? "notLoaded",
88
+ ...activeFlags.length ? { activeFlags } : {}
89
+ };
90
+ }
91
+ function toCatalogSession(thread, archived, sanitize, preparedPreview) {
48
92
  const source = normalizeInteractiveThreadSource(thread.source);
49
93
  if (!source) return;
50
- const record = thread;
51
94
  const threadId = boundedCatalogString(thread.id, 256);
52
95
  if (!threadId) return;
53
- const activeFlags = thread.status?.type === "active" ? thread.status.activeFlags?.flatMap((flag) => {
54
- const normalized = boundedCatalogString(flag, 128);
55
- return normalized ? [normalized] : [];
56
- }).slice(0, MAX_ACTIVE_FLAGS) : void 0;
57
- const gitInfo = isRecord(record.gitInfo) ? record.gitInfo : void 0;
96
+ const gitInfo = isRecord(thread.gitInfo) ? thread.gitInfo : void 0;
58
97
  const sessionId = boundedCatalogString(thread.sessionId, 256);
59
- const name = boundedCatalogString(thread.name, MAX_SESSION_NAME_LENGTH, "truncate");
60
- const fallbackName = name ? void 0 : catalogPreview(thread.preview, sanitize);
98
+ const name = codexCatalogThreadName(thread.name);
99
+ const fallbackName = name ? void 0 : preparedPreview ? preparedPreview.value : catalogPreview(thread.preview, sanitize);
61
100
  const cwd = boundedCatalogString(thread.cwd, MAX_CWD_LENGTH);
62
- const modelProvider = boundedCatalogString(record.modelProvider, MAX_METADATA_LENGTH, "truncate");
63
- const cliVersion = boundedCatalogString(record.cliVersion, MAX_METADATA_LENGTH, "truncate");
101
+ const modelProvider = boundedCatalogString(thread.modelProvider, MAX_METADATA_LENGTH, "truncate");
102
+ const cliVersion = boundedCatalogString(thread.cliVersion, MAX_METADATA_LENGTH, "truncate");
64
103
  const gitBranch = boundedCatalogString(gitInfo?.branch, MAX_METADATA_LENGTH, "truncate");
65
104
  return {
66
105
  threadId,
67
- status: thread.status?.type ?? "notLoaded",
106
+ ...codexCatalogThreadStatus(thread.status),
68
107
  archived,
69
108
  ...sessionId ? { sessionId } : {},
70
109
  ...thread.name === null ? { name: null } : name ? { name } : {},
71
110
  ...fallbackName ? { fallbackName } : {},
72
111
  ...cwd ? { cwd } : {},
73
- ...activeFlags?.length ? { activeFlags } : {},
74
112
  ...typeof thread.createdAt === "number" && Number.isFinite(thread.createdAt) ? { createdAt: thread.createdAt } : {},
75
113
  ...typeof thread.updatedAt === "number" && Number.isFinite(thread.updatedAt) ? { updatedAt: thread.updatedAt } : {},
76
- ...typeof record.recencyAt === "number" && Number.isFinite(record.recencyAt) ? { recencyAt: record.recencyAt } : record.recencyAt === null ? { recencyAt: null } : {},
114
+ ...typeof thread.recencyAt === "number" && Number.isFinite(thread.recencyAt) ? { recencyAt: thread.recencyAt } : thread.recencyAt === null ? { recencyAt: null } : {},
77
115
  source,
78
116
  ...modelProvider ? { modelProvider } : {},
79
117
  ...cliVersion ? { cliVersion } : {},
@@ -169,7 +207,7 @@ function parseJsonParams(paramsJSON) {
169
207
  function parseOptionalCatalogString(value, field, maxLength) {
170
208
  if (value === void 0) return;
171
209
  if (typeof value !== "string" || value.length > maxLength) throw new Error(`Codex session catalog returned an invalid ${field}`);
172
- return value;
210
+ return detachCodexCatalogString(value);
173
211
  }
174
212
  function parseCatalogSession(value, options = {}) {
175
213
  if (!isRecord(value) || typeof value.threadId !== "string" || !value.threadId.trim() || value.threadId.length > 256 || value.archived !== false) throw new Error("Codex session catalog returned an invalid session");
@@ -195,7 +233,7 @@ function parseCatalogSession(value, options = {}) {
195
233
  const updatedAt = asFiniteNumber(value.updatedAt);
196
234
  const recencyAt = value.recencyAt === null ? null : asFiniteNumber(value.recencyAt);
197
235
  return {
198
- threadId: value.threadId,
236
+ threadId: detachCodexCatalogString(value.threadId),
199
237
  status,
200
238
  archived: value.archived,
201
239
  ...sessionId !== void 0 ? { sessionId } : {},
@@ -277,85 +315,158 @@ function requireBoundThread(entry) {
277
315
  return entry.boundThreadId;
278
316
  }
279
317
  //#endregion
280
- //#region extensions/codex/src/app-server/thread-history-page.ts
281
- const TURN_ITEM_CURSOR_PREFIX = "turn-item:";
282
- function encodeTurnItemCursor(turnCursor, itemId) {
283
- return TURN_ITEM_CURSOR_PREFIX + Buffer.from(JSON.stringify([turnCursor, itemId])).toString("base64url");
284
- }
285
- function decodeTurnItemCursor(cursor) {
286
- if (!cursor?.startsWith(TURN_ITEM_CURSOR_PREFIX)) return { turnCursor: cursor };
287
- let value;
288
- try {
289
- value = JSON.parse(Buffer.from(cursor.slice(10), "base64url").toString());
290
- } catch {
291
- throw new CatalogParamsError("invalid Codex transcript item cursor");
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);
292
359
  }
293
- if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== "string" || !value[0] || typeof value[1] !== "string" || !value[1]) throw new CatalogParamsError("invalid Codex transcript item cursor");
294
- return {
295
- turnCursor: value[0],
296
- itemId: value[1]
297
- };
298
360
  }
299
- /** Legacy stores expose only turn cursors; an item identity preserves paging across appends. */
300
- async function readLegacyCodexHistoryPage(readTurns, request, projection) {
301
- const { turnCursor, itemId } = decodeTurnItemCursor(request.cursor);
302
- const page = parseTranscriptPage(await readTurns({
303
- threadId: request.threadId,
304
- limit: 1,
305
- sortDirection: "desc",
306
- itemsView: "full",
307
- ...turnCursor ? { cursor: turnCursor } : {}
308
- }));
309
- const source = page.data.flatMap(({ items, ...turn }) => items.toReversed().map((item) => ({
310
- turnId: turn.id,
311
- item,
312
- turn
313
- })));
314
- const anchorIndex = itemId ? source.findIndex(({ item }) => item.id === itemId) : -1;
315
- if (itemId && anchorIndex < 0) throw new CatalogParamsError("Codex transcript changed; refresh the session before loading older items");
316
- const remaining = source.slice(anchorIndex + 1);
317
- const items = projection.project(remaining.slice(0, request.limit), request.limit);
318
- const result = () => {
319
- const lastSource = remaining[items.length - 1];
320
- const partial = lastSource !== void 0 && items.length < remaining.length;
321
- const nativeCursor = partial ? page.backwardsCursor : page.nextCursor;
322
- const cursor = nativeCursor ? partial ? encodeTurnItemCursor(nativeCursor, lastSource.item.id) : nativeCursor : void 0;
323
- if (partial && !cursor) throw new Error("Codex app-server did not provide a transcript continuation anchor");
324
- return {
325
- items,
326
- ...cursor ? { nextCursor: cursor } : {}
327
- };
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
328
399
  };
329
- let bounded = result();
330
- while (!projection.fits(bounded)) {
331
- if (items.length <= 1) throw new Error("Codex transcript item exceeds the safe response size");
332
- items.pop();
333
- bounded = result();
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
+ }
334
453
  }
335
- return bounded;
336
- }
337
- /** Callers authorize the thread; this reader owns native cursor and response-size semantics. */
338
- async function readCodexThreadHistoryPage(control, thread, request, projection) {
339
- if (thread.historyMode !== "paginated") return readLegacyCodexHistoryPage((params) => control.listTurnPage(params), request, projection);
340
- let limit = request.limit;
341
- for (;;) {
342
- const page = await control.listItemPage({
343
- threadId: request.threadId,
344
- limit,
345
- sortDirection: "desc",
346
- ...request.cursor ? { cursor: request.cursor } : {}
347
- });
348
- const nextCursor = readControlCursor(page.nextCursor, "transcript next response");
349
- const items = projection.project(page.data, limit);
350
- const result = {
351
- items,
352
- ...nextCursor ? { nextCursor } : {}
353
- };
354
- const fittingCount = items.length - (projection.fits(result) ? 0 : 1);
355
- if (fittingCount === page.data.length) return result;
356
- if (fittingCount < 1) throw new Error("Codex transcript item exceeds the safe response size");
357
- limit = fittingCount;
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
+ }
358
468
  }
469
+ return page;
359
470
  }
360
471
  //#endregion
361
- export { readPageParams as C, unwrapNodeInvokePayload as D, toCatalogSession as E, readGatewayParams as S, requireOnlyKeys as T, parseCatalogPage as _, CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND as a, readBoundedOptionalString as b, CatalogParamsError as c, NODE_INVOKE_TIMEOUT_MS as d, boundedCatalogString as f, normalizeLimit as g, isInteractiveThreadSource as h, CODEX_APP_SERVER_THREADS_LIST_COMMAND as i, MAX_CURSOR_LENGTH as l, filterCatalogPageByTitle as m, readLegacyCodexHistoryPage as n, CODEX_CATALOG_TRANSCRIPT_READ_COMMAND as o, catalogError as p, CODEX_APP_SERVER_THREADS_CAPABILITY as r, CODEX_LOCAL_SESSION_HOST_ID as s, readCodexThreadHistoryPage as t, MAX_TRANSCRIPT_PAGE_BYTES as u, parseJsonParams as v, requireBoundThread as w, readControlCursor as x, parseTranscriptPage as y };
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 };
@@ -1,8 +1,8 @@
1
- import { c as CatalogParamsError } from "./thread-history-page-D0JIp48V.js";
1
+ import { g as CatalogParamsError } from "./session-catalog-native-projection-ChV3cCtm.mjs";
2
2
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
4
- import { resolveStorePath } from "openclaw/plugin-sdk/session-store-paths";
5
4
  import { listSessionCatalogEntries, sessionCatalogAdoptedSessionKey, sessionCatalogAdoptedSourceKey } from "openclaw/plugin-sdk/session-catalog";
5
+ import { resolveStorePath } from "openclaw/plugin-sdk/session-store-paths";
6
6
  //#region extensions/codex/src/session-catalog-node-adoption.ts
7
7
  const CODEX_NODE_SESSION_KEY_PREFIX = "harness:codex:node-session:";
8
8
  const continueOperations = /* @__PURE__ */ new Map();
@@ -144,7 +144,7 @@ async function createOrReuseNodeAdoptedSession(params) {
144
144
  },
145
145
  afterCreate: async (entry) => {
146
146
  const storePath = resolveStorePath(params.config.session?.store, { agentId: entry.agentId });
147
- const { importCodexThreadHistoryToTranscript } = await import("./transcript-mirror-C5CKgNy6.js").then((n) => n.a);
147
+ const { importCodexThreadHistoryToTranscript } = await import("./transcript-mirror-D4qp_leP.mjs").then((n) => n.a);
148
148
  await importCodexThreadHistoryToTranscript({
149
149
  thread: params.history.thread,
150
150
  throughTurnId: params.history.throughTurnId,
@@ -1,10 +1,10 @@
1
- import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-BiodpIzq.js";
2
- import { t as CODEX_CLI_SESSION_RESUME_COMMAND } from "./node-cli-sessions-DKaOmVUh.js";
3
- import { a as lookupNodeCodexCatalogRecord } from "./session-catalog-ct-AH01I.js";
4
- import { D as unwrapNodeInvokePayload, _ as parseCatalogPage, a as CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND, c as CatalogParamsError, d as NODE_INVOKE_TIMEOUT_MS, f as boundedCatalogString, h as isInteractiveThreadSource, i as CODEX_APP_SERVER_THREADS_LIST_COMMAND, m as filterCatalogPageByTitle, p as catalogError, y as parseTranscriptPage } from "./thread-history-page-D0JIp48V.js";
5
- import { t as codexLastTerminalTurnId } from "./session-upstream-marker-D15C9NHp.js";
6
- import { n as withTimeout } from "./timeout-BVw8aaM1.js";
7
- import { createOrReuseNodeAdoptedSession, finalizeNodeAdoptedSession, findNodeAdoptedSessionEntry, nodeSessionMarker, runSessionActionExclusive } from "./session-catalog-node-adoption-B1tgDW-m.js";
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";
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";
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