@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,20 +1,198 @@
1
- import { h as resolveCodexAppServerHomeDir } from "./config-security-BRQ2mgW9.mjs";
2
- import { c as isCodexAppServerIndeterminateTransportError, o as isCodexAppServerConnectionClosedError, s as isCodexAppServerIndeterminateRequestCancellationError } from "./client-vXs2929Q.mjs";
3
- import { o as resolveCodexComputerUseConfig } from "./config-options-BsanJ8QG.mjs";
4
- import { l as resolveMacOSDesktopCodexBundledMarketplaceCandidates, s as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand } from "./managed-binary-DP6Rib3P.mjs";
5
- import { n as describeControlFailure } from "./capabilities-_vXcZGSx.mjs";
6
- import { i as requestCodexAppServerJson } from "./request-BioXJLYa.mjs";
7
- import "./config-CedDWjM-.mjs";
8
- import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-CeAhl_h4.mjs";
9
- import { $ as assertNotSymlink, D as acquireCodexNativeConfigFence, Q as resolveCodexManagedBundledMarketplacePath, Y as reconcileCodexComputerUseStartArtifacts, b as waitForCodexAppServerClientDesktopGenerationDrain, c as getLeasedSharedCodexAppServerClient, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, p as readCodexAppServerClientProcessIdentity, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-BpTtuLQ5.mjs";
10
- import { existsSync } from "node:fs";
1
+ import { t as resolveCodexAppServerHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
2
+ import { o as resolveCodexComputerUseConfig } from "./config-options-CzyWLTJt.mjs";
3
+ import { d as resolveMacOSDesktopCodexBundledMarketplaceCandidates, t as isManagedCodexDesktopCommand } from "./managed-binary-kiWRhNRE.mjs";
4
+ import { n as describeControlFailure } from "./capabilities-B3WEZl4e.mjs";
5
+ import { r as requestCodexAppServerClientJson } from "./request-BHZ1nz8d.mjs";
6
+ import "./config-DKhXquav.mjs";
7
+ import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-C0NbLms1.mjs";
8
+ import { $ as reconcileCodexComputerUseStartArtifacts, O as acquireCodexNativeConfigFence, at as isLegacyCodexComputerUsePluginDisabled, b as withLeasedCodexAppServerClientStartSelectionRetry, c as getLeasedSharedCodexAppServerClient, ct as assertNotSymlink, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, it as hasLegacyCodexComputerUseMcpPolicy, nt as resolveBundledComputerUseMarketplacePath, ot as resolveManagedCodexComputerUseConfig, p as readCodexAppServerClientProcessIdentity, rt as resolveClientManagedBundledMarketplacePath, st as ensureCodexComputerUseSharedPluginCache, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError, y as waitForCodexAppServerClientDesktopGenerationDrain } from "./shared-client-DqyTMYug.mjs";
9
+ import { c as isCodexAppServerIndeterminateTransportError, o as isCodexAppServerConnectionClosedError, s as isCodexAppServerIndeterminateRequestCancellationError } from "./client-N0JpgSzF.mjs";
10
+ import { r as CodexAppServerUnsafeSubscriptionError, u as retireUnsafeCodexTurnClientBestEffort } from "./attempt-client-cleanup-DOP-cW5j.mjs";
11
11
  import path from "node:path";
12
- import fs$1 from "node:fs/promises";
12
+ import fs from "node:fs/promises";
13
+ import { toErrorObject } from "openclaw/plugin-sdk/error-runtime";
14
+ //#region extensions/codex/src/app-server/computer-use-readiness.ts
15
+ /** Computer Use readiness probes and their native subscription lifecycle. */
16
+ function createComputerUseRequest(params) {
17
+ const assertCurrent = params.assertCurrent;
18
+ if (params.request) {
19
+ const request = params.request;
20
+ if (!assertCurrent) return request;
21
+ return async (method, requestParams, options) => {
22
+ if (method !== "thread/unsubscribe") assertCurrent();
23
+ return await request(method, requestParams, options);
24
+ };
25
+ }
26
+ const client = params.client;
27
+ if (!client) throw new Error("Computer Use setup requires an acquired app-server client");
28
+ return async (method, requestParams, options) => await client.request(method, requestParams, {
29
+ timeoutMs: options?.timeoutMs ?? params.timeoutMs,
30
+ signal: options?.signal ?? params.signal,
31
+ ...method === "thread/unsubscribe" ? {} : { assertCurrent }
32
+ });
33
+ }
34
+ const COMPUTER_USE_LIVE_TEST_RETRY_COUNT = 1;
35
+ const COMPUTER_USE_LIVE_TEST_THREAD_NAME = "OpenClaw Computer Use readiness probe";
36
+ const COMPUTER_USE_LIST_APPS_TOOL = "list_apps";
37
+ const COMPUTER_USE_UNIFIED_JS_TOOL = "js";
38
+ const COMPUTER_USE_UNIFIED_JS_PROBE = "await cua.getState();";
39
+ async function runCodexComputerUseLiveTest(params) {
40
+ const startedAt = Date.now();
41
+ let lastError;
42
+ let repair;
43
+ const probe = resolveComputerUseLiveTestProbe(params.tools);
44
+ for (let attempt = 0; attempt <= COMPUTER_USE_LIVE_TEST_RETRY_COUNT; attempt += 1) {
45
+ let threadId;
46
+ let outcome;
47
+ try {
48
+ threadId = (await params.request("thread/start", {
49
+ input: [],
50
+ developerInstructions: COMPUTER_USE_LIVE_TEST_THREAD_NAME,
51
+ ephemeral: true
52
+ }, { timeoutMs: params.config.liveTestTimeoutMs })).thread.id;
53
+ if ((await params.request("mcpServer/tool/call", {
54
+ threadId,
55
+ server: params.config.mcpServerName,
56
+ tool: probe.tool,
57
+ arguments: probe.arguments
58
+ }, { timeoutMs: params.config.toolCallTimeoutMs })).isError === true) throw new Error(`Computer Use readiness tool ${params.config.mcpServerName}.${probe.tool} returned an error result`);
59
+ outcome = {
60
+ ok: true,
61
+ liveTest: {
62
+ status: "passed",
63
+ ok: true,
64
+ attempted: true,
65
+ attempts: attempt + 1,
66
+ timeoutMs: params.config.liveTestTimeoutMs,
67
+ retried: attempt > 0,
68
+ repaired: Boolean(repair?.attempted && repair.warnings.length === 0),
69
+ durationMs: Math.max(0, Date.now() - startedAt),
70
+ message: "Computer Use live test passed."
71
+ }
72
+ };
73
+ } catch (error) {
74
+ outcome = {
75
+ ok: false,
76
+ error
77
+ };
78
+ }
79
+ let cleanupError;
80
+ if (threadId) try {
81
+ await cleanupComputerUseProbeThread(params, threadId);
82
+ } catch (error) {
83
+ cleanupError = toErrorObject(error, "Computer Use readiness cleanup failed");
84
+ }
85
+ if (!outcome.ok && (params.signal?.aborted || isCodexAppServerStartSelectionChangedError(outcome.error))) throw toErrorObject(outcome.error, "Computer Use live test failed");
86
+ if (cleanupError) throw cleanupError;
87
+ if (outcome.ok) return {
88
+ liveTest: outcome.liveTest,
89
+ ...repair ? { repair } : {}
90
+ };
91
+ lastError = outcome.error;
92
+ if (attempt < COMPUTER_USE_LIVE_TEST_RETRY_COUNT && params.config.autoRepair) repair = await repairComputerUseMcpRuntime(params.request, params.config);
93
+ }
94
+ const errorMessage = describeControlFailure(lastError);
95
+ return {
96
+ liveTest: {
97
+ status: "failed",
98
+ ok: false,
99
+ attempted: true,
100
+ attempts: 2,
101
+ timeoutMs: params.config.liveTestTimeoutMs,
102
+ retried: true,
103
+ repaired: Boolean(repair?.attempted && repair.warnings.length === 0),
104
+ durationMs: Math.max(0, Date.now() - startedAt),
105
+ message: `Computer Use live test failed after 2 attempts: ${errorMessage}`,
106
+ error: errorMessage
107
+ },
108
+ ...repair ? { repair } : {}
109
+ };
110
+ }
111
+ function resolveComputerUseLiveTestProbe(tools) {
112
+ if (tools?.includes(COMPUTER_USE_UNIFIED_JS_TOOL) && !tools.includes(COMPUTER_USE_LIST_APPS_TOOL)) return {
113
+ tool: COMPUTER_USE_UNIFIED_JS_TOOL,
114
+ arguments: { code: COMPUTER_USE_UNIFIED_JS_PROBE }
115
+ };
116
+ return {
117
+ tool: COMPUTER_USE_LIST_APPS_TOOL,
118
+ arguments: {}
119
+ };
120
+ }
121
+ async function repairComputerUseMcpRuntime(request, config) {
122
+ try {
123
+ await request("config/mcpServer/reload", void 0, { timeoutMs: config.liveTestTimeoutMs });
124
+ return {
125
+ attempted: true,
126
+ killedPids: [],
127
+ warnings: [],
128
+ message: "Reloaded Computer Use MCP servers through Codex app-server."
129
+ };
130
+ } catch (error) {
131
+ const message = `Could not reload Computer Use MCP servers: ${describeControlFailure(error)}`;
132
+ return {
133
+ attempted: true,
134
+ killedPids: [],
135
+ warnings: [message],
136
+ message
137
+ };
138
+ }
139
+ }
140
+ async function cleanupComputerUseProbeThread(params, threadId) {
141
+ try {
142
+ await params.request("thread/unsubscribe", { threadId }, {
143
+ timeoutMs: params.config.liveTestTimeoutMs,
144
+ signal: AbortSignal.timeout(params.config.liveTestTimeoutMs)
145
+ });
146
+ } catch (error) {
147
+ if (params.client) await retireUnsafeCodexTurnClientBestEffort(params.client, "Computer Use readiness cleanup");
148
+ throw new CodexAppServerUnsafeSubscriptionError("Computer Use readiness cleanup failed", { cause: error });
149
+ }
150
+ }
151
+ function skippedLiveTestStatus(config, message) {
152
+ return {
153
+ status: "skipped",
154
+ ok: false,
155
+ attempted: false,
156
+ attempts: 0,
157
+ timeoutMs: config.liveTestTimeoutMs,
158
+ retried: false,
159
+ repaired: false,
160
+ message
161
+ };
162
+ }
163
+ //#endregion
164
+ //#region extensions/codex/src/app-server/computer-use-status.ts
165
+ function unavailableStatus(config, reason, message) {
166
+ const disabled = reason === "disabled";
167
+ return {
168
+ enabled: !disabled,
169
+ ready: false,
170
+ reason,
171
+ installed: reason === "plugin_disabled" ? null : false,
172
+ pluginEnabled: false,
173
+ mcpServerAvailable: false,
174
+ pluginName: config.pluginName,
175
+ mcpServerName: config.mcpServerName,
176
+ ...!disabled && config.marketplaceName ? { marketplaceName: config.marketplaceName } : {},
177
+ ...!disabled && config.marketplacePath ? { marketplacePath: config.marketplacePath } : {},
178
+ tools: [],
179
+ installation: {
180
+ status: disabled ? "disabled" : reason === "plugin_disabled" ? "unchecked" : reason === "marketplace_missing" ? "marketplace_missing" : "not_installed",
181
+ ok: false,
182
+ message
183
+ },
184
+ exposure: {
185
+ status: "skipped",
186
+ ok: false,
187
+ message: disabled ? "MCP exposure was not checked because Computer Use is disabled." : "MCP exposure was not checked because Computer Use installation is not ready."
188
+ },
189
+ liveTest: skippedLiveTestStatus(config, disabled ? "Computer Use live test was not run because Computer Use is disabled." : "Computer Use live test was not run because installation is not ready."),
190
+ warnings: [],
191
+ message
192
+ };
193
+ }
194
+ //#endregion
13
195
  //#region extensions/codex/src/app-server/computer-use.ts
14
- /**
15
- * Computer Use plugin/MCP readiness checks and optional install flow for Codex
16
- * app-server sessions.
17
- */
18
196
  var CodexComputerUseSetupError = class extends Error {
19
197
  constructor(status) {
20
198
  super(status.message);
@@ -31,53 +209,50 @@ const COMPUTER_USE_MARKETPLACE_NAME_PRIORITY = [
31
209
  "openai-curated-remote",
32
210
  "local"
33
211
  ];
34
- const COMPUTER_USE_LIVE_TEST_RETRY_COUNT = 1;
35
- const COMPUTER_USE_LIVE_TEST_THREAD_NAME = "OpenClaw Computer Use readiness probe";
36
- const COMPUTER_USE_LIST_APPS_TOOL = "list_apps";
37
- const COMPUTER_USE_UNIFIED_JS_TOOL = "js";
38
- const COMPUTER_USE_UNIFIED_JS_PROBE = "await cua.getState();";
39
212
  /** Reads Computer Use readiness without installing or mutating app-server state. */
40
213
  async function readCodexComputerUseStatus(params = {}) {
41
214
  const config = resolveComputerUseConfig(params);
42
- if (!config.enabled) return disabledStatus(config);
215
+ if (!config.enabled) return unavailableStatus(config, "disabled", "Computer Use is disabled.");
43
216
  try {
44
217
  return await inspectCodexComputerUse({
45
218
  ...params,
46
219
  computerUseConfig: config,
47
- installPlugin: false
220
+ runLiveTest: true,
221
+ installMode: "none"
48
222
  });
49
223
  } catch (error) {
50
224
  return unavailableStatus(config, "check_failed", `Computer Use check failed: ${describeControlFailure(error)}`);
51
225
  }
52
226
  }
53
227
  /**
54
- * Ensures Computer Use is ready when enabled, optionally installing when config
55
- * allows safe auto-install.
228
+ * Ensures installation and MCP exposure before a turn, optionally installing when
229
+ * config allows safe auto-install. Only strict startup waits for a live probe.
56
230
  */
57
231
  async function ensureCodexComputerUse(params = {}) {
58
232
  const config = resolveComputerUseConfig(params);
59
- if (!config.enabled) return disabledStatus(config);
233
+ if (!config.enabled) return unavailableStatus(config, "disabled", "Computer Use is disabled.");
60
234
  const status = await inspectCodexComputerUse({
61
235
  ...params,
62
236
  computerUseConfig: config,
63
- installPlugin: false
237
+ runLiveTest: config.strictReadiness,
238
+ installMode: "none",
239
+ refreshSharedCache: config.autoInstall
64
240
  });
65
241
  if (status.ready) return status;
66
- if (isNonStrictLiveTestStartupAllowed(status, config)) return status;
67
242
  if (config.autoInstall) {
68
243
  const blockedAutoInstallStatus = blockUnsafeAutoInstallStatus(config);
69
244
  if (blockedAutoInstallStatus) throw new CodexComputerUseSetupError(blockedAutoInstallStatus);
70
245
  const installedStatus = await inspectCodexComputerUse({
71
246
  ...params,
72
247
  computerUseConfig: config,
73
- installPlugin: true
248
+ runLiveTest: config.strictReadiness,
249
+ installMode: "automatic",
250
+ refreshSharedCache: true
74
251
  });
75
- if (isNonStrictLiveTestStartupAllowed(installedStatus, config)) return installedStatus;
76
252
  if (!installedStatus.ready) throw new CodexComputerUseSetupError(installedStatus);
77
253
  return installedStatus;
78
254
  }
79
- if (!status.ready) throw new CodexComputerUseSetupError(status);
80
- return status;
255
+ throw new CodexComputerUseSetupError(status);
81
256
  }
82
257
  /** Forces Computer Use plugin installation and returns the ready status. */
83
258
  async function installCodexComputerUse(params = {}) {
@@ -93,13 +268,13 @@ async function installCodexComputerUse(params = {}) {
93
268
  const status = await inspectCodexComputerUse({
94
269
  ...params,
95
270
  computerUseConfig: config,
96
- installPlugin: true
271
+ runLiveTest: true,
272
+ installMode: "explicit"
97
273
  });
98
274
  if (!status.ready) throw new CodexComputerUseSetupError(status);
99
275
  return status;
100
276
  }
101
277
  async function inspectCodexComputerUse(params) {
102
- if (!params.installPlugin) return await inspectCodexComputerUseWithoutFence(params);
103
278
  const resolvedRuntime = resolveCodexAppServerRuntimeOptions({
104
279
  pluginConfig: params.pluginConfig,
105
280
  managedCommandOrder: "desktop-first"
@@ -107,19 +282,57 @@ async function inspectCodexComputerUse(params) {
107
282
  const operationTimeoutMs = params.timeoutMs ?? resolvedRuntime.requestTimeoutMs;
108
283
  const deadline = operationTimeoutMs > 0 ? Date.now() + operationTimeoutMs : void 0;
109
284
  const remainingTimeoutMs = () => deadline === void 0 ? operationTimeoutMs : Math.max(1, deadline - Date.now());
110
- let leasedClient;
285
+ const clientOptions = {
286
+ startOptions: resolvedRuntime.start,
287
+ pluginConfig: params.pluginConfig,
288
+ config: params.config,
289
+ agentDir: params.agentDir,
290
+ abandonSignal: params.signal,
291
+ assertCurrent: params.assertCurrent
292
+ };
293
+ const lease = {};
111
294
  try {
112
295
  let client = params.client;
113
296
  if (!client && !params.request) {
114
297
  client = await getLeasedSharedCodexAppServerClient({
115
- startOptions: resolvedRuntime.start,
116
- pluginConfig: params.pluginConfig,
117
- timeoutMs: remainingTimeoutMs(),
118
- config: params.config,
119
- agentDir: params.agentDir,
120
- abandonSignal: params.signal
298
+ ...clientOptions,
299
+ timeoutMs: remainingTimeoutMs()
300
+ });
301
+ lease.client = client;
302
+ }
303
+ if (params.installMode === "none" && !params.refreshSharedCache) {
304
+ if (!lease.client) return await inspectCodexComputerUseWithoutFence(params);
305
+ return await withLeasedCodexAppServerClientStartSelectionRetry({
306
+ lease,
307
+ options: {
308
+ ...clientOptions,
309
+ timeoutMs: remainingTimeoutMs()
310
+ },
311
+ signal: params.signal,
312
+ run: async (readClient, requestOptions) => {
313
+ const { assertCurrent } = requestOptions();
314
+ return await inspectCodexComputerUseWithoutFence({
315
+ ...params,
316
+ client: readClient,
317
+ request: async (method, requestParams, options) => {
318
+ const scopedOptions = method === "thread/unsubscribe" ? {
319
+ timeoutMs: options?.timeoutMs ?? operationTimeoutMs,
320
+ signal: options?.signal,
321
+ assertCurrent
322
+ } : requestOptions();
323
+ return await requestCodexAppServerClientJson({
324
+ client: readClient,
325
+ method,
326
+ requestParams,
327
+ config: params.config,
328
+ timeoutMs: Math.min(options?.timeoutMs ?? operationTimeoutMs, scopedOptions.timeoutMs),
329
+ signal: scopedOptions.signal,
330
+ assertCurrent: scopedOptions.assertCurrent
331
+ });
332
+ }
333
+ });
334
+ }
121
335
  });
122
- leasedClient = client;
123
336
  }
124
337
  const explicitManagedInstall = client && !resolveCodexComputerUseConfig({ pluginConfig: params.pluginConfig }).autoInstall ? await resolveExplicitManagedComputerUseInstallContext({
125
338
  ...params,
@@ -154,56 +367,78 @@ async function inspectCodexComputerUse(params) {
154
367
  });
155
368
  let releaseFenceOnReturn = true;
156
369
  try {
157
- try {
158
- return await inspectCodexComputerUseWithoutFence({
159
- ...inspectionParams,
160
- releaseNativeConfigFence: release
161
- });
162
- } catch (error) {
163
- if (client && (isCodexAppServerIndeterminateRequestCancellationError(error) || isCodexAppServerIndeterminateTransportError(error) || isCodexAppServerConnectionClosedError(error))) {
164
- releaseFenceOnReturn = false;
165
- await client.closeAndRunAfterExit(release, "Computer Use config mutation");
166
- }
167
- throw error;
370
+ return await inspectCodexComputerUseWithoutFence({
371
+ ...inspectionParams,
372
+ releaseNativeConfigFence: release
373
+ });
374
+ } catch (error) {
375
+ if (client && (isCodexAppServerIndeterminateRequestCancellationError(error) || isCodexAppServerIndeterminateTransportError(error) || isCodexAppServerConnectionClosedError(error))) {
376
+ releaseFenceOnReturn = false;
377
+ await client.closeAndRunAfterExit(release, "Computer Use config mutation");
168
378
  }
379
+ throw error;
169
380
  } finally {
170
381
  if (releaseFenceOnReturn) release();
171
382
  }
172
383
  } finally {
173
- if (leasedClient) releaseLeasedSharedCodexAppServerClient(leasedClient);
384
+ if (lease.client) releaseLeasedSharedCodexAppServerClient(lease.client);
174
385
  }
175
386
  }
176
387
  async function inspectCodexComputerUseWithoutFence(params) {
177
388
  const request = createComputerUseRequest(params);
178
- if (params.installPlugin) {
389
+ if (params.installMode !== "none") {
179
390
  if (!resolveCodexComputerUseConfig({ pluginConfig: params.pluginConfig }).autoInstall) await prepareExplicitManagedComputerUseInstall(params);
180
- await request("experimentalFeature/enablement/set", { enablement: { plugins: true } });
181
391
  }
182
- const managedMarketplacePath = await resolveClientManagedBundledMarketplacePath(params.client, params.agentDir);
392
+ const managedMarketplacePath = await resolveClientManagedBundledMarketplacePath(params.client?.getRuntimeIdentity()?.codexHome, params.agentDir);
183
393
  const managedCodexHome = managedMarketplacePath ? params.client?.getRuntimeIdentity()?.codexHome : void 0;
184
- if (params.installPlugin && managedCodexHome) await assertNotSymlink(path.join(managedCodexHome, "config.toml"), "Codex config");
394
+ let computerUseConfig = await resolveManagedCodexComputerUseConfig(params.computerUseConfig, managedMarketplacePath);
395
+ const nativeDisableStatus = computerUseConfig !== params.computerUseConfig && params.installMode !== "explicit" ? unavailableStatus(params.computerUseConfig, "plugin_disabled", "Computer Use is disabled by native plugin policy. Run /codex computer-use install for explicit recovery, or enable computer-use@openai-bundled in native Codex config for automatic replacement.") : void 0;
396
+ if (computerUseConfig !== params.computerUseConfig) {
397
+ const nativeConfig = await request("config/read", { includeLayers: false });
398
+ if (nativeDisableStatus && isLegacyCodexComputerUsePluginDisabled(nativeConfig.config)) return nativeDisableStatus;
399
+ if (hasLegacyCodexComputerUseMcpPolicy(nativeConfig.config)) computerUseConfig = params.computerUseConfig;
400
+ }
401
+ if (params.installMode !== "none") await request("experimentalFeature/enablement/set", { enablement: { plugins: true } });
402
+ if (params.installMode !== "none" && managedCodexHome) await assertNotSymlink(path.join(managedCodexHome, "config.toml"), "Codex config");
185
403
  const marketplace = await resolveMarketplaceRef({
186
404
  request,
187
- config: params.computerUseConfig,
188
- allowAdd: params.installPlugin,
405
+ config: computerUseConfig,
406
+ allowAdd: params.installMode !== "none",
189
407
  signal: params.signal,
190
408
  defaultBundledMarketplacePath: params.defaultBundledMarketplacePath ?? managedMarketplacePath,
191
409
  defaultBundledMarketplacePathCandidates: params.defaultBundledMarketplacePathCandidates,
192
410
  managedCodexHome
193
411
  });
194
- if (!marketplace.marketplace) return unavailableStatus(params.computerUseConfig, "marketplace_missing", marketplace.message ?? `No Codex marketplace containing ${params.computerUseConfig.pluginName} is registered. Configure computerUse.marketplaceSource or computerUse.marketplacePath, then run /codex computer-use install.`);
412
+ if (!marketplace.marketplace) return unavailableStatus(computerUseConfig, "marketplace_missing", marketplace.message ?? `No Codex marketplace containing ${computerUseConfig.pluginName} is registered. Configure computerUse.marketplaceSource or computerUse.marketplacePath, then run /codex computer-use install.`);
195
413
  const pluginInspection = await ensureComputerUsePlugin({
196
414
  request,
197
- config: params.computerUseConfig,
415
+ config: computerUseConfig,
198
416
  marketplace: marketplace.marketplace,
199
- installPlugin: params.installPlugin
417
+ nativeDisableStatus,
418
+ installPlugin: params.installMode !== "none"
200
419
  });
201
420
  if (!pluginInspection.ok) return pluginInspection.status;
421
+ if (params.refreshSharedCache && computerUseConfig !== params.computerUseConfig && managedCodexHome && managedMarketplacePath && params.agentDir && params.client) {
422
+ const client = params.client;
423
+ await ensureCodexComputerUseSharedPluginCache({
424
+ codexHome: managedCodexHome,
425
+ ownershipRoot: params.agentDir,
426
+ bundledMarketplacePath: managedMarketplacePath,
427
+ config: computerUseConfig,
428
+ assertCurrent: () => {
429
+ params.assertCurrent?.();
430
+ assertCodexAppServerClientStartSelectionCurrent({ client });
431
+ }
432
+ });
433
+ }
202
434
  return await readComputerUseTools({
203
435
  request,
204
- config: params.computerUseConfig,
436
+ client: params.client,
437
+ signal: params.signal,
438
+ config: computerUseConfig,
205
439
  plugin: pluginInspection.plugin,
206
- installPlugin: params.installPlugin,
440
+ runLiveTest: params.runLiveTest,
441
+ installPlugin: params.installMode !== "none",
207
442
  releaseNativeConfigFence: params.releaseNativeConfigFence
208
443
  });
209
444
  }
@@ -227,7 +462,10 @@ async function prepareExplicitManagedComputerUseInstall(params) {
227
462
  ownsIsolatedCodexHome: true,
228
463
  desktopGeneration: context.desktopGeneration,
229
464
  forceCacheRefresh: true,
230
- assertCurrent: () => assertCodexAppServerClientStartSelectionCurrent({ client: context.client })
465
+ assertCurrent: () => {
466
+ params.assertCurrent?.();
467
+ assertCodexAppServerClientStartSelectionCurrent({ client: context.client });
468
+ }
231
469
  });
232
470
  }
233
471
  async function resolveExplicitManagedComputerUseInstallContext(params) {
@@ -239,7 +477,7 @@ async function resolveExplicitManagedComputerUseInstallContext(params) {
239
477
  const desktopGeneration = readCodexAppServerClientDesktopGeneration(params.client);
240
478
  if (!desktopGeneration) throw new Error("Codex Computer Use install requires a desktop-generation-bound client; reconnect and retry.");
241
479
  const expectedHome = resolveCodexAppServerHomeDir(params.agentDir);
242
- const [actualRealHome, expectedRealHome] = await Promise.all([fs$1.realpath(codexHome).catch(() => void 0), fs$1.realpath(expectedHome).catch(() => void 0)]);
480
+ const [actualRealHome, expectedRealHome] = await Promise.all([fs.realpath(codexHome).catch(() => void 0), fs.realpath(expectedHome).catch(() => void 0)]);
243
481
  if (!actualRealHome || actualRealHome !== expectedRealHome) return;
244
482
  return {
245
483
  client: params.client,
@@ -249,29 +487,18 @@ async function resolveExplicitManagedComputerUseInstallContext(params) {
249
487
  desktopGeneration
250
488
  };
251
489
  }
252
- async function resolveClientManagedBundledMarketplacePath(client, agentDir) {
253
- const codexHome = client?.getRuntimeIdentity()?.codexHome;
254
- if (!codexHome || !agentDir) return;
255
- const [actualRealHome, expectedRealHome] = await Promise.all([fs$1.realpath(codexHome).catch(() => void 0), fs$1.realpath(resolveCodexAppServerHomeDir(agentDir)).catch(() => void 0)]);
256
- if (!actualRealHome || actualRealHome !== expectedRealHome) return;
257
- const managedPath = resolveCodexManagedBundledMarketplacePath(codexHome);
258
- return existsSync(managedPath) ? managedPath : void 0;
259
- }
260
490
  async function ensureComputerUsePlugin(params) {
261
491
  let plugin = await readComputerUsePlugin(params.request, params.marketplace, params.config.pluginName);
262
- if (!plugin.summary.installed || !plugin.summary.enabled) {
263
- if (!params.installPlugin) return {
492
+ if (params.nativeDisableStatus) {
493
+ const nativeConfig = await params.request("config/read", { includeLayers: false });
494
+ if (isLegacyCodexComputerUsePluginDisabled(nativeConfig.config)) return {
264
495
  ok: false,
265
- status: statusFromPlugin({
266
- config: params.config,
267
- plugin,
268
- tools: [],
269
- reason: pluginSetupReason(plugin),
270
- message: pluginSetupMessage(params.config, plugin)
271
- })
496
+ status: params.nativeDisableStatus
272
497
  };
498
+ }
499
+ if (params.installPlugin && (!plugin.summary.installed || !plugin.summary.enabled)) {
273
500
  await params.request("plugin/install", pluginRequestParams(params.marketplace, params.config.pluginName));
274
- await reloadMcpServers(params.request);
501
+ await params.request("config/mcpServer/reload", void 0);
275
502
  plugin = await readComputerUsePlugin(params.request, params.marketplace, params.config.pluginName);
276
503
  }
277
504
  if (!plugin.summary.installed || !plugin.summary.enabled) return {
@@ -280,8 +507,8 @@ async function ensureComputerUsePlugin(params) {
280
507
  config: params.config,
281
508
  plugin,
282
509
  tools: [],
283
- reason: pluginSetupReason(plugin),
284
- message: pluginSetupMessage(params.config, plugin)
510
+ reason: plugin.summary.installed ? "plugin_disabled" : "plugin_not_installed",
511
+ message: plugin.summary.installed ? `Computer Use is installed, but the ${params.config.pluginName} plugin is disabled. Run /codex computer-use install or enable computerUse.autoInstall to re-enable it.` : "Computer Use is available but not installed. Run /codex computer-use install or enable computerUse.autoInstall."
285
512
  })
286
513
  };
287
514
  return {
@@ -293,7 +520,7 @@ async function readComputerUseTools(params) {
293
520
  let server = await readMcpServerStatus(params.request, params.config.mcpServerName);
294
521
  let tools = Object.keys(server?.tools ?? {}).toSorted();
295
522
  if ((!server || tools.length === 0) && params.installPlugin) {
296
- await reloadMcpServers(params.request);
523
+ await params.request("config/mcpServer/reload", void 0);
297
524
  server = await readMcpServerStatus(params.request, params.config.mcpServerName);
298
525
  tools = Object.keys(server?.tools ?? {}).toSorted();
299
526
  }
@@ -318,9 +545,12 @@ async function readComputerUseTools(params) {
318
545
  reason: "ready",
319
546
  message: "Computer Use is ready."
320
547
  });
548
+ if (!params.runLiveTest) return status;
321
549
  params.releaseNativeConfigFence?.();
322
550
  const { liveTest, repair } = await runCodexComputerUseLiveTest({
323
551
  request: params.request,
552
+ client: params.client,
553
+ signal: params.signal,
324
554
  config: params.config,
325
555
  tools
326
556
  });
@@ -339,99 +569,6 @@ async function readComputerUseTools(params) {
339
569
  message: liveTest.ok ? "Computer Use is ready." : compatibilityStartupAllowed ? `${liveTest.message} Startup is allowed because computerUse.strictReadiness is false.` : liveTest.message
340
570
  };
341
571
  }
342
- function isNonStrictLiveTestStartupAllowed(status, config) {
343
- return !config.strictReadiness && status.reason === "live_test_failed" && status.installed && status.pluginEnabled && status.mcpServerAvailable && status.installation.ok && status.exposure.ok;
344
- }
345
- async function runCodexComputerUseLiveTest(params) {
346
- const startedAt = Date.now();
347
- let lastError;
348
- let repair;
349
- const probe = resolveComputerUseLiveTestProbe(params.tools);
350
- for (let attempt = 0; attempt <= COMPUTER_USE_LIVE_TEST_RETRY_COUNT; attempt += 1) {
351
- let threadId;
352
- try {
353
- threadId = (await params.request("thread/start", {
354
- input: [],
355
- developerInstructions: COMPUTER_USE_LIVE_TEST_THREAD_NAME,
356
- ephemeral: true
357
- }, { timeoutMs: params.config.liveTestTimeoutMs })).thread.id;
358
- if ((await params.request("mcpServer/tool/call", {
359
- threadId,
360
- server: params.config.mcpServerName,
361
- tool: probe.tool,
362
- arguments: probe.arguments
363
- }, { timeoutMs: params.config.toolCallTimeoutMs })).isError === true) throw new Error(`Computer Use readiness tool ${params.config.mcpServerName}.${probe.tool} returned an error result`);
364
- return {
365
- liveTest: {
366
- status: "passed",
367
- ok: true,
368
- attempted: true,
369
- attempts: attempt + 1,
370
- timeoutMs: params.config.liveTestTimeoutMs,
371
- retried: attempt > 0,
372
- repaired: Boolean(repair?.attempted && repair.warnings.length === 0),
373
- durationMs: Math.max(0, Date.now() - startedAt),
374
- message: "Computer Use live test passed."
375
- },
376
- ...repair ? { repair } : {}
377
- };
378
- } catch (error) {
379
- if (isCodexAppServerStartSelectionChangedError(error)) throw error;
380
- lastError = error;
381
- } finally {
382
- if (threadId) await cleanupComputerUseProbeThread(params.request, threadId, params.config);
383
- }
384
- if (attempt < COMPUTER_USE_LIVE_TEST_RETRY_COUNT && params.config.autoRepair) repair = await repairComputerUseMcpRuntime(params.request, params.config);
385
- }
386
- const errorMessage = describeControlFailure(lastError);
387
- return {
388
- liveTest: {
389
- status: "failed",
390
- ok: false,
391
- attempted: true,
392
- attempts: 2,
393
- timeoutMs: params.config.liveTestTimeoutMs,
394
- retried: true,
395
- repaired: Boolean(repair?.attempted && repair.warnings.length === 0),
396
- durationMs: Math.max(0, Date.now() - startedAt),
397
- message: `Computer Use live test failed after 2 attempts: ${errorMessage}`,
398
- error: errorMessage
399
- },
400
- ...repair ? { repair } : {}
401
- };
402
- }
403
- function resolveComputerUseLiveTestProbe(tools) {
404
- if (tools?.includes(COMPUTER_USE_UNIFIED_JS_TOOL) && !tools.includes(COMPUTER_USE_LIST_APPS_TOOL)) return {
405
- tool: COMPUTER_USE_UNIFIED_JS_TOOL,
406
- arguments: { code: COMPUTER_USE_UNIFIED_JS_PROBE }
407
- };
408
- return {
409
- tool: COMPUTER_USE_LIST_APPS_TOOL,
410
- arguments: {}
411
- };
412
- }
413
- async function repairComputerUseMcpRuntime(request, config) {
414
- try {
415
- await request("config/mcpServer/reload", void 0, { timeoutMs: config.liveTestTimeoutMs });
416
- return {
417
- attempted: true,
418
- killedPids: [],
419
- warnings: [],
420
- message: "Reloaded Computer Use MCP servers through Codex app-server."
421
- };
422
- } catch (error) {
423
- const message = `Could not reload Computer Use MCP servers: ${describeControlFailure(error)}`;
424
- return {
425
- attempted: true,
426
- killedPids: [],
427
- warnings: [message],
428
- message
429
- };
430
- }
431
- }
432
- async function cleanupComputerUseProbeThread(request, threadId, config) {
433
- await Promise.allSettled([request("thread/unsubscribe", { threadId }, { timeoutMs: config.liveTestTimeoutMs }), request("thread/archive", { threadId }, { timeoutMs: config.liveTestTimeoutMs })]);
434
- }
435
572
  async function resolveMarketplaceRef(params) {
436
573
  let preferredMarketplaceName = params.config.marketplaceName;
437
574
  if (params.config.marketplaceSource && params.allowAdd) {
@@ -503,11 +640,6 @@ function blockUnsafeAutoInstallStatus(config) {
503
640
  function shouldAddBundledComputerUseMarketplace(params) {
504
641
  return params.allowAdd && !params.config.marketplaceSource && !params.config.marketplacePath && !params.config.marketplaceName && Boolean(resolveBundledComputerUseMarketplacePath(params));
505
642
  }
506
- function resolveBundledComputerUseMarketplacePath(params) {
507
- if (params.defaultBundledMarketplacePath) return existsSync(params.defaultBundledMarketplacePath) ? params.defaultBundledMarketplacePath : void 0;
508
- if (!params.defaultBundledMarketplacePathCandidates) return;
509
- return resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath({ candidates: params.defaultBundledMarketplacePathCandidates });
510
- }
511
643
  function findComputerUseMarketplaces(listed, pluginName) {
512
644
  return listed.marketplaces.flatMap((marketplace) => {
513
645
  const plugin = marketplace.plugins.find((candidate) => candidate.name === pluginName || candidate.id === pluginName || candidate.id === `${pluginName}@${marketplace.name}`);
@@ -572,9 +704,6 @@ async function readMcpServerStatus(request, serverName) {
572
704
  cursor = response.nextCursor;
573
705
  } while (cursor);
574
706
  }
575
- async function reloadMcpServers(request) {
576
- await request("config/mcpServer/reload", void 0);
577
- }
578
707
  function pluginRequestParams(marketplace, pluginName) {
579
708
  return marketplace.kind === "local" ? {
580
709
  marketplacePath: marketplace.path,
@@ -584,13 +713,6 @@ function pluginRequestParams(marketplace, pluginName) {
584
713
  pluginName: marketplace.remotePluginId
585
714
  };
586
715
  }
587
- function pluginSetupReason(plugin) {
588
- return plugin.summary.installed ? "plugin_disabled" : "plugin_not_installed";
589
- }
590
- function pluginSetupMessage(config, plugin) {
591
- if (!plugin.summary.installed) return "Computer Use is available but not installed. Run /codex computer-use install or enable computerUse.autoInstall.";
592
- return `Computer Use is installed, but the ${config.pluginName} plugin is disabled. Run /codex computer-use install or enable computerUse.autoInstall to re-enable it.`;
593
- }
594
716
  function statusFromPlugin(params) {
595
717
  return {
596
718
  enabled: true,
@@ -607,131 +729,26 @@ function statusFromPlugin(params) {
607
729
  installation: installationStatusFromPlugin(params.plugin, params.message),
608
730
  exposure: exposureStatusFromTools(params.config, params.tools),
609
731
  liveTest: skippedLiveTestStatus(params.config, "Computer Use live test was not run."),
610
- warnings: pluginWarnings(params.plugin),
732
+ warnings: params.plugin.summary.source?.type === "remote" ? ["Computer Use plugin is resolved from a remote marketplace; live local bundles are preferred."] : [],
611
733
  message: params.message
612
734
  };
613
735
  }
614
- function disabledStatus(config) {
615
- return {
616
- enabled: false,
617
- ready: false,
618
- reason: "disabled",
619
- installed: false,
620
- pluginEnabled: false,
621
- mcpServerAvailable: false,
622
- pluginName: config.pluginName,
623
- mcpServerName: config.mcpServerName,
624
- tools: [],
625
- installation: {
626
- status: "disabled",
627
- ok: false,
628
- message: "Computer Use is disabled."
629
- },
630
- exposure: {
631
- status: "skipped",
632
- ok: false,
633
- message: "MCP exposure was not checked because Computer Use is disabled."
634
- },
635
- liveTest: skippedLiveTestStatus(config, "Computer Use live test was not run because Computer Use is disabled."),
636
- warnings: [],
637
- message: "Computer Use is disabled."
638
- };
639
- }
640
- function unavailableStatus(config, reason, message) {
641
- return {
642
- enabled: true,
643
- ready: false,
644
- reason,
645
- installed: false,
646
- pluginEnabled: false,
647
- mcpServerAvailable: false,
648
- pluginName: config.pluginName,
649
- mcpServerName: config.mcpServerName,
650
- ...config.marketplaceName ? { marketplaceName: config.marketplaceName } : {},
651
- ...config.marketplacePath ? { marketplacePath: config.marketplacePath } : {},
652
- tools: [],
653
- installation: {
654
- status: reason === "marketplace_missing" ? "marketplace_missing" : "not_installed",
655
- ok: false,
656
- message
657
- },
658
- exposure: {
659
- status: "skipped",
660
- ok: false,
661
- message: "MCP exposure was not checked because Computer Use installation is not ready."
662
- },
663
- liveTest: skippedLiveTestStatus(config, "Computer Use live test was not run because installation is not ready."),
664
- warnings: [],
665
- message
666
- };
667
- }
668
736
  function installationStatusFromPlugin(plugin, message) {
669
- if (!plugin.summary.installed) return {
670
- status: "not_installed",
671
- ok: false,
672
- message
673
- };
674
- if (!plugin.summary.enabled) return {
675
- status: "installed_disabled",
676
- ok: false,
677
- message
678
- };
737
+ const installed = plugin.summary.installed && plugin.summary.enabled;
679
738
  return {
680
- status: "installed",
681
- ok: true,
682
- message: "Computer Use plugin is installed and enabled."
739
+ status: !plugin.summary.installed ? "not_installed" : installed ? "installed" : "installed_disabled",
740
+ ok: installed,
741
+ message: installed ? "Computer Use plugin is installed and enabled." : message
683
742
  };
684
743
  }
685
744
  function exposureStatusFromTools(config, tools) {
686
- if (tools.length === 0) return {
687
- status: "missing",
688
- ok: false,
689
- message: `Computer Use MCP server ${config.mcpServerName} is not exposed.`
690
- };
745
+ const available = tools.length > 0;
691
746
  return {
692
- status: "available",
693
- ok: true,
694
- message: `Computer Use MCP server ${config.mcpServerName} exposes ${tools.length} tools.`
747
+ status: available ? "available" : "missing",
748
+ ok: available,
749
+ message: available ? `Computer Use MCP server ${config.mcpServerName} exposes ${tools.length} tools.` : `Computer Use MCP server ${config.mcpServerName} is not exposed.`
695
750
  };
696
751
  }
697
- function skippedLiveTestStatus(config, message) {
698
- return {
699
- status: "skipped",
700
- ok: false,
701
- attempted: false,
702
- attempts: 0,
703
- timeoutMs: config.liveTestTimeoutMs,
704
- retried: false,
705
- repaired: false,
706
- message
707
- };
708
- }
709
- function pluginWarnings(plugin) {
710
- const warnings = [];
711
- const source = plugin.summary.source;
712
- if (source && typeof source === "object" && "type" in source && source.type === "remote") warnings.push("Computer Use plugin is resolved from a remote marketplace; live local bundles are preferred.");
713
- return warnings;
714
- }
715
- function createComputerUseRequest(params) {
716
- if (params.request) return params.request;
717
- if (params.client) return async (method, requestParams, options) => await params.client.request(method, requestParams, {
718
- timeoutMs: options?.timeoutMs ?? params.timeoutMs,
719
- signal: params.signal
720
- });
721
- const runtime = resolveCodexAppServerRuntimeOptions({
722
- pluginConfig: params.pluginConfig,
723
- managedCommandOrder: "desktop-first"
724
- });
725
- return async (method, requestParams, options) => await requestCodexAppServerJson({
726
- method,
727
- requestParams,
728
- timeoutMs: options?.timeoutMs ?? params.timeoutMs ?? runtime.requestTimeoutMs,
729
- pluginConfig: params.pluginConfig,
730
- startOptions: runtime.start,
731
- config: params.config,
732
- agentDir: params.agentDir
733
- });
734
- }
735
752
  function resolveComputerUseConfig(params) {
736
753
  const overrides = params.forceEnable ? {
737
754
  ...params.overrides,
@@ -745,7 +762,6 @@ function resolveComputerUseConfig(params) {
745
762
  //#endregion
746
763
  //#region extensions/codex/src/app-server/plugin-metadata-cache.ts
747
764
  const CODEX_PLUGIN_METADATA_CACHE_TTL_MS = 36e5;
748
- /** Process-local plugin metadata cache with coalesced loads per query. */
749
765
  var CodexPluginMetadataCache = class {
750
766
  constructor(nowMs = Date.now) {
751
767
  this.nowMs = nowMs;
@@ -754,7 +770,6 @@ var CodexPluginMetadataCache = class {
754
770
  this.generations = /* @__PURE__ */ new Map();
755
771
  this.clearGeneration = 0;
756
772
  }
757
- /** Returns a fresh cached snapshot without issuing a request. */
758
773
  read(appCacheKey, queryKind, requestParams, catalogScope) {
759
774
  const entryKey = buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catalogScope);
760
775
  const entry = this.entries.get(entryKey);
@@ -787,7 +802,7 @@ var CodexPluginMetadataCache = class {
787
802
  queryKind: params.queryKind,
788
803
  response
789
804
  };
790
- if (generation === (this.generations.get(params.appCacheKey) ?? 0) && clearGeneration === this.clearGeneration && !hasMarketplaceLoadErrors(response) && (params.cacheable?.(response) ?? true)) this.entries.set(entryKey, {
805
+ if (generation === (this.generations.get(params.appCacheKey) ?? 0) && clearGeneration === this.clearGeneration && response.marketplaceLoadErrors.length === 0 && (params.cacheable?.(response) ?? true)) this.entries.set(entryKey, {
791
806
  snapshot,
792
807
  expiresAtMs: this.nowMs() + CODEX_PLUGIN_METADATA_CACHE_TTL_MS
793
808
  });
@@ -803,7 +818,6 @@ var CodexPluginMetadataCache = class {
803
818
  if (this.inFlight.get(entryKey)?.promise === promise) this.inFlight.delete(entryKey);
804
819
  }
805
820
  }
806
- /** Invalidates all plugin metadata queries for one app-server runtime. */
807
821
  invalidate(appCacheKey) {
808
822
  this.generations.set(appCacheKey, (this.generations.get(appCacheKey) ?? 0) + 1);
809
823
  for (const [entryKey, entry] of this.entries) if (entry.snapshot.appCacheKey === appCacheKey) this.entries.delete(entryKey);
@@ -817,11 +831,7 @@ var CodexPluginMetadataCache = class {
817
831
  this.inFlight.clear();
818
832
  }
819
833
  };
820
- /** Shared plugin metadata cache used by Codex app-server runtime paths. */
821
834
  const defaultCodexPluginMetadataCache = new CodexPluginMetadataCache();
822
- function hasMarketplaceLoadErrors(response) {
823
- return response.marketplaceLoadErrors.length > 0;
824
- }
825
835
  function buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catalogScope) {
826
836
  if (queryKind !== "installed") {
827
837
  const listParams = requestParams;
@@ -843,4 +853,4 @@ function buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catal
843
853
  ]);
844
854
  }
845
855
  //#endregion
846
- export { runCodexComputerUseLiveTest as a, readCodexComputerUseStatus as i, ensureCodexComputerUse as n, installCodexComputerUse as r, defaultCodexPluginMetadataCache as t };
856
+ export { createComputerUseRequest as a, readCodexComputerUseStatus as i, ensureCodexComputerUse as n, runCodexComputerUseLiveTest as o, installCodexComputerUse as r, defaultCodexPluginMetadataCache as t };