@openclaw/codex 2026.9.5 → 2026.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +2 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
  4. package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
  5. package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
  6. package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
  7. package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
  8. package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
  9. package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
  10. package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
  11. package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
  12. package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
  13. package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
  14. package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
  15. package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
  16. package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
  17. package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
  18. package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  19. package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
  20. package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
  21. package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
  22. package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
  23. package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
  24. package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
  25. package/dist/.setup/compact-C2WamavS.mjs +776 -0
  26. package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
  27. package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
  28. package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
  29. package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
  30. package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
  31. package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
  32. package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
  33. package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
  34. package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
  35. package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
  36. package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
  37. package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
  38. package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
  39. package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
  40. package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
  41. package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
  42. package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
  43. package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
  44. package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
  45. package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
  46. package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
  47. package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
  48. package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
  49. package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
  50. package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
  51. package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
  52. package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
  53. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  54. package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
  55. package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
  56. package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
  57. package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
  58. package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
  59. package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
  60. package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
  61. package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
  62. package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
  63. package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
  64. package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
  65. package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
  66. package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
  67. package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
  68. package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
  69. package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
  70. package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
  71. package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
  72. package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
  73. package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
  74. package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
  75. package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
  76. package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
  77. package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
  78. package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
  79. package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
  80. package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
  81. package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
  82. package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
  83. package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
  84. package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
  85. package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
  86. package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
  87. package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
  88. package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
  89. package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
  90. package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
  91. package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
  92. package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
  93. package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
  94. package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
  95. package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
  96. package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
  97. package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
  98. package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
  99. package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
  100. package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
  101. package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
  102. package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
  103. package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
  104. package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
  105. package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
  106. package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
  107. package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
  108. package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
  109. package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
  110. package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
  111. package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
  112. package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
  113. package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
  114. package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
  115. package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
  116. package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
  117. package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
  118. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  119. package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
  120. package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
  121. package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
  122. package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
  123. package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
  124. package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
  125. package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
  126. package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
  127. package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
  128. package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
  129. package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
  130. package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
  131. package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
  132. package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
  133. package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
  134. package/dist/api.js +25 -16
  135. package/dist/catalog-page-worker-entrypoint.js +12 -0
  136. package/dist/catalog-page.worker.js +9 -0
  137. package/dist/cli-metadata.js +1 -1
  138. package/dist/doctor-contract-api.js +50 -8
  139. package/dist/harness.js +344 -1
  140. package/dist/index.js +345 -346
  141. package/dist/media-understanding-provider.js +9 -22
  142. package/dist/migration-provider-api.js +1 -1
  143. package/dist/provider-discovery.js +1 -1
  144. package/dist/session-history-worker-runtime.js +16 -33
  145. package/dist/session-history.worker.js +1 -1
  146. package/openclaw.plugin.json +14 -2
  147. package/package.json +11 -7
  148. package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
  149. package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
  150. package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
  151. package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
  152. package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
  153. package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
  154. package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
  155. package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
  156. package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
  157. package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
  158. package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
  159. package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
  160. package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
  161. package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
  162. package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
  163. package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
  164. package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
  165. package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
  166. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
  167. package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
  168. package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
  169. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
  170. package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
  171. package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
  172. package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
  173. package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
  174. package/dist/.setup/version-CoqzXPgK.mjs +0 -12
@@ -1,11 +1,18 @@
1
- import { r as normalizeCodexAppServerArgs } from "./launch-args-DnMak49W.mjs";
1
+ import { r as normalizeCodexAppServerArgs } from "./launch-args-DbFCehO7.mjs";
2
+ import { i as resolveManagedCodexNativeCommand } from "./managed-binary-kiWRhNRE.mjs";
3
+ import { i as recordCodexAppServerSpawnFailure, r as getCodexAppServerSpawnFailure } from "./spawn-error-CL3n6MAa.mjs";
2
4
  import { createHash, randomUUID } from "node:crypto";
5
+ import { stripVTControlCharacters } from "node:util";
6
+ import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-registration";
3
7
  import { z } from "zod";
4
8
  import { materializeWindowsSpawnProgram, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
5
9
  import { closeSync, constants, openSync, readSync } from "node:fs";
6
10
  import path from "node:path";
7
11
  import { readFile, readdir } from "node:fs/promises";
12
+ import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
8
13
  import { once } from "node:events";
14
+ import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
15
+ import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
9
16
  import { execFile, spawn } from "node:child_process";
10
17
  import { setImmediate } from "node:timers/promises";
11
18
  import { finished } from "node:stream/promises";
@@ -302,6 +309,8 @@ const MAX_PROCESS_QUIESCE_PASSES = 16;
302
309
  /** Discharges the registered root obligation, including an already-obsolete PID. */
303
310
  async function terminateCodexAppServerOrphan(expected) {
304
311
  const deadline = Date.now() + MAX_PROCESS_CONTAINMENT_MS;
312
+ const initial = (await readCodexAppServerProcessSnapshot(deadline, [expected.pid])).find((row) => row.pid === expected.pid);
313
+ if (!initial || !hasSameIdentity(initial, expected) || isDeadProcessState(initial.state)) return true;
305
314
  const result = await terminateCodexAppServerDescendants({
306
315
  pid: expected.pid,
307
316
  kill: (signal) => signalProcess(expected.pid, signal ?? "SIGTERM")
@@ -314,7 +323,7 @@ async function terminateCodexAppServerOrphan(expected) {
314
323
  if (current && isSameLiveRoot(current, contained.root, true)) signalProcess(current.pgid === current.pid ? -current.pid : current.pid, "SIGKILL");
315
324
  }
316
325
  while (Date.now() < deadline) {
317
- const snapshot = await readCodexAppServerProcessSnapshot(deadline).catch(() => void 0);
326
+ const snapshot = await readCodexAppServerProcessSnapshot(deadline, [expected.pid]).catch(() => void 0);
318
327
  if (!snapshot?.some((row) => row.pid === process.pid)) return false;
319
328
  const current = snapshot.find((row) => row.pid === expected.pid);
320
329
  if (!current || !hasSameIdentity(current, expected) || isDeadProcessState(current.state)) {
@@ -531,21 +540,37 @@ const registrationSchema = z.object({
531
540
  parent: processIdentity,
532
541
  child: childIdentity
533
542
  }).strict();
543
+ const registrationCleanup = /* @__PURE__ */ new WeakMap();
544
+ const processReaper = resolveGlobalSingleton(Symbol.for("openclaw.codexAppServerProcessReaper"), () => new KeyedAsyncQueue());
545
+ /** Join bookkeeping after the transport owner has observed physical exit. */
546
+ async function waitForCodexAppServerProcessRegistrationCleanup(child) {
547
+ await registrationCleanup.get(child);
548
+ }
534
549
  function fingerprintProcessCommand(command) {
535
550
  return createHash("sha256").update(command).digest("hex");
536
551
  }
537
552
  async function openProcessRegistrationStore() {
538
- const { createPluginStateSyncKeyedStore } = await import("openclaw/plugin-sdk/plugin-state-store-runtime");
539
- return createPluginStateSyncKeyedStore("codex", {
553
+ const env = {
554
+ ...process.env,
555
+ OPENCLAW_STATE_DIR: resolveStateDir()
556
+ };
557
+ const { createPluginStateKeyedStore } = await import("openclaw/plugin-sdk/plugin-state-store-runtime");
558
+ return createPluginStateKeyedStore("codex", {
540
559
  namespace: "app-server-processes",
541
560
  maxEntries: 512,
542
- overflowPolicy: "reject-new"
561
+ overflowPolicy: "reject-new",
562
+ env
543
563
  });
544
564
  }
545
565
  async function reapRegisteredCodexAppServerOrphans() {
546
566
  const store = await openProcessRegistrationStore();
567
+ await processReaper.enqueue("orphans", () => sweepRegisteredCodexAppServerOrphans(store));
568
+ return store;
569
+ }
570
+ async function sweepRegisteredCodexAppServerOrphans(store) {
571
+ const entries = await store.entries();
547
572
  const deadline = Date.now() + PROCESS_REGISTRATION_INSPECTION_MS;
548
- for (const entry of store.entries()) {
573
+ for (const entry of entries) {
549
574
  if (Date.now() >= deadline) throw new Error("Codex orphan cleanup exceeded its startup budget. Retry to finish cleanup.");
550
575
  const registration = registrationSchema.parse(entry.value);
551
576
  const snapshot = await readCodexAppServerProcessSnapshot(deadline, [registration.parent.pid, registration.child.pid]);
@@ -557,29 +582,34 @@ async function reapRegisteredCodexAppServerOrphans() {
557
582
  try {
558
583
  command = await readCodexAppServerProcessCommand(child, deadline);
559
584
  } catch (error) {
560
- if ((await readCodexAppServerProcessSnapshot(deadline, [registration.child.pid])).find((row) => row.pid === registration.child.pid)?.startedAt === registration.child.startedAt) throw error;
585
+ const current = (await readCodexAppServerProcessSnapshot(deadline, [registration.child.pid])).find((row) => row.pid === registration.child.pid);
586
+ if (current?.startedAt === registration.child.startedAt && !isDeadProcessState(current.state)) throw error;
561
587
  }
562
588
  if (command !== void 0 && fingerprintProcessCommand(command) !== registration.child.commandFingerprint) {
563
- store.delete(entry.key);
589
+ await store.delete(entry.key);
564
590
  continue;
565
591
  }
566
592
  }
567
593
  if (!await terminateCodexAppServerOrphan(registration.child)) throw new Error(`Cannot reap registered Codex process ${registration.child.pid}. Stop it before retrying.`);
568
- store.delete(entry.key);
594
+ await store.delete(entry.key);
569
595
  }
570
596
  }
571
597
  function createCodexAppServerProcessReaperService() {
598
+ let pendingSweep;
572
599
  return {
573
600
  id: "codex-app-server-process-reaper",
574
601
  start(ctx) {
575
602
  if (process.platform === "win32") return;
576
- (async () => {
603
+ pendingSweep = (async () => {
577
604
  try {
578
605
  await reapRegisteredCodexAppServerOrphans();
579
606
  } catch (error) {
580
607
  ctx.logger.warn(`Codex app-server orphan cleanup failed: ${String(error)}`);
581
608
  }
582
609
  })();
610
+ },
611
+ async stop() {
612
+ await pendingSweep;
583
613
  }
584
614
  };
585
615
  }
@@ -588,8 +618,7 @@ async function prepareCodexAppServerProcessRegistration() {
588
618
  if (process.platform === "win32") return async (child) => {
589
619
  await once(child, "spawn");
590
620
  };
591
- await reapRegisteredCodexAppServerOrphans();
592
- const store = await openProcessRegistrationStore();
621
+ const store = await reapRegisteredCodexAppServerOrphans();
593
622
  return async (child) => {
594
623
  await once(child, "spawn");
595
624
  if (!child.pid) throw new ProcessInspectionError("unavailable");
@@ -601,21 +630,63 @@ async function prepareCodexAppServerProcessRegistration() {
601
630
  const command = await readCodexAppServerProcessCommand(spawned, deadline);
602
631
  if (child.exitCode !== null || child.signalCode !== null) throw new Error("Cannot register the Codex child process command: the child exited during inspection. Retry.");
603
632
  const key = randomUUID();
604
- store.register(key, {
633
+ const value = {
605
634
  parent: processIdentity.parse(parent),
606
635
  child: childIdentity.parse({
607
636
  ...spawned,
608
637
  commandFingerprint: fingerprintProcessCommand(command)
609
638
  })
639
+ };
640
+ const exited = new Promise((resolve) => {
641
+ child.once("exit", () => resolve());
610
642
  });
611
- child.once("exit", () => {
643
+ const registered = store.register(key, value);
644
+ const cleanup = (async () => {
645
+ await exited;
646
+ await registered.catch(() => void 0);
612
647
  try {
613
- store.delete(key);
648
+ await store.delete(key);
614
649
  } catch {}
615
- });
650
+ })();
651
+ registrationCleanup.set(child, cleanup);
652
+ await registered;
653
+ if (child.exitCode !== null || child.signalCode !== null) {
654
+ await cleanup;
655
+ throw new Error("Cannot register the Codex child process: the child exited during registration. Retry.");
656
+ }
616
657
  };
617
658
  }
618
659
  //#endregion
660
+ //#region extensions/codex/src/app-server/managed-launcher-failure.ts
661
+ /** The official npm launcher prints Node's native spawn error and exits before initialization. */
662
+ function observeManagedCodexLauncherFailure(child, nativeCommand) {
663
+ let prefix = "";
664
+ let launchCode;
665
+ const startupFailure = { complete() {
666
+ child.stderr.off("data", onData);
667
+ child.off("exit", onExit);
668
+ prefix = "";
669
+ } };
670
+ const onData = (chunk) => {
671
+ if (launchCode || prefix.length >= 16384) return;
672
+ prefix = (prefix + stripVTControlCharacters(chunk.toString())).slice(0, 16384);
673
+ if (/\bError: spawn\b/u.test(prefix) && /syscall: ['"]spawn(?: [^'"\r\n]*)?['"]/u.test(prefix)) launchCode = /\bcode: ['"](ENOENT|EACCES|EBADARCH|Unknown system error -86)['"]/u.exec(prefix)?.[1];
674
+ else if (/Error: Missing optional dependency @openai\/codex-[\w-]+\. Reinstall Codex:/u.test(prefix)) launchCode = "ENOENT";
675
+ };
676
+ const onExit = (code) => {
677
+ startupFailure.complete();
678
+ if (code !== 1 || !launchCode) return;
679
+ const described = recordCodexAppServerSpawnFailure(Object.assign(/* @__PURE__ */ new Error(`spawn ${launchCode}`), {
680
+ code: launchCode,
681
+ syscall: "spawn"
682
+ }), nativeCommand, nativeCommand);
683
+ if (described instanceof Error) startupFailure.error = described;
684
+ };
685
+ child.stderr.on("data", onData);
686
+ child.once("exit", onExit);
687
+ Object.assign(child, { startupFailure });
688
+ }
689
+ //#endregion
619
690
  //#region extensions/codex/src/app-server/transport.ts
620
691
  /**
621
692
  * Shared transport lifecycle helpers for stdio and WebSocket Codex app-server
@@ -645,12 +716,7 @@ function beginCodexAppServerTransportClose(child, options) {
645
716
  finishCodexAppServerTransportClose(child, options, forceKill);
646
717
  return "uncertain";
647
718
  }
648
- let contained;
649
- try {
650
- contained = await terminateCodexAppServerDescendants(child);
651
- } catch {
652
- contained = void 0;
653
- }
719
+ const contained = await terminateCodexAppServerDescendants(child).catch(() => void 0);
654
720
  if (contained === "exited") return "natural";
655
721
  try {
656
722
  finishCodexAppServerTransportClose(child, options, forceKill, contained?.resume);
@@ -696,6 +762,7 @@ async function closeCodexAppServerTransportAndWait(child, options = {}) {
696
762
  const closure = beginCodexAppServerTransportClose(child, options);
697
763
  const containment = await closure.closing;
698
764
  const settled = await waitForCodexAppServerTransportExit(child, options.exitTimeoutMs ?? 2e3, drained);
765
+ if (settled) await waitForCodexAppServerProcessRegistrationCleanup(child);
699
766
  closure.naturalExit = containment === "natural" && settled;
700
767
  if (options.drainStdio) {
701
768
  child.stdout.destroy?.();
@@ -710,7 +777,7 @@ async function closeCodexAppServerTransportAndWait(child, options = {}) {
710
777
  };
711
778
  }
712
779
  function hasCodexAppServerTransportExited(child) {
713
- return child.exitCode !== null && child.exitCode !== void 0 ? true : child.signalCode !== null && child.signalCode !== void 0;
780
+ return child.exitCode != null || child.signalCode != null;
714
781
  }
715
782
  async function waitForCodexAppServerTransportExit(child, timeoutMs, drained) {
716
783
  return await new Promise((resolve) => {
@@ -756,46 +823,36 @@ const RUNTIME_INJECTION_ENVIRONMENT_KEYS = /* @__PURE__ */ new Set([
756
823
  "LD_PRELOAD"
757
824
  ]);
758
825
  const QA_PARENT_PID_ENV = "OPENCLAW_QA_PARENT_PID";
759
- const DEFAULT_SPAWN_RUNTIME = {
760
- platform: process.platform,
761
- env: process.env,
762
- execPath: process.execPath,
763
- isBun: typeof process.versions.bun === "string"
764
- };
765
826
  /** Resolves the concrete command/argv/shell settings used to spawn Codex app-server. */
766
- function resolveCodexAppServerSpawnInvocation(options, runtime = DEFAULT_SPAWN_RUNTIME) {
827
+ function resolveCodexAppServerSpawnInvocation(options, env) {
767
828
  if (options.commandSource === "managed") throw new Error("Managed Codex app-server start options must be resolved before spawn.");
768
829
  const program = resolveWindowsSpawnProgram({
769
830
  command: options.command,
770
- platform: runtime.platform,
771
- env: runtime.env,
772
- execPath: runtime.execPath,
831
+ platform: process.platform,
832
+ env,
833
+ execPath: process.execPath,
773
834
  packageName: "@openai/codex"
774
835
  });
775
836
  const args = normalizeCodexAppServerArgs(options.args);
776
837
  const resolved = materializeWindowsSpawnProgram(program, args);
777
- if (runtime.isBun && options.commandSource === "resolved-managed" && resolved.resolution === "direct" && [
838
+ if (options.commandSource === "resolved-managed" && resolved.resolution === "direct" && [
778
839
  ".cjs",
779
840
  ".js",
780
841
  ".mjs"
781
842
  ].includes(path.extname(resolved.command).toLowerCase())) return {
782
- command: runtime.execPath,
783
- args: [resolved.command, ...resolved.argv],
784
- windowsHide: resolved.windowsHide
785
- };
786
- return {
787
- command: resolved.command,
788
- args: resolved.argv,
789
- shell: resolved.shell,
790
- windowsHide: resolved.windowsHide
843
+ ...resolved,
844
+ command: process.execPath,
845
+ argv: [resolved.command, ...resolved.argv],
846
+ resolution: "node-entrypoint"
791
847
  };
848
+ return resolved;
792
849
  }
793
850
  /** Merges app-server environment overrides while honoring clearEnv and unsafe key filtering. */
794
851
  function resolveCodexAppServerSpawnEnv(options, baseEnv = process.env, platform = process.platform) {
795
852
  const env = Object.create(null);
796
853
  copySafeEnvironmentEntries(env, baseEnv);
797
854
  copySafeEnvironmentEntries(env, options.env ?? {});
798
- const keysToClear = normalizedEnvironmentKeys(options.clearEnv ?? []);
855
+ const keysToClear = (options.clearEnv ?? []).map((key) => key.trim()).filter(Boolean);
799
856
  if (platform === "win32") {
800
857
  const lowerCaseKeysToClear = new Set(keysToClear.map((key) => key.toLowerCase()));
801
858
  for (const candidate of Object.keys(env)) if (lowerCaseKeysToClear.has(candidate.toLowerCase())) delete env[candidate];
@@ -807,18 +864,6 @@ function isCodexRuntimeInjectionEnvironmentKey(rawKey) {
807
864
  const key = rawKey.toUpperCase();
808
865
  return RUNTIME_INJECTION_ENVIRONMENT_KEYS.has(key) || key.startsWith("DYLD_");
809
866
  }
810
- /** Keeps QA-owned app-server processes inside the gateway process-group cleanup boundary. */
811
- function resolveCodexAppServerDetachedMode(env, platform = process.platform) {
812
- return platform !== "win32" && !env[QA_PARENT_PID_ENV]?.trim();
813
- }
814
- function normalizedEnvironmentKeys(rawKeys) {
815
- const keys = [];
816
- for (const rawKey of rawKeys) {
817
- const key = rawKey.trim();
818
- if (key.length > 0) keys.push(key);
819
- }
820
- return keys;
821
- }
822
867
  function copySafeEnvironmentEntries(target, source) {
823
868
  for (const [key, value] of Object.entries(source)) {
824
869
  if (UNSAFE_ENVIRONMENT_KEYS.has(key)) continue;
@@ -828,27 +873,45 @@ function copySafeEnvironmentEntries(target, source) {
828
873
  /** Spawns the Codex app-server process and returns the shared transport interface. */
829
874
  async function createStdioTransport(options, baseEnv = process.env, assertCurrent, onSpawn) {
830
875
  const env = resolveCodexAppServerSpawnEnv(options, baseEnv);
831
- const invocation = resolveCodexAppServerSpawnInvocation(options, {
832
- platform: process.platform,
833
- env,
834
- execPath: process.execPath,
835
- isBun: typeof process.versions.bun === "string"
836
- });
876
+ const invocation = resolveCodexAppServerSpawnInvocation(options, env);
877
+ const nativeCommand = options.commandSource === "resolved-managed" ? resolveManagedCodexNativeCommand(options.command, { pathExists: () => true }) : void 0;
878
+ const launchKey = JSON.stringify([
879
+ invocation.command,
880
+ options.cwd ?? process.cwd(),
881
+ nativeCommand ?? null,
882
+ path.isAbsolute(invocation.command) ? null : env.PATH ?? env.Path
883
+ ]);
884
+ const previousFailure = getCodexAppServerSpawnFailure(launchKey) ?? (nativeCommand ? getCodexAppServerSpawnFailure(nativeCommand) : void 0);
885
+ if (previousFailure) throw previousFailure;
837
886
  const register = await prepareCodexAppServerProcessRegistration();
838
887
  assertCurrent?.();
839
- const child = spawn(invocation.command, invocation.args, {
840
- ...options.cwd !== void 0 ? { cwd: options.cwd } : {},
841
- env,
842
- detached: resolveCodexAppServerDetachedMode(env),
843
- shell: invocation.shell,
844
- stdio: [
845
- "pipe",
846
- "pipe",
847
- "pipe"
848
- ],
849
- windowsHide: invocation.windowsHide
888
+ embeddedAgentLog.debug("Codex app-server spawn", {
889
+ command: invocation.command,
890
+ launcher: options.command,
891
+ ...options.cwd ? { cwd: options.cwd } : {},
892
+ ...nativeCommand ? { nativeCommand } : {},
893
+ platform: process.platform,
894
+ arch: process.arch
850
895
  });
896
+ let child;
897
+ try {
898
+ child = spawn(invocation.command, invocation.argv, {
899
+ ...options.cwd !== void 0 ? { cwd: options.cwd } : {},
900
+ env,
901
+ detached: process.platform !== "win32" && !env[QA_PARENT_PID_ENV]?.trim(),
902
+ shell: invocation.shell,
903
+ stdio: [
904
+ "pipe",
905
+ "pipe",
906
+ "pipe"
907
+ ],
908
+ windowsHide: invocation.windowsHide
909
+ });
910
+ } catch (error) {
911
+ throw recordCodexAppServerSpawnFailure(error, invocation.command, launchKey);
912
+ }
851
913
  try {
914
+ if (nativeCommand && invocation.resolution === "node-entrypoint") observeManagedCodexLauncherFailure(child, nativeCommand);
852
915
  onSpawn?.(child);
853
916
  await register(child);
854
917
  assertCurrent?.();
@@ -856,8 +919,8 @@ async function createStdioTransport(options, baseEnv = process.env, assertCurren
856
919
  } catch (error) {
857
920
  await closeCodexAppServerTransportAndWait(child, { drainStdio: true });
858
921
  assertCurrent?.();
859
- throw error;
922
+ throw child.startupFailure?.error ?? recordCodexAppServerSpawnFailure(error, invocation.command, launchKey);
860
923
  }
861
924
  }
862
925
  //#endregion
863
- export { hasCodexAppServerNaturalExit as a, closeCodexAppServerTransportAndWait as i, resolveCodexAppServerSpawnEnv as n, createCodexAppServerProcessReaperService as o, closeCodexAppServerTransport as r, createStdioTransport as t };
926
+ export { closeCodexAppServerTransportAndWait as a, closeCodexAppServerTransport as i, resolveCodexAppServerSpawnEnv as n, hasCodexAppServerNaturalExit as o, resolveCodexAppServerSpawnInvocation as r, createCodexAppServerProcessReaperService as s, createStdioTransport as t };
@@ -0,0 +1,211 @@
1
+ import { r as resolveCodexAppServerUserHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
2
+ import "./config-DKhXquav.mjs";
3
+ import path from "node:path";
4
+ import { EventEmitter } from "node:events";
5
+ import net from "node:net";
6
+ import { PassThrough, Writable } from "node:stream";
7
+ import { StringDecoder } from "node:string_decoder";
8
+ import { WebSocket } from "openclaw/plugin-sdk/websocket-runtime";
9
+ //#region extensions/codex/src/app-server/transport-websocket.ts
10
+ /**
11
+ * Adapts a remote Codex app-server WebSocket endpoint to the shared stdio-like
12
+ * transport interface.
13
+ */
14
+ const WEBSOCKET_HANDSHAKE_TIMEOUT_MS = 1e4;
15
+ const WEBSOCKET_PING_INTERVAL_MS = 2e4;
16
+ const WEBSOCKET_PONG_TIMEOUT_MS = 2e4;
17
+ const MAX_CONSECUTIVE_MISSED_WEBSOCKET_PONGS = 5;
18
+ /** Only the transport can prove that its buffered initialize never reached a peer. */
19
+ function isCodexWebSocketOpenFailure(error) {
20
+ const seen = /* @__PURE__ */ new Set();
21
+ let current = error;
22
+ while (current instanceof Error && !seen.has(current)) {
23
+ seen.add(current);
24
+ if ("code" in current && current.code === "CODEX_APP_SERVER_WEBSOCKET_OPEN_FAILED") return true;
25
+ current = current.cause;
26
+ }
27
+ return false;
28
+ }
29
+ /** Opens a WebSocket app-server transport and maps newline-delimited frames to stdout/stdin. */
30
+ function createWebSocketTransport(options) {
31
+ if (!options.url) throw new Error("codex app-server websocket transport requires plugins.entries.codex.config.appServer.url");
32
+ const events = new EventEmitter();
33
+ const stdout = new PassThrough();
34
+ const stderr = new PassThrough();
35
+ const websocketOptions = {
36
+ headers: {
37
+ ...options.headers,
38
+ ...options.authToken ? { Authorization: `Bearer ${options.authToken}` } : {}
39
+ },
40
+ perMessageDeflate: false,
41
+ ...options.transport === "websocket" ? { handshakeTimeout: WEBSOCKET_HANDSHAKE_TIMEOUT_MS } : {}
42
+ };
43
+ const unixSocketPath = resolveCodexAppServerUnixSocketPath(options);
44
+ const socket = unixSocketPath ? new WebSocket("ws://localhost/", {
45
+ ...websocketOptions,
46
+ createConnection: () => connectCodexAppServerUnixSocket(unixSocketPath)
47
+ }) : new WebSocket(options.url, websocketOptions);
48
+ const pendingFrames = [];
49
+ const stdinDecoder = new StringDecoder("utf8");
50
+ let pendingLine = "";
51
+ let opened = false;
52
+ let killed = false;
53
+ let exitCode = null;
54
+ let pingTimeout;
55
+ let pongTimeout;
56
+ let expectedPong;
57
+ let consecutiveMissedPongs = 0;
58
+ let heartbeatSequence = 0;
59
+ const clearConnectionHealthTimers = () => {
60
+ if (pingTimeout) {
61
+ clearTimeout(pingTimeout);
62
+ pingTimeout = void 0;
63
+ }
64
+ if (pongTimeout) {
65
+ clearTimeout(pongTimeout);
66
+ pongTimeout = void 0;
67
+ }
68
+ expectedPong = void 0;
69
+ };
70
+ const sendHeartbeatPing = () => {
71
+ if (socket.readyState !== WebSocket.OPEN || pongTimeout) return;
72
+ const payload = Buffer.from(`openclaw-codex-${++heartbeatSequence}`);
73
+ expectedPong = payload;
74
+ pongTimeout = setTimeout(() => {
75
+ pongTimeout = void 0;
76
+ expectedPong = void 0;
77
+ consecutiveMissedPongs += 1;
78
+ if (consecutiveMissedPongs >= MAX_CONSECUTIVE_MISSED_WEBSOCKET_PONGS) {
79
+ socket.terminate();
80
+ return;
81
+ }
82
+ sendHeartbeatPing();
83
+ }, WEBSOCKET_PONG_TIMEOUT_MS);
84
+ pongTimeout.unref();
85
+ socket.ping(payload, void 0, (error) => {
86
+ if (error) socket.terminate();
87
+ });
88
+ };
89
+ const scheduleHeartbeatPing = () => {
90
+ if (options.transport !== "websocket" || socket.readyState !== WebSocket.OPEN || pingTimeout || pongTimeout) return;
91
+ pingTimeout = setTimeout(() => {
92
+ pingTimeout = void 0;
93
+ sendHeartbeatPing();
94
+ }, WEBSOCKET_PING_INTERVAL_MS);
95
+ pingTimeout.unref();
96
+ };
97
+ const recordConnectionActivity = () => {
98
+ consecutiveMissedPongs = 0;
99
+ if (pongTimeout) {
100
+ clearTimeout(pongTimeout);
101
+ pongTimeout = void 0;
102
+ }
103
+ expectedPong = void 0;
104
+ scheduleHeartbeatPing();
105
+ };
106
+ const sendFrame = (frame) => {
107
+ const trimmed = frame.trim();
108
+ if (!trimmed) return;
109
+ if (socket.readyState === WebSocket.OPEN) {
110
+ socket.send(trimmed);
111
+ return;
112
+ }
113
+ pendingFrames.push(trimmed);
114
+ };
115
+ socket.once("open", () => {
116
+ opened = true;
117
+ for (const frame of pendingFrames.splice(0)) socket.send(frame);
118
+ scheduleHeartbeatPing();
119
+ });
120
+ socket.on("pong", (payload) => {
121
+ if (expectedPong?.equals(payload)) recordConnectionActivity();
122
+ });
123
+ socket.once("error", (error) => {
124
+ clearConnectionHealthTimers();
125
+ const code = "code" in error ? error.code : void 0;
126
+ if (options.transport === "websocket" && !opened && (code === "ECONNREFUSED" || code === "ECONNRESET" || code === "ETIMEDOUT" || error.message === "Opening handshake has timed out")) {
127
+ events.emit("error", Object.assign(new Error(error.message, { cause: error }), { code: "CODEX_APP_SERVER_WEBSOCKET_OPEN_FAILED" }));
128
+ return;
129
+ }
130
+ events.emit("error", error);
131
+ });
132
+ socket.once("close", (code, reason) => {
133
+ clearConnectionHealthTimers();
134
+ killed = true;
135
+ exitCode = code;
136
+ events.emit("exit", code, reason.toString("utf8"));
137
+ });
138
+ socket.on("message", (data) => {
139
+ if (options.transport === "websocket") recordConnectionActivity();
140
+ const frame = websocketFrameToBuffer(data);
141
+ const writable = stdout.write(frame);
142
+ const delimited = frame.at(-1) === 10 || stdout.write(Buffer.from("\n"));
143
+ if (!writable || !delimited) socket.pause();
144
+ });
145
+ stdout.on("drain", () => {
146
+ if (socket.readyState === WebSocket.OPEN) socket.resume();
147
+ });
148
+ const stdin = new Writable({
149
+ write(chunk, _encoding, callback) {
150
+ pendingLine += stdinDecoder.write(chunk);
151
+ const lines = pendingLine.split("\n");
152
+ pendingLine = lines.pop() ?? "";
153
+ for (const frame of lines) sendFrame(frame);
154
+ callback();
155
+ },
156
+ final(callback) {
157
+ pendingLine += stdinDecoder.end();
158
+ if (pendingLine) sendFrame(pendingLine);
159
+ pendingLine = "";
160
+ callback();
161
+ }
162
+ });
163
+ const closeSocket = () => {
164
+ if (socket.readyState === WebSocket.CLOSED || socket.readyState === WebSocket.CLOSING) return;
165
+ socket.close();
166
+ };
167
+ stdin.once("finish", closeSocket);
168
+ stdin.once("close", closeSocket);
169
+ return {
170
+ maxFrameBytes: 16777216,
171
+ stdin,
172
+ stdout,
173
+ stderr,
174
+ get killed() {
175
+ return killed;
176
+ },
177
+ get exitCode() {
178
+ return exitCode;
179
+ },
180
+ kill: (signal) => {
181
+ killed = true;
182
+ clearConnectionHealthTimers();
183
+ if (signal === "SIGKILL") socket.terminate();
184
+ else socket.close();
185
+ },
186
+ once: (event, listener) => events.once(event, listener),
187
+ off: (event, listener) => events.off(event, listener)
188
+ };
189
+ }
190
+ /** Named local-only socket boundary for the egress classifier. */
191
+ function connectCodexAppServerUnixSocket(socketPath) {
192
+ return net.createConnection(socketPath);
193
+ }
194
+ /** Resolves the canonical or explicitly configured Codex control socket. */
195
+ function resolveCodexAppServerUnixSocketPath(options) {
196
+ if (options.transport !== "unix") {
197
+ if (options.url?.startsWith("unix://")) throw new Error("codex app-server unix URL requires unix transport");
198
+ return;
199
+ }
200
+ const url = options.url ?? "unix://";
201
+ if (!url.startsWith("unix://")) throw new Error("codex app-server unix transport requires a unix:// URL");
202
+ return url.slice(7) || path.join(resolveCodexAppServerUserHomeDir(options.env ?? process.env), "app-server-control", "app-server-control.sock");
203
+ }
204
+ function websocketFrameToBuffer(data) {
205
+ if (typeof data === "string") return Buffer.from(data);
206
+ if (Buffer.isBuffer(data)) return data;
207
+ if (Array.isArray(data)) return Buffer.concat(data);
208
+ return Buffer.from(data);
209
+ }
210
+ //#endregion
211
+ export { isCodexWebSocketOpenFailure as n, resolveCodexAppServerUnixSocketPath as r, createWebSocketTransport as t };
@@ -1,4 +1,4 @@
1
- import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { asOptionalRecord, readNonEmptyStringPreservingWhitespace } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  //#region extensions/codex/src/app-server/upstream-prompt-provenance.ts
3
3
  const UPSTREAM_USER_TEXT_META_KEY = "upstreamUserText";
4
4
  const MIRROR_IDENTITY_META_KEY = "mirrorIdentity";
@@ -16,10 +16,7 @@ function attachCodexMirrorIdentity(message, identity) {
16
16
  }
17
17
  function readMirrorIdentity(message) {
18
18
  const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
19
- const record = asOptionalRecord(meta);
20
- if (!record) return;
21
- const id = record[MIRROR_IDENTITY_META_KEY];
22
- return typeof id === "string" && id ? id : void 0;
19
+ return readNonEmptyStringPreservingWhitespace(asOptionalRecord(meta)?.[MIRROR_IDENTITY_META_KEY]);
23
20
  }
24
21
  function attachUpstreamUserText(message, text) {
25
22
  const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
@@ -34,10 +31,7 @@ function attachUpstreamUserText(message, text) {
34
31
  }
35
32
  function readUpstreamUserText(message) {
36
33
  const meta = message && CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
37
- const record = asOptionalRecord(meta);
38
- if (!record) return;
39
- const text = record[UPSTREAM_USER_TEXT_META_KEY];
40
- return typeof text === "string" && text ? text : void 0;
34
+ return readNonEmptyStringPreservingWhitespace(asOptionalRecord(meta)?.[UPSTREAM_USER_TEXT_META_KEY]);
41
35
  }
42
36
  //#endregion
43
37
  export { readUpstreamUserText as i, attachUpstreamUserText as n, readMirrorIdentity as r, attachCodexMirrorIdentity as t };