@openclaw/codex 2026.9.5 → 2026.9.6

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/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-Eem_WGqY.mjs} +5 -5
  2. package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-DDOi8uNx.mjs} +22 -28
  3. package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-CEv1cKwF.mjs} +58 -43
  4. package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +331 -0
  5. package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-B2mpaI9D.mjs} +9 -81
  6. package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
  7. package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
  8. package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-ThoatDcb.mjs} +1 -1
  9. package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-yoHrABt-.mjs} +4 -4
  10. package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-B2HScEgT.mjs} +138 -32
  11. package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-C7EnDVgr.mjs} +1 -1
  12. package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-CDXOOFdZ.mjs} +1 -1
  13. package/dist/.setup/{client-vXs2929Q.mjs → client-Cs08OXVQ.mjs} +583 -559
  14. package/dist/.setup/client-catalog-response-BMgt_4q4.mjs +285 -0
  15. package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-B4JuOsOk.mjs} +8 -4
  16. package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-Bmqvr9tO.mjs} +8 -4
  17. package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-DW7Lx9oH.mjs} +106 -172
  18. package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-DixIj3HW.mjs} +36 -21
  19. package/dist/.setup/{compact-C3i3qlzj.mjs → compact-Du5UvtxA.mjs} +14 -21
  20. package/dist/.setup/{config-CedDWjM-.mjs → config-BoTP_mrL.mjs} +3 -3
  21. package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-BvaRs51b.mjs} +46 -30
  22. package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C8Rw1m1m.mjs} +1 -1
  23. package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-BEReZ6go.mjs} +35 -120
  24. package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-DP-gMrBP.mjs} +21 -32
  25. package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-uK9Jomlc.mjs} +28 -67
  26. package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-BDXl-8Cw.mjs} +848 -578
  27. package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CvnvnGIe.mjs} +3 -3
  28. package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-poidXgek.mjs} +9 -6
  29. package/dist/.setup/{event-projector-assistant-message-DNUR1s0A.mjs → event-projector-assistant-message-BsruvNrH.mjs} +2 -4
  30. package/dist/.setup/{event-projector-items-DyTQ_XqL.mjs → event-projector-items-C6L_5ZiT.mjs} +42 -8
  31. package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-CnBS8Wa3.mjs} +1 -1
  32. package/dist/.setup/{harness-rxaaoN-o.mjs → harness-a_MsE4-_.mjs} +23 -17
  33. package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D96l9-ew.mjs} +1 -1
  34. package/dist/.setup/inference-proxy-b-aJMSxm.mjs +601 -0
  35. package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-BIZFhTNG.mjs} +17 -10
  36. package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
  37. package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-BnshlFag.mjs} +13 -2
  38. package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-CfXJf9Ay.mjs} +9 -10
  39. package/dist/.setup/{models-BDFgm_G-.mjs → models-KnqBv0hE.mjs} +3 -3
  40. package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-rWbGbMn3.mjs} +4 -4
  41. package/dist/.setup/{native-subagent-history-YXaL6dMd.mjs → native-subagent-history-0nYYgo0k.mjs} +26 -13
  42. package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-D3filLY2.mjs} +145 -317
  43. package/dist/.setup/{native-subagent-task-ids-DsuOonKv.mjs → native-subagent-task-ids-wb8CKZGN.mjs} +69 -39
  44. package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-r3avj02l.mjs} +86 -68
  45. package/dist/.setup/node-exec-server.runtime-BDwWXVpK.mjs +247 -0
  46. package/dist/.setup/{plan-xD7WKYTM.mjs → plan-CN3VwfNU.mjs} +74 -76
  47. package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-DT3MNtqj.mjs} +7 -16
  48. package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-B2CsSdnV.mjs} +4 -20
  49. package/dist/.setup/{plugin-approval-roundtrip-CjfzafAZ.mjs → plugin-approval-roundtrip-C0MZzCuP.mjs} +1 -1
  50. package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-BoRei8Z4.mjs} +16 -7
  51. package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-CDOi8IFs.mjs} +4 -1
  52. package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-Ctmo83k_.mjs} +224 -154
  53. package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
  54. package/dist/.setup/{provider-fFh_-VR3.mjs → provider-BOsxQHOM.mjs} +9 -5
  55. package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-BfE88FZ5.mjs} +31 -3
  56. package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-CMU3DUD0.mjs} +116 -137
  57. package/dist/.setup/{request-BioXJLYa.mjs → request-D2L0zMrq.mjs} +23 -15
  58. package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-BHu11r7h.mjs} +1197 -617
  59. package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-CLZ8udh-.mjs} +29 -45
  60. package/dist/.setup/{sandbox-guard-BBP-RbTf.mjs → sandbox-guard-C2sRMOEY.mjs} +1 -1
  61. package/dist/.setup/{session-binding-_0W_fHRr.mjs → session-binding-Cm0apEbd.mjs} +3 -32
  62. package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-BGoz8wOK.mjs} +22 -3
  63. package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-BlB5EvIS.mjs} +48 -45
  64. package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-Pno1xGcl.mjs} +482 -182
  65. package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BI6UTDZT.mjs} +57 -25
  66. package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-lHBqzhaO.mjs} +6 -6
  67. package/dist/.setup/{session-catalog-events-jMcYfQyd.mjs → session-catalog-events-Bj6j94E_.mjs} +122 -25
  68. package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-B9_VQIUz.mjs} +178 -78
  69. package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-hcdz07yN.mjs} +2 -2
  70. package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-Dgh8ORJm.mjs} +5 -2
  71. package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-native-projection-DowriLid.mjs} +30 -13
  72. package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-ITddWx_X.mjs} +24 -12
  73. package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-6g6qi4A9.mjs} +22 -13
  74. package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-zK_PUsiE.mjs} +13 -5
  75. package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-irrD-uo7.mjs} +4 -4
  76. package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-BrqhSCf9.mjs} +17 -22
  77. package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-D-3wAgOP.mjs} +4 -4
  78. package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-CaCh0xF_.mjs} +5 -18
  79. package/dist/.setup/{session-initialization-DH1z6fXn.mjs → session-initialization-rcgbZiid.mjs} +2 -2
  80. package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-BI1QK_98.mjs} +2 -2
  81. package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-BH-S6qkJ.mjs} +25 -6
  82. package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-DiAi6Kx6.mjs} +8 -8
  83. package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DA4VR4Eb.mjs} +59 -89
  84. package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-BJ1wSDcB.mjs} +147 -211
  85. package/dist/.setup/{source-Bjp4UQij.mjs → source-CUzJq5WN.mjs} +9 -9
  86. package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
  87. package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
  88. package/dist/.setup/{thread-history-page-BTx-4xsg.mjs → thread-history-page-DoVpnHim.mjs} +1 -1
  89. package/dist/.setup/{thread-lifecycle-Cik28qWn.mjs → thread-lifecycle-B3mfz1TG.mjs} +172 -2271
  90. package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-DcTtAcXj.mjs} +4 -2
  91. package/dist/.setup/{thread-policy-Cjs4B8xf.mjs → thread-policy-DGuQsuFC.mjs} +19 -3
  92. package/dist/.setup/thread-requests-BLvGkP2R.mjs +2205 -0
  93. package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-DIBXwOpE.mjs} +6 -6
  94. package/dist/.setup/{timeout-DZF05XrR.mjs → timeout-C910MdAB.mjs} +19 -2
  95. package/dist/.setup/{transcript-history-projection-DHNBDhCU.mjs → transcript-history-projection-ZZpkFkJ_.mjs} +94 -64
  96. package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-BtHDBp1G.mjs} +218 -198
  97. package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-h2VHOskC.mjs} +135 -55
  98. package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-BUr4OUbC.mjs} +44 -36
  99. package/dist/.setup/{usage-BOgBEKso.mjs → usage-BML0r-ua.mjs} +5 -4
  100. package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-DUMbefVY.mjs} +4 -4
  101. package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-CDKlN-Rv.mjs} +4 -3
  102. package/dist/api.js +23 -12
  103. package/dist/catalog-page-worker-entrypoint.js +12 -0
  104. package/dist/catalog-page.worker.js +9 -0
  105. package/dist/cli-metadata.js +1 -1
  106. package/dist/doctor-contract-api.js +2 -2
  107. package/dist/harness.js +1 -1
  108. package/dist/index.js +221 -170
  109. package/dist/media-understanding-provider.js +2 -2
  110. package/dist/migration-provider-api.js +1 -1
  111. package/dist/provider-discovery.js +1 -1
  112. package/dist/session-history-worker-runtime.js +15 -32
  113. package/dist/session-history.worker.js +1 -1
  114. package/package.json +9 -6
  115. package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
  116. package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
  117. package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
  118. package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
  119. package/dist/.setup/version-CoqzXPgK.mjs +0 -12
  120. package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-umd0tgh4.mjs} +1 -1
@@ -1,16 +1,18 @@
1
- import { p as sessionBindingIdentity } from "./session-binding-record-TH3xA0zj.mjs";
2
- import { _ as resolveCodexAppServerUserHomeDir, f as assertCodexThreadForkParams, g as resolveCodexAppServerLocalHomeDir, h as resolveCodexAppServerHomeDir } from "./config-security-BRQ2mgW9.mjs";
1
+ import { m as sessionBindingIdentity } from "./session-binding-record-BGoz8wOK.mjs";
2
+ import { d as resolveCodexAppServerHomeDir, f as resolveCodexAppServerLocalHomeDir, p as resolveCodexAppServerUserHomeDir } from "./config-security-BEReZ6go.mjs";
3
3
  import { d as readCodexPluginConfig } from "./config-parsing-CcB9iPoq.mjs";
4
- import { A as parseTranscriptPage, B as unwrapNodeInvokePayload, E as isInteractiveThreadSource, I as requireOnlyKeys, M as readControlCursor, N as readGatewayParams, O as parseCatalogPage, P as readPageParams, S as catalogError, T as filterCatalogPageByTitle, _ as MAX_CURSOR_LENGTH, b as NODE_INVOKE_TIMEOUT_MS, d as CODEX_APP_SERVER_THREADS_CAPABILITY, f as CODEX_APP_SERVER_THREADS_LIST_COMMAND, g as CatalogParamsError, h as CODEX_LOCAL_SESSION_HOST_ID, j as readBoundedOptionalString, k as parseJsonParams, m as CODEX_CATALOG_TRANSCRIPT_READ_COMMAND, p as CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND, y as MAX_TRANSCRIPT_PAGE_BYTES } from "./session-catalog-native-projection-ChV3cCtm.mjs";
5
- import { a as isCodexThreadReadMissingError, i as CodexAppServerRpcError, n as withTimeout } from "./timeout-DZF05XrR.mjs";
6
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-_vXcZGSx.mjs";
7
- import { r as compareCodexCatalogRows } from "./session-catalog-index-order-Cc5BzlQr.mjs";
8
- import { n as readLegacyCodexHistoryPage, t as readCodexThreadHistoryPage } from "./thread-history-page-BTx-4xsg.mjs";
9
- import { i as projectCodexUserItemText } from "./transcript-history-projection-DHNBDhCU.mjs";
4
+ import { A as parseCatalogPage, D as filterCatalogPageByTitle, F as readGatewayParams, H as unwrapNodeInvokePayload, I as readPageParams, M as parseTranscriptPage, N as readBoundedOptionalString, O as isInteractiveThreadSource, P as readControlCursor, R as requireOnlyKeys, S as NODE_INVOKE_TIMEOUT_MS, _ as CODEX_LOCAL_SESSION_HOST_ID, g as CODEX_CATALOG_TRANSCRIPT_READ_COMMAND, h as CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND, j as parseJsonParams, m as CODEX_APP_SERVER_THREADS_LIST_COMMAND, p as CODEX_APP_SERVER_THREADS_CAPABILITY, v as CatalogParamsError, w as catalogError, x as MAX_TRANSCRIPT_PAGE_BYTES, y as MAX_CURSOR_LENGTH } from "./session-catalog-native-projection-DowriLid.mjs";
5
+ import { n as assertCodexThreadForkParams } from "./protocol-CANUwXJ3.mjs";
6
+ import { c as codexCatalogHomeIdFromCanonicalPath, m as hasActiveSharedCodexAppServerWork, o as readCodexSessionMeta, p as getSharedCodexAppServerClientState, t as codexCatalogResidentHomeKey } from "./session-catalog-events-Bj6j94E_.mjs";
7
+ import { i as withTimeout, o as CodexAppServerRpcError, s as isCodexThreadReadMissingError } from "./timeout-C910MdAB.mjs";
8
+ import { t as CODEX_CONTROL_METHODS } from "./capabilities-CDXOOFdZ.mjs";
9
+ import { r as compareCodexCatalogRows } from "./session-catalog-index-order-hcdz07yN.mjs";
10
+ import { n as readLegacyCodexHistoryPage, t as readCodexThreadHistoryPage } from "./thread-history-page-DoVpnHim.mjs";
11
+ import { i as projectCodexUserItemText } from "./transcript-history-projection-ZZpkFkJ_.mjs";
10
12
  import { r as codexUpstreamContinueResult } from "./session-upstream-marker-D15C9NHp.mjs";
11
- import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-BOxKP7db.mjs";
12
- import { c as readCodexSessionMeta, o as codexCatalogHomeIdFromCanonicalPath, t as codexCatalogResidentHomeKey } from "./session-catalog-events-jMcYfQyd.mjs";
13
- import { a as setCodexCatalogConnectionHomeResolver } from "./binding-connection-Bm38niE8.mjs";
13
+ import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-B2CsSdnV.mjs";
14
+ import { n as findCodexAppServerSpawnError } from "./spawn-error-CL3n6MAa.mjs";
15
+ import { a as setCodexCatalogConnectionHomeResolver } from "./binding-connection-ThoatDcb.mjs";
14
16
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
15
17
  import { randomUUID } from "node:crypto";
16
18
  import { embeddedAgentLog, resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-harness-registration";
@@ -18,6 +20,7 @@ import { listAgentIds, resolveAgentDir, resolveDefaultAgentId, resolveSessionAge
18
20
  import { z } from "zod";
19
21
  import path from "node:path";
20
22
  import fs from "node:fs/promises";
23
+ import { canonicalPathFromExistingAncestor } from "openclaw/plugin-sdk/file-access-runtime";
21
24
  import { scheduler } from "node:timers/promises";
22
25
  import { AsyncLocalStorage } from "node:async_hooks";
23
26
  import { isMainThread, threadId } from "node:worker_threads";
@@ -337,6 +340,110 @@ var CodexCatalogAvailability = class {
337
340
  }
338
341
  };
339
342
  //#endregion
343
+ //#region extensions/codex/src/session-catalog-node-snapshot.ts
344
+ /** One query-compatible native page per node, owned by the registered catalog provider. */
345
+ var CodexCatalogNodeSnapshots = class {
346
+ constructor() {
347
+ this.generation = 0;
348
+ this.inventoryGeneration = 0;
349
+ this.configGeneration = 0;
350
+ this.nodes = /* @__PURE__ */ new Map();
351
+ }
352
+ start(config) {
353
+ if (this.config !== config) {
354
+ this.nodes.clear();
355
+ this.config = config;
356
+ this.configGeneration = this.generation + 1;
357
+ this.inventoryGeneration = this.configGeneration;
358
+ }
359
+ return ++this.generation;
360
+ }
361
+ observe(generation, nodes) {
362
+ if (generation < this.inventoryGeneration) return;
363
+ this.inventoryGeneration = generation;
364
+ const connected = new Map(nodes.filter((node) => node.connected).map((node) => [node.nodeId, node]));
365
+ for (const [nodeId, publication] of this.nodes) {
366
+ const node = connected.get(nodeId);
367
+ if (!node || node.connectedAtMs !== publication.connection) this.nodes.delete(nodeId);
368
+ }
369
+ for (const node of connected.values()) if (!this.nodes.has(node.nodeId)) this.nodes.set(node.nodeId, {
370
+ connection: node.connectedAtMs,
371
+ generation: 0
372
+ });
373
+ }
374
+ forNode(node, generation, key) {
375
+ let publication = this.nodes.get(node.nodeId);
376
+ if (!publication) {
377
+ publication = {
378
+ connection: node.connectedAtMs,
379
+ generation: 0
380
+ };
381
+ if (generation >= this.inventoryGeneration) this.nodes.set(node.nodeId, publication);
382
+ }
383
+ const valid = () => generation >= this.configGeneration && this.nodes.get(node.nodeId) === publication && publication.connection === node.connectedAtMs;
384
+ return {
385
+ read: () => valid() && publication.snapshot?.key === key ? publication.snapshot : void 0,
386
+ publish: (host) => {
387
+ if (!valid() || generation < publication.generation) return false;
388
+ publication.generation = generation;
389
+ publication.snapshot = node.connected && host.connected ? {
390
+ key,
391
+ generation,
392
+ host
393
+ } : void 0;
394
+ return true;
395
+ },
396
+ isCurrent: (snapshot) => valid() && publication.snapshot === snapshot,
397
+ valid
398
+ };
399
+ }
400
+ };
401
+ function createNodeHostPublication(publication, adopted, sourceKey, onHost, signal, partial, waitUntil) {
402
+ let publishedSnapshot;
403
+ let publishedHost;
404
+ const project = (host) => ({
405
+ ...host,
406
+ sessions: host.sessions.map((session) => {
407
+ const entry = session.sourceHomeId ? adopted.get(sourceKey(host.hostId, session.threadId, session.sourceHomeId)) : void 0;
408
+ return entry ? {
409
+ ...session,
410
+ sessionKey: entry.key
411
+ } : session;
412
+ })
413
+ });
414
+ const emit = (host) => {
415
+ publishedHost = project(host);
416
+ return onHost?.(publishedHost);
417
+ };
418
+ return {
419
+ project,
420
+ readPublished: () => publishedHost,
421
+ publish: (host) => {
422
+ if (signal?.aborted) return partial ? void 0 : onHost?.(project(host));
423
+ if (!publication.valid()) return;
424
+ if (publication.publish(host)) {
425
+ publishedSnapshot = publication.read();
426
+ return emit(host);
427
+ }
428
+ const latest = publication.read();
429
+ return emit(latest?.host ?? host);
430
+ },
431
+ publishCached: (snapshot) => {
432
+ if (signal?.aborted || snapshot === publishedSnapshot || !publication.isCurrent(snapshot)) return;
433
+ const completion = createDeferred();
434
+ completion.promise.catch(() => void 0);
435
+ try {
436
+ waitUntil?.(completion.promise);
437
+ completion.resolve(emit(snapshot.host));
438
+ publishedSnapshot = snapshot;
439
+ } catch (error) {
440
+ completion.reject(error);
441
+ throw error;
442
+ }
443
+ }
444
+ };
445
+ }
446
+ //#endregion
340
447
  //#region extensions/codex/src/session-catalog-node-lookup.ts
341
448
  async function lookupNodeCodexCatalogRecord(params) {
342
449
  const deadline = performance.now() + NODE_INVOKE_TIMEOUT_MS;
@@ -347,6 +454,8 @@ async function lookupNodeCodexCatalogRecord(params) {
347
454
  return timeoutMs;
348
455
  };
349
456
  let cursor;
457
+ let sourceHomeId = params.sourceHomeId;
458
+ let firstPage = true;
350
459
  const seenCursors = /* @__PURE__ */ new Set();
351
460
  for (;;) {
352
461
  const timeoutMs = remaining();
@@ -355,6 +464,7 @@ async function lookupNodeCodexCatalogRecord(params) {
355
464
  command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
356
465
  params: {
357
466
  agentId: params.agentId,
467
+ ...sourceHomeId ? { sourceHomeId } : {},
358
468
  limit: 100,
359
469
  ...cursor ? { cursor } : {}
360
470
  },
@@ -363,10 +473,15 @@ async function lookupNodeCodexCatalogRecord(params) {
363
473
  }), timeoutMs, "Codex session eligibility could not be verified", unverified);
364
474
  remaining();
365
475
  const page = parseCatalogPage(unwrapNodeInvokePayload(raw));
476
+ if ((!firstPage || sourceHomeId !== void 0) && page.sourceHomeId !== sourceHomeId) throw new CatalogParamsError("Codex session source home changed; refresh the catalog and retry");
477
+ sourceHomeId = page.sourceHomeId;
478
+ firstPage = false;
366
479
  const record = page.sessions.find((candidate) => candidate.threadId === params.threadId);
367
480
  if (record) return {
368
481
  kind: "found",
369
- record
482
+ record,
483
+ sourceHomeId,
484
+ canContinueCodex: page.canContinueCodex
370
485
  };
371
486
  const nextCursor = page.nextCursor?.trim();
372
487
  if (!nextCursor) break;
@@ -390,6 +505,7 @@ function createCodexTerminalStartNodeHostCommand() {
390
505
  cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
391
506
  dangerous: false,
392
507
  duplex: true,
508
+ hasActiveWork: () => false,
393
509
  isAvailable: ({ env }) => Boolean(resolveNodeHostExecutable("codex", {
394
510
  env,
395
511
  strategy: "direct"
@@ -416,6 +532,7 @@ function resolveCodexCatalogTerminalHome(sources) {
416
532
  if (!runtimeConfig) throw new Error("OpenClaw runtime config is unavailable");
417
533
  const agentDir = sources.source?.agentDir ?? (sources.agentId ? resolveAgentDir(runtimeConfig, sources.agentId) : resolveDefaultAgentDir(runtimeConfig));
418
534
  const startOptions = sources.source?.appServer.start ?? sources.resolveRuntimeOptions({ pluginConfig: sources.getPluginConfig() }).start;
535
+ if (startOptions.transport !== "stdio") throw new CatalogParamsError("Native terminal requires a local Codex source");
419
536
  return resolveCodexAppServerLocalHomeDir(startOptions, agentDir);
420
537
  }
421
538
  function resolveLocalCodexTerminalExecutable(env = process.env) {
@@ -441,7 +558,8 @@ function createCodexTerminalNodeHostCommand(bindRequest) {
441
558
  cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
442
559
  dangerous: false,
443
560
  duplex: true,
444
- isAvailable: ({ env }) => Boolean(resolveNodeHostExecutable("codex", {
561
+ hasActiveWork: () => false,
562
+ isAvailable: ({ config, env }) => (readCodexPluginConfig(config.plugins?.entries?.codex?.config).appServer?.transport ?? "stdio") === "stdio" && Boolean(resolveNodeHostExecutable("codex", {
445
563
  env,
446
564
  pathEnv: env.PATH ?? env.Path ?? "",
447
565
  strategy: "direct"
@@ -449,6 +567,7 @@ function createCodexTerminalNodeHostCommand(bindRequest) {
449
567
  handle: async (paramsJSON, io) => {
450
568
  if (!io) throw new Error("Codex terminal command requires duplex transport");
451
569
  const request = await bindRequest(paramsJSON);
570
+ if (request.transport !== "stdio") throw new CatalogParamsError("Native terminal requires a local Codex source");
452
571
  const resume = decodeNodePtyResumeParams(request.paramsJSON, (value) => {
453
572
  if (typeof value !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(value)) throw new CatalogParamsError("threadId must be a UUID");
454
573
  return value;
@@ -460,9 +579,11 @@ function createCodexTerminalNodeHostCommand(bindRequest) {
460
579
  strategy: "direct"
461
580
  });
462
581
  if (!resolution) throw new Error("Codex CLI is unavailable");
582
+ request.assertCurrent();
463
583
  return JSON.stringify(await runNodePtyCommand({
464
584
  file: resolution.executable,
465
585
  args: ["resume", resume.threadId],
586
+ assertCurrent: () => request.assertCurrent(),
466
587
  ...record.cwd ? { cwd: record.cwd } : {},
467
588
  env: { CODEX_HOME: request.codexHome },
468
589
  cols: resume.cols,
@@ -500,7 +621,8 @@ async function openCodexCatalogTerminal(params) {
500
621
  agentId: params.agentId,
501
622
  runtime: params.api.runtime,
502
623
  nodeId,
503
- threadId: params.threadId
624
+ threadId: params.threadId,
625
+ sourceHomeId: params.sourceHomeId
504
626
  });
505
627
  if (lookup.kind !== "found" || !isInteractiveThreadSource(lookup.record.source)) throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
506
628
  const record = lookup.record;
@@ -511,7 +633,8 @@ async function openCodexCatalogTerminal(params) {
511
633
  uploadPathStyle: "native",
512
634
  paramsJSON: JSON.stringify({
513
635
  agentId: params.agentId,
514
- threadId: params.threadId
636
+ threadId: params.threadId,
637
+ ...lookup.sourceHomeId ? { sourceHomeId: lookup.sourceHomeId } : {}
515
638
  }),
516
639
  ...record.cwd ? { cwd: record.cwd } : {},
517
640
  title
@@ -752,6 +875,24 @@ async function listVisiblePage(params) {
752
875
  }
753
876
  //#endregion
754
877
  //#region extensions/codex/src/session-catalog-list-operation.ts
878
+ async function boundedHost(pending) {
879
+ let timer;
880
+ try {
881
+ return await Promise.race([pending, new Promise((resolve) => {
882
+ timer = setTimeout(() => resolve(void 0), 250);
883
+ })]);
884
+ } finally {
885
+ clearTimeout(timer);
886
+ }
887
+ }
888
+ function measureNodeHost(host, diagnostics, started) {
889
+ return diagnostics ? host.finally(() => {
890
+ if (!diagnostics.closed) {
891
+ diagnostics.fields.pairedNodeSettled = (diagnostics.fields.pairedNodeSettled ?? 0) + 1;
892
+ diagnostics.fields.nodeWaitSumMs = (diagnostics.fields.nodeWaitSumMs ?? 0) + performance.now() - started;
893
+ }
894
+ }) : host;
895
+ }
755
896
  function hostFailure(source, error) {
756
897
  return {
757
898
  hostId: source?.hostId ?? "gateway:local",
@@ -767,7 +908,7 @@ function hostFailure(source, error) {
767
908
  }
768
909
  async function projectLocalHost(params, agentId, source, page) {
769
910
  params.signal?.throwIfAborted();
770
- const { listAdoptedSessionEntries } = await import("./session-catalog-adoption-CR_whkEW.mjs");
911
+ const { listAdoptedSessionEntries } = await import("./session-catalog-adoption-BI6UTDZT.mjs");
771
912
  const { sessionCatalogAdoptedSourceKey } = await import("openclaw/plugin-sdk/session-catalog");
772
913
  params.signal?.throwIfAborted();
773
914
  const diagnostics = currentCodexCatalogListDiagnostics();
@@ -823,6 +964,19 @@ function managedMarker(store, sourceHomeId, managed) {
823
964
  }
824
965
  };
825
966
  }
967
+ async function finishLocalHost(params, agentId, host) {
968
+ try {
969
+ for (;;) {
970
+ const step = await host.page.next();
971
+ params.signal?.throwIfAborted();
972
+ if (step.done) return await projectLocalHost(params, agentId, host.source, step.page);
973
+ }
974
+ } catch (error) {
975
+ return hostFailure(host.source, error);
976
+ } finally {
977
+ host.page.close();
978
+ }
979
+ }
826
980
  function createNodePublicationTracker(publications, waitUntil) {
827
981
  const settled = () => {
828
982
  publications.pending--;
@@ -838,6 +992,7 @@ var CodexCatalogListDriver = class {
838
992
  constructor(params) {
839
993
  this.locals = [];
840
994
  this.nodeActive = false;
995
+ this.nodeResults = [];
841
996
  this.nodeDiscoveryFailed = false;
842
997
  this.nodePublications = { pending: 0 };
843
998
  this.nodesStarted = false;
@@ -846,6 +1001,8 @@ var CodexCatalogListDriver = class {
846
1001
  this.running = false;
847
1002
  this.complete = false;
848
1003
  this.params = params;
1004
+ this.nodeSnapshots = params.nodeSnapshots ?? new CodexCatalogNodeSnapshots();
1005
+ this.nodeGeneration = this.nodeSnapshots.start(params.config);
849
1006
  }
850
1007
  request() {
851
1008
  if (!this.params) throw new Error("Codex catalog list operation is closed");
@@ -908,6 +1065,20 @@ var CodexCatalogListDriver = class {
908
1065
  }
909
1066
  async readHost(host) {
910
1067
  const params = this.request();
1068
+ if (params.allowPartialResults === true && params.onHost && params.waitUntil) {
1069
+ host.background = true;
1070
+ const completion = finishLocalHost(params, this.selection().agentId, host);
1071
+ completion.then(host.completion.resolve, host.completion.reject);
1072
+ host.value = await boundedHost(completion) ?? {
1073
+ hostId: host.source?.hostId ?? "gateway:local",
1074
+ label: host.source?.label ?? "Local Codex",
1075
+ kind: "gateway",
1076
+ connected: true,
1077
+ pending: true,
1078
+ sessions: []
1079
+ };
1080
+ return;
1081
+ }
911
1082
  try {
912
1083
  const page = await host.page.next();
913
1084
  params.signal?.throwIfAborted();
@@ -940,9 +1111,11 @@ var CodexCatalogListDriver = class {
940
1111
  const started = diagnostics ? performance.now() : 0;
941
1112
  if (diagnostics) diagnostics.fields.nodeRegistryCalls = 1;
942
1113
  let nodes;
1114
+ let inventory;
943
1115
  try {
944
1116
  try {
945
- nodes = (await (params.listNodes?.() ?? params.runtime.nodes.list())).nodes.filter((node) => node.gatewayLocal !== true && (node.commands?.includes("codex.appServer.threads.list.v1") || codexNodeTerminalCapability(node).canStartTerminal) && (!requestedHostIds || requestedHostIds.has(`node:${node.nodeId}`))).slice(0, 100 - this.locals.length);
1117
+ inventory = (await (params.listNodes?.() ?? params.runtime.nodes.list())).nodes;
1118
+ nodes = inventory.filter((node) => node.gatewayLocal !== true && (node.commands?.includes("codex.appServer.threads.list.v1") || codexNodeTerminalCapability(node).canStartTerminal) && (!requestedHostIds || requestedHostIds.has(`node:${node.nodeId}`))).slice(0, 100 - this.locals.length);
946
1119
  } finally {
947
1120
  if (diagnostics && !diagnostics.closed) diagnostics.fields.nodeRegistryMs = performance.now() - started;
948
1121
  }
@@ -961,8 +1134,9 @@ var CodexCatalogListDriver = class {
961
1134
  return [host];
962
1135
  }
963
1136
  params.signal?.throwIfAborted();
964
- const { listNodeAdoptedSessionEntries } = await import("./session-catalog-node-adoption-BVRsYOSh.mjs");
965
- const { compareNodeLabels, listPairedNode } = await import("./session-catalog-node-continue-Dowv8osw.mjs");
1137
+ this.nodeSnapshots.observe(this.nodeGeneration, inventory);
1138
+ const { listNodeAdoptedSessionEntries, nodeAdoptedSourceKey } = await import("./session-catalog-node-adoption-ITddWx_X.mjs");
1139
+ const { compareNodeLabels, listPairedNode, nodeLabel } = await import("./session-catalog-node-continue-6g6qi4A9.mjs");
966
1140
  params.signal?.throwIfAborted();
967
1141
  const adopted = listNodeAdoptedSessionEntries({
968
1142
  agentId,
@@ -975,29 +1149,64 @@ var CodexCatalogListDriver = class {
975
1149
  diagnostics.fields.pairedNodeSettled = 0;
976
1150
  }
977
1151
  const trackPublication = createNodePublicationTracker(this.nodePublications, params.waitUntil);
1152
+ const partial = params.allowPartialResults === true && Boolean(params.onHost && params.waitUntil);
978
1153
  const pendingHosts = nodes.toSorted(compareNodeLabels).map((node) => {
1154
+ const key = JSON.stringify([
1155
+ agentId,
1156
+ query.limitPerHost,
1157
+ query.search,
1158
+ query.cursors?.[`node:${node.nodeId}`],
1159
+ node.displayName,
1160
+ node.remoteIp,
1161
+ node.caps,
1162
+ node.commands,
1163
+ node.invocableCommands
1164
+ ]);
1165
+ const publication = this.nodeSnapshots.forNode(node, this.nodeGeneration, key);
1166
+ const { project, publish, publishCached, readPublished } = createNodeHostPublication(publication, adopted, nodeAdoptedSourceKey, params.onHost, params.signal, partial, trackPublication);
1167
+ const cached = partial ? publication.read() : void 0;
1168
+ let result;
1169
+ this.nodeResults.push(() => {
1170
+ const latest = partial ? publication.read() : void 0;
1171
+ if (latest) {
1172
+ publishCached(latest);
1173
+ return project(latest.host);
1174
+ }
1175
+ return !partial ? result : publication.valid() ? readPublished() ?? result : void 0;
1176
+ });
1177
+ if (cached) publishCached(cached);
979
1178
  const nodeStarted = diagnostics ? performance.now() : 0;
980
1179
  if (diagnostics && !diagnostics.closed) diagnostics.fields.pairedNodeCalls = (diagnostics.fields.pairedNodeCalls ?? 0) + 1;
981
- const host = listPairedNode({
1180
+ const completion = measureNodeHost(listPairedNode({
982
1181
  agentId,
983
1182
  runtime: params.runtime,
984
1183
  node,
985
1184
  query,
986
- adoptedSessions: adopted,
987
1185
  terminalCapabilities: codexNodeTerminalCapability(node),
988
1186
  waitUntil: trackPublication,
989
1187
  signal: params.signal,
990
- ...params.onHost ? { onHost: params.onHost } : {}
1188
+ onHost: publish
1189
+ }), diagnostics, nodeStarted);
1190
+ if (cached) {
1191
+ completion.catch(() => void 0);
1192
+ return Promise.resolve(project(cached.host));
1193
+ }
1194
+ return (partial ? boundedHost(completion) : completion).then((value) => {
1195
+ result = value ? project(value) : {
1196
+ hostId: `node:${node.nodeId}`,
1197
+ label: nodeLabel(node),
1198
+ kind: "node",
1199
+ nodeId: node.nodeId,
1200
+ connected: true,
1201
+ pending: true,
1202
+ ...codexNodeTerminalCapability(node),
1203
+ sessions: []
1204
+ };
1205
+ return result;
991
1206
  });
992
- return diagnostics ? host.finally(() => {
993
- if (!diagnostics.closed) {
994
- diagnostics.fields.pairedNodeSettled = (diagnostics.fields.pairedNodeSettled ?? 0) + 1;
995
- diagnostics.fields.nodeWaitSumMs = (diagnostics.fields.nodeWaitSumMs ?? 0) + performance.now() - nodeStarted;
996
- }
997
- }) : host;
998
1207
  });
999
1208
  try {
1000
- return await Promise.all(pendingHosts);
1209
+ return (await Promise.all(pendingHosts)).filter((host) => host !== void 0);
1001
1210
  } catch (error) {
1002
1211
  await Promise.allSettled(pendingHosts);
1003
1212
  throw error;
@@ -1021,13 +1230,20 @@ var CodexCatalogListDriver = class {
1021
1230
  if (this.active > 0 || !this.step) return;
1022
1231
  if (this.failure) {
1023
1232
  if (!this.nodeActive) this.step.reject(this.failure.error);
1024
- } else if (this.nodeHosts && this.locals.every((host) => host.value !== void 0)) {
1233
+ } else if (this.nodeHosts && this.locals.every((host) => host.value !== void 0)) try {
1025
1234
  this.complete = true;
1026
1235
  this.step.resolve({
1027
1236
  done: true,
1028
- hosts: [...this.locals.flatMap((host) => host.value ? [host.value] : []), ...this.nodeHosts]
1237
+ hosts: [...this.locals.flatMap((host) => host.value ? [host.value] : []), ...this.nodeResults.length ? this.nodeResults.flatMap((read) => {
1238
+ const host = read();
1239
+ return host ? [host] : [];
1240
+ }) : this.nodeHosts]
1029
1241
  });
1030
- } else if (this.canPause()) this.step.resolve({ done: false });
1242
+ } catch (error) {
1243
+ this.failure ??= { error };
1244
+ this.step.reject(error);
1245
+ }
1246
+ else if (this.canPause()) this.step.resolve({ done: false });
1031
1247
  }
1032
1248
  async next() {
1033
1249
  const params = this.request();
@@ -1052,12 +1268,13 @@ var CodexCatalogListDriver = class {
1052
1268
  const reason = this.failure?.error ?? this.params.signal?.reason ?? /* @__PURE__ */ new Error("Codex catalog list operation closed");
1053
1269
  this.params = void 0;
1054
1270
  for (const host of this.locals) {
1055
- host.page.close();
1271
+ if (!host.background) host.page.close();
1056
1272
  if (!host.value) host.completion.reject(reason);
1057
1273
  }
1058
1274
  this.locals = [];
1059
1275
  this.prepared = void 0;
1060
1276
  this.nodeHosts = void 0;
1277
+ this.nodeResults = [];
1061
1278
  this.failure = void 0;
1062
1279
  }
1063
1280
  };
@@ -1167,10 +1384,14 @@ function createCodexSessionCatalogNodeHostCommands(controlFactory, bindingStore)
1167
1384
  const parsed = parseJsonParams(paramsJSON);
1168
1385
  if (!isRecord(parsed)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
1169
1386
  const agentId = readBoundedOptionalString(parsed, "agentId", 256);
1387
+ const sourceHomeId = readBoundedOptionalString(parsed, "sourceHomeId", 256);
1388
+ const source = await controlFactory.forNode(agentId);
1389
+ if (sourceHomeId && sourceHomeId !== source.sourceHomeId) throw new CatalogParamsError("Codex catalog source home changed. Reopen the session from the catalog.");
1170
1390
  const request = { ...parsed };
1171
1391
  delete request.agentId;
1392
+ delete request.sourceHomeId;
1172
1393
  return {
1173
- ...await controlFactory.forNode(agentId),
1394
+ ...source,
1174
1395
  params: request,
1175
1396
  paramsJSON: JSON.stringify(request)
1176
1397
  };
@@ -1180,6 +1401,8 @@ function createCodexSessionCatalogNodeHostCommands(controlFactory, bindingStore)
1180
1401
  command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
1181
1402
  cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
1182
1403
  dangerous: false,
1404
+ hasActiveWork: controlFactory.hasActiveWork,
1405
+ onDisconnect: controlFactory.disconnect,
1183
1406
  handle: async (paramsJSON) => {
1184
1407
  const request = await bindRequest(paramsJSON);
1185
1408
  const pageParams = readPageParams(request.params);
@@ -1202,7 +1425,11 @@ function createCodexSessionCatalogNodeHostCommands(controlFactory, bindingStore)
1202
1425
  } } : {},
1203
1426
  searchTerm: pageParams.searchTerm
1204
1427
  });
1205
- return JSON.stringify(page);
1428
+ return JSON.stringify({
1429
+ ...page,
1430
+ sourceHomeId: request.sourceHomeId,
1431
+ canContinueCodex: request.transport === "stdio"
1432
+ });
1206
1433
  } catch {
1207
1434
  throw new Error("Codex app-server catalog is unavailable");
1208
1435
  }
@@ -1212,6 +1439,8 @@ function createCodexSessionCatalogNodeHostCommands(controlFactory, bindingStore)
1212
1439
  command: CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND,
1213
1440
  cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
1214
1441
  dangerous: false,
1442
+ hasActiveWork: controlFactory.hasActiveWork,
1443
+ onDisconnect: controlFactory.disconnect,
1215
1444
  handle: async (paramsJSON) => {
1216
1445
  const request = await bindRequest(paramsJSON);
1217
1446
  const action = readNodeTranscriptParams(request.params);
@@ -1235,6 +1464,8 @@ function createCodexSessionCatalogNodeHostCommands(controlFactory, bindingStore)
1235
1464
  command: CODEX_CATALOG_TRANSCRIPT_READ_COMMAND,
1236
1465
  cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
1237
1466
  dangerous: false,
1467
+ hasActiveWork: controlFactory.hasActiveWork,
1468
+ onDisconnect: controlFactory.disconnect,
1238
1469
  handle: async (paramsJSON) => {
1239
1470
  const request = await bindRequest(paramsJSON);
1240
1471
  const action = readNodeTranscriptParams(request.params);
@@ -1298,6 +1529,7 @@ async function readCodexSessionTranscript(params) {
1298
1529
  params: {
1299
1530
  agentId: params.agentId,
1300
1531
  threadId: params.threadId,
1532
+ ...params.sourceHomeId ? { sourceHomeId: params.sourceHomeId } : {},
1301
1533
  ...request
1302
1534
  },
1303
1535
  timeoutMs: NODE_INVOKE_TIMEOUT_MS,
@@ -1314,7 +1546,7 @@ async function readCodexSessionTranscript(params) {
1314
1546
  cursor,
1315
1547
  limit
1316
1548
  });
1317
- const { nodeLabel } = await import("./session-catalog-node-continue-Dowv8osw.mjs");
1549
+ const { nodeLabel } = await import("./session-catalog-node-continue-6g6qi4A9.mjs");
1318
1550
  return {
1319
1551
  hostId: params.hostId,
1320
1552
  label: nodeLabel(node),
@@ -1400,9 +1632,11 @@ async function checkCodexUpstreamActivity(probes, control, resolveThreadId = (pr
1400
1632
  limit: CODEX_UPSTREAM_TURN_LIMIT,
1401
1633
  sortDirection: "desc",
1402
1634
  itemsView: "full"
1635
+ }).catch((error) => {
1636
+ if (error instanceof CodexAppServerRpcError && error.code === -32600) return;
1637
+ throw error;
1403
1638
  });
1404
- const marker = readMarker(probe);
1405
- if (page.data.length === 0 && marker) {
1639
+ if (!page?.data.length && readMarker(probe)) {
1406
1640
  try {
1407
1641
  await pinned.readThread(threadId, false);
1408
1642
  } catch (error) {
@@ -1413,7 +1647,7 @@ async function checkCodexUpstreamActivity(probes, control, resolveThreadId = (pr
1413
1647
  }
1414
1648
  continue;
1415
1649
  }
1416
- const activity = classifyCodexUpstreamTurns({
1650
+ const activity = page && classifyCodexUpstreamTurns({
1417
1651
  probe,
1418
1652
  turns: page.data
1419
1653
  });
@@ -1479,8 +1713,8 @@ async function requireEligibleCodexThread(params) {
1479
1713
  remaining();
1480
1714
  if (thread.id !== threadId || thread.ephemeral === true || !isInteractiveThreadSource(thread.source)) throw unverified();
1481
1715
  if (!root) {
1482
- const { CODEX_CATALOG_NATIVE_PAGE_LIMIT } = await import("./session-catalog-native-projection-ChV3cCtm.mjs").then((n) => n.i);
1483
- const { CODEX_CATALOG_MAX_ROWS } = await import("./session-catalog-native-projection-ChV3cCtm.mjs").then((n) => n.U);
1716
+ const { CODEX_CATALOG_NATIVE_PAGE_LIMIT } = await import("./session-catalog-native-projection-DowriLid.mjs").then((n) => n.a);
1717
+ const { CODEX_CATALOG_MAX_ROWS } = await import("./session-catalog-native-projection-DowriLid.mjs").then((n) => n.G);
1484
1718
  let cursor;
1485
1719
  const seenCursors = /* @__PURE__ */ new Set();
1486
1720
  for (;;) {
@@ -1522,6 +1756,91 @@ async function requireEligibleCodexThread(params) {
1522
1756
  return await withTimeout(verify(), requests.requestTimeoutMs, "Codex session eligibility could not be verified", unverified);
1523
1757
  }
1524
1758
  //#endregion
1759
+ //#region extensions/codex/src/session-catalog-control-requests.ts
1760
+ function createCodexCatalogRequestSnapshot(requestTimeoutMs, request, index, beginList, catalogRead = false) {
1761
+ const read = (method, params, timeoutMs, observation) => {
1762
+ const scope = catalogRead ? void 0 : currentCodexCatalogListRequest();
1763
+ if (!scope) return request(method, params, timeoutMs, void 0, observation);
1764
+ return scope.read(timeoutMs ?? requestTimeoutMs, async (remaining) => {
1765
+ const attempt = beginList(scope);
1766
+ if (!attempt.allowed) throw attempt.error;
1767
+ return await request(method, params, remaining, void 0, observation);
1768
+ });
1769
+ };
1770
+ return {
1771
+ index,
1772
+ beginList,
1773
+ get requestTimeoutMs() {
1774
+ return catalogRead ? requestTimeoutMs : currentCodexCatalogListRequest()?.remaining(requestTimeoutMs) ?? requestTimeoutMs;
1775
+ },
1776
+ listThreads: (params, timeoutMs, observation) => read(CODEX_CONTROL_METHODS.listThreads, params, timeoutMs, observation),
1777
+ listThreadTurns: (params) => read(CODEX_CONTROL_METHODS.listThreadTurns, params),
1778
+ listThreadItems: (params) => read(CODEX_CONTROL_METHODS.listThreadItems, params),
1779
+ forkThread: (params, assertCurrent) => request(CODEX_CONTROL_METHODS.forkThread, assertCodexThreadForkParams(params), void 0, assertCurrent),
1780
+ readThread: async (threadId, includeTurns, timeoutMs) => (await read(CODEX_CONTROL_METHODS.readThread, {
1781
+ threadId,
1782
+ includeTurns
1783
+ }, timeoutMs)).thread,
1784
+ archiveThread: async (threadId, assertCurrent) => {
1785
+ await request(CODEX_CONTROL_METHODS.archiveThread, { threadId }, void 0, assertCurrent);
1786
+ }
1787
+ };
1788
+ }
1789
+ function createCodexSessionCatalogControlFromRequests(params) {
1790
+ return {
1791
+ forkContext: params.forkContext,
1792
+ ...params.clientId ? { clientId: params.clientId } : {},
1793
+ ...params.connectionFingerprint ? { connectionFingerprint: params.connectionFingerprint } : {},
1794
+ withPinnedConnection: params.withPinnedConnection,
1795
+ async initialize() {
1796
+ await (await params.createRequestSnapshot().index()).initialize();
1797
+ },
1798
+ requireEligibleThread: (threadId) => requireEligibleCodexThread({
1799
+ threadId,
1800
+ requests: params.createRequestSnapshot(),
1801
+ localSessionsRoot: params.localSessionsRoot,
1802
+ sourceHomeId: params.sourceHomeId,
1803
+ managedThreads: params.managedThreads,
1804
+ now: params.now
1805
+ }),
1806
+ retireConnection: params.retireConnection,
1807
+ async listPage(pageParams) {
1808
+ readControlCursor(pageParams.cursor, "request");
1809
+ const query = readPageParams(pageParams);
1810
+ return await withCodexCatalogListRequest(async (request) => {
1811
+ const requests = params.createRequestSnapshot();
1812
+ const timeoutMs = Math.min(requests.requestTimeoutMs, 5e3);
1813
+ const deadline = request.constrainDeadline(performance.now() + timeoutMs);
1814
+ return await (await withTimeout(requests.index(), request.remaining(timeoutMs), "Codex session catalog is still loading", () => new CodexCatalogLoadingError())).list(query, deadline);
1815
+ });
1816
+ },
1817
+ async listDescendantPage(listParams) {
1818
+ const requests = params.createRequestSnapshot();
1819
+ return await requests.listThreads(listParams, requests.requestTimeoutMs);
1820
+ },
1821
+ async readThread(threadId, includeTurns = false) {
1822
+ return await params.createRequestSnapshot().readThread(threadId, includeTurns);
1823
+ },
1824
+ async listTurnPage(listParams) {
1825
+ return await params.createRequestSnapshot().listThreadTurns(listParams);
1826
+ },
1827
+ listItemPage: (listParams) => params.createRequestSnapshot().listThreadItems(listParams),
1828
+ async forkThread(forkParams, assertCurrent) {
1829
+ const requests = params.createRequestSnapshot();
1830
+ const index = forkParams.ephemeral === true ? void 0 : await requests.index();
1831
+ const response = await requests.forkThread(forkParams, assertCurrent);
1832
+ if (index && !index.get(response.thread.id)) await index.upsertThread(response.thread);
1833
+ return response;
1834
+ },
1835
+ async archiveThread(threadId, assertCurrent) {
1836
+ const requests = params.createRequestSnapshot();
1837
+ const index = await requests.index();
1838
+ await requests.archiveThread(threadId, assertCurrent);
1839
+ index.archive(threadId);
1840
+ }
1841
+ };
1842
+ }
1843
+ //#endregion
1525
1844
  //#region extensions/codex/src/session-catalog-homes.ts
1526
1845
  /** Discovers path facts on demand; runtime projections belong only to their requesting owner. */
1527
1846
  function createCodexCatalogHomeResolver(params) {
@@ -1560,7 +1879,7 @@ function createCodexCatalogHomeResolver(params) {
1560
1879
  const cached = snapshot.paths.get(value);
1561
1880
  if (cached !== void 0) return cached;
1562
1881
  const resolved = path.resolve(value);
1563
- const discovery = fs.realpath(resolved).catch(() => resolved).then(async (canonical) => {
1882
+ const discovery = canonicalPathFromExistingAncestor(resolved).catch(() => resolved).then(async (canonical) => {
1564
1883
  if (await fs.stat(canonical).then((stat) => stat.isDirectory(), () => false)) snapshot.directories.add(value);
1565
1884
  snapshot.paths.set(value, canonical);
1566
1885
  return canonical;
@@ -1582,7 +1901,8 @@ function createCodexCatalogHomeResolver(params) {
1582
1901
  };
1583
1902
  for (const id of agentIds(snapshot)) {
1584
1903
  await scheduler.yield();
1585
- await append(resolveCodexAppServerHomeDir(agentDir(snapshot, id)), id);
1904
+ const directory = await homePath(snapshot, agentDir(snapshot, id));
1905
+ await append(resolveCodexAppServerHomeDir(directory), id);
1586
1906
  if (candidates.length === 100) return candidates;
1587
1907
  }
1588
1908
  for (const entry of readCodexPluginConfig(snapshot.pluginConfig).sessionCatalog?.homes ?? []) {
@@ -1600,7 +1920,7 @@ function createCodexCatalogHomeResolver(params) {
1600
1920
  await scheduler.yield();
1601
1921
  snapshot.assertCurrent();
1602
1922
  if (!agentIds(snapshot).includes(agentId)) return [];
1603
- const ownerAgentDir = agentDir(snapshot, agentId);
1923
+ const ownerAgentDir = await homePath(snapshot, agentDir(snapshot, agentId));
1604
1924
  const base = params.resolveRuntimeOptions({
1605
1925
  config: snapshot.config,
1606
1926
  pluginConfig: snapshot.pluginConfig,
@@ -1641,15 +1961,18 @@ function createCodexCatalogHomeResolver(params) {
1641
1961
  hostId: primary ? CODEX_LOCAL_SESSION_HOST_ID : `${CODEX_LOCAL_SESSION_HOST_ID}:${sourceHomeId}`,
1642
1962
  label: candidate.label,
1643
1963
  agentDir: ownerAgentDir,
1644
- appServer: primary ? base : {
1964
+ appServer: base.start.transport !== "stdio" ? base : {
1645
1965
  ...base,
1646
1966
  start: {
1647
1967
  ...base.start,
1648
- homeScope: "user",
1649
- env: {
1650
- ...base.start.env,
1651
- CODEX_HOME: candidate.codexHome
1652
- }
1968
+ codexHome: candidate.codexHome,
1969
+ ...!primary ? {
1970
+ homeScope: "user",
1971
+ env: {
1972
+ ...base.start.env,
1973
+ CODEX_HOME: candidate.codexHome
1974
+ }
1975
+ } : {}
1653
1976
  }
1654
1977
  },
1655
1978
  ...base.connectionClass === "remote" ? {} : { localSessionsRoot: path.join(candidate.codexHome, "sessions") },
@@ -1752,7 +2075,7 @@ var CodexCatalogSourceBackoff = class {
1752
2075
  if (failure) failure.probing = false;
1753
2076
  return;
1754
2077
  }
1755
- const delayMs = failure ? Math.min(failure.delayMs * 2 || INITIAL_BACKOFF_MS, MAX_BACKOFF_MS) : 0;
2078
+ const delayMs = findCodexAppServerSpawnError(error) ? Infinity : failure ? Math.min(failure.delayMs * 2 || INITIAL_BACKOFF_MS, MAX_BACKOFF_MS) : 0;
1756
2079
  sources.set(key, { failure: {
1757
2080
  error,
1758
2081
  delayMs,
@@ -1768,127 +2091,67 @@ var CodexCatalogSourceBackoff = class {
1768
2091
  };
1769
2092
  //#endregion
1770
2093
  //#region extensions/codex/src/session-catalog-control.ts
1771
- function createCodexCatalogRequestSnapshot(requestTimeoutMs, request, index, beginList, catalogRead = false) {
1772
- const read = (method, params, timeoutMs, observation) => {
1773
- const scope = catalogRead ? void 0 : currentCodexCatalogListRequest();
1774
- if (!scope) return request(method, params, timeoutMs, void 0, observation);
1775
- return scope.read(timeoutMs ?? requestTimeoutMs, async (remaining) => {
1776
- const attempt = beginList(scope);
1777
- if (!attempt.allowed) throw attempt.error;
1778
- return await request(method, params, remaining, void 0, observation);
1779
- });
1780
- };
1781
- return {
1782
- index,
1783
- beginList,
1784
- get requestTimeoutMs() {
1785
- return catalogRead ? requestTimeoutMs : currentCodexCatalogListRequest()?.remaining(requestTimeoutMs) ?? requestTimeoutMs;
1786
- },
1787
- listThreads: (params, timeoutMs, observation) => read(CODEX_CONTROL_METHODS.listThreads, params, timeoutMs, observation),
1788
- listThreadTurns: (params) => read(CODEX_CONTROL_METHODS.listThreadTurns, params),
1789
- listThreadItems: (params) => read(CODEX_CONTROL_METHODS.listThreadItems, params),
1790
- forkThread: (params, assertCurrent) => request(CODEX_CONTROL_METHODS.forkThread, assertCodexThreadForkParams(params), void 0, assertCurrent),
1791
- readThread: async (threadId, includeTurns, timeoutMs) => (await read(CODEX_CONTROL_METHODS.readThread, {
1792
- threadId,
1793
- includeTurns
1794
- }, timeoutMs)).thread,
1795
- archiveThread: async (threadId, assertCurrent) => {
1796
- await request(CODEX_CONTROL_METHODS.archiveThread, { threadId }, void 0, assertCurrent);
1797
- }
1798
- };
1799
- }
1800
- function createCodexSessionCatalogControlFromRequests(params) {
1801
- return {
1802
- forkContext: params.forkContext,
1803
- ...params.clientId ? { clientId: params.clientId } : {},
1804
- ...params.connectionFingerprint ? { connectionFingerprint: params.connectionFingerprint } : {},
1805
- withPinnedConnection: params.withPinnedConnection,
1806
- async initialize() {
1807
- await (await params.createRequestSnapshot().index()).initialize();
1808
- },
1809
- requireEligibleThread: (threadId) => requireEligibleCodexThread({
1810
- threadId,
1811
- requests: params.createRequestSnapshot(),
1812
- localSessionsRoot: params.localSessionsRoot,
1813
- sourceHomeId: params.sourceHomeId,
1814
- managedThreads: params.managedThreads,
1815
- now: params.now
1816
- }),
1817
- retireConnection: params.retireConnection,
1818
- async listPage(pageParams) {
1819
- readControlCursor(pageParams.cursor, "request");
1820
- const query = readPageParams(pageParams);
1821
- return await withCodexCatalogListRequest(async (request) => {
1822
- const requests = params.createRequestSnapshot();
1823
- const deadline = request.deadline(requests.requestTimeoutMs);
1824
- return await (await withTimeout(requests.index(), request.remaining(requests.requestTimeoutMs), "Codex session catalog is still loading", () => new CodexCatalogLoadingError())).list(query, deadline);
1825
- });
1826
- },
1827
- async listDescendantPage(listParams) {
1828
- const requests = params.createRequestSnapshot();
1829
- return await requests.listThreads(listParams, requests.requestTimeoutMs);
1830
- },
1831
- async readThread(threadId, includeTurns = false) {
1832
- return await params.createRequestSnapshot().readThread(threadId, includeTurns);
1833
- },
1834
- async listTurnPage(listParams) {
1835
- return await params.createRequestSnapshot().listThreadTurns(listParams);
1836
- },
1837
- listItemPage: (listParams) => params.createRequestSnapshot().listThreadItems(listParams),
1838
- async forkThread(forkParams, assertCurrent) {
1839
- const requests = params.createRequestSnapshot();
1840
- const index = forkParams.ephemeral === true ? void 0 : await requests.index();
1841
- const response = await requests.forkThread(forkParams, assertCurrent);
1842
- if (index && !index.get(response.thread.id)) await index.upsertThread(response.thread);
1843
- return response;
1844
- },
1845
- async archiveThread(threadId, assertCurrent) {
1846
- const requests = params.createRequestSnapshot();
1847
- const index = await requests.index();
1848
- await requests.archiveThread(threadId, assertCurrent);
1849
- index.archive(threadId);
1850
- }
1851
- };
1852
- }
1853
2094
  /** Builds the passive catalog over the Codex plugin's canonical shared client. */
1854
2095
  function createCodexSessionCatalogControl(params) {
1855
2096
  const now = params.now ?? Date.now;
1856
2097
  const sourceBackoff = new CodexCatalogSourceBackoff(now);
1857
2098
  const noConfig = {};
1858
2099
  const getPluginConfig = () => params.getPluginConfig();
2100
+ const resolveRuntimeOptions = (options) => {
2101
+ const runtime = params.resolveRuntimeOptions(options);
2102
+ return runtime.start.transport === "stdio" && runtime.start.commandSource === "managed" ? {
2103
+ ...runtime,
2104
+ start: {
2105
+ ...runtime.start,
2106
+ managedCommandOrder: "package-only"
2107
+ }
2108
+ } : runtime;
2109
+ };
1859
2110
  const homeResolver = createCodexCatalogHomeResolver({
1860
2111
  config: params.config ?? {},
1861
2112
  getRuntimeConfig: params.getRuntimeConfig,
1862
2113
  getPluginConfig: params.getPluginConfig,
1863
- resolveRuntimeOptions: params.resolveRuntimeOptions,
2114
+ resolveRuntimeOptions,
1864
2115
  ...params.env ? { env: params.env } : {}
1865
2116
  });
1866
2117
  const requestOptionsByConfig = /* @__PURE__ */ new WeakMap();
1867
2118
  const indexes = /* @__PURE__ */ new Map();
1868
2119
  const retiringState = /* @__PURE__ */ new Map();
1869
2120
  const directHomes = /* @__PURE__ */ new Map();
2121
+ const residentRequests = /* @__PURE__ */ new Set();
1870
2122
  let generation = params.getRuntimeConfig();
2123
+ let residentEpoch = 0;
2124
+ let starting = 0;
1871
2125
  let closed = false;
1872
2126
  let runBackground = (run) => run();
1873
- let retiring = Promise.resolve();
1874
- const residentFor = async (agentId, source) => {
2127
+ let retiring;
2128
+ const retireIndexes = () => {
2129
+ residentEpoch++;
2130
+ const closing = [];
2131
+ for (const [homeId, index] of indexes) {
2132
+ const writes = index.retire().finally(() => {
2133
+ if (retiringState.get(homeId) === writes) retiringState.delete(homeId);
2134
+ });
2135
+ retiringState.set(homeId, writes);
2136
+ closing.push(writes, index.close());
2137
+ }
2138
+ indexes.clear();
2139
+ directHomes.clear();
2140
+ const drain = Promise.allSettled([retiring, ...closing]).then(() => {
2141
+ if (retiring === drain) retiring = void 0;
2142
+ });
2143
+ retiring = drain;
2144
+ return drain;
2145
+ };
2146
+ const resolveResident = async (agentId, source) => {
1875
2147
  if (closed) throw new Error("Codex resident catalog is closed");
1876
2148
  const config = params.getRuntimeConfig();
1877
2149
  if (generation !== config) {
1878
2150
  generation = config;
1879
- const closing = [];
1880
- for (const [homeId, index] of indexes) {
1881
- const writes = index.retire().finally(() => {
1882
- if (retiringState.get(homeId) === writes) retiringState.delete(homeId);
1883
- });
1884
- retiringState.set(homeId, writes);
1885
- closing.push(writes, index.close());
1886
- }
1887
- retiring = Promise.allSettled([retiring, ...closing]).then(() => void 0);
1888
- indexes.clear();
1889
- directHomes.clear();
2151
+ retireIndexes();
1890
2152
  }
1891
- const runtime = source?.appServer ?? params.resolveRuntimeOptions({ pluginConfig: getPluginConfig() });
2153
+ const epoch = residentEpoch;
2154
+ const runtime = source?.appServer ?? resolveRuntimeOptions({ pluginConfig: getPluginConfig() });
1892
2155
  const requestOptions = resolveRequestOptions(runtime.start, agentId, source);
1893
2156
  const key = source?.sourceHomeId ?? agentId ?? "";
1894
2157
  let home = directHomes.get(key);
@@ -1902,12 +2165,12 @@ function createCodexSessionCatalogControl(params) {
1902
2165
  }
1903
2166
  const homeId = await home;
1904
2167
  await retiringState.get(homeId);
1905
- if (closed || generation !== config) throw new Error("Codex catalog configuration changed");
2168
+ if (closed || generation !== config || residentEpoch !== epoch) throw new Error("Codex catalog configuration changed");
1906
2169
  let index = indexes.get(homeId);
1907
2170
  if (!index) {
1908
- const [{ CodexCatalogIndex }, { canReuseCodexCatalogPreview, projectCodexCatalogDeltaPage, projectCodexCatalogPage }] = await Promise.all([import("./session-catalog-index-B141u15s.mjs"), import("./session-catalog-projection-C1Bj9Jl-.mjs")]);
2171
+ const [{ CodexCatalogIndex }, { canReuseCodexCatalogPreview, projectCodexCatalogDeltaPage, projectCodexCatalogPage }] = await Promise.all([import("./session-catalog-index-B9_VQIUz.mjs"), import("./session-catalog-projection-zK_PUsiE.mjs")]);
1909
2172
  source?.assertCurrent();
1910
- if (closed || generation !== config) throw new Error("Codex catalog configuration changed");
2173
+ if (closed || generation !== config || residentEpoch !== epoch) throw new Error("Codex catalog configuration changed");
1911
2174
  index = indexes.get(homeId);
1912
2175
  if (index) return index;
1913
2176
  const root = source?.localSessionsRoot ?? (runtime.connectionClass !== "remote" ? path.join(resolveCodexAppServerLocalHomeDir(requestOptions.startOptions, requestOptions.agentDir, params.env), "sessions") : void 0);
@@ -1940,17 +2203,9 @@ function createCodexSessionCatalogControl(params) {
1940
2203
  const page = await project(response, diagnostics);
1941
2204
  foreground?.assertActive();
1942
2205
  outcome = "resolved";
1943
- if (!foreground && !page.nextCursor) {
1944
- attempt.resolved();
1945
- nativeAttempt = void 0;
1946
- }
1947
2206
  return page;
1948
2207
  } catch (error) {
1949
2208
  observation?.rejected();
1950
- if (!foreground) {
1951
- attempt.rejected(error);
1952
- nativeAttempt = void 0;
1953
- }
1954
2209
  throw error;
1955
2210
  } finally {
1956
2211
  observation?.close();
@@ -1963,9 +2218,21 @@ function createCodexSessionCatalogControl(params) {
1963
2218
  runBackground: (run) => runBackground(run),
1964
2219
  localSessionsRoot: root,
1965
2220
  state: params.openResidentState?.(homeId),
2221
+ runNativeWalk: async (run) => {
2222
+ try {
2223
+ const result = await run();
2224
+ if (nativeAttempt?.allowed) nativeAttempt.resolved();
2225
+ return result;
2226
+ } catch (error) {
2227
+ if (nativeAttempt?.allowed) nativeAttempt.rejected(error);
2228
+ throw error;
2229
+ } finally {
2230
+ nativeAttempt = void 0;
2231
+ }
2232
+ },
1966
2233
  assertCurrent: () => {
1967
2234
  source?.assertCurrent();
1968
- if (closed || params.getRuntimeConfig() !== config) throw new Error("Codex catalog configuration changed");
2235
+ if (closed || params.getRuntimeConfig() !== config || residentEpoch !== epoch) throw new Error("Codex catalog configuration changed");
1969
2236
  },
1970
2237
  readNative: (query, remainingRows, foreground) => readNativePage(query, Math.min(64, remainingRows), async (response, diagnostics) => {
1971
2238
  const { sanitizeTerminalText } = await import("openclaw/plugin-sdk/text-chunking");
@@ -1988,6 +2255,13 @@ function createCodexSessionCatalogControl(params) {
1988
2255
  }
1989
2256
  return index;
1990
2257
  };
2258
+ const residentFor = (agentId, source) => {
2259
+ const request = resolveResident(agentId, source);
2260
+ residentRequests.add(request);
2261
+ const release = () => residentRequests.delete(request);
2262
+ request.then(release, release);
2263
+ return request;
2264
+ };
1991
2265
  const resolveRequestOptions = (startOptions, agentId, source) => {
1992
2266
  source?.assertCurrent();
1993
2267
  const runtimeConfig = params.getRuntimeConfig();
@@ -2016,10 +2290,10 @@ function createCodexSessionCatalogControl(params) {
2016
2290
  };
2017
2291
  const createRequestSnapshot = (agentId, source, catalogPreview, catalogPreviewCache, catalogRows) => {
2018
2292
  const pluginConfig = getPluginConfig();
2019
- const runtime = source?.appServer ?? params.resolveRuntimeOptions({ pluginConfig });
2293
+ const runtime = source?.appServer ?? resolveRuntimeOptions({ pluginConfig });
2020
2294
  const requestOptions = resolveRequestOptions(runtime.start, agentId, source);
2021
2295
  return createCodexCatalogRequestSnapshot(runtime.requestTimeoutMs, async (method, requestParams, timeoutMs, assertCurrent, observation) => {
2022
- const { codexControlRequest } = await import("./command-rpc-DHFpn4le.mjs").then((n) => n.n);
2296
+ const { codexControlRequest } = await import("./command-rpc-DixIj3HW.mjs").then((n) => n.n);
2023
2297
  return await codexControlRequest(pluginConfig, method, requestParams, {
2024
2298
  ...requestOptions,
2025
2299
  authProfileId: null,
@@ -2038,12 +2312,12 @@ function createCodexSessionCatalogControl(params) {
2038
2312
  source?.assertCurrent();
2039
2313
  const withPinnedConnection = async (run) => {
2040
2314
  const pluginConfig = getPluginConfig();
2041
- const runtime = source?.appServer ?? params.resolveRuntimeOptions({ pluginConfig });
2315
+ const runtime = source?.appServer ?? resolveRuntimeOptions({ pluginConfig });
2042
2316
  const { agentDir, config: runtimeConfig, startOptions } = resolveRequestOptions(runtime.start, agentId, source);
2043
2317
  let catalogIndex;
2044
- const { getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient, retireSharedCodexAppServerClientIfCurrent } = await import("./shared-client-BpTtuLQ5.mjs").then((n) => n.y);
2045
- const { resolveCodexAppServerClientInstanceId } = await import("./client-vXs2929Q.mjs").then((n) => n.n);
2046
- const { requestCodexAppServerClientJson } = await import("./request-BioXJLYa.mjs").then((n) => n.a);
2318
+ const { getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient, retireSharedCodexAppServerClientIfCurrent } = await import("./shared-client-DA4VR4Eb.mjs").then((n) => n.y);
2319
+ const { resolveCodexAppServerClientInstanceId } = await import("./client-Cs08OXVQ.mjs").then((n) => n.n);
2320
+ const { requestCodexAppServerClientJson } = await import("./request-D2L0zMrq.mjs").then((n) => n.a);
2047
2321
  const client = await getLeasedSharedCodexAppServerClient({
2048
2322
  agentDir,
2049
2323
  config: runtimeConfig,
@@ -2106,20 +2380,37 @@ function createCodexSessionCatalogControl(params) {
2106
2380
  return source ? forRequest(agentId, source) : void 0;
2107
2381
  };
2108
2382
  return {
2383
+ hasActiveWork: () => starting > 0 || residentRequests.size > 0 || retiring !== void 0 || hasActiveSharedCodexAppServerWork() || [...indexes.values()].some((index) => index.hasActiveWork()),
2384
+ async disconnect() {
2385
+ await retireIndexes();
2386
+ await Promise.allSettled(residentRequests);
2387
+ const clients = getSharedCodexAppServerClientState();
2388
+ if (clients.liveClients.size > 0 || clients.startup.pending.size > 0) {
2389
+ const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-DA4VR4Eb.mjs").then((n) => n.y);
2390
+ await clearSharedCodexAppServerClientAndWait();
2391
+ }
2392
+ },
2109
2393
  async start() {
2110
- const serviceScope = AsyncLocalStorage.snapshot();
2111
- runBackground = (run) => serviceScope(run);
2112
- for (const agentId of listAgentIds(params.getRuntimeConfig() ?? params.config ?? {})) for (const source of await homeResolver.forAgent(agentId)) {
2113
- if (source.usesProcessHomeFallback) continue;
2114
- forRequest(agentId, source).initialize().catch((error) => embeddedAgentLog.warn("Codex catalog hydration failed", { error }));
2394
+ const epoch = residentEpoch;
2395
+ starting++;
2396
+ try {
2397
+ const serviceScope = AsyncLocalStorage.snapshot();
2398
+ runBackground = (run) => serviceScope(run);
2399
+ for (const agentId of listAgentIds(params.getRuntimeConfig() ?? params.config ?? {})) for (const source of await homeResolver.forAgent(agentId)) {
2400
+ if (closed || residentEpoch !== epoch) return;
2401
+ if (source.usesProcessHomeFallback) continue;
2402
+ forRequest(agentId, source).initialize().catch((error) => {
2403
+ if (!findCodexAppServerSpawnError(error)) embeddedAgentLog.warn("Codex catalog hydration failed", { error });
2404
+ });
2405
+ }
2406
+ } finally {
2407
+ starting--;
2115
2408
  }
2116
2409
  },
2117
2410
  async stop() {
2118
2411
  closed = true;
2119
- await Promise.allSettled([...indexes.values()].map((index) => index.close()));
2120
- await retiring;
2121
- indexes.clear();
2122
- directHomes.clear();
2412
+ await retireIndexes();
2413
+ await Promise.allSettled(residentRequests);
2123
2414
  },
2124
2415
  forRequest,
2125
2416
  forUpstream,
@@ -2127,9 +2418,11 @@ function createCodexSessionCatalogControl(params) {
2127
2418
  async forNode(agentId) {
2128
2419
  const source = await homeResolver.forNode(agentId);
2129
2420
  return {
2421
+ assertCurrent: () => source.assertCurrent(),
2130
2422
  control: forRequest(source.agentId, source),
2131
2423
  sourceHomeId: source.sourceHomeId,
2132
- codexHome: source.codexHome
2424
+ codexHome: source.codexHome,
2425
+ transport: source.appServer.start.transport
2133
2426
  };
2134
2427
  }
2135
2428
  };
@@ -2167,6 +2460,7 @@ function toGenericCatalogHost(host, localTerminalAvailable) {
2167
2460
  label: host.label,
2168
2461
  kind: host.kind,
2169
2462
  connected: host.connected,
2463
+ ...host.pending ? { pending: true } : {},
2170
2464
  ...host.nodeId ? { nodeId: host.nodeId } : {},
2171
2465
  sessions: host.sessions.map((session) => {
2172
2466
  const continuableStatus = !session.archived && (session.status === "idle" || session.status === "notLoaded");
@@ -2257,9 +2551,10 @@ function catalogHostMapper(localTerminalAvailable, localHomes) {
2257
2551
  const diagnostics = currentCodexCatalogListDiagnostics();
2258
2552
  const started = diagnostics ? performance.now() : 0;
2259
2553
  try {
2554
+ const localSourceAvailable = localTerminalAvailable && localHomes.some((home) => home.hostId === host.hostId && home.appServer.start.transport === "stdio");
2260
2555
  return {
2261
- ...toGenericCatalogHost(host, localTerminalAvailable),
2262
- canStartTerminal: host.kind === "gateway" ? localTerminalAvailable && host.hostId === "gateway:local" && localHomes.some((home) => home.hostId === host.hostId && home.appServer.start.transport === "stdio") : host.canStartTerminal === true
2556
+ ...toGenericCatalogHost(host, localSourceAvailable),
2557
+ canStartTerminal: host.kind === "gateway" ? localSourceAvailable && host.hostId === "gateway:local" : host.canStartTerminal === true
2263
2558
  };
2264
2559
  } finally {
2265
2560
  if (diagnostics && !diagnostics.closed) diagnostics.fields.mappingMs = (diagnostics.fields.mappingMs ?? 0) + performance.now() - started;
@@ -2312,8 +2607,9 @@ function registerCodexSessionCatalog(params) {
2312
2607
  };
2313
2608
  };
2314
2609
  const checkUpstreamActivity = createChecker(params);
2610
+ const nodeSnapshots = new CodexCatalogNodeSnapshots();
2315
2611
  const createListOperation = (query) => withCatalogListScope(async () => {
2316
- const { agentId: requestedAgentId, allowProcessHomeFallback, listNodes, onHost, waitUntil, signal, sessionEntries, ...gatewayQuery } = query;
2612
+ const { agentId: requestedAgentId, allowProcessHomeFallback, allowPartialResults, listNodes, onHost, waitUntil, signal, sessionEntries, ...gatewayQuery } = query;
2317
2613
  const agentId = resolveRequestAgentId(requestedAgentId);
2318
2614
  const selectedQuery = readGatewayParams(gatewayQuery);
2319
2615
  const localHomes = selectedQuery.hostIds && !selectedQuery.hostIds.some(isLocalCodexCatalogHost) ? [] : [...await catalogHomes(agentId, allowProcessHomeFallback)];
@@ -2330,6 +2626,8 @@ function registerCodexSessionCatalog(params) {
2330
2626
  signal,
2331
2627
  sessionEntries,
2332
2628
  localHomes,
2629
+ allowPartialResults,
2630
+ nodeSnapshots,
2333
2631
  ...onHost ? { onHost: mappedHostPublisher(onHost, mapHost) } : {}
2334
2632
  }), mapHost);
2335
2633
  });
@@ -2348,6 +2646,7 @@ function registerCodexSessionCatalog(params) {
2348
2646
  control,
2349
2647
  hostId: request.hostId,
2350
2648
  threadId: request.threadId,
2649
+ sourceHomeId: request.sourceHomeId,
2351
2650
  cursor: request.cursor,
2352
2651
  limit: request.limit ?? 20,
2353
2652
  ...source ? { source } : {}
@@ -2362,6 +2661,7 @@ function registerCodexSessionCatalog(params) {
2362
2661
  config,
2363
2662
  hostId: request.hostId,
2364
2663
  threadId: request.threadId,
2664
+ sourceHomeId: request.sourceHomeId,
2365
2665
  clientScopes: request.clientScopes
2366
2666
  });
2367
2667
  if (!isLocalCodexCatalogHost(request.hostId)) throw new CatalogParamsError("Codex session catalog hostId is invalid");
@@ -2449,15 +2749,15 @@ const codexSessionCatalogRuntime = {
2449
2749
  archiveLocal: archiveLocalCodexSession
2450
2750
  };
2451
2751
  async function continueLocalCodexSession(...args) {
2452
- const { continueLocalCodexSession: run } = await import("./session-catalog-adoption-CR_whkEW.mjs");
2752
+ const { continueLocalCodexSession: run } = await import("./session-catalog-adoption-BI6UTDZT.mjs");
2453
2753
  return run(...args);
2454
2754
  }
2455
2755
  async function archiveLocalCodexSession(...args) {
2456
- const { archiveLocalCodexSession: run } = await import("./session-catalog-archive-CwZaPacf.mjs");
2756
+ const { archiveLocalCodexSession: run } = await import("./session-catalog-archive-lHBqzhaO.mjs");
2457
2757
  return run(...args);
2458
2758
  }
2459
2759
  async function continueNodeCodexSession(...args) {
2460
- const { continueNodeCodexSession: run } = await import("./session-catalog-node-continue-Dowv8osw.mjs");
2760
+ const { continueNodeCodexSession: run } = await import("./session-catalog-node-continue-6g6qi4A9.mjs");
2461
2761
  return run(...args);
2462
2762
  }
2463
2763
  //#endregion