@harness-mix/cli 0.1.3

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 (655) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +14 -0
  4. package/README.md +262 -0
  5. package/Start-Codex.cmd +5 -0
  6. package/config/codex-desktop-compatibility.json +29 -0
  7. package/docs/chatgpt-web-sidebar.md +27 -0
  8. package/docs/cross-platform.md +73 -0
  9. package/docs/harness-management.md +44 -0
  10. package/docs/images/codex-desktop-home.png +0 -0
  11. package/docs/images/codex-desktop-session.png +0 -0
  12. package/docs/kiro-cursor-integration.md +3 -0
  13. package/docs/multi-agent-collaboration.md +89 -0
  14. package/docs/native-acp.md +122 -0
  15. package/docs/native-codex.md +95 -0
  16. package/docs/superpowers/specs/2026-09-13-native-hardening-design.md +326 -0
  17. package/licenses/codex-host-MIT.txt +21 -0
  18. package/output/native-build/desktop-controller.mjs +1466 -0
  19. package/output/native-build/harness-mix-appx.exe +0 -0
  20. package/output/native-build/harness-mix-secret.exe +0 -0
  21. package/output/native-build/harness-mix-shim.exe +0 -0
  22. package/output/native-build/renderer-extension.js +29380 -0
  23. package/package.json +168 -0
  24. package/scripts/acp-capabilities-probe.cjs +100 -0
  25. package/scripts/adapters-test.cjs +17 -0
  26. package/scripts/antigravity-adapter-test.cjs +529 -0
  27. package/scripts/architecture-test.cjs +62 -0
  28. package/scripts/build-native.cjs +56 -0
  29. package/scripts/catalog-test.cjs +25 -0
  30. package/scripts/cdp-eval.cjs +40 -0
  31. package/scripts/cdp-watch.cjs +36 -0
  32. package/scripts/check.cjs +23 -0
  33. package/scripts/codebuddy-migration-test.cjs +47 -0
  34. package/scripts/codex-adapter-test.cjs +83 -0
  35. package/scripts/collaboration-recovery-test.cjs +111 -0
  36. package/scripts/collaboration-test.cjs +108 -0
  37. package/scripts/collaboration-ui-smoke.cjs +57 -0
  38. package/scripts/concurrency-layers-test.cjs +181 -0
  39. package/scripts/contracts-test.cjs +105 -0
  40. package/scripts/core-concurrency-test.cjs +103 -0
  41. package/scripts/core-replay-test.cjs +179 -0
  42. package/scripts/core-runtime-test.cjs +104 -0
  43. package/scripts/core-services-test.cjs +50 -0
  44. package/scripts/determinism-test.cjs +36 -0
  45. package/scripts/diagnostics.cjs +63 -0
  46. package/scripts/docs-command-test.cjs +49 -0
  47. package/scripts/dsh-adapter-test.cjs +90 -0
  48. package/scripts/dsh-collaboration-acp-test.cjs +19 -0
  49. package/scripts/dsh-native.cjs +9 -0
  50. package/scripts/dsh-native.cmd +2 -0
  51. package/scripts/e2e-codex.cjs +82 -0
  52. package/scripts/e2e-collaboration.cjs +60 -0
  53. package/scripts/e2e-core-files.cjs +58 -0
  54. package/scripts/e2e-core-fork.cjs +49 -0
  55. package/scripts/e2e-core-resume.cjs +49 -0
  56. package/scripts/e2e-delegate.cjs +38 -0
  57. package/scripts/e2e-dsh.cjs +23 -0
  58. package/scripts/e2e-native-acp.cjs +42 -0
  59. package/scripts/e2e-native-commands.cjs +54 -0
  60. package/scripts/e2e-native-host.cjs +144 -0
  61. package/scripts/e2e-openclaw-image.cjs +59 -0
  62. package/scripts/e2e-openclaw.cjs +21 -0
  63. package/scripts/e2e-pi.cjs +23 -0
  64. package/scripts/e2e-shadow.cjs +52 -0
  65. package/scripts/fixture-capture.cjs +103 -0
  66. package/scripts/harness-health-check.cjs +72 -0
  67. package/scripts/kiro-cursor-adapters-test.cjs +82 -0
  68. package/scripts/launch-codex.cjs +5 -0
  69. package/scripts/native-acp-depth-test.cjs +189 -0
  70. package/scripts/native-compatibility-test.cjs +42 -0
  71. package/scripts/native-config-test.cjs +25 -0
  72. package/scripts/native-file-change-test.cjs +94 -0
  73. package/scripts/native-host.cjs +8 -0
  74. package/scripts/native-images-test.cjs +56 -0
  75. package/scripts/native-job-object-test.cjs +83 -0
  76. package/scripts/native-protocol-test.cjs +258 -0
  77. package/scripts/native-rollback-test.cjs +46 -0
  78. package/scripts/native-secret-test.cjs +57 -0
  79. package/scripts/native-shim-test.cjs +41 -0
  80. package/scripts/native-sidebar-test.cjs +88 -0
  81. package/scripts/native-ui-smoke.cjs +94 -0
  82. package/scripts/native-update-apply-test.cjs +215 -0
  83. package/scripts/native-updater-test.cjs +109 -0
  84. package/scripts/native-vendor-adapters-test.cjs +88 -0
  85. package/scripts/openclaw-acp-probe.cjs +39 -0
  86. package/scripts/openclaw-adapter-test.cjs +180 -0
  87. package/scripts/openclaw-models-probe.cjs +13 -0
  88. package/scripts/platform-test.cjs +62 -0
  89. package/scripts/projector-test.cjs +144 -0
  90. package/scripts/sequence-test.cjs +57 -0
  91. package/scripts/shadow-test.cjs +154 -0
  92. package/scripts/support/legacy-projection.cjs +95 -0
  93. package/scripts/support/legacy-transcript.cjs +48 -0
  94. package/scripts/support/parity-observer.cjs +27 -0
  95. package/scripts/support/shadow-comparator.cjs +62 -0
  96. package/scripts/support/shadow.cjs +114 -0
  97. package/scripts/switch-harness-test.cjs +145 -0
  98. package/scripts/thread-title-test.cjs +98 -0
  99. package/scripts/tool-concurrency-regression-test.cjs +119 -0
  100. package/scripts/transcript-test.cjs +24 -0
  101. package/scripts/turn-manager-test.cjs +91 -0
  102. package/scripts/workspace-test.cjs +86 -0
  103. package/src/assets/brand-harness-mix.png +0 -0
  104. package/src/assets/icons/antigravity-color.svg +1 -0
  105. package/src/assets/icons/claude-color.svg +1 -0
  106. package/src/assets/icons/codebuddy-color.svg +1 -0
  107. package/src/assets/icons/codex-color.svg +1 -0
  108. package/src/assets/icons/codex-harness.svg +1 -0
  109. package/src/assets/icons/cursor-cli-color.svg +1 -0
  110. package/src/assets/icons/cursor.svg +1 -0
  111. package/src/assets/icons/deepseek-color.svg +1 -0
  112. package/src/assets/icons/grok-color.svg +1 -0
  113. package/src/assets/icons/hermes-color.svg +1 -0
  114. package/src/assets/icons/kiro-cli-color.svg +11 -0
  115. package/src/assets/icons/model-astra.svg +1 -0
  116. package/src/assets/icons/model-claude.svg +1 -0
  117. package/src/assets/icons/model-deepseek.svg +1 -0
  118. package/src/assets/icons/model-gemini.svg +1 -0
  119. package/src/assets/icons/model-grok.svg +1 -0
  120. package/src/assets/icons/model-hunyuan.svg +1 -0
  121. package/src/assets/icons/model-kimi.svg +1 -0
  122. package/src/assets/icons/model-minimax.svg +1 -0
  123. package/src/assets/icons/model-openai.svg +1 -0
  124. package/src/assets/icons/model-qwen-color.svg +1 -0
  125. package/src/assets/icons/model-xiaomimimo.svg +1 -0
  126. package/src/assets/icons/model-zai.svg +1 -0
  127. package/src/assets/icons/omp-color.svg +1 -0
  128. package/src/assets/icons/openclaw-color.svg +1 -0
  129. package/src/assets/icons/opencode-color.svg +1 -0
  130. package/src/assets/icons/pi.svg +1 -0
  131. package/src/assets/icons/pinumber1_80899.svg +48 -0
  132. package/src/assets/icons/qoder-color.svg +1 -0
  133. package/src/assets/icons/trae-color.svg +1 -0
  134. package/src/assets/icons/workbuddy-color.svg +1 -0
  135. package/src/assets/icons/zcode-color.svg +1 -0
  136. package/src/main/adapters/acp-interactions.js +132 -0
  137. package/src/main/adapters/acp.js +191 -0
  138. package/src/main/adapters/antigravity.js +1368 -0
  139. package/src/main/adapters/claude.js +520 -0
  140. package/src/main/adapters/codebuddy-history.js +90 -0
  141. package/src/main/adapters/codebuddy.js +2 -0
  142. package/src/main/adapters/codex-app-server.js +119 -0
  143. package/src/main/adapters/codex.js +559 -0
  144. package/src/main/adapters/cursor.js +2 -0
  145. package/src/main/adapters/dsh-web-host.js +202 -0
  146. package/src/main/adapters/dsh.js +446 -0
  147. package/src/main/adapters/grok.js +277 -0
  148. package/src/main/adapters/hermes.js +24 -0
  149. package/src/main/adapters/index.js +32 -0
  150. package/src/main/adapters/kiro-history.js +43 -0
  151. package/src/main/adapters/kiro.js +2 -0
  152. package/src/main/adapters/native-acp-command.js +47 -0
  153. package/src/main/adapters/native-acp.js +435 -0
  154. package/src/main/adapters/omp.js +12 -0
  155. package/src/main/adapters/openclaw-gateway.js +211 -0
  156. package/src/main/adapters/openclaw.js +337 -0
  157. package/src/main/adapters/opencode-server.js +73 -0
  158. package/src/main/adapters/opencode.js +178 -0
  159. package/src/main/adapters/pi-family.js +342 -0
  160. package/src/main/adapters/pi-usage.js +24 -0
  161. package/src/main/adapters/pi.js +10 -0
  162. package/src/main/adapters/qoder.js +7 -0
  163. package/src/main/adapters/trae.js +7 -0
  164. package/src/main/adapters/workbuddy.js +2 -0
  165. package/src/main/adapters/zcode.js +7 -0
  166. package/src/main/harness-adapter/contract-test.js +53 -0
  167. package/src/main/harness-adapter/contract.js +34 -0
  168. package/src/main/harness-adapter/event-normalizer.js +252 -0
  169. package/src/main/harness-adapter/fixture-recorder.js +56 -0
  170. package/src/main/harness-adapter/index.js +6 -0
  171. package/src/main/harness-adapter/manifest.js +44 -0
  172. package/src/main/host/collaboration-mcp.cjs +35 -0
  173. package/src/main/host/collaboration-pi.mjs +17 -0
  174. package/src/main/host/collaboration-tools.js +16 -0
  175. package/src/main/host/collaboration-worktree.js +151 -0
  176. package/src/main/host/collaboration.js +264 -0
  177. package/src/main/host/core-session.js +81 -0
  178. package/src/main/host/handoff.js +46 -0
  179. package/src/main/host/history-import.js +55 -0
  180. package/src/main/host/jsonl.js +116 -0
  181. package/src/main/host/native-history.js +79 -0
  182. package/src/main/host/runtime.js +1050 -0
  183. package/src/main/host/session-history.js +63 -0
  184. package/src/main/host/store.js +75 -0
  185. package/src/main/native/compatibility.js +56 -0
  186. package/src/main/native/config.js +55 -0
  187. package/src/main/native/host.js +153 -0
  188. package/src/main/native/icons.js +105 -0
  189. package/src/main/native/input.js +43 -0
  190. package/src/main/native/launcher.js +188 -0
  191. package/src/main/native/platform.js +64 -0
  192. package/src/main/native/process-utils.js +57 -0
  193. package/src/main/native/protocol.js +836 -0
  194. package/src/main/native/redact.js +35 -0
  195. package/src/main/native/rs/Cargo.lock +15 -0
  196. package/src/main/native/rs/Cargo.toml +9 -0
  197. package/src/main/native/rs/crates/appx/Cargo.toml +13 -0
  198. package/src/main/native/rs/crates/appx/src/main.rs +309 -0
  199. package/src/main/native/rs/crates/secret/Cargo.toml +10 -0
  200. package/src/main/native/rs/crates/secret/src/main.rs +262 -0
  201. package/src/main/native/rs/crates/shim/Cargo.toml +10 -0
  202. package/src/main/native/rs/crates/shim/src/job.rs +83 -0
  203. package/src/main/native/rs/crates/shim/src/main.rs +257 -0
  204. package/src/main/native/secure-store.js +59 -0
  205. package/src/main/native/thread-list.js +38 -0
  206. package/src/main/native/update-state.js +110 -0
  207. package/src/main/native/updater.js +394 -0
  208. package/src/main/native/usage.js +105 -0
  209. package/src/main/protocol-core/capability-manager.js +16 -0
  210. package/src/main/protocol-core/event-router.js +32 -0
  211. package/src/main/protocol-core/file-change-projector.js +45 -0
  212. package/src/main/protocol-core/index.js +8 -0
  213. package/src/main/protocol-core/interaction-router.js +30 -0
  214. package/src/main/protocol-core/projector.js +238 -0
  215. package/src/main/protocol-core/protocol-core.js +132 -0
  216. package/src/main/protocol-core/sequence-validator.js +44 -0
  217. package/src/main/protocol-core/thread-manager.js +50 -0
  218. package/src/main/protocol-core/turn-manager.js +63 -0
  219. package/src/main/shared-contracts/capability.js +35 -0
  220. package/src/main/shared-contracts/event.js +55 -0
  221. package/src/main/shared-contracts/ids.js +12 -0
  222. package/src/main/shared-contracts/index.js +11 -0
  223. package/src/main/shared-contracts/interaction.js +37 -0
  224. package/src/main/shared-contracts/item.js +51 -0
  225. package/src/main/shared-contracts/native-ref.js +24 -0
  226. package/src/main/shared-contracts/thread.js +36 -0
  227. package/src/main/shared-contracts/turn.js +54 -0
  228. package/src/main/workspace/core-review.js +53 -0
  229. package/src/main/workspace/diff.js +27 -0
  230. package/src/main/workspace/file-changes.js +21 -0
  231. package/src/main/workspace/files.js +76 -0
  232. package/src/main/workspace/review-controller.js +102 -0
  233. package/src/main/workspace/review.js +88 -0
  234. package/src/native-ui/LICENSE +21 -0
  235. package/src/native-ui/README.md +16 -0
  236. package/src/native-ui/desktop-control/dist/cdp-client.d.ts +53 -0
  237. package/src/native-ui/desktop-control/dist/cdp-client.d.ts.map +1 -0
  238. package/src/native-ui/desktop-control/dist/cdp-client.js +258 -0
  239. package/src/native-ui/desktop-control/dist/cdp-client.js.map +1 -0
  240. package/src/native-ui/desktop-control/dist/contract-audit.d.ts +73 -0
  241. package/src/native-ui/desktop-control/dist/contract-audit.d.ts.map +1 -0
  242. package/src/native-ui/desktop-control/dist/contract-audit.js +152 -0
  243. package/src/native-ui/desktop-control/dist/contract-audit.js.map +1 -0
  244. package/src/native-ui/desktop-control/dist/controller-attachment-server.d.ts +10 -0
  245. package/src/native-ui/desktop-control/dist/controller-attachment-server.d.ts.map +1 -0
  246. package/src/native-ui/desktop-control/dist/controller-attachment-server.js +77 -0
  247. package/src/native-ui/desktop-control/dist/controller-attachment-server.js.map +1 -0
  248. package/src/native-ui/desktop-control/dist/index.d.ts +21 -0
  249. package/src/native-ui/desktop-control/dist/index.d.ts.map +1 -0
  250. package/src/native-ui/desktop-control/dist/index.js +14 -0
  251. package/src/native-ui/desktop-control/dist/index.js.map +1 -0
  252. package/src/native-ui/desktop-control/dist/main-process-title-policy.d.ts +24 -0
  253. package/src/native-ui/desktop-control/dist/main-process-title-policy.d.ts.map +1 -0
  254. package/src/native-ui/desktop-control/dist/main-process-title-policy.js +284 -0
  255. package/src/native-ui/desktop-control/dist/main-process-title-policy.js.map +1 -0
  256. package/src/native-ui/desktop-control/dist/production-controller.d.ts +32 -0
  257. package/src/native-ui/desktop-control/dist/production-controller.d.ts.map +1 -0
  258. package/src/native-ui/desktop-control/dist/production-controller.js +294 -0
  259. package/src/native-ui/desktop-control/dist/production-controller.js.map +1 -0
  260. package/src/native-ui/desktop-control/dist/release-main.d.ts +2 -0
  261. package/src/native-ui/desktop-control/dist/release-main.d.ts.map +1 -0
  262. package/src/native-ui/desktop-control/dist/release-main.js +17 -0
  263. package/src/native-ui/desktop-control/dist/release-main.js.map +1 -0
  264. package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.d.ts +49 -0
  265. package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.d.ts.map +1 -0
  266. package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js +214 -0
  267. package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js.map +1 -0
  268. package/src/native-ui/desktop-control/dist/renderer-control-session.d.ts +79 -0
  269. package/src/native-ui/desktop-control/dist/renderer-control-session.d.ts.map +1 -0
  270. package/src/native-ui/desktop-control/dist/renderer-control-session.js +366 -0
  271. package/src/native-ui/desktop-control/dist/renderer-control-session.js.map +1 -0
  272. package/src/native-ui/desktop-control/dist/renderer-dom.d.ts +24 -0
  273. package/src/native-ui/desktop-control/dist/renderer-dom.d.ts.map +1 -0
  274. package/src/native-ui/desktop-control/dist/renderer-dom.js +110 -0
  275. package/src/native-ui/desktop-control/dist/renderer-dom.js.map +1 -0
  276. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.d.ts +20 -0
  277. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.d.ts.map +1 -0
  278. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.js +173 -0
  279. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.js.map +1 -0
  280. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.d.ts +38 -0
  281. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.d.ts.map +1 -0
  282. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js +637 -0
  283. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js.map +1 -0
  284. package/src/native-ui/desktop-control/dist/tsconfig.tsbuildinfo +1 -0
  285. package/src/native-ui/desktop-control/package.json +22 -0
  286. package/src/native-ui/desktop-control/scripts/build-release.mjs +94 -0
  287. package/src/native-ui/desktop-control/src/cdp-client.ts +347 -0
  288. package/src/native-ui/desktop-control/src/contract-audit.ts +291 -0
  289. package/src/native-ui/desktop-control/src/controller-attachment-server.ts +93 -0
  290. package/src/native-ui/desktop-control/src/index.ts +91 -0
  291. package/src/native-ui/desktop-control/src/main-process-title-policy.ts +372 -0
  292. package/src/native-ui/desktop-control/src/production-controller.ts +347 -0
  293. package/src/native-ui/desktop-control/src/release-main.ts +18 -0
  294. package/src/native-ui/desktop-control/src/renderer-cdp-control-session.ts +358 -0
  295. package/src/native-ui/desktop-control/src/renderer-control-session.ts +595 -0
  296. package/src/native-ui/desktop-control/src/renderer-dom.ts +144 -0
  297. package/src/native-ui/desktop-control/src/renderer-draft-prewarm-policy.ts +217 -0
  298. package/src/native-ui/desktop-control/src/renderer-draft-prewarm-runtime.ts +749 -0
  299. package/src/native-ui/desktop-control/test/cdp-client.test.ts +157 -0
  300. package/src/native-ui/desktop-control/test/contract-audit.test.ts +56 -0
  301. package/src/native-ui/desktop-control/test/controller-attachment-server.test.ts +98 -0
  302. package/src/native-ui/desktop-control/test/index.test.ts +11 -0
  303. package/src/native-ui/desktop-control/test/main-process-title-policy.test.ts +168 -0
  304. package/src/native-ui/desktop-control/test/production-controller.test.ts +392 -0
  305. package/src/native-ui/desktop-control/test/renderer-cdp-control-session.test.ts +205 -0
  306. package/src/native-ui/desktop-control/test/renderer-control-session.test.ts +451 -0
  307. package/src/native-ui/desktop-control/test/renderer-dom.test.ts +62 -0
  308. package/src/native-ui/desktop-control/test/renderer-draft-prewarm-policy.test.ts +1029 -0
  309. package/src/native-ui/desktop-control/tsconfig.json +12 -0
  310. package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts +39 -0
  311. package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts.map +1 -0
  312. package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts +85 -0
  313. package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts.map +1 -0
  314. package/src/native-ui/renderer-extension/dist/types/audit-entry.d.ts +2 -0
  315. package/src/native-ui/renderer-extension/dist/types/audit-entry.d.ts.map +1 -0
  316. package/src/native-ui/renderer-extension/dist/types/codex-locale-adapter.d.ts +23 -0
  317. package/src/native-ui/renderer-extension/dist/types/codex-locale-adapter.d.ts.map +1 -0
  318. package/src/native-ui/renderer-extension/dist/types/collaboration-icon.d.ts +2 -0
  319. package/src/native-ui/renderer-extension/dist/types/collaboration-icon.d.ts.map +1 -0
  320. package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts +37 -0
  321. package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts.map +1 -0
  322. package/src/native-ui/renderer-extension/dist/types/harness-mix-icons.d.ts +3 -0
  323. package/src/native-ui/renderer-extension/dist/types/harness-mix-icons.d.ts.map +1 -0
  324. package/src/native-ui/renderer-extension/dist/types/harness-mix-settings.d.ts +3 -0
  325. package/src/native-ui/renderer-extension/dist/types/harness-mix-settings.d.ts.map +1 -0
  326. package/src/native-ui/renderer-extension/dist/types/index.d.ts +51 -0
  327. package/src/native-ui/renderer-extension/dist/types/index.d.ts.map +1 -0
  328. package/src/native-ui/renderer-extension/dist/types/install-renderer-binding.d.ts +4 -0
  329. package/src/native-ui/renderer-extension/dist/types/install-renderer-binding.d.ts.map +1 -0
  330. package/src/native-ui/renderer-extension/dist/types/probe-entry.d.ts +2 -0
  331. package/src/native-ui/renderer-extension/dist/types/probe-entry.d.ts.map +1 -0
  332. package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts +9 -0
  333. package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts.map +1 -0
  334. package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts +4 -0
  335. package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts.map +1 -0
  336. package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts +62 -0
  337. package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts.map +1 -0
  338. package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts +70 -0
  339. package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -0
  340. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts +34 -0
  341. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts.map +1 -0
  342. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts +19 -0
  343. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts.map +1 -0
  344. package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts +40 -0
  345. package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts.map +1 -0
  346. package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts +82 -0
  347. package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts.map +1 -0
  348. package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts +21 -0
  349. package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts.map +1 -0
  350. package/src/native-ui/renderer-extension/dist/types/renderer-external-steering.d.ts +7 -0
  351. package/src/native-ui/renderer-extension/dist/types/renderer-external-steering.d.ts.map +1 -0
  352. package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts +34 -0
  353. package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts.map +1 -0
  354. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts +4 -0
  355. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts.map +1 -0
  356. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts +15 -0
  357. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts.map +1 -0
  358. package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts +25 -0
  359. package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts.map +1 -0
  360. package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts +23 -0
  361. package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts.map +1 -0
  362. package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +102 -0
  363. package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -0
  364. package/src/native-ui/renderer-extension/dist/types/renderer-model-picker-positioning.d.ts +22 -0
  365. package/src/native-ui/renderer-extension/dist/types/renderer-model-picker-positioning.d.ts.map +1 -0
  366. package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts +54 -0
  367. package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts.map +1 -0
  368. package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts +18 -0
  369. package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts.map +1 -0
  370. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts +42 -0
  371. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts.map +1 -0
  372. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts +9 -0
  373. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts.map +1 -0
  374. package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts +9 -0
  375. package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts.map +1 -0
  376. package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts +12 -0
  377. package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts.map +1 -0
  378. package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts +18 -0
  379. package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts.map +1 -0
  380. package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts +45 -0
  381. package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts.map +1 -0
  382. package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts +23 -0
  383. package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts.map +1 -0
  384. package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts +3 -0
  385. package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts.map +1 -0
  386. package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts +72 -0
  387. package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts.map +1 -0
  388. package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts +24 -0
  389. package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts.map +1 -0
  390. package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts +18 -0
  391. package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts.map +1 -0
  392. package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts +27 -0
  393. package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts.map +1 -0
  394. package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts +44 -0
  395. package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts.map +1 -0
  396. package/src/native-ui/renderer-extension/dist/types/settings/core.d.ts +38 -0
  397. package/src/native-ui/renderer-extension/dist/types/settings/core.d.ts.map +1 -0
  398. package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts +21 -0
  399. package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts.map +1 -0
  400. package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts +6 -0
  401. package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts.map +1 -0
  402. package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts +247 -0
  403. package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts.map +1 -0
  404. package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +23 -0
  405. package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -0
  406. package/src/native-ui/renderer-extension/dist/types/settings/release-notes.d.ts +4 -0
  407. package/src/native-ui/renderer-extension/dist/types/settings/release-notes.d.ts.map +1 -0
  408. package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts +12 -0
  409. package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts.map +1 -0
  410. package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts +8 -0
  411. package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts.map +1 -0
  412. package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts +24 -0
  413. package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts.map +1 -0
  414. package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts +45 -0
  415. package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts.map +1 -0
  416. package/src/native-ui/renderer-extension/dist/types/settings/update-request.d.ts +6 -0
  417. package/src/native-ui/renderer-extension/dist/types/settings/update-request.d.ts.map +1 -0
  418. package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -0
  419. package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts +143 -0
  420. package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts.map +1 -0
  421. package/src/native-ui/renderer-extension/package.json +22 -0
  422. package/src/native-ui/renderer-extension/src/agent-group-preference.ts +174 -0
  423. package/src/native-ui/renderer-extension/src/agent-selection-state.ts +627 -0
  424. package/src/native-ui/renderer-extension/src/assets/README.md +13 -0
  425. package/src/native-ui/renderer-extension/src/assets/antigravity-agent.svg +1 -0
  426. package/src/native-ui/renderer-extension/src/assets/codex-agent.png +0 -0
  427. package/src/native-ui/renderer-extension/src/assets/grok-agent.png +0 -0
  428. package/src/native-ui/renderer-extension/src/assets/kiro-agent.svg +11 -0
  429. package/src/native-ui/renderer-extension/src/assets/omp-agent.svg +14 -0
  430. package/src/native-ui/renderer-extension/src/assets/opencode-agent.png +0 -0
  431. package/src/native-ui/renderer-extension/src/assets.d.ts +26 -0
  432. package/src/native-ui/renderer-extension/src/audit-entry.ts +5 -0
  433. package/src/native-ui/renderer-extension/src/codex-locale-adapter.ts +321 -0
  434. package/src/native-ui/renderer-extension/src/collaboration-icon.ts +13 -0
  435. package/src/native-ui/renderer-extension/src/contract-audit.ts +102 -0
  436. package/src/native-ui/renderer-extension/src/harness-mix-icons.ts +31 -0
  437. package/src/native-ui/renderer-extension/src/harness-mix-settings.ts +88 -0
  438. package/src/native-ui/renderer-extension/src/index.ts +275 -0
  439. package/src/native-ui/renderer-extension/src/install-renderer-binding.ts +30 -0
  440. package/src/native-ui/renderer-extension/src/probe-entry.ts +4 -0
  441. package/src/native-ui/renderer-extension/src/production-entry.ts +23 -0
  442. package/src/native-ui/renderer-extension/src/renderer-agent-icon.ts +146 -0
  443. package/src/native-ui/renderer-extension/src/renderer-agent-picker.ts +814 -0
  444. package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +3002 -0
  445. package/src/native-ui/renderer-extension/src/renderer-codex-account-options.ts +281 -0
  446. package/src/native-ui/renderer-extension/src/renderer-codex-account-state.ts +53 -0
  447. package/src/native-ui/renderer-extension/src/renderer-collab-cards.ts +198 -0
  448. package/src/native-ui/renderer-extension/src/renderer-composer-dom.ts +782 -0
  449. package/src/native-ui/renderer-extension/src/renderer-credits-control.ts +520 -0
  450. package/src/native-ui/renderer-extension/src/renderer-external-steering.ts +339 -0
  451. package/src/native-ui/renderer-extension/src/renderer-fork-control.ts +273 -0
  452. package/src/native-ui/renderer-extension/src/renderer-harness-command-claim.ts +64 -0
  453. package/src/native-ui/renderer-extension/src/renderer-harness-command-control.ts +417 -0
  454. package/src/native-ui/renderer-extension/src/renderer-harness-localization.ts +144 -0
  455. package/src/native-ui/renderer-extension/src/renderer-harness-mentions.ts +306 -0
  456. package/src/native-ui/renderer-extension/src/renderer-model-client.ts +572 -0
  457. package/src/native-ui/renderer-extension/src/renderer-model-picker-positioning.ts +65 -0
  458. package/src/native-ui/renderer-extension/src/renderer-model-picker.ts +640 -0
  459. package/src/native-ui/renderer-extension/src/renderer-new-thread-preference.ts +177 -0
  460. package/src/native-ui/renderer-extension/src/renderer-permission-mode-picker.ts +413 -0
  461. package/src/native-ui/renderer-extension/src/renderer-permission-mode-preference.ts +49 -0
  462. package/src/native-ui/renderer-extension/src/renderer-request-sender.ts +43 -0
  463. package/src/native-ui/renderer-extension/src/renderer-session-import-client.ts +68 -0
  464. package/src/native-ui/renderer-extension/src/renderer-settings-lifecycle.ts +239 -0
  465. package/src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts +457 -0
  466. package/src/native-ui/renderer-extension/src/renderer-transcript-dom.ts +47 -0
  467. package/src/native-ui/renderer-extension/src/renderer-trigger-chip-style.ts +52 -0
  468. package/src/native-ui/renderer-extension/src/renderer-usage-control.ts +633 -0
  469. package/src/native-ui/renderer-extension/src/settings/accounts-list.ts +236 -0
  470. package/src/native-ui/renderer-extension/src/settings/accounts-page.ts +585 -0
  471. package/src/native-ui/renderer-extension/src/settings/accounts-usage.ts +221 -0
  472. package/src/native-ui/renderer-extension/src/settings/accounts.css +683 -0
  473. package/src/native-ui/renderer-extension/src/settings/connections-page.ts +1394 -0
  474. package/src/native-ui/renderer-extension/src/settings/core.ts +158 -0
  475. package/src/native-ui/renderer-extension/src/settings/harness-accounts.ts +195 -0
  476. package/src/native-ui/renderer-extension/src/settings/icons.ts +141 -0
  477. package/src/native-ui/renderer-extension/src/settings/localization.ts +800 -0
  478. package/src/native-ui/renderer-extension/src/settings/pages.ts +632 -0
  479. package/src/native-ui/renderer-extension/src/settings/release-notes.ts +222 -0
  480. package/src/native-ui/renderer-extension/src/settings/session-import-list-controls.ts +128 -0
  481. package/src/native-ui/renderer-extension/src/settings/session-import-page.ts +461 -0
  482. package/src/native-ui/renderer-extension/src/settings/shell.css +2238 -0
  483. package/src/native-ui/renderer-extension/src/settings/shell.ts +329 -0
  484. package/src/native-ui/renderer-extension/src/settings/trigger.ts +323 -0
  485. package/src/native-ui/renderer-extension/src/settings/update-request.ts +49 -0
  486. package/src/native-ui/renderer-extension/src/versioned-renderer-adapter.ts +1289 -0
  487. package/src/native-ui/renderer-extension/test/agent-selection-state.test.ts +611 -0
  488. package/src/native-ui/renderer-extension/test/codebuddy-migration.test.ts +22 -0
  489. package/src/native-ui/renderer-extension/test/codex-locale-adapter.test.ts +152 -0
  490. package/src/native-ui/renderer-extension/test/contract-audit.test.ts +71 -0
  491. package/src/native-ui/renderer-extension/test/harness-mix-icons.test.ts +58 -0
  492. package/src/native-ui/renderer-extension/test/index.test.ts +9 -0
  493. package/src/native-ui/renderer-extension/test/renderer-agent-icon.test.ts +98 -0
  494. package/src/native-ui/renderer-extension/test/renderer-agent-picker.test.ts +226 -0
  495. package/src/native-ui/renderer-extension/test/renderer-binding-probe-host-catalog.test.ts +728 -0
  496. package/src/native-ui/renderer-extension/test/renderer-binding-probe.test.ts +1290 -0
  497. package/src/native-ui/renderer-extension/test/renderer-codex-account-state.test.ts +65 -0
  498. package/src/native-ui/renderer-extension/test/renderer-collab-cards.test.ts +45 -0
  499. package/src/native-ui/renderer-extension/test/renderer-composer-permissions.test.ts +75 -0
  500. package/src/native-ui/renderer-extension/test/renderer-credits-control.test.ts +70 -0
  501. package/src/native-ui/renderer-extension/test/renderer-external-steering-rpc.test.ts +184 -0
  502. package/src/native-ui/renderer-extension/test/renderer-external-steering.test.ts +279 -0
  503. package/src/native-ui/renderer-extension/test/renderer-fork-control.test.ts +363 -0
  504. package/src/native-ui/renderer-extension/test/renderer-harness-command-claim.test.ts +167 -0
  505. package/src/native-ui/renderer-extension/test/renderer-harness-command-control.test.ts +54 -0
  506. package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +709 -0
  507. package/src/native-ui/renderer-extension/test/renderer-model-picker.test.ts +302 -0
  508. package/src/native-ui/renderer-extension/test/renderer-native-thread-ownership.test.ts +84 -0
  509. package/src/native-ui/renderer-extension/test/renderer-new-thread-preference.test.ts +81 -0
  510. package/src/native-ui/renderer-extension/test/renderer-permission-mode-picker.test.ts +269 -0
  511. package/src/native-ui/renderer-extension/test/renderer-permission-mode-preference.test.ts +48 -0
  512. package/src/native-ui/renderer-extension/test/renderer-settings-lifecycle.test.ts +156 -0
  513. package/src/native-ui/renderer-extension/test/renderer-sidebar-agent-icons.test.ts +575 -0
  514. package/src/native-ui/renderer-extension/test/renderer-unsupported-methods.test.ts +167 -0
  515. package/src/native-ui/renderer-extension/test/renderer-usage-control.test.ts +96 -0
  516. package/src/native-ui/renderer-extension/test/settings/accounts-usage.test.ts +208 -0
  517. package/src/native-ui/renderer-extension/test/settings/core.test.ts +145 -0
  518. package/src/native-ui/renderer-extension/test/settings/harness-settings.test.ts +92 -0
  519. package/src/native-ui/renderer-extension/test/settings/localization.test.ts +80 -0
  520. package/src/native-ui/renderer-extension/test/settings/pages.test.ts +2000 -0
  521. package/src/native-ui/renderer-extension/test/settings/release-notes.test.ts +163 -0
  522. package/src/native-ui/renderer-extension/test/settings/shell.test.ts +74 -0
  523. package/src/native-ui/renderer-extension/test/settings/trigger.test.ts +270 -0
  524. package/src/native-ui/renderer-extension/test/settings/update-request.test.ts +48 -0
  525. package/src/native-ui/renderer-extension/test/versioned-renderer-adapter.test.ts +695 -0
  526. package/src/native-ui/renderer-extension/tsconfig.json +15 -0
  527. package/src/native-ui/shared-contracts/dist/codex-accounts.d.ts +246 -0
  528. package/src/native-ui/shared-contracts/dist/codex-accounts.d.ts.map +1 -0
  529. package/src/native-ui/shared-contracts/dist/codex-accounts.js +99 -0
  530. package/src/native-ui/shared-contracts/dist/codex-accounts.js.map +1 -0
  531. package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.d.ts +37 -0
  532. package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.d.ts.map +1 -0
  533. package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.js +36 -0
  534. package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.js.map +1 -0
  535. package/src/native-ui/shared-contracts/dist/errors.d.ts +17 -0
  536. package/src/native-ui/shared-contracts/dist/errors.d.ts.map +1 -0
  537. package/src/native-ui/shared-contracts/dist/errors.js +14 -0
  538. package/src/native-ui/shared-contracts/dist/errors.js.map +1 -0
  539. package/src/native-ui/shared-contracts/dist/external-thread-fork.d.ts +11 -0
  540. package/src/native-ui/shared-contracts/dist/external-thread-fork.d.ts.map +1 -0
  541. package/src/native-ui/shared-contracts/dist/external-thread-fork.js +14 -0
  542. package/src/native-ui/shared-contracts/dist/external-thread-fork.js.map +1 -0
  543. package/src/native-ui/shared-contracts/dist/harness-accounts.d.ts +78 -0
  544. package/src/native-ui/shared-contracts/dist/harness-accounts.d.ts.map +1 -0
  545. package/src/native-ui/shared-contracts/dist/harness-accounts.js +27 -0
  546. package/src/native-ui/shared-contracts/dist/harness-accounts.js.map +1 -0
  547. package/src/native-ui/shared-contracts/dist/harness-commands.d.ts +46 -0
  548. package/src/native-ui/shared-contracts/dist/harness-commands.d.ts.map +1 -0
  549. package/src/native-ui/shared-contracts/dist/harness-commands.js +61 -0
  550. package/src/native-ui/shared-contracts/dist/harness-commands.js.map +1 -0
  551. package/src/native-ui/shared-contracts/dist/harness-models.d.ts +300 -0
  552. package/src/native-ui/shared-contracts/dist/harness-models.d.ts.map +1 -0
  553. package/src/native-ui/shared-contracts/dist/harness-models.js +318 -0
  554. package/src/native-ui/shared-contracts/dist/harness-models.js.map +1 -0
  555. package/src/native-ui/shared-contracts/dist/harness-permission-modes.d.ts +30 -0
  556. package/src/native-ui/shared-contracts/dist/harness-permission-modes.d.ts.map +1 -0
  557. package/src/native-ui/shared-contracts/dist/harness-permission-modes.js +57 -0
  558. package/src/native-ui/shared-contracts/dist/harness-permission-modes.js.map +1 -0
  559. package/src/native-ui/shared-contracts/dist/harness-plugins.d.ts +56 -0
  560. package/src/native-ui/shared-contracts/dist/harness-plugins.d.ts.map +1 -0
  561. package/src/native-ui/shared-contracts/dist/harness-plugins.js +75 -0
  562. package/src/native-ui/shared-contracts/dist/harness-plugins.js.map +1 -0
  563. package/src/native-ui/shared-contracts/dist/harness-route.d.ts +16 -0
  564. package/src/native-ui/shared-contracts/dist/harness-route.d.ts.map +1 -0
  565. package/src/native-ui/shared-contracts/dist/harness-route.js +42 -0
  566. package/src/native-ui/shared-contracts/dist/harness-route.js.map +1 -0
  567. package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts +54 -0
  568. package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts.map +1 -0
  569. package/src/native-ui/shared-contracts/dist/harness-session-import.js +72 -0
  570. package/src/native-ui/shared-contracts/dist/harness-session-import.js.map +1 -0
  571. package/src/native-ui/shared-contracts/dist/ids.d.ts +12 -0
  572. package/src/native-ui/shared-contracts/dist/ids.d.ts.map +1 -0
  573. package/src/native-ui/shared-contracts/dist/ids.js +10 -0
  574. package/src/native-ui/shared-contracts/dist/ids.js.map +1 -0
  575. package/src/native-ui/shared-contracts/dist/index.d.ts +47 -0
  576. package/src/native-ui/shared-contracts/dist/index.d.ts.map +1 -0
  577. package/src/native-ui/shared-contracts/dist/index.js +29 -0
  578. package/src/native-ui/shared-contracts/dist/index.js.map +1 -0
  579. package/src/native-ui/shared-contracts/dist/json-rpc.d.ts +84 -0
  580. package/src/native-ui/shared-contracts/dist/json-rpc.d.ts.map +1 -0
  581. package/src/native-ui/shared-contracts/dist/json-rpc.js +65 -0
  582. package/src/native-ui/shared-contracts/dist/json-rpc.js.map +1 -0
  583. package/src/native-ui/shared-contracts/dist/json-value.d.ts +13 -0
  584. package/src/native-ui/shared-contracts/dist/json-value.d.ts.map +1 -0
  585. package/src/native-ui/shared-contracts/dist/json-value.js +60 -0
  586. package/src/native-ui/shared-contracts/dist/json-value.js.map +1 -0
  587. package/src/native-ui/shared-contracts/dist/native-refs.d.ts +43 -0
  588. package/src/native-ui/shared-contracts/dist/native-refs.d.ts.map +1 -0
  589. package/src/native-ui/shared-contracts/dist/native-refs.js +35 -0
  590. package/src/native-ui/shared-contracts/dist/native-refs.js.map +1 -0
  591. package/src/native-ui/shared-contracts/dist/reasoning-transcript.d.ts +7 -0
  592. package/src/native-ui/shared-contracts/dist/reasoning-transcript.d.ts.map +1 -0
  593. package/src/native-ui/shared-contracts/dist/reasoning-transcript.js +7 -0
  594. package/src/native-ui/shared-contracts/dist/reasoning-transcript.js.map +1 -0
  595. package/src/native-ui/shared-contracts/dist/thread-delegate.d.ts +22 -0
  596. package/src/native-ui/shared-contracts/dist/thread-delegate.d.ts.map +1 -0
  597. package/src/native-ui/shared-contracts/dist/thread-delegate.js +30 -0
  598. package/src/native-ui/shared-contracts/dist/thread-delegate.js.map +1 -0
  599. package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts +16 -0
  600. package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts.map +1 -0
  601. package/src/native-ui/shared-contracts/dist/thread-harness-switch.js +19 -0
  602. package/src/native-ui/shared-contracts/dist/thread-harness-switch.js.map +1 -0
  603. package/src/native-ui/shared-contracts/dist/thread-usage.d.ts +106 -0
  604. package/src/native-ui/shared-contracts/dist/thread-usage.d.ts.map +1 -0
  605. package/src/native-ui/shared-contracts/dist/thread-usage.js +103 -0
  606. package/src/native-ui/shared-contracts/dist/thread-usage.js.map +1 -0
  607. package/src/native-ui/shared-contracts/dist/tsconfig.tsbuildinfo +1 -0
  608. package/src/native-ui/shared-contracts/dist/updates.d.ts +128 -0
  609. package/src/native-ui/shared-contracts/dist/updates.d.ts.map +1 -0
  610. package/src/native-ui/shared-contracts/dist/updates.js +58 -0
  611. package/src/native-ui/shared-contracts/dist/updates.js.map +1 -0
  612. package/src/native-ui/shared-contracts/dist/version.d.ts +2 -0
  613. package/src/native-ui/shared-contracts/dist/version.d.ts.map +1 -0
  614. package/src/native-ui/shared-contracts/dist/version.js +2 -0
  615. package/src/native-ui/shared-contracts/dist/version.js.map +1 -0
  616. package/src/native-ui/shared-contracts/package.json +25 -0
  617. package/src/native-ui/shared-contracts/src/codex-accounts.ts +140 -0
  618. package/src/native-ui/shared-contracts/src/deepseek-modern-sessions.ts +67 -0
  619. package/src/native-ui/shared-contracts/src/errors.ts +25 -0
  620. package/src/native-ui/shared-contracts/src/external-thread-fork.ts +20 -0
  621. package/src/native-ui/shared-contracts/src/harness-accounts.ts +32 -0
  622. package/src/native-ui/shared-contracts/src/harness-commands.ts +81 -0
  623. package/src/native-ui/shared-contracts/src/harness-models.ts +406 -0
  624. package/src/native-ui/shared-contracts/src/harness-permission-modes.ts +73 -0
  625. package/src/native-ui/shared-contracts/src/harness-plugins.ts +96 -0
  626. package/src/native-ui/shared-contracts/src/harness-route.ts +47 -0
  627. package/src/native-ui/shared-contracts/src/harness-session-import.ts +90 -0
  628. package/src/native-ui/shared-contracts/src/ids.ts +20 -0
  629. package/src/native-ui/shared-contracts/src/index.ts +320 -0
  630. package/src/native-ui/shared-contracts/src/json-rpc.ts +80 -0
  631. package/src/native-ui/shared-contracts/src/json-value.ts +78 -0
  632. package/src/native-ui/shared-contracts/src/native-refs.ts +58 -0
  633. package/src/native-ui/shared-contracts/src/reasoning-transcript.ts +6 -0
  634. package/src/native-ui/shared-contracts/src/thread-delegate.ts +40 -0
  635. package/src/native-ui/shared-contracts/src/thread-harness-switch.ts +25 -0
  636. package/src/native-ui/shared-contracts/src/thread-usage.ts +126 -0
  637. package/src/native-ui/shared-contracts/src/updates.ts +78 -0
  638. package/src/native-ui/shared-contracts/src/version.ts +1 -0
  639. package/src/native-ui/shared-contracts/test/browser-bundle.test.ts +36 -0
  640. package/src/native-ui/shared-contracts/test/deepseek-modern-sessions.test.ts +120 -0
  641. package/src/native-ui/shared-contracts/test/errors.test.ts +72 -0
  642. package/src/native-ui/shared-contracts/test/harness-commands.test.ts +64 -0
  643. package/src/native-ui/shared-contracts/test/harness-models.test.ts +390 -0
  644. package/src/native-ui/shared-contracts/test/harness-permission-modes.test.ts +134 -0
  645. package/src/native-ui/shared-contracts/test/harness-plugins.test.ts +113 -0
  646. package/src/native-ui/shared-contracts/test/harness-session-import.test.ts +117 -0
  647. package/src/native-ui/shared-contracts/test/ids.test.ts +69 -0
  648. package/src/native-ui/shared-contracts/test/index.test.ts +80 -0
  649. package/src/native-ui/shared-contracts/test/json-rpc.test.ts +177 -0
  650. package/src/native-ui/shared-contracts/test/json-value.test.ts +62 -0
  651. package/src/native-ui/shared-contracts/test/native-refs.test.ts +95 -0
  652. package/src/native-ui/shared-contracts/test/thread-usage.test.ts +115 -0
  653. package/src/native-ui/shared-contracts/test/updates.test.ts +120 -0
  654. package/src/native-ui/shared-contracts/tsconfig.json +10 -0
  655. package/src/tsconfig.base.json +19 -0
@@ -0,0 +1,1029 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+
3
+ import {
4
+ installRendererDraftPrewarmPolicy,
5
+ installRendererDraftPrewarmPolicyDirect,
6
+ selectRendererRequestManager,
7
+ rendererRequestManagerFromHook,
8
+ } from "../src/renderer-draft-prewarm-policy.js";
9
+ import {
10
+ installDraftPrewarmPolicyBridge,
11
+ installDraftPrewarmPolicyInRenderer,
12
+ type DraftPrewarmPolicyTarget,
13
+ type RendererDebugger,
14
+ type RendererHostRequestBridge,
15
+ type RendererHostRequestManager,
16
+ type RendererWebContents,
17
+ } from "../src/renderer-draft-prewarm-runtime.js";
18
+
19
+ function requestManagerFixture(): Required<RendererHostRequestManager> {
20
+ return {
21
+ onNotification: vi.fn(),
22
+ onRequest: vi.fn(),
23
+ dispatchAppServerResponse: vi.fn(),
24
+ };
25
+ }
26
+
27
+ describe("Desktop connection snapshot discovery", () => {
28
+ const manager = {
29
+ getHostId: () => "local",
30
+ sendRequest: vi.fn(),
31
+ requestClient: { sendRequest: vi.fn(), prewarmThreadStart: vi.fn(), enqueueRequest: vi.fn() },
32
+ prewarmedThreadManager: { discardAllPrewarmedThreads: vi.fn() },
33
+ };
34
+ it("supports both legacy managers and ready 26.908 connection snapshots", () => {
35
+ expect(rendererRequestManagerFromHook(manager)).toBe(manager);
36
+ expect(rendererRequestManagerFromHook({ manager, hostId: "local", status: "ready" })).toBe(manager);
37
+ });
38
+ it("rejects disconnected, mismatched and incomplete native connections", () => {
39
+ expect(rendererRequestManagerFromHook({ manager, hostId: "local", status: "connecting" })).toBeNull();
40
+ expect(rendererRequestManagerFromHook({ manager, hostId: "remote", status: "ready" })).toBeNull();
41
+ expect(rendererRequestManagerFromHook({ manager: {}, hostId: "local", status: "ready" })).toBeNull();
42
+ });
43
+ it("preserves the new local approval transport without adding a phantom handler", () => {
44
+ const nativeManager = { onNotification: vi.fn(), onRequest: vi.fn() };
45
+ const target = {};
46
+ installDraftPrewarmPolicyBridge(nativeManager, requestBridgeFixture(), "local", target,
47
+ { discardAllPrewarmedThreads: vi.fn() });
48
+ expect("dispatchAppServerResponse" in nativeManager).toBe(false);
49
+ });
50
+ it("explicitly rejects unsupported remote approval hooks before changing transport", () => {
51
+ const bridge = requestBridgeFixture();
52
+ const send = bridge.sendRequest;
53
+ expect(() => installDraftPrewarmPolicyBridge({ onNotification: vi.fn(), onRequest: vi.fn() },
54
+ bridge, "remote-control:test", {}, { discardAllPrewarmedThreads: vi.fn() }))
55
+ .toThrow("approval response bridge is unavailable");
56
+ expect(bridge.sendRequest).toBe(send);
57
+ });
58
+ });
59
+
60
+ function requestBridgeFixture(
61
+ input: {
62
+ sendRequest?: RendererHostRequestBridge["sendRequest"];
63
+ prewarmThreadStart?: RendererHostRequestBridge["prewarmThreadStart"];
64
+ } = {},
65
+ ): RendererHostRequestBridge {
66
+ return {
67
+ sendRequest: input.sendRequest ?? vi.fn(),
68
+ prewarmThreadStart: input.prewarmThreadStart ?? vi.fn(),
69
+ enqueueRequest: vi.fn(),
70
+ onResult: vi.fn(),
71
+ onError: vi.fn(),
72
+ };
73
+ }
74
+
75
+ function remoteRequestBridgeFixture(): {
76
+ bridge: RendererHostRequestBridge;
77
+ directSend: ReturnType<typeof vi.fn>;
78
+ } {
79
+ let nextRequestId = 1;
80
+ const pending = new Map<
81
+ number,
82
+ { resolve: (value: unknown) => void; reject: (reason: unknown) => void }
83
+ >();
84
+ const directSend = vi.fn((): Promise<unknown> => Promise.resolve({}));
85
+ const bridge: RendererHostRequestBridge = {
86
+ sendRequest: directSend,
87
+ prewarmThreadStart: vi.fn(),
88
+ enqueueRequest(method, parameters, _options, dispatch) {
89
+ const id = nextRequestId;
90
+ nextRequestId += 1;
91
+ const promise = new Promise<unknown>((resolve, reject) => {
92
+ pending.set(id, { resolve, reject });
93
+ });
94
+ dispatch?.({ id, method, params: parameters });
95
+ return promise;
96
+ },
97
+ onResult(id, result) {
98
+ const entry = pending.get(Number(id));
99
+ pending.delete(Number(id));
100
+ entry?.resolve(result);
101
+ },
102
+ onError(id, error) {
103
+ const entry = pending.get(Number(id));
104
+ pending.delete(Number(id));
105
+ entry?.reject(error);
106
+ },
107
+ };
108
+ return { bridge, directSend };
109
+ }
110
+
111
+ function emitBridgeOutput(
112
+ manager: RendererHostRequestManager,
113
+ processHandle: string,
114
+ value: Record<string, unknown> | string,
115
+ ): void {
116
+ const text = typeof value === "string" ? value : `${JSON.stringify(value)}\n`;
117
+ manager.onNotification("process/outputDelta", {
118
+ processHandle,
119
+ stream: "stdout",
120
+ deltaBase64: Buffer.from(text, "utf8").toString("base64"),
121
+ capReached: false,
122
+ });
123
+ }
124
+
125
+ function remoteNotificationTargetFixture(hostId = "remote-control:fixture-host"): {
126
+ target: DraftPrewarmPolicyTarget;
127
+ emit(method: string, parameters: unknown): void;
128
+ } {
129
+ const listeners = new Set<(event: Event) => void>();
130
+ return {
131
+ target: {
132
+ addEventListener(type, listener) {
133
+ if (type === "message") listeners.add(listener);
134
+ },
135
+ removeEventListener(type, listener) {
136
+ if (type === "message") listeners.delete(listener);
137
+ },
138
+ },
139
+ emit(method, parameters) {
140
+ const event = {
141
+ data: { type: "mcp-notification", hostId, method, params: parameters },
142
+ } as MessageEvent;
143
+ for (const listener of listeners) listener(event);
144
+ },
145
+ };
146
+ }
147
+
148
+ function emitRemoteBridgeOutput(
149
+ fixture: ReturnType<typeof remoteNotificationTargetFixture>,
150
+ processHandle: string,
151
+ value: Record<string, unknown> | string,
152
+ ): void {
153
+ const text = typeof value === "string" ? value : `${JSON.stringify(value)}\n`;
154
+ fixture.emit("process/outputDelta", {
155
+ processHandle,
156
+ stream: "stdout",
157
+ deltaBase64: Buffer.from(text, "utf8").toString("base64"),
158
+ capReached: false,
159
+ });
160
+ }
161
+
162
+ function writtenBridgeFrames(directSend: ReturnType<typeof vi.fn>): Record<string, unknown>[] {
163
+ return directSend.mock.calls
164
+ .filter(([method]) => method === "process/writeStdin")
165
+ .map(([, parameters]) => {
166
+ const deltaBase64 = (parameters as { deltaBase64: string }).deltaBase64;
167
+ return JSON.parse(Buffer.from(deltaBase64, "base64").toString("utf8")) as Record<
168
+ string,
169
+ unknown
170
+ >;
171
+ });
172
+ }
173
+
174
+ function rendererFixture(
175
+ options: {
176
+ candidateCount?: number;
177
+ hostId?: string;
178
+ includePrewarmedThreadManager?: boolean;
179
+ } = {},
180
+ ): {
181
+ contents: RendererWebContents;
182
+ sendCommand: ReturnType<typeof vi.fn>;
183
+ attach: ReturnType<typeof vi.fn>;
184
+ detach: ReturnType<typeof vi.fn>;
185
+ } {
186
+ let attached = false;
187
+ const attach = vi.fn(() => {
188
+ attached = true;
189
+ });
190
+ const detach = vi.fn(() => {
191
+ attached = false;
192
+ });
193
+ const sendCommand = vi.fn(
194
+ async (method: string, parameters: Record<string, unknown> = {}): Promise<unknown> => {
195
+ if (method === "Runtime.enable") return {};
196
+ if (method === "Runtime.evaluate") return { result: { objectId: "manager-result" } };
197
+ if (method === "Runtime.getProperties") {
198
+ switch (parameters.objectId) {
199
+ case "manager-result":
200
+ return {
201
+ result: [
202
+ { name: "candidateCount", value: { value: options.candidateCount ?? 1 } },
203
+ { name: "hostId", value: { value: options.hostId ?? "local" } },
204
+ { name: "manager", value: { objectId: "outer-request-manager" } },
205
+ { name: "requestClient", value: { objectId: "request-client" } },
206
+ ...(options.includePrewarmedThreadManager === false
207
+ ? []
208
+ : [
209
+ {
210
+ name: "prewarmedThreadManager",
211
+ value: { objectId: "prewarm-manager" },
212
+ },
213
+ ]),
214
+ ],
215
+ };
216
+ default:
217
+ throw new Error(`Unexpected Runtime.getProperties object: ${parameters.objectId}`);
218
+ }
219
+ }
220
+ if (method === "Runtime.callFunctionOn") {
221
+ return { result: { value: { state: "ready", reason: "owned-request-bridge" } } };
222
+ }
223
+ throw new Error(`Unexpected CDP command: ${method}`);
224
+ },
225
+ );
226
+ const debugger_: RendererDebugger = {
227
+ isAttached: () => attached,
228
+ attach,
229
+ detach,
230
+ sendCommand,
231
+ };
232
+ return {
233
+ contents: {
234
+ isDestroyed: () => false,
235
+ getType: () => "window",
236
+ debugger: debugger_,
237
+ },
238
+ sendCommand,
239
+ attach,
240
+ detach,
241
+ };
242
+ }
243
+
244
+ describe("Renderer draft prewarm policy", () => {
245
+ it("selects the request manager owned by the active remote Composer Host", () => {
246
+ const localManager = {};
247
+ const remoteManager = {};
248
+ const local = {
249
+ manager: localManager,
250
+ requestClient: { hostId: "local" },
251
+ hostId: "local",
252
+ prewarmedThreadManager: null,
253
+ };
254
+ const remote = {
255
+ manager: remoteManager,
256
+ requestClient: { hostId: "remote-ssh-discovered:mac" },
257
+ hostId: "remote-ssh-discovered:mac",
258
+ prewarmedThreadManager: {},
259
+ };
260
+
261
+ expect(
262
+ selectRendererRequestManager(
263
+ [local, remote, { ...remote, requestClient: remote.requestClient }],
264
+ ["remote-ssh-discovered:mac", "remote-ssh-discovered:mac"],
265
+ ),
266
+ ).toEqual(remote);
267
+ });
268
+
269
+ it("fails closed when the active Composer exposes conflicting Hosts", () => {
270
+ expect(
271
+ selectRendererRequestManager(
272
+ [
273
+ {
274
+ manager: {},
275
+ requestClient: {},
276
+ hostId: "remote-ssh-discovered:mac",
277
+ prewarmedThreadManager: null,
278
+ },
279
+ ],
280
+ ["local", "remote-ssh-discovered:mac"],
281
+ ),
282
+ ).toBeNull();
283
+ });
284
+
285
+ it("retains the single-manager fallback when the Composer has no Host markers", () => {
286
+ const candidate = {
287
+ manager: {},
288
+ requestClient: {},
289
+ hostId: "local",
290
+ prewarmedThreadManager: null,
291
+ };
292
+ expect(selectRendererRequestManager([candidate], [])).toBe(candidate);
293
+ });
294
+
295
+ it("generates syntactically valid main-process code", async () => {
296
+ const evaluate = vi.fn(async (expression: string): Promise<unknown> => {
297
+ expect(() => new Function(`return ${expression}`)).not.toThrow();
298
+ return { state: "ready", reason: "owned-request-bridge" };
299
+ });
300
+ const inspector = {
301
+ async evaluate<T>(expression: string): Promise<T> {
302
+ return (await evaluate(expression)) as T;
303
+ },
304
+ };
305
+
306
+ await expect(installRendererDraftPrewarmPolicy(inspector, 17)).resolves.toEqual({
307
+ state: "ready",
308
+ reason: "owned-request-bridge",
309
+ });
310
+ expect(evaluate).toHaveBeenCalledOnce();
311
+ const expression = evaluate.mock.calls[0]?.[0] ?? "";
312
+ expect(expression).toContain("webContents.fromId(17)");
313
+ expect(expression).toContain("rendererRequestManagerFromHook");
314
+ expect(expression).toContain("executionTargetHostId");
315
+ expect(expression).toContain("permissionsHostId");
316
+ });
317
+
318
+ it("retries while the current Renderer request manager is mounting", async () => {
319
+ const evaluate = vi
320
+ .fn<() => Promise<unknown>>()
321
+ .mockRejectedValueOnce(new Error("Renderer request manager is ambiguous"))
322
+ .mockResolvedValue({ state: "ready", reason: "owned-request-bridge" });
323
+ const inspector = {
324
+ async evaluate<T>(): Promise<T> {
325
+ return (await evaluate()) as T;
326
+ },
327
+ };
328
+
329
+ await expect(installRendererDraftPrewarmPolicy(inspector, 17)).resolves.toEqual({
330
+ state: "ready",
331
+ reason: "owned-request-bridge",
332
+ });
333
+ expect(evaluate).toHaveBeenCalledTimes(2);
334
+ });
335
+
336
+ it("installs the fixed policy on the uniquely owned Host request bridge", async () => {
337
+ const fixture = rendererFixture();
338
+
339
+ await expect(
340
+ installDraftPrewarmPolicyInRenderer(
341
+ fixture.contents,
342
+ "synthetic-manager-expression",
343
+ "function syntheticPolicy() {}",
344
+ ),
345
+ ).resolves.toEqual({ state: "ready", reason: "owned-request-bridge" });
346
+
347
+ expect(fixture.attach).toHaveBeenCalledWith("1.3");
348
+ expect(fixture.detach).toHaveBeenCalledOnce();
349
+ expect(fixture.sendCommand).toHaveBeenCalledWith("Runtime.evaluate", {
350
+ expression: "synthetic-manager-expression",
351
+ });
352
+ expect(fixture.sendCommand).toHaveBeenCalledWith(
353
+ "Runtime.callFunctionOn",
354
+ expect.objectContaining({
355
+ objectId: "outer-request-manager",
356
+ functionDeclaration: "function syntheticPolicy() {}",
357
+ arguments: [
358
+ { objectId: "request-client" },
359
+ { value: "local" },
360
+ { objectId: "prewarm-manager" },
361
+ ],
362
+ }),
363
+ );
364
+ });
365
+
366
+ it("installs the fixed policy on a uniquely owned remote Host request bridge", async () => {
367
+ const fixture = rendererFixture({ hostId: "remote-ssh-discovered:mac" });
368
+
369
+ await expect(
370
+ installDraftPrewarmPolicyInRenderer(
371
+ fixture.contents,
372
+ "synthetic-manager-expression",
373
+ "function syntheticPolicy() {}",
374
+ ),
375
+ ).resolves.toEqual({ state: "ready", reason: "owned-request-bridge" });
376
+
377
+ expect(fixture.sendCommand).toHaveBeenCalledWith(
378
+ "Runtime.callFunctionOn",
379
+ expect.objectContaining({
380
+ objectId: "outer-request-manager",
381
+ arguments: [
382
+ { objectId: "request-client" },
383
+ { value: "remote-ssh-discovered:mac" },
384
+ { objectId: "prewarm-manager" },
385
+ ],
386
+ }),
387
+ );
388
+ });
389
+
390
+ it.each([
391
+ [{ candidateCount: 2 }, "request manager is ambiguous"],
392
+ [{ hostId: "" }, "request manager is ambiguous"],
393
+ [{ includePrewarmedThreadManager: false }, "prewarmed Thread manager is unavailable"],
394
+ ] as const)("fails closed for an unsupported request bridge", async (options, error) => {
395
+ const fixture = rendererFixture(options);
396
+
397
+ await expect(
398
+ installDraftPrewarmPolicyInRenderer(fixture.contents, "manager", "policy"),
399
+ ).rejects.toThrow(error);
400
+ expect(fixture.detach).toHaveBeenCalledOnce();
401
+ });
402
+
403
+ it("rejects an unavailable owned Renderer before attaching", async () => {
404
+ await expect(installDraftPrewarmPolicyInRenderer(null, "manager", "policy")).rejects.toThrow(
405
+ "Owned Renderer is unavailable",
406
+ );
407
+ });
408
+
409
+ it("clears drafts through the current prewarmed Thread manager", async () => {
410
+ const discardAllPrewarmedThreads = vi.fn();
411
+ const sendRequest = vi.fn();
412
+ const prewarmThreadStart = vi.fn();
413
+ const manager = requestManagerFixture();
414
+ const bridge = requestBridgeFixture({ sendRequest, prewarmThreadStart });
415
+ const target: DraftPrewarmPolicyTarget = {};
416
+ installDraftPrewarmPolicyBridge(manager, bridge, "local", target, {
417
+ discardAllPrewarmedThreads,
418
+ });
419
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as { clear(): Promise<void> };
420
+
421
+ await policy.clear();
422
+
423
+ expect(discardAllPrewarmedThreads).toHaveBeenCalledOnce();
424
+ expect(sendRequest).not.toHaveBeenCalled();
425
+ });
426
+
427
+ it("publishes the exact owned request target before announcing the policy", () => {
428
+ const manager = requestManagerFixture();
429
+ const bridge = requestBridgeFixture();
430
+ let announcedPolicy: unknown;
431
+ const target: DraftPrewarmPolicyTarget = {
432
+ dispatchEvent: vi.fn(() => {
433
+ announcedPolicy = target.__codexhostDraftPrewarmPolicyV1;
434
+ return true;
435
+ }),
436
+ };
437
+
438
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-ssh-discovered:mac", target, {
439
+ discardAllPrewarmedThreads: vi.fn(),
440
+ });
441
+
442
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as {
443
+ requestTarget(): RendererHostRequestManager;
444
+ };
445
+ expect(announcedPolicy).toBe(policy);
446
+ expect(Object.isFrozen(policy)).toBe(true);
447
+ expect(policy.requestTarget()).toBe(manager);
448
+ expect(target.dispatchEvent).toHaveBeenCalledOnce();
449
+ });
450
+
451
+ it("keeps the selected route when the same Host bridge is reconciled", () => {
452
+ const sendRequest = vi.fn();
453
+ const prewarmThreadStart = vi.fn();
454
+ const manager = requestManagerFixture();
455
+ const bridge = requestBridgeFixture({ sendRequest, prewarmThreadStart });
456
+ const target: DraftPrewarmPolicyTarget = {};
457
+ const prewarmedThreadManager = { discardAllPrewarmedThreads: vi.fn() };
458
+ installDraftPrewarmPolicyBridge(
459
+ manager,
460
+ bridge,
461
+ "remote-ssh-discovered:mac",
462
+ target,
463
+ prewarmedThreadManager,
464
+ );
465
+ const first = target.__codexhostDraftPrewarmPolicyV1 as {
466
+ hostId: string;
467
+ select(model: string | null): boolean;
468
+ };
469
+ first.select("codexhost/claude-code-native");
470
+
471
+ installDraftPrewarmPolicyBridge(
472
+ manager,
473
+ bridge,
474
+ "remote-ssh-discovered:mac",
475
+ target,
476
+ prewarmedThreadManager,
477
+ );
478
+
479
+ expect(target.__codexhostDraftPrewarmPolicyV1).toBe(first);
480
+ expect(first.hostId).toBe("remote-ssh-discovered:mac");
481
+ void bridge.sendRequest("thread/start", { model: "gpt-5" });
482
+ expect(sendRequest).toHaveBeenCalledWith("thread/start", {
483
+ model: "codexhost/claude-code-native",
484
+ });
485
+ });
486
+
487
+ it("routes the current request client's direct and prewarm Thread starts", async () => {
488
+ const sendRequest = vi.fn<(method: string, parameters: unknown) => Promise<void>>(
489
+ async () => undefined,
490
+ );
491
+ const prewarmThreadStart = vi.fn(async (parameters: unknown) => parameters);
492
+ const manager = requestManagerFixture();
493
+ const bridge = requestBridgeFixture({ sendRequest, prewarmThreadStart });
494
+ const target: DraftPrewarmPolicyTarget = {};
495
+ installDraftPrewarmPolicyBridge(manager, bridge, "local", target, {
496
+ discardAllPrewarmedThreads: vi.fn(),
497
+ });
498
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as {
499
+ select(model: string | null): boolean;
500
+ };
501
+
502
+ policy.select("codexhost/pi-native");
503
+ await bridge.sendRequest("thread/start", { cwd: "/tmp/project", model: "gpt-5" });
504
+ await bridge.prewarmThreadStart?.({ cwd: "/tmp/project", model: "gpt-5" });
505
+ await bridge.prewarmThreadStart?.({ ephemeral: true, model: "gpt-5" });
506
+
507
+ expect(sendRequest).toHaveBeenCalledWith("thread/start", {
508
+ cwd: "/tmp/project",
509
+ model: "codexhost/pi-native",
510
+ });
511
+ expect(prewarmThreadStart).toHaveBeenNthCalledWith(1, {
512
+ cwd: "/tmp/project",
513
+ model: "codexhost/pi-native",
514
+ ephemeral: true,
515
+ });
516
+ expect(prewarmThreadStart).toHaveBeenNthCalledWith(2, {
517
+ ephemeral: true,
518
+ model: "gpt-5",
519
+ });
520
+ });
521
+
522
+ it("routes a draft Codex Account without changing the default Account", async () => {
523
+ const sendRequest = vi.fn(async () => undefined);
524
+ const manager = requestManagerFixture();
525
+ const bridge = requestBridgeFixture({ sendRequest });
526
+ const target: DraftPrewarmPolicyTarget = {};
527
+ installDraftPrewarmPolicyBridge(manager, bridge, "local", target, {
528
+ discardAllPrewarmedThreads: vi.fn(),
529
+ });
530
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as {
531
+ selectAccount(accountId: string | null): boolean;
532
+ };
533
+
534
+ expect(policy.selectAccount("reviewer")).toBe(true);
535
+ await bridge.sendRequest("thread/start", { cwd: "/tmp/project", model: "gpt-5" });
536
+ await bridge.sendRequest("thread/start", { cwd: "/tmp/next", model: "gpt-5" });
537
+
538
+ expect(sendRequest).toHaveBeenNthCalledWith(1, "thread/start", {
539
+ cwd: "/tmp/project",
540
+ model: "gpt-5",
541
+ __codexhostAccountId: "reviewer",
542
+ });
543
+ expect(sendRequest).toHaveBeenNthCalledWith(2, "thread/start", {
544
+ cwd: "/tmp/next",
545
+ model: "gpt-5",
546
+ });
547
+ });
548
+
549
+ it("tunnels private Host requests through the stock Remote Control app-server", async () => {
550
+ const manager = requestManagerFixture();
551
+ const originalNotification = manager.onNotification as ReturnType<typeof vi.fn>;
552
+ const originalServerRequest = manager.onRequest as ReturnType<typeof vi.fn>;
553
+ const originalServerResponse = manager.dispatchAppServerResponse as ReturnType<typeof vi.fn>;
554
+ const { bridge, directSend } = remoteRequestBridgeFixture();
555
+ const notifications = remoteNotificationTargetFixture();
556
+ const target = notifications.target;
557
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-control:fixture-host", target, {
558
+ discardAllPrewarmedThreads: vi.fn(),
559
+ });
560
+
561
+ const inspectPromise = bridge.sendRequest("codexhost/harness/inspect", {
562
+ harnessId: "claude-code",
563
+ }) as Promise<unknown>;
564
+ const spawnParameters = directSend.mock.calls[0]?.[1] as {
565
+ command: string[];
566
+ processHandle: string;
567
+ };
568
+ const encodedCommandIndex = spawnParameters.command.indexOf("-EncodedCommand") + 1;
569
+ expect(encodedCommandIndex).toBeGreaterThan(0);
570
+ const encodedCommand = spawnParameters.command[encodedCommandIndex];
571
+ const encodedCommandBytes = atob(encodedCommand ?? "");
572
+ let decodedCommand = "";
573
+ for (let index = 0; index < encodedCommandBytes.length; index += 2) {
574
+ decodedCommand += String.fromCharCode(
575
+ encodedCommandBytes.charCodeAt(index) | (encodedCommandBytes.charCodeAt(index + 1) << 8),
576
+ );
577
+ }
578
+ expect(decodedCommand).toContain("--codexhost-remote-control-bridge");
579
+ expect(decodedCommand).toContain("remote-control-bridge-v1.json");
580
+ expect(directSend).toHaveBeenCalledWith(
581
+ "process/spawn",
582
+ expect.objectContaining({
583
+ command: expect.arrayContaining(["powershell.exe", "-EncodedCommand"]),
584
+ cwd: "C:\\",
585
+ streamStdin: true,
586
+ streamStdoutStderr: true,
587
+ outputBytesCap: null,
588
+ timeoutMs: null,
589
+ }),
590
+ );
591
+ expect(directSend).not.toHaveBeenCalledWith("codexhost/harness/inspect", expect.anything());
592
+ const processHandle = spawnParameters.processHandle;
593
+
594
+ emitRemoteBridgeOutput(notifications, processHandle, {
595
+ method: "codexhost/remote-control-bridge/ready",
596
+ params: { protocolVersion: 1 },
597
+ });
598
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(1));
599
+ const initialize = writtenBridgeFrames(directSend)[0];
600
+ expect(initialize).toMatchObject({ method: "initialize" });
601
+
602
+ emitRemoteBridgeOutput(notifications, processHandle, { id: initialize?.id, result: {} });
603
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(3));
604
+ const frames = writtenBridgeFrames(directSend);
605
+ expect(frames[1]).toEqual({ method: "initialized", params: {} });
606
+ expect(frames[2]).toMatchObject({
607
+ method: "codexhost/harness/inspect",
608
+ params: { harnessId: "claude-code" },
609
+ });
610
+
611
+ emitRemoteBridgeOutput(notifications, processHandle, {
612
+ id: frames[2]?.id,
613
+ result: { harnessId: "claude-code", status: "ready" },
614
+ });
615
+ await expect(inspectPromise).resolves.toEqual({
616
+ harnessId: "claude-code",
617
+ status: "ready",
618
+ });
619
+
620
+ emitRemoteBridgeOutput(notifications, processHandle, {
621
+ method: "thread/started",
622
+ params: { thread: { id: "external-1", modelProvider: "codexhost" } },
623
+ });
624
+ expect(originalNotification).toHaveBeenCalledWith("thread/started", {
625
+ thread: { id: "external-1", modelProvider: "codexhost" },
626
+ });
627
+
628
+ const readPromise = bridge.sendRequest("thread/read", {
629
+ threadId: "external-1",
630
+ }) as Promise<unknown>;
631
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(4));
632
+ const read = writtenBridgeFrames(directSend)[3];
633
+ expect(read).toMatchObject({ method: "thread/read", params: { threadId: "external-1" } });
634
+ emitRemoteBridgeOutput(notifications, processHandle, {
635
+ id: read?.id,
636
+ result: { thread: { id: "external-1" } },
637
+ });
638
+ await expect(readPromise).resolves.toEqual({ thread: { id: "external-1" } });
639
+
640
+ emitRemoteBridgeOutput(notifications, processHandle, {
641
+ id: -71,
642
+ method: "item/commandExecution/requestApproval",
643
+ params: { threadId: "external-1" },
644
+ });
645
+ const bridgedServerRequest = originalServerRequest.mock.lastCall?.[0] as Record<
646
+ string,
647
+ unknown
648
+ >;
649
+ expect(bridgedServerRequest).toMatchObject({
650
+ method: "item/commandExecution/requestApproval",
651
+ params: { threadId: "external-1" },
652
+ });
653
+ expect(bridgedServerRequest.id).toEqual(expect.any(String));
654
+ expect(bridgedServerRequest.id).not.toBe(-71);
655
+
656
+ manager.dispatchAppServerResponse("item/commandExecution/requestApproval", {
657
+ id: -71,
658
+ result: { decision: "decline" },
659
+ });
660
+ expect(originalServerResponse).toHaveBeenCalledWith("item/commandExecution/requestApproval", {
661
+ id: -71,
662
+ result: { decision: "decline" },
663
+ });
664
+ expect(writtenBridgeFrames(directSend)).toHaveLength(4);
665
+
666
+ manager.dispatchAppServerResponse("item/commandExecution/requestApproval", {
667
+ id: bridgedServerRequest.id,
668
+ result: { decision: "accept" },
669
+ });
670
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(5));
671
+ expect(writtenBridgeFrames(directSend)[4]).toEqual({
672
+ id: -71,
673
+ result: { decision: "accept" },
674
+ });
675
+ });
676
+
677
+ it("routes external Thread management from persisted ownership without restoring its Harness", async () => {
678
+ const manager = requestManagerFixture();
679
+ const { bridge, directSend } = remoteRequestBridgeFixture();
680
+ const notifications = remoteNotificationTargetFixture();
681
+ installDraftPrewarmPolicyBridge(
682
+ manager,
683
+ bridge,
684
+ "remote-control:fixture-host",
685
+ notifications.target,
686
+ { discardAllPrewarmedThreads: vi.fn() },
687
+ );
688
+
689
+ const archive = bridge.sendRequest("thread/archive", {
690
+ threadId: "external-after-reload",
691
+ }) as Promise<unknown>;
692
+ const spawn = directSend.mock.calls.find(([method]) => method === "process/spawn");
693
+ expect(spawn).toBeDefined();
694
+ const processHandle = (spawn?.[1] as { processHandle: string }).processHandle;
695
+ emitRemoteBridgeOutput(notifications, processHandle, {
696
+ method: "codexhost/remote-control-bridge/ready",
697
+ params: { protocolVersion: 1 },
698
+ });
699
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(1));
700
+ const initialize = writtenBridgeFrames(directSend)[0];
701
+ emitRemoteBridgeOutput(notifications, processHandle, { id: initialize?.id, result: {} });
702
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(3));
703
+ const ownership = writtenBridgeFrames(directSend)[2];
704
+ expect(ownership).toMatchObject({
705
+ method: "codexhost/thread/ownership/list",
706
+ params: { threadIds: ["external-after-reload"] },
707
+ });
708
+ emitRemoteBridgeOutput(notifications, processHandle, {
709
+ id: ownership?.id,
710
+ result: {
711
+ threads: [
712
+ {
713
+ threadId: "external-after-reload",
714
+ owner: "external",
715
+ harnessId: "claude-code",
716
+ },
717
+ ],
718
+ },
719
+ });
720
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(4));
721
+ const bridgedArchive = writtenBridgeFrames(directSend)[3];
722
+ expect(bridgedArchive).toMatchObject({
723
+ method: "thread/archive",
724
+ params: { threadId: "external-after-reload" },
725
+ });
726
+ emitRemoteBridgeOutput(notifications, processHandle, {
727
+ id: bridgedArchive?.id,
728
+ result: {},
729
+ });
730
+
731
+ await expect(archive).resolves.toEqual({});
732
+ expect(directSend).not.toHaveBeenCalledWith("thread/archive", expect.anything());
733
+ expect(
734
+ writtenBridgeFrames(directSend).some(({ method }) => method === "codexhost/thread/inspect"),
735
+ ).toBe(false);
736
+ });
737
+
738
+ it("keeps an unknown official Thread on the stock Remote Control app-server", async () => {
739
+ const manager = requestManagerFixture();
740
+ const { bridge, directSend } = remoteRequestBridgeFixture();
741
+ const notifications = remoteNotificationTargetFixture();
742
+ installDraftPrewarmPolicyBridge(
743
+ manager,
744
+ bridge,
745
+ "remote-control:fixture-host",
746
+ notifications.target,
747
+ { discardAllPrewarmedThreads: vi.fn() },
748
+ );
749
+
750
+ const read = bridge.sendRequest("thread/read", {
751
+ threadId: "official-after-reload",
752
+ }) as Promise<unknown>;
753
+ const spawn = directSend.mock.calls.find(([method]) => method === "process/spawn");
754
+ const processHandle = (spawn?.[1] as { processHandle: string }).processHandle;
755
+ emitRemoteBridgeOutput(notifications, processHandle, {
756
+ method: "codexhost/remote-control-bridge/ready",
757
+ params: { protocolVersion: 1 },
758
+ });
759
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(1));
760
+ const initialize = writtenBridgeFrames(directSend)[0];
761
+ emitRemoteBridgeOutput(notifications, processHandle, { id: initialize?.id, result: {} });
762
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(3));
763
+ const ownership = writtenBridgeFrames(directSend)[2];
764
+ expect(ownership).toMatchObject({
765
+ method: "codexhost/thread/ownership/list",
766
+ params: { threadIds: ["official-after-reload"] },
767
+ });
768
+ emitRemoteBridgeOutput(notifications, processHandle, {
769
+ id: ownership?.id,
770
+ result: {
771
+ threads: [{ threadId: "official-after-reload", owner: "codex" }],
772
+ },
773
+ });
774
+
775
+ await expect(read).resolves.toEqual({});
776
+ expect(directSend).toHaveBeenCalledWith("thread/read", {
777
+ threadId: "official-after-reload",
778
+ });
779
+ expect(writtenBridgeFrames(directSend)).toHaveLength(3);
780
+
781
+ await bridge.sendRequest("thread/read", { threadId: "official-after-reload" });
782
+ expect(directSend).toHaveBeenCalledTimes(6);
783
+ expect(writtenBridgeFrames(directSend)).toHaveLength(3);
784
+ });
785
+
786
+ it("leaves stock Remote Control requests direct and terminates its bridge on dispose", async () => {
787
+ const manager = requestManagerFixture();
788
+ const { bridge, directSend } = remoteRequestBridgeFixture();
789
+ const target: DraftPrewarmPolicyTarget = {};
790
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-control:fixture-host", target, {
791
+ discardAllPrewarmedThreads: vi.fn(),
792
+ });
793
+
794
+ await bridge.sendRequest("model/list", {});
795
+ await bridge.sendRequest("thread/start", { model: "gpt-5", cwd: "C:\\workspace" });
796
+ expect(directSend).toHaveBeenNthCalledWith(1, "model/list", {});
797
+ expect(directSend).toHaveBeenNthCalledWith(2, "thread/start", {
798
+ model: "gpt-5",
799
+ cwd: "C:\\workspace",
800
+ });
801
+
802
+ const pending = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
803
+ void pending.catch(() => undefined);
804
+ const processHandle = (directSend.mock.calls[2]?.[1] as { processHandle: string })
805
+ .processHandle;
806
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as { dispose(): void };
807
+ policy.dispose();
808
+
809
+ expect(directSend).toHaveBeenCalledWith("process/kill", { processHandle });
810
+ });
811
+
812
+ it("replaces a failed Remote Control bridge process when diagnostics retry", async () => {
813
+ const manager = requestManagerFixture();
814
+ const { bridge, directSend } = remoteRequestBridgeFixture();
815
+ const target: DraftPrewarmPolicyTarget = {};
816
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-control:fixture-host", target, {
817
+ discardAllPrewarmedThreads: vi.fn(),
818
+ });
819
+
820
+ const first = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
821
+ const firstStart = directSend.mock.calls.find(([method]) => method === "process/spawn");
822
+ const firstProcessHandle = (firstStart?.[1] as { processHandle: string }).processHandle;
823
+ emitBridgeOutput(manager, firstProcessHandle, {
824
+ method: "codexhost/remote-control-bridge/ready",
825
+ params: { protocolVersion: 99 },
826
+ });
827
+ await expect(first).rejects.toThrow("unsupported protocol version");
828
+ expect(directSend).toHaveBeenCalledWith("process/kill", {
829
+ processHandle: firstProcessHandle,
830
+ });
831
+
832
+ const second = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
833
+ void second.catch(() => undefined);
834
+ const starts = directSend.mock.calls.filter(([method]) => method === "process/spawn");
835
+ expect(starts).toHaveLength(2);
836
+ const secondProcessHandle = (starts[1]?.[1] as { processHandle: string }).processHandle;
837
+ expect(secondProcessHandle).not.toBe(firstProcessHandle);
838
+
839
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as { dispose(): void };
840
+ policy.dispose();
841
+ });
842
+
843
+ it("reports a Remote Control bridge process exit and permits a clean retry", async () => {
844
+ const manager = requestManagerFixture();
845
+ const originalNotification = manager.onNotification as ReturnType<typeof vi.fn>;
846
+ const { bridge, directSend } = remoteRequestBridgeFixture();
847
+ const notifications = remoteNotificationTargetFixture();
848
+ const target = notifications.target;
849
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-control:fixture-host", target, {
850
+ discardAllPrewarmedThreads: vi.fn(),
851
+ });
852
+
853
+ const first = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
854
+ const firstStart = directSend.mock.calls.find(([method]) => method === "process/spawn");
855
+ const firstProcessHandle = (firstStart?.[1] as { processHandle: string }).processHandle;
856
+ notifications.emit("process/exited", {
857
+ processHandle: firstProcessHandle,
858
+ exitCode: 7,
859
+ stdout: "",
860
+ stdoutCapReached: false,
861
+ stderr: "bridge failed",
862
+ stderrCapReached: false,
863
+ });
864
+
865
+ await expect(first).rejects.toThrow("process exited unexpectedly with code 7: bridge failed");
866
+ expect(originalNotification).not.toHaveBeenCalledWith(
867
+ "process/exited",
868
+ expect.objectContaining({ processHandle: firstProcessHandle }),
869
+ );
870
+ expect(directSend).not.toHaveBeenCalledWith("process/kill", {
871
+ processHandle: firstProcessHandle,
872
+ });
873
+
874
+ const second = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
875
+ void second.catch(() => undefined);
876
+ const starts = directSend.mock.calls.filter(([method]) => method === "process/spawn");
877
+ expect(starts).toHaveLength(2);
878
+ expect((starts[1]?.[1] as { processHandle: string }).processHandle).not.toBe(
879
+ firstProcessHandle,
880
+ );
881
+
882
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as { dispose(): void };
883
+ policy.dispose();
884
+ });
885
+
886
+ it("replaces a Remote Control bridge after writing to a stale process handle", async () => {
887
+ const manager = requestManagerFixture();
888
+ const { bridge, directSend } = remoteRequestBridgeFixture();
889
+ const notifications = remoteNotificationTargetFixture();
890
+ const target = notifications.target;
891
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-control:fixture-host", target, {
892
+ discardAllPrewarmedThreads: vi.fn(),
893
+ });
894
+
895
+ const first = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
896
+ const firstStart = directSend.mock.calls.find(([method]) => method === "process/spawn");
897
+ const firstProcessHandle = (firstStart?.[1] as { processHandle: string }).processHandle;
898
+ emitRemoteBridgeOutput(notifications, firstProcessHandle, {
899
+ method: "codexhost/remote-control-bridge/ready",
900
+ params: { protocolVersion: 1 },
901
+ });
902
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(1));
903
+ const initialize = writtenBridgeFrames(directSend)[0];
904
+ emitRemoteBridgeOutput(notifications, firstProcessHandle, { id: initialize?.id, result: {} });
905
+ await vi.waitFor(() => expect(writtenBridgeFrames(directSend)).toHaveLength(3));
906
+ const inspect = writtenBridgeFrames(directSend)[2];
907
+ emitRemoteBridgeOutput(notifications, firstProcessHandle, {
908
+ id: inspect?.id,
909
+ result: { status: "ready" },
910
+ });
911
+ await expect(first).resolves.toEqual({ status: "ready" });
912
+
913
+ directSend.mockRejectedValueOnce(
914
+ new Error(`no active process for process handle "${firstProcessHandle}"`),
915
+ );
916
+ const stale = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
917
+ await expect(stale).rejects.toThrow("no active process for process handle");
918
+
919
+ const retry = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
920
+ void retry.catch(() => undefined);
921
+ const starts = directSend.mock.calls.filter(([method]) => method === "process/spawn");
922
+ expect(starts).toHaveLength(2);
923
+ expect((starts[1]?.[1] as { processHandle: string }).processHandle).not.toBe(
924
+ firstProcessHandle,
925
+ );
926
+
927
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as { dispose(): void };
928
+ policy.dispose();
929
+ });
930
+
931
+ it("times out a stalled Remote Control initialization and permits a clean retry", async () => {
932
+ vi.useFakeTimers();
933
+ try {
934
+ const manager = requestManagerFixture();
935
+ const { bridge, directSend } = remoteRequestBridgeFixture();
936
+ const notifications = remoteNotificationTargetFixture();
937
+ const target = notifications.target;
938
+ installDraftPrewarmPolicyBridge(manager, bridge, "remote-control:fixture-host", target, {
939
+ discardAllPrewarmedThreads: vi.fn(),
940
+ });
941
+
942
+ const first = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
943
+ const firstRejected = expect(first).rejects.toThrow("initialization timed out after 15000ms");
944
+ const firstStart = directSend.mock.calls.find(([method]) => method === "process/spawn");
945
+ const firstProcessHandle = (firstStart?.[1] as { processHandle: string }).processHandle;
946
+ notifications.emit("process/outputDelta", {
947
+ processHandle: firstProcessHandle,
948
+ stream: "stdout",
949
+ deltaBase64: Buffer.from(
950
+ `${JSON.stringify({
951
+ method: "codexhost/remote-control-bridge/ready",
952
+ params: { protocolVersion: 1 },
953
+ })}\n`,
954
+ "utf8",
955
+ ).toString("base64"),
956
+ capReached: false,
957
+ });
958
+ await vi.advanceTimersByTimeAsync(0);
959
+ expect(writtenBridgeFrames(directSend)).toHaveLength(1);
960
+
961
+ await vi.advanceTimersByTimeAsync(15_000);
962
+ await firstRejected;
963
+ expect(directSend).toHaveBeenCalledWith("process/kill", {
964
+ processHandle: firstProcessHandle,
965
+ });
966
+
967
+ const second = bridge.sendRequest("codexhost/harness/inspect", {}) as Promise<unknown>;
968
+ void second.catch(() => undefined);
969
+ const starts = directSend.mock.calls.filter(([method]) => method === "process/spawn");
970
+ expect(starts).toHaveLength(2);
971
+ expect((starts[1]?.[1] as { processHandle: string }).processHandle).not.toBe(
972
+ firstProcessHandle,
973
+ );
974
+
975
+ const policy = target.__codexhostDraftPrewarmPolicyV1 as { dispose(): void };
976
+ policy.dispose();
977
+ } finally {
978
+ vi.useRealTimers();
979
+ }
980
+ });
981
+
982
+ it("installs the owned request bridge through direct Renderer evaluation", async () => {
983
+ const evaluate = vi.fn(async (expression: string): Promise<unknown> => {
984
+ void expression;
985
+ return {
986
+ state: "ready",
987
+ reason: "owned-request-bridge",
988
+ };
989
+ });
990
+ const renderer = {
991
+ async evaluate<T>(expression: string): Promise<T> {
992
+ return (await evaluate(expression)) as T;
993
+ },
994
+ };
995
+
996
+ await expect(installRendererDraftPrewarmPolicyDirect(renderer)).resolves.toEqual({
997
+ state: "ready",
998
+ reason: "owned-request-bridge",
999
+ });
1000
+ const expression = evaluate.mock.calls[0]?.[0];
1001
+ expect(expression).toContain("document.querySelectorAll");
1002
+ expect(expression).toContain("installDraftPrewarmPolicyBridge");
1003
+ expect(expression).not.toContain("webContents.fromId");
1004
+ });
1005
+
1006
+ it("rejects an invalid Renderer identity before inspecting the Desktop", async () => {
1007
+ const evaluate = vi.fn();
1008
+
1009
+ await expect(installRendererDraftPrewarmPolicy({ evaluate }, 0)).rejects.toThrow(
1010
+ "Renderer webContents ID must be a positive integer",
1011
+ );
1012
+ expect(evaluate).not.toHaveBeenCalled();
1013
+ });
1014
+
1015
+ it("fails closed on an invalid installation result", async () => {
1016
+ const evaluate = vi.fn(async (): Promise<unknown> => {
1017
+ return { state: "ready", reason: "ambiguous" };
1018
+ });
1019
+ const inspector = {
1020
+ async evaluate<T>(): Promise<T> {
1021
+ return (await evaluate()) as T;
1022
+ },
1023
+ };
1024
+
1025
+ await expect(installRendererDraftPrewarmPolicy(inspector, 17)).rejects.toThrow(
1026
+ "Renderer draft prewarm policy returned an invalid status",
1027
+ );
1028
+ });
1029
+ });