@openclaw/codex 2026.9.2 → 2026.9.4

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 (120) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +29 -26
  3. package/dist/apply-CvT8tW5i.js +356 -0
  4. package/dist/{attempt-client-cleanup-Bp1ZOnk2.js → attempt-client-cleanup-DKHzbwt5.js} +38 -214
  5. package/dist/{attempt-context-CSazkWns.js → attempt-context-D44yeDII.js} +9 -7
  6. package/dist/{event-projector-usage-ZqEVbAEY.js → attempt-notifications-C9XufG6l.js} +3 -106
  7. package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-CWlKVccJ.js} +2 -2
  8. package/dist/auth-cache-key-7orQae_j.js +498 -0
  9. package/dist/auth-profile-CwzO4_RG.js +43 -0
  10. package/dist/auth-profile-selection-DFu9e167.js +45 -0
  11. package/dist/binding-connection-D3udKbIE.js +60 -0
  12. package/dist/{bounded-turn-DxGJRYbY.js → bounded-turn-C_Hneydj.js} +28 -125
  13. package/dist/build-state-BCmg9-5p.js +19 -0
  14. package/dist/{capabilities-B1mgvpP8.js → capabilities-8vx68WLH.js} +1 -1
  15. package/dist/cli-metadata.js +1 -1
  16. package/dist/client-B57KWPQx.js +4005 -0
  17. package/dist/command-dispatch-BpduNGVf.js +21 -0
  18. package/dist/{command-formatters-DSbGMXA0.js → command-formatters-lxlkNZgU.js} +4 -3
  19. package/dist/{command-handlers-DOJvGv6-.js → command-handlers-tiL9iWj7.js} +788 -135
  20. package/dist/command-rpc-CR5EOEZX.js +233 -0
  21. package/dist/{compact-Y_xBqrHN.js → compact-B_H3AOd7.js} +19 -14
  22. package/dist/config-oIORaQ5T.js +106 -0
  23. package/dist/{config-CyapYSji.js → config-options-CXMq1T-C.js} +205 -593
  24. package/dist/config-runtime-D0zGNIHu.js +11 -0
  25. package/dist/{config-utils-C57JiJrU.js → config-utils-DujwEnhg.js} +2 -4
  26. package/dist/conversation-binding-DsB4-O7U.js +900 -0
  27. package/dist/{plugin-marketplace-discovery-B7gHXJ3d.js → conversation-control-CtUu1b3m.js} +11 -143
  28. package/dist/doctor-contract-api.js +5 -5
  29. package/dist/{dynamic-tools-BwpvTxaX.js → dynamic-tools-CmN5RAip.js} +133 -76
  30. package/dist/{effective-mcp-catalog-CY9Jn4bA.js → effective-mcp-catalog-Bd73bqA8.js} +3 -3
  31. package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
  32. package/dist/ephemeral-turn-D78_VmzO.js +101 -0
  33. package/dist/{event-projector-assistant-message-B9kp6iGC.js → event-projector-assistant-message-BmBM4qBV.js} +12 -25
  34. package/dist/event-projector-items-5VhsECCO.js +200 -0
  35. package/dist/event-projector-usage-BfXmpOec.js +102 -0
  36. package/dist/{harness-Czh2Sdoc.js → harness-C7rRa7bm.js} +48 -24
  37. package/dist/harness.js +1 -1
  38. package/dist/history-rejection-B4nOXNXF.js +13 -0
  39. package/dist/incognito-session-uhrBF6wJ.js +15 -0
  40. package/dist/index.js +406 -2915
  41. package/dist/inference-context-Dr_mzvk4.js +94 -0
  42. package/dist/inference-proxy-HGXKUIre.js +311 -0
  43. package/dist/{isolated-completion-CRh-51AK.js → isolated-completion-DWVb5U2J.js} +7 -4
  44. package/dist/launch-args-RXQwn8zV.js +90 -0
  45. package/dist/{managed-binary-DcpnJF9x.js → managed-binary-D22rNEcR.js} +13 -103
  46. package/dist/managed-thread-store-D1t5jh3G.js +66 -0
  47. package/dist/media-understanding-provider.js +4 -1
  48. package/dist/migration-provider-api.js +2 -0
  49. package/dist/{model-catalog-DT5vo6qo.js → model-catalog-Dq2n8f_p.js} +6 -5
  50. package/dist/{models-CcrgSMQR.js → models-PCKOim-h.js} +3 -3
  51. package/dist/native-execution-policy-umd0tgh4.js +128 -0
  52. package/dist/native-subagent-history-DjtPloaU.js +140 -0
  53. package/dist/native-subagent-history-owner-Pcp7JuVF.js +34 -0
  54. package/dist/{native-subagent-monitor-B3bvQGcg.js → native-subagent-monitor-fQ7eIXEf.js} +115 -460
  55. package/dist/native-subagent-task-ids-BzTdT0Uw.js +387 -0
  56. package/dist/node-cli-sessions-DKaOmVUh.js +527 -0
  57. package/dist/{node-exec-server.runtime-nfbUOtUB.js → node-exec-server.runtime-Cl2vapEi.js} +55 -24
  58. package/dist/plan-7uG-Fp36.js +947 -0
  59. package/dist/plugin-activation-BYQculil.js +138 -0
  60. package/dist/{thread-resume-BLgqkUc1.js → plugin-app-cache-key-d0eKxy7b.js} +4 -52
  61. package/dist/{plugin-approval-roundtrip-aQVdyL5g.js → plugin-approval-roundtrip-Bz3FT8W5.js} +1 -1
  62. package/dist/plugin-inventory-oL4Na1ZG.js +328 -0
  63. package/dist/plugin-marketplace-discovery-P-Vndfqq.js +137 -0
  64. package/dist/{plugin-metadata-cache-BwCLTY_U.js → plugin-metadata-cache-ClPJpRio.js} +17 -9
  65. package/dist/protocol-5bh1G-H7.js +275 -0
  66. package/dist/provider-MQ8PVkuE.js +50 -0
  67. package/dist/{provider-capabilities-BpG9Ltc5.js → provider-capabilities-BvCUL69A.js} +2 -2
  68. package/dist/{rate-limits-Fx_l4eNa.js → rate-limits-CBMmWBr9.js} +1 -1
  69. package/dist/request-B7hEkBGq.js +212 -0
  70. package/dist/rpc-error-ttN_QjEm.js +30 -0
  71. package/dist/{run-attempt-BzthFQSM.js → run-attempt-CvsAAGa0.js} +664 -377
  72. package/dist/{runtime-artifact-Bh_gf6-t.js → runtime-artifact-BJ0rXBZ_.js} +27 -27
  73. package/dist/sandbox-guard-BxgyoM8M.js +166 -0
  74. package/dist/{session-binding-4Ki04sW-.js → session-binding-CI8UuilT.js} +30 -48
  75. package/dist/{session-binding-record-CyaXZvTe.js → session-binding-record-Bcvslnhf.js} +12 -26
  76. package/dist/session-catalog-adoption-tcZi1IfX.js +251 -0
  77. package/dist/session-catalog-archive-CwKg8Xz2.js +56 -0
  78. package/dist/session-catalog-ct-AH01I.js +1477 -0
  79. package/dist/session-catalog-home-id-CwhLdC03.js +18 -0
  80. package/dist/session-catalog-node-adoption-B1tgDW-m.js +182 -0
  81. package/dist/session-catalog-node-continue-Ci-DXyJP.js +238 -0
  82. package/dist/session-catalog-provenance-D-dIfRAH.js +96 -0
  83. package/dist/{session-cli-BjLhpmS1.js → session-cli-DNN_jhGc.js} +3 -2
  84. package/dist/{session-history-DWmMqiqW.js → session-history-Cz-tOOYj.js} +6 -3
  85. package/dist/{session-upstream-marker-DReTpGz6.js → session-history-import-DwyijFI6.js} +5 -50
  86. package/dist/{session-history-read-LHldwvyh.js → session-history-read-cxPUxyVV.js} +21 -7
  87. package/dist/session-history-worker-runtime.js +18 -6
  88. package/dist/session-history.worker-BeK1YOyT.js +378 -0
  89. package/dist/session-history.worker.js +1 -1
  90. package/dist/{session-initialization-BCFVnLL4.js → session-initialization-Ct0_Hzmg.js} +2 -2
  91. package/dist/{session-permission-policy-BaueHmSj.js → session-permission-policy-BBmXA8Eg.js} +4 -7
  92. package/dist/{session-retirement-DNdmYdFc.js → session-retirement-B2YfbAAT.js} +6 -5
  93. package/dist/session-upstream-marker-D15C9NHp.js +46 -0
  94. package/dist/{settled-turn-context-BOM3Y1pl.js → settled-turn-context-Du6gdUDd.js} +9 -9
  95. package/dist/{settled-turn-finalizer-BI-b1sry.js → settled-turn-finalizer-Dn91stmc.js} +8 -7
  96. package/dist/shared-client-CscigXXL.js +3109 -0
  97. package/dist/{side-question-B6DWAw1A.js → side-question-BGMJQf4U.js} +65 -170
  98. package/dist/source-CElXU0Oy.js +518 -0
  99. package/dist/thread-archive-guard-DfpBr-Sz.js +53 -0
  100. package/dist/thread-history-page-D0JIp48V.js +361 -0
  101. package/dist/{thread-lifecycle-DPK30jad.js → thread-lifecycle-DXl1-I6b.js} +187 -639
  102. package/dist/{thread-ownership-CbucAmmp.js → thread-ownership-BsDRTsyp.js} +13 -15
  103. package/dist/thread-policy-BuEQfE0g.js +54 -0
  104. package/dist/thread-resume-DsDOZpFg.js +52 -0
  105. package/dist/timeout-BVw8aaM1.js +33 -0
  106. package/dist/transcript-history-projection-v17wXgdK.js +238 -0
  107. package/dist/{transcript-mirror-_njEB84z.js → transcript-mirror-C5CKgNy6.js} +50 -260
  108. package/dist/{transcript-mirror-attestation-Byl34PC-.js → transcript-mirror-attestation-DibE0krH.js} +17 -4
  109. package/dist/{transport-stdio-CzTngV0j.js → transport-stdio-BGjHoYLr.js} +73 -43
  110. package/dist/{upstream-session-fork-1fwbNKzQ.js → upstream-session-fork-BZerMte_.js} +27 -19
  111. package/dist/{usage-i9fv5-4m.js → usage-tCk-mg_x.js} +4 -3
  112. package/dist/version-omm6IPI3.js +12 -0
  113. package/dist/{web-search-provider.runtime-DKQn67A7.js → web-search-provider.runtime-B7bGbGWq.js} +3 -3
  114. package/openclaw.plugin.json +23 -1
  115. package/package.json +4 -4
  116. package/dist/request-C8H22rPi.js +0 -475
  117. package/dist/session-catalog-B47uwekb.js +0 -3272
  118. package/dist/session-history.worker-zZVcx0ME.js +0 -267
  119. package/dist/shared-client-CKhX2kFt.js +0 -7505
  120. package/dist/thread-policy-CTalhWFy.js +0 -105
@@ -0,0 +1,361 @@
1
+ import { n as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, t as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES } from "./protocol-5bh1G-H7.js";
2
+ import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
+ //#region extensions/codex/src/session-catalog-parsing.ts
5
+ const DEFAULT_PAGE_LIMIT = 50;
6
+ const CODEX_APP_SERVER_THREADS_CAPABILITY = "codex-app-server-threads";
7
+ const CODEX_APP_SERVER_THREADS_LIST_COMMAND = "codex.appServer.threads.list.v1";
8
+ const CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND = "codex.appServer.thread.turns.list.v1";
9
+ const CODEX_CATALOG_TRANSCRIPT_READ_COMMAND = "codex.sessionCatalog.transcript.read.v1";
10
+ const CODEX_LOCAL_SESSION_HOST_ID = "gateway:local";
11
+ const NODE_INVOKE_TIMEOUT_MS = 65e3;
12
+ const MAX_SEARCH_LENGTH = 500;
13
+ const MAX_CURSOR_LENGTH = 4096;
14
+ const MAX_CURSOR_COUNT = 100;
15
+ const MAX_HOST_ID_LENGTH = 256;
16
+ const MAX_CWD_LENGTH = 4096;
17
+ const MAX_SESSION_NAME_LENGTH = 500;
18
+ const MAX_SESSION_PREVIEW_LENGTH = 500;
19
+ const MAX_SESSION_KEY_LENGTH = 1024;
20
+ const MAX_METADATA_LENGTH = 500;
21
+ const MAX_ACTIVE_FLAGS = 16;
22
+ const MAX_TRANSCRIPT_PAGE_BYTES = 20971520;
23
+ var CatalogParamsError = class extends Error {};
24
+ function readControlCursor(value, label) {
25
+ if (value === void 0 || value === null) return;
26
+ if (typeof value !== "string" || !value.trim() || value.length > 4096) throw new CatalogParamsError(`invalid Codex session catalog ${label} cursor`);
27
+ return value;
28
+ }
29
+ function boundedCatalogString(value, maxLength, overflow = "omit") {
30
+ if (typeof value !== "string") return;
31
+ const normalized = value.trim();
32
+ if (!normalized) return;
33
+ if (normalized.length <= maxLength) return normalized;
34
+ return overflow === "truncate" ? truncateUtf16Safe(normalized, maxLength) : void 0;
35
+ }
36
+ function catalogPreview(value, sanitize) {
37
+ if (typeof value !== "string") return;
38
+ return boundedCatalogString(sanitize(value.replace(/\s+/g, " ")), MAX_SESSION_PREVIEW_LENGTH, "truncate");
39
+ }
40
+ function normalizeInteractiveThreadSource(source) {
41
+ if (CODEX_INTERACTIVE_THREAD_SOURCE_KINDS.some((kind) => kind === source) || CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source)) return source;
42
+ if (isRecord(source) && CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source.custom)) return source.custom;
43
+ }
44
+ function isInteractiveThreadSource(source) {
45
+ return normalizeInteractiveThreadSource(source) !== void 0;
46
+ }
47
+ function toCatalogSession(thread, archived, sanitize) {
48
+ const source = normalizeInteractiveThreadSource(thread.source);
49
+ if (!source) return;
50
+ const record = thread;
51
+ const threadId = boundedCatalogString(thread.id, 256);
52
+ 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;
58
+ 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);
61
+ 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");
64
+ const gitBranch = boundedCatalogString(gitInfo?.branch, MAX_METADATA_LENGTH, "truncate");
65
+ return {
66
+ threadId,
67
+ status: thread.status?.type ?? "notLoaded",
68
+ archived,
69
+ ...sessionId ? { sessionId } : {},
70
+ ...thread.name === null ? { name: null } : name ? { name } : {},
71
+ ...fallbackName ? { fallbackName } : {},
72
+ ...cwd ? { cwd } : {},
73
+ ...activeFlags?.length ? { activeFlags } : {},
74
+ ...typeof thread.createdAt === "number" && Number.isFinite(thread.createdAt) ? { createdAt: thread.createdAt } : {},
75
+ ...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 } : {},
77
+ source,
78
+ ...modelProvider ? { modelProvider } : {},
79
+ ...cliVersion ? { cliVersion } : {},
80
+ ...gitBranch ? { gitBranch } : {}
81
+ };
82
+ }
83
+ function normalizeLimit(value, key) {
84
+ if (value === void 0) return DEFAULT_PAGE_LIMIT;
85
+ if (!Number.isInteger(value) || value < 1 || value > 100) throw new CatalogParamsError(`${key} must be an integer from 1 to 100`);
86
+ return value;
87
+ }
88
+ function readBoundedOptionalString(params, key, maxLength) {
89
+ const value = params[key];
90
+ if (value === void 0) return;
91
+ if (typeof value !== "string") throw new CatalogParamsError(`${key} must be a string`);
92
+ const trimmed = value.trim();
93
+ if (!trimmed) return;
94
+ if (trimmed.length > maxLength) throw new CatalogParamsError(`${key} must be at most ${maxLength} characters`);
95
+ return trimmed;
96
+ }
97
+ function requireOnlyKeys(params, allowed) {
98
+ const unknown = Object.keys(params).find((key) => !allowed.has(key));
99
+ if (unknown) throw new CatalogParamsError(`unknown Codex session catalog parameter: ${unknown}`);
100
+ }
101
+ function readPageParams(value) {
102
+ if (!isRecord(value)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
103
+ const params = value;
104
+ requireOnlyKeys(params, /* @__PURE__ */ new Set([
105
+ "cursor",
106
+ "limit",
107
+ "searchTerm",
108
+ "cwd"
109
+ ]));
110
+ const cursor = readBoundedOptionalString(params, "cursor", MAX_CURSOR_LENGTH);
111
+ const searchTerm = readBoundedOptionalString(params, "searchTerm", MAX_SEARCH_LENGTH);
112
+ const cwd = readBoundedOptionalString(params, "cwd", MAX_CWD_LENGTH);
113
+ return {
114
+ limit: normalizeLimit(params.limit, "limit"),
115
+ ...cursor ? { cursor } : {},
116
+ ...searchTerm ? { searchTerm } : {},
117
+ ...cwd ? { cwd } : {}
118
+ };
119
+ }
120
+ function readGatewayParams(value) {
121
+ if (value !== void 0 && !isRecord(value)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
122
+ const params = isRecord(value) ? value : {};
123
+ requireOnlyKeys(params, /* @__PURE__ */ new Set([
124
+ "search",
125
+ "limitPerHost",
126
+ "hostIds",
127
+ "cursors"
128
+ ]));
129
+ const search = readBoundedOptionalString(params, "search", MAX_SEARCH_LENGTH);
130
+ let hostIds;
131
+ if (params.hostIds !== void 0) {
132
+ if (!Array.isArray(params.hostIds) || params.hostIds.length > 100) throw new CatalogParamsError(`hostIds must contain at most 100 host ids`);
133
+ hostIds = [...new Set(params.hostIds.map((hostId) => readHostId(hostId)))];
134
+ }
135
+ let cursors;
136
+ if (params.cursors !== void 0) {
137
+ if (!isRecord(params.cursors)) throw new CatalogParamsError("cursors must be an object");
138
+ const entries = Object.entries(params.cursors);
139
+ if (entries.length > MAX_CURSOR_COUNT) throw new CatalogParamsError(`cursors may contain at most ${MAX_CURSOR_COUNT} hosts`);
140
+ cursors = {};
141
+ for (const [hostId, cursor] of entries) {
142
+ const normalizedHostId = hostId.trim();
143
+ 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}`);
144
+ if (typeof cursor !== "string" || !cursor.trim() || cursor.trim().length > 4096) throw new CatalogParamsError(`invalid cursor for Codex session catalog host: ${hostId}`);
145
+ cursors[normalizedHostId] = cursor.trim();
146
+ }
147
+ }
148
+ return {
149
+ limitPerHost: normalizeLimit(params.limitPerHost, "limitPerHost"),
150
+ ...search ? { search } : {},
151
+ ...hostIds && hostIds.length > 0 ? { hostIds } : {},
152
+ ...cursors && Object.keys(cursors).length > 0 ? { cursors } : {}
153
+ };
154
+ }
155
+ function readHostId(value) {
156
+ if (typeof value !== "string") throw new CatalogParamsError("Codex session catalog host ids must be strings");
157
+ const hostId = value.trim();
158
+ if (hostId.length === 0 || hostId.length > MAX_HOST_ID_LENGTH || !hostId.startsWith("gateway:") && !hostId.startsWith("node:")) throw new CatalogParamsError(`invalid Codex session catalog host id: ${value}`);
159
+ return hostId;
160
+ }
161
+ function parseJsonParams(paramsJSON) {
162
+ if (!paramsJSON?.trim()) return {};
163
+ try {
164
+ return JSON.parse(paramsJSON);
165
+ } catch (error) {
166
+ throw new Error("Codex session catalog parameters must be valid JSON", { cause: error });
167
+ }
168
+ }
169
+ function parseOptionalCatalogString(value, field, maxLength) {
170
+ if (value === void 0) return;
171
+ if (typeof value !== "string" || value.length > maxLength) throw new Error(`Codex session catalog returned an invalid ${field}`);
172
+ return value;
173
+ }
174
+ function parseCatalogSession(value, options = {}) {
175
+ 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");
176
+ const status = parseOptionalCatalogString(value.status, "status", 64);
177
+ if (!status?.trim()) throw new Error("Codex session catalog returned an invalid status");
178
+ if (value.activeFlags !== void 0 && !Array.isArray(value.activeFlags)) throw new Error("Codex session catalog returned invalid active flags");
179
+ if (Array.isArray(value.activeFlags) && value.activeFlags.length > MAX_ACTIVE_FLAGS) throw new Error("Codex session catalog returned too many active flags");
180
+ const activeFlags = Array.isArray(value.activeFlags) ? value.activeFlags.map((entry) => {
181
+ const flag = parseOptionalCatalogString(entry, "active flag", 128);
182
+ if (flag === void 0) throw new Error("Codex session catalog returned an invalid active flag");
183
+ return flag;
184
+ }) : void 0;
185
+ const sessionId = parseOptionalCatalogString(value.sessionId, "session id", 256);
186
+ const name = value.name === null ? null : parseOptionalCatalogString(value.name, "session name", MAX_SESSION_NAME_LENGTH);
187
+ const fallbackName = parseOptionalCatalogString(value.fallbackName, "session fallback name", MAX_SESSION_PREVIEW_LENGTH);
188
+ const cwd = parseOptionalCatalogString(value.cwd, "cwd", MAX_CWD_LENGTH);
189
+ const source = parseOptionalCatalogString(value.source, "source", MAX_METADATA_LENGTH);
190
+ const modelProvider = parseOptionalCatalogString(value.modelProvider, "model provider", MAX_METADATA_LENGTH);
191
+ const cliVersion = parseOptionalCatalogString(value.cliVersion, "CLI version", MAX_METADATA_LENGTH);
192
+ const gitBranch = parseOptionalCatalogString(value.gitBranch, "Git branch", MAX_METADATA_LENGTH);
193
+ const sessionKey = options.allowSessionKey ? parseOptionalCatalogString(value.sessionKey, "OpenClaw session key", MAX_SESSION_KEY_LENGTH) : void 0;
194
+ const createdAt = asFiniteNumber(value.createdAt);
195
+ const updatedAt = asFiniteNumber(value.updatedAt);
196
+ const recencyAt = value.recencyAt === null ? null : asFiniteNumber(value.recencyAt);
197
+ return {
198
+ threadId: value.threadId,
199
+ status,
200
+ archived: value.archived,
201
+ ...sessionId !== void 0 ? { sessionId } : {},
202
+ ...name !== void 0 ? { name } : {},
203
+ ...fallbackName !== void 0 ? { fallbackName } : {},
204
+ ...cwd !== void 0 ? { cwd } : {},
205
+ ...activeFlags && activeFlags.length > 0 ? { activeFlags } : {},
206
+ ...createdAt !== void 0 ? { createdAt } : {},
207
+ ...updatedAt !== void 0 ? { updatedAt } : {},
208
+ ...recencyAt !== void 0 ? { recencyAt } : {},
209
+ ...source !== void 0 ? { source } : {},
210
+ ...modelProvider !== void 0 ? { modelProvider } : {},
211
+ ...cliVersion !== void 0 ? { cliVersion } : {},
212
+ ...gitBranch !== void 0 ? { gitBranch } : {},
213
+ ...sessionKey !== void 0 ? { sessionKey } : {}
214
+ };
215
+ }
216
+ function parseCatalogPage(value, options = {}) {
217
+ if (!isRecord(value) || !Array.isArray(value.sessions) || value.sessions.length > 100) throw new Error("Codex session catalog returned an invalid page");
218
+ const nextCursor = parseOptionalCatalogString(value.nextCursor, "next cursor", MAX_CURSOR_LENGTH);
219
+ const backwardsCursor = parseOptionalCatalogString(value.backwardsCursor, "backwards cursor", MAX_CURSOR_LENGTH);
220
+ return {
221
+ sessions: value.sessions.map((session) => parseCatalogSession(session, options)),
222
+ ...nextCursor ? { nextCursor } : {},
223
+ ...backwardsCursor ? { backwardsCursor } : {}
224
+ };
225
+ }
226
+ function filterCatalogPageByTitle(page, searchTerm) {
227
+ if (!searchTerm) return page;
228
+ return {
229
+ ...page,
230
+ sessions: page.sessions.filter((session) => (session.name ?? session.fallbackName)?.toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase()))
231
+ };
232
+ }
233
+ function unwrapNodeInvokePayload(value) {
234
+ if (!isRecord(value)) return value;
235
+ if (typeof value.payloadJSON === "string" && value.payloadJSON.trim()) try {
236
+ return JSON.parse(value.payloadJSON);
237
+ } catch (error) {
238
+ throw new Error("Codex node returned malformed session catalog JSON", { cause: error });
239
+ }
240
+ return "payload" in value ? value.payload : value;
241
+ }
242
+ function catalogErrorDetail(error) {
243
+ if (error instanceof Error) return error.message.trim();
244
+ if (typeof error === "string") return error.trim();
245
+ if (error && typeof error === "object" && "message" in error) {
246
+ const message = error.message;
247
+ return typeof message === "string" ? message.trim() : "";
248
+ }
249
+ return "";
250
+ }
251
+ function catalogError(code, error) {
252
+ const summary = {
253
+ APP_SERVER_UNAVAILABLE: "Codex app-server is unavailable on this host",
254
+ NODE_INVOKE_FAILED: "The paired node could not return its Codex session catalog",
255
+ NODE_LIST_FAILED: "Paired nodes could not be listed"
256
+ }[code] ?? "Codex session catalog request failed";
257
+ const detail = code === "NODE_LIST_FAILED" ? catalogErrorDetail(error) : "";
258
+ return {
259
+ code,
260
+ message: detail && detail !== summary ? `${summary}: ${detail}` : summary
261
+ };
262
+ }
263
+ function parseTranscriptPage(value) {
264
+ if (!isRecord(value) || !Array.isArray(value.data) || value.data.length > 50 || value.data.some((turn) => !isRecord(turn) || !Array.isArray(turn.items) || turn.items.some((item) => !isRecord(item)))) throw new Error("Codex app-server returned an invalid transcript page");
265
+ const nextCursor = readControlCursor(value.nextCursor, "transcript next response");
266
+ const backwardsCursor = readControlCursor(value.backwardsCursor, "transcript backwards response");
267
+ const page = {
268
+ data: value.data,
269
+ ...nextCursor ? { nextCursor } : {},
270
+ ...backwardsCursor ? { backwardsCursor } : {}
271
+ };
272
+ if (Buffer.byteLength(JSON.stringify(page), "utf8") > 20971520) throw new Error("Codex app-server transcript page exceeds the safe response size");
273
+ return page;
274
+ }
275
+ function requireBoundThread(entry) {
276
+ if (!entry.boundThreadId) throw new CatalogParamsError("Codex adoption is missing its bound thread. Retry.");
277
+ return entry.boundThreadId;
278
+ }
279
+ //#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");
292
+ }
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
+ }
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
+ };
328
+ };
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();
334
+ }
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;
358
+ }
359
+ }
360
+ //#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 };