@harness-mix/cli 0.1.11 → 0.1.12

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 (306) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/NOTICE +16 -2
  3. package/README.md +265 -3
  4. package/docs/cross-platform.md +3 -3
  5. package/docs/multi-agent-collaboration.md +37 -23
  6. package/docs/native-acp.md +2 -2
  7. package/docs/native-codex.md +5 -5
  8. package/docs/{superpowers/specs → specs}/2026-09-13-native-hardening-design.md +2 -2
  9. package/docs/storage-verification-design.md +5 -5
  10. package/licenses/lobe-icons-MIT.txt +21 -0
  11. package/output/native-build/desktop-controller.mjs +24 -24
  12. package/output/native-build/harness-mix-secret.exe +0 -0
  13. package/output/native-build/harness-mix-shim.exe +0 -0
  14. package/output/native-build/renderer-extension.js +1325 -658
  15. package/package.json +2 -2
  16. package/scripts/adapters-test.cjs +9 -1
  17. package/scripts/antigravity-adapter-test.cjs +381 -284
  18. package/scripts/build-native.cjs +64 -46
  19. package/scripts/codex-accounts-test.cjs +1 -1
  20. package/scripts/codex-accounts-ui-smoke.cjs +1 -1
  21. package/scripts/collaboration-recovery-test.cjs +11 -2
  22. package/scripts/collaboration-test.cjs +114 -27
  23. package/scripts/collaboration-ui-smoke.cjs +45 -8
  24. package/scripts/concurrency-layers-test.cjs +5 -0
  25. package/scripts/diagnostics.cjs +1 -1
  26. package/scripts/e2e-native-host.cjs +13 -13
  27. package/scripts/error-kind-test.cjs +3 -3
  28. package/scripts/integrations-test.cjs +2 -2
  29. package/scripts/integrations-ui-smoke.cjs +6 -6
  30. package/scripts/native-config-test.cjs +6 -6
  31. package/scripts/native-job-object-test.cjs +1 -1
  32. package/scripts/native-protocol-test.cjs +44 -38
  33. package/scripts/native-rollback-test.cjs +1 -1
  34. package/scripts/native-secret-test.cjs +1 -1
  35. package/scripts/native-shim-test.cjs +1 -1
  36. package/scripts/native-sidebar-test.cjs +4 -4
  37. package/scripts/native-ui-smoke.cjs +12 -12
  38. package/scripts/pets-test.cjs +223 -3
  39. package/scripts/platform-test.cjs +6 -6
  40. package/scripts/publish-native-package.cjs +1 -1
  41. package/scripts/test-live-mentions.cjs +2 -2
  42. package/scripts/workspace-test.cjs +4 -2
  43. package/src/assets/icons/PROVENANCE.md +92 -0
  44. package/src/main/adapters/antigravity.js +1415 -1368
  45. package/src/main/adapters/claude.js +1 -1
  46. package/src/main/adapters/codex-app-server.js +1 -1
  47. package/src/main/adapters/dsh.js +1 -1
  48. package/src/main/adapters/index.js +1 -1
  49. package/src/main/adapters/pi-usage.js +2 -2
  50. package/src/main/harness-adapter/error-kind.js +1 -1
  51. package/src/main/harness-adapter/manifest.js +7 -1
  52. package/src/main/host/collaboration-tools.js +8 -1
  53. package/src/main/host/collaboration-worktree.js +27 -1
  54. package/src/main/host/collaboration.js +348 -15
  55. package/src/main/host/runtime.js +23 -15
  56. package/src/main/native/codex-accounts.js +1 -1
  57. package/src/main/native/config.js +9 -9
  58. package/src/main/native/host.js +1 -1
  59. package/src/main/native/launcher.js +10 -8
  60. package/src/main/native/pets.js +188 -49
  61. package/src/main/native/platform.js +19 -9
  62. package/src/main/native/protocol.js +83 -80
  63. package/src/main/native/rs/crates/appx/Cargo.toml +1 -1
  64. package/src/main/native/rs/crates/secret/Cargo.toml +1 -1
  65. package/src/main/native/rs/crates/secret/src/main.rs +3 -3
  66. package/src/main/native/rs/crates/shim/Cargo.toml +1 -1
  67. package/src/main/native/rs/crates/shim/src/main.rs +2 -2
  68. package/src/main/native/thread-list.js +1 -1
  69. package/src/main/shared-contracts/capability.js +3 -1
  70. package/src/main/workspace/core-review.js +4 -3
  71. package/src/native-ui/README.md +2 -2
  72. package/src/native-ui/desktop-control/dist/contract-audit.js +4 -4
  73. package/src/native-ui/desktop-control/dist/index.d.ts +1 -1
  74. package/src/native-ui/desktop-control/dist/index.js +2 -2
  75. package/src/native-ui/desktop-control/dist/index.js.map +1 -1
  76. package/src/native-ui/desktop-control/dist/main-process-title-policy.js +5 -5
  77. package/src/native-ui/desktop-control/dist/main-process-title-policy.js.map +1 -1
  78. package/src/native-ui/desktop-control/dist/production-controller.js +3 -3
  79. package/src/native-ui/desktop-control/dist/production-controller.js.map +1 -1
  80. package/src/native-ui/desktop-control/dist/release-main.js +1 -1
  81. package/src/native-ui/desktop-control/dist/release-main.js.map +1 -1
  82. package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js +1 -1
  83. package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js.map +1 -1
  84. package/src/native-ui/desktop-control/dist/renderer-control-session.js +3 -3
  85. package/src/native-ui/desktop-control/dist/renderer-control-session.js.map +1 -1
  86. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js +25 -25
  87. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js.map +1 -1
  88. package/src/native-ui/desktop-control/dist/tsconfig.tsbuildinfo +1 -1
  89. package/src/native-ui/desktop-control/package.json +2 -2
  90. package/src/native-ui/desktop-control/scripts/build-release.mjs +2 -2
  91. package/src/native-ui/desktop-control/src/contract-audit.ts +4 -4
  92. package/src/native-ui/desktop-control/src/index.ts +2 -2
  93. package/src/native-ui/desktop-control/src/main-process-title-policy.ts +5 -5
  94. package/src/native-ui/desktop-control/src/production-controller.ts +3 -3
  95. package/src/native-ui/desktop-control/src/release-main.ts +1 -1
  96. package/src/native-ui/desktop-control/src/renderer-cdp-control-session.ts +1 -1
  97. package/src/native-ui/desktop-control/src/renderer-control-session.ts +3 -3
  98. package/src/native-ui/desktop-control/src/renderer-draft-prewarm-runtime.ts +25 -25
  99. package/src/native-ui/desktop-control/test/index.test.ts +1 -1
  100. package/src/native-ui/desktop-control/test/production-controller.test.ts +1 -1
  101. package/src/native-ui/desktop-control/test/renderer-cdp-control-session.test.ts +1 -1
  102. package/src/native-ui/desktop-control/test/renderer-draft-prewarm-policy.test.ts +43 -43
  103. package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts +1 -1
  104. package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts.map +1 -1
  105. package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts +1 -1
  106. package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts.map +1 -1
  107. package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts +1 -1
  108. package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts.map +1 -1
  109. package/src/native-ui/renderer-extension/dist/types/index.d.ts +3 -1
  110. package/src/native-ui/renderer-extension/dist/types/index.d.ts.map +1 -1
  111. package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts +1 -1
  112. package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts.map +1 -1
  113. package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts +2 -2
  114. package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts.map +1 -1
  115. package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts +3 -3
  116. package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -1
  117. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts +1 -1
  118. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts.map +1 -1
  119. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts +1 -1
  120. package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts.map +1 -1
  121. package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts +1 -1
  122. package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts.map +1 -1
  123. package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts +1 -1
  124. package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts.map +1 -1
  125. package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts +1 -1
  126. package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts.map +1 -1
  127. package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts +1 -1
  128. package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts.map +1 -1
  129. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts +1 -1
  130. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts.map +1 -1
  131. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts +1 -1
  132. package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts.map +1 -1
  133. package/src/native-ui/renderer-extension/dist/types/renderer-harness-handoff.d.ts +1 -1
  134. package/src/native-ui/renderer-extension/dist/types/renderer-harness-handoff.d.ts.map +1 -1
  135. package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts +1 -1
  136. package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts.map +1 -1
  137. package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts +1 -0
  138. package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts.map +1 -1
  139. package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +36 -31
  140. package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -1
  141. package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts +1 -1
  142. package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts.map +1 -1
  143. package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts +2 -2
  144. package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts.map +1 -1
  145. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts +1 -1
  146. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts.map +1 -1
  147. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts +2 -2
  148. package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts.map +1 -1
  149. package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts +18 -2
  150. package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts.map +1 -1
  151. package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts +1 -1
  152. package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts.map +1 -1
  153. package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts +2 -2
  154. package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts.map +1 -1
  155. package/src/native-ui/renderer-extension/dist/types/renderer-team-cards.d.ts +58 -0
  156. package/src/native-ui/renderer-extension/dist/types/renderer-team-cards.d.ts.map +1 -0
  157. package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts +1 -1
  158. package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts +1 -1
  159. package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts.map +1 -1
  160. package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts +1 -1
  161. package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts.map +1 -1
  162. package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts +1 -1
  163. package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts.map +1 -1
  164. package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts +1 -1
  165. package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts.map +1 -1
  166. package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts +1 -1
  167. package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts.map +1 -1
  168. package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts +3 -3
  169. package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts.map +1 -1
  170. package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts +1 -1
  171. package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts.map +1 -1
  172. package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +4 -4
  173. package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -1
  174. package/src/native-ui/renderer-extension/dist/types/settings/pet-market.d.ts.map +1 -1
  175. package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts +1 -1
  176. package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts.map +1 -1
  177. package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts +1 -1
  178. package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts.map +1 -1
  179. package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts +2 -2
  180. package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts.map +1 -1
  181. package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts +1 -1
  182. package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts.map +1 -1
  183. package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -1
  184. package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts +18 -18
  185. package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts.map +1 -1
  186. package/src/native-ui/renderer-extension/package.json +2 -2
  187. package/src/native-ui/renderer-extension/src/agent-group-preference.ts +1 -1
  188. package/src/native-ui/renderer-extension/src/agent-selection-state.ts +31 -16
  189. package/src/native-ui/renderer-extension/src/audit-entry.ts +1 -1
  190. package/src/native-ui/renderer-extension/src/contract-audit.ts +4 -4
  191. package/src/native-ui/renderer-extension/src/index.ts +4 -2
  192. package/src/native-ui/renderer-extension/src/install-renderer-binding.ts +2 -2
  193. package/src/native-ui/renderer-extension/src/production-entry.ts +3 -3
  194. package/src/native-ui/renderer-extension/src/renderer-agent-picker.ts +7 -7
  195. package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +112 -89
  196. package/src/native-ui/renderer-extension/src/renderer-codex-account-options.ts +1 -1
  197. package/src/native-ui/renderer-extension/src/renderer-codex-account-state.ts +1 -1
  198. package/src/native-ui/renderer-extension/src/renderer-collab-cards.ts +1 -1
  199. package/src/native-ui/renderer-extension/src/renderer-composer-dom.ts +12 -12
  200. package/src/native-ui/renderer-extension/src/renderer-credits-control.ts +7 -7
  201. package/src/native-ui/renderer-extension/src/renderer-external-steering.ts +3 -3
  202. package/src/native-ui/renderer-extension/src/renderer-fork-control.ts +1 -1
  203. package/src/native-ui/renderer-extension/src/renderer-harness-command-claim.ts +1 -1
  204. package/src/native-ui/renderer-extension/src/renderer-harness-command-control.ts +3 -3
  205. package/src/native-ui/renderer-extension/src/renderer-harness-handoff.ts +1 -1
  206. package/src/native-ui/renderer-extension/src/renderer-harness-localization.ts +1 -1
  207. package/src/native-ui/renderer-extension/src/renderer-harness-mentions.ts +4 -0
  208. package/src/native-ui/renderer-extension/src/renderer-integrations-client.ts +5 -5
  209. package/src/native-ui/renderer-extension/src/renderer-model-client.ts +63 -42
  210. package/src/native-ui/renderer-extension/src/renderer-model-picker.ts +16 -16
  211. package/src/native-ui/renderer-extension/src/renderer-new-thread-preference.ts +2 -2
  212. package/src/native-ui/renderer-extension/src/renderer-permission-mode-picker.ts +3 -3
  213. package/src/native-ui/renderer-extension/src/renderer-permission-mode-preference.ts +2 -2
  214. package/src/native-ui/renderer-extension/src/renderer-request-sender.ts +46 -3
  215. package/src/native-ui/renderer-extension/src/renderer-session-import-client.ts +4 -4
  216. package/src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts +24 -20
  217. package/src/native-ui/renderer-extension/src/renderer-team-cards.ts +312 -0
  218. package/src/native-ui/renderer-extension/src/renderer-transcript-dom.ts +1 -1
  219. package/src/native-ui/renderer-extension/src/renderer-trigger-chip-style.ts +2 -2
  220. package/src/native-ui/renderer-extension/src/renderer-usage-control.ts +4 -4
  221. package/src/native-ui/renderer-extension/src/settings/accounts-list.ts +1 -1
  222. package/src/native-ui/renderer-extension/src/settings/accounts-page.ts +1 -1
  223. package/src/native-ui/renderer-extension/src/settings/accounts-usage.ts +1 -1
  224. package/src/native-ui/renderer-extension/src/settings/connections-page.ts +7 -7
  225. package/src/native-ui/renderer-extension/src/settings/harness-accounts.ts +1 -1
  226. package/src/native-ui/renderer-extension/src/settings/icons.ts +2 -2
  227. package/src/native-ui/renderer-extension/src/settings/pages.ts +11 -11
  228. package/src/native-ui/renderer-extension/src/settings/pet-market.css +33 -0
  229. package/src/native-ui/renderer-extension/src/settings/pet-market.ts +173 -91
  230. package/src/native-ui/renderer-extension/src/settings/pets-client.ts +5 -5
  231. package/src/native-ui/renderer-extension/src/settings/release-notes.ts +1 -1
  232. package/src/native-ui/renderer-extension/src/settings/session-import-list-controls.ts +1 -1
  233. package/src/native-ui/renderer-extension/src/settings/session-import-page.ts +1 -1
  234. package/src/native-ui/renderer-extension/src/settings/shell.css +15 -15
  235. package/src/native-ui/renderer-extension/src/settings/shell.ts +11 -11
  236. package/src/native-ui/renderer-extension/src/settings/skin-runtime.ts +17 -17
  237. package/src/native-ui/renderer-extension/src/settings/trigger.ts +1 -1
  238. package/src/native-ui/renderer-extension/src/versioned-renderer-adapter.ts +20 -20
  239. package/src/native-ui/renderer-extension/test/agent-selection-state.test.ts +60 -1
  240. package/src/native-ui/renderer-extension/test/codebuddy-migration.test.ts +1 -1
  241. package/src/native-ui/renderer-extension/test/renderer-agent-picker.test.ts +1 -1
  242. package/src/native-ui/renderer-extension/test/renderer-binding-probe-host-catalog.test.ts +15 -9
  243. package/src/native-ui/renderer-extension/test/renderer-binding-probe.test.ts +15 -15
  244. package/src/native-ui/renderer-extension/test/renderer-codex-account-state.test.ts +1 -1
  245. package/src/native-ui/renderer-extension/test/renderer-composer-permissions.test.ts +4 -4
  246. package/src/native-ui/renderer-extension/test/renderer-external-steering-rpc.test.ts +2 -2
  247. package/src/native-ui/renderer-extension/test/renderer-external-steering.test.ts +3 -3
  248. package/src/native-ui/renderer-extension/test/renderer-fork-control.test.ts +4 -4
  249. package/src/native-ui/renderer-extension/test/renderer-harness-command-claim.test.ts +1 -1
  250. package/src/native-ui/renderer-extension/test/renderer-harness-command-control.test.ts +1 -1
  251. package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +12 -11
  252. package/src/native-ui/renderer-extension/test/renderer-model-picker.test.ts +1 -1
  253. package/src/native-ui/renderer-extension/test/renderer-native-thread-ownership.test.ts +6 -6
  254. package/src/native-ui/renderer-extension/test/renderer-new-thread-preference.test.ts +1 -1
  255. package/src/native-ui/renderer-extension/test/renderer-permission-mode-picker.test.ts +1 -1
  256. package/src/native-ui/renderer-extension/test/renderer-permission-mode-preference.test.ts +1 -1
  257. package/src/native-ui/renderer-extension/test/renderer-request-timeout.test.ts +80 -0
  258. package/src/native-ui/renderer-extension/test/renderer-settings-lifecycle.test.ts +2 -2
  259. package/src/native-ui/renderer-extension/test/renderer-sidebar-agent-icons.test.ts +10 -3
  260. package/src/native-ui/renderer-extension/test/renderer-unsupported-methods.test.ts +1 -1
  261. package/src/native-ui/renderer-extension/test/settings/pages.test.ts +5 -5
  262. package/src/native-ui/renderer-extension/test/settings/release-notes.test.ts +9 -9
  263. package/src/native-ui/renderer-extension/test/versioned-renderer-adapter.test.ts +3 -3
  264. package/src/native-ui/shared-contracts/dist/errors.d.ts +2 -2
  265. package/src/native-ui/shared-contracts/dist/errors.d.ts.map +1 -1
  266. package/src/native-ui/shared-contracts/dist/errors.js +1 -1
  267. package/src/native-ui/shared-contracts/dist/errors.js.map +1 -1
  268. package/src/native-ui/shared-contracts/dist/harness-models.d.ts +40 -0
  269. package/src/native-ui/shared-contracts/dist/harness-models.d.ts.map +1 -1
  270. package/src/native-ui/shared-contracts/dist/harness-models.js +23 -2
  271. package/src/native-ui/shared-contracts/dist/harness-models.js.map +1 -1
  272. package/src/native-ui/shared-contracts/dist/harness-route.d.ts +1 -1
  273. package/src/native-ui/shared-contracts/dist/harness-route.d.ts.map +1 -1
  274. package/src/native-ui/shared-contracts/dist/harness-route.js +1 -1
  275. package/src/native-ui/shared-contracts/dist/harness-route.js.map +1 -1
  276. package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts +1 -1
  277. package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts.map +1 -1
  278. package/src/native-ui/shared-contracts/dist/harness-session-import.js +1 -1
  279. package/src/native-ui/shared-contracts/dist/harness-session-import.js.map +1 -1
  280. package/src/native-ui/shared-contracts/dist/index.d.ts +3 -3
  281. package/src/native-ui/shared-contracts/dist/index.d.ts.map +1 -1
  282. package/src/native-ui/shared-contracts/dist/index.js +2 -2
  283. package/src/native-ui/shared-contracts/dist/index.js.map +1 -1
  284. package/src/native-ui/shared-contracts/dist/tsconfig.tsbuildinfo +1 -1
  285. package/src/native-ui/shared-contracts/dist/updates.js +1 -1
  286. package/src/native-ui/shared-contracts/dist/updates.js.map +1 -1
  287. package/src/native-ui/shared-contracts/package.json +1 -1
  288. package/src/native-ui/shared-contracts/src/errors.ts +3 -3
  289. package/src/native-ui/shared-contracts/src/harness-models.ts +23 -2
  290. package/src/native-ui/shared-contracts/src/harness-route.ts +1 -1
  291. package/src/native-ui/shared-contracts/src/harness-session-import.ts +1 -1
  292. package/src/native-ui/shared-contracts/src/index.ts +3 -3
  293. package/src/native-ui/shared-contracts/src/updates.ts +1 -1
  294. package/src/native-ui/shared-contracts/test/browser-bundle.test.ts +3 -3
  295. package/src/native-ui/shared-contracts/test/deepseek-modern-sessions.test.ts +1 -1
  296. package/src/native-ui/shared-contracts/test/errors.test.ts +9 -9
  297. package/src/native-ui/shared-contracts/test/harness-commands.test.ts +1 -1
  298. package/src/native-ui/shared-contracts/test/harness-models.test.ts +3 -3
  299. package/src/native-ui/shared-contracts/test/harness-permission-modes.test.ts +1 -1
  300. package/src/native-ui/shared-contracts/test/harness-plugins.test.ts +1 -1
  301. package/src/native-ui/shared-contracts/test/harness-session-import.test.ts +1 -1
  302. package/src/native-ui/shared-contracts/test/index.test.ts +3 -3
  303. package/src/native-ui/shared-contracts/test/json-rpc.test.ts +1 -1
  304. package/src/native-ui/shared-contracts/test/thread-usage.test.ts +1 -1
  305. package/src/native-ui/shared-contracts/test/updates.test.ts +4 -4
  306. /package/licenses/{codex-host-MIT.txt → bytepioneer-MIT.txt} +0 -0
@@ -119,8 +119,8 @@ async function main() {
119
119
  const globalOnly = await blocked.ensureSkillRoots({ cwd: 'relative-not-absolute' }, adapters.get('codex'), {});
120
120
  assert.equal(globalOnly.length, 1);
121
121
  // Exercise the real protocol dispatcher without starting native processes.
122
- assert.equal((await NativeProtocol.prototype.request.call({ runtime }, 'codexhost/integrations/catalog', {})).harnesses.length, 17);
123
- assert.equal((await NativeProtocol.prototype.request.call({ runtime }, 'codexhost/integrations/list', local)).skills.length, 3);
122
+ assert.equal((await NativeProtocol.prototype.request.call({ runtime }, 'harnessmix/integrations/catalog', {})).harnesses.length, 17);
123
+ assert.equal((await NativeProtocol.prototype.request.call({ runtime }, 'harnessmix/integrations/list', local)).skills.length, 3);
124
124
  console.log('integrations: scope precedence, persistence, native status projection, no credential fields, unsupported capabilities, skill install/disable/restore, links, and protocol PASS');
125
125
  }
126
126
  main().catch(error => { console.error(error); process.exitCode = 1; });
@@ -17,10 +17,10 @@ app.whenReady().then(async () => {
17
17
  const preload = path.join(out, 'preload.cjs');
18
18
  await fs.writeFile(preload, `const {contextBridge,ipcRenderer}=require('electron');contextBridge.exposeInMainWorld('integrationTest',{request:(method,params)=>ipcRenderer.invoke('integrations-test',method,params)});`);
19
19
  ipcMain.handle('integrations-test', (_event, method, params) => {
20
- assert.ok(method.startsWith('codexhost/integrations/'));
20
+ assert.ok(method.startsWith('harnessmix/integrations/'));
21
21
  return NativeProtocol.prototype.request.call({ runtime }, method, params);
22
22
  });
23
- const build = await esbuild.build({ stdin: { contents: `export {createMcpSettingsPage,createSkillsSettingsPage} from './src/native-ui/renderer-extension/src/settings/integrations-page.ts'; export {mountRendererSettingsShell} from './src/native-ui/renderer-extension/src/settings/shell.ts'; export {createRendererSettingsPageRegistry} from './src/native-ui/renderer-extension/src/settings/core.ts'; export {rendererSettingsMessages} from './src/native-ui/renderer-extension/src/settings/localization.ts'; export {createRendererIntegrationsClient} from './src/native-ui/renderer-extension/src/renderer-integrations-client.ts';`, resolveDir: process.cwd() }, bundle: true, platform: 'browser', format: 'iife', globalName: 'IntegrationUI', write: false, alias: { '@codexhost/shared-contracts': path.resolve('src/native-ui/shared-contracts/src/index.ts') }, loader: { '.svg': 'dataurl', '.png': 'dataurl', '.css': 'text' } });
23
+ const build = await esbuild.build({ stdin: { contents: `export {createMcpSettingsPage,createSkillsSettingsPage} from './src/native-ui/renderer-extension/src/settings/integrations-page.ts'; export {mountRendererSettingsShell} from './src/native-ui/renderer-extension/src/settings/shell.ts'; export {createRendererSettingsPageRegistry} from './src/native-ui/renderer-extension/src/settings/core.ts'; export {rendererSettingsMessages} from './src/native-ui/renderer-extension/src/settings/localization.ts'; export {createRendererIntegrationsClient} from './src/native-ui/renderer-extension/src/renderer-integrations-client.ts';`, resolveDir: process.cwd() }, bundle: true, platform: 'browser', format: 'iife', globalName: 'IntegrationUI', write: false, alias: { '@harnessmix/shared-contracts': path.resolve('src/native-ui/shared-contracts/src/index.ts') }, loader: { '.svg': 'dataurl', '.png': 'dataurl', '.css': 'text' } });
24
24
  const consoleProblems = [];
25
25
  const win = new BrowserWindow({ show: false, width: 1100, height: 900, webPreferences: { preload, contextIsolation: true, sandbox: true, offscreen: true } });
26
26
  win.webContents.on('console-message', (_event, details) => { if (details.level === 'error' || details.level === 'warning') consoleProblems.push(details.message); });
@@ -74,7 +74,7 @@ app.whenReady().then(async () => {
74
74
  await fs.writeFile(path.join(out, 'settings.png'), overviewImage);
75
75
  await fs.writeFile(path.join(out, 'skills.png'), overviewImage);
76
76
  await win.webContents.executeJavaScript(`(async()=>{
77
- const root=document.querySelector('[data-codexhost-settings-shell]').shadowRoot;
77
+ const root=document.querySelector('[data-harnessmix-settings-shell]').shadowRoot;
78
78
  root.querySelector('button[data-page-id="mcp"]').click();
79
79
  const wait=async predicate=>{for(let i=0;i<100;i++){if(predicate())return;await new Promise(r=>setTimeout(r,30));}throw Error('MCP screenshot timed out');};
80
80
  await wait(()=>root.querySelector('select')?.options.length===17&&!root.querySelector('select').disabled);
@@ -92,7 +92,7 @@ app.whenReady().then(async () => {
92
92
  await new Promise(r => setTimeout(r, 60));
93
93
  await fs.writeFile(path.join(out, 'mcp-matrix.png'), (await win.webContents.capturePage()).toPNG());
94
94
  await win.webContents.executeJavaScript(`(async()=>{
95
- const root=document.querySelector('[data-codexhost-settings-shell]').shadowRoot;
95
+ const root=document.querySelector('[data-harnessmix-settings-shell]').shadowRoot;
96
96
  const byHarnessBtn=Array.from(root.querySelectorAll('.settings-mcp-tabs button')).find(b=>b.textContent.includes('Harness'));
97
97
  byHarnessBtn?.click();
98
98
  const wait=async predicate=>{for(let i=0;i<100;i++){if(predicate())return;await new Promise(r=>setTimeout(r,30));}throw Error('MCP switch timed out');};
@@ -101,7 +101,7 @@ app.whenReady().then(async () => {
101
101
  await new Promise(r => setTimeout(r, 60));
102
102
  await fs.writeFile(path.join(out, 'mcp-overview.png'), (await win.webContents.capturePage()).toPNG());
103
103
  await win.webContents.executeJavaScript(`(async()=>{
104
- const root=document.querySelector('[data-codexhost-settings-shell]').shadowRoot;
104
+ const root=document.querySelector('[data-harnessmix-settings-shell]').shadowRoot;
105
105
  const [harness,scope]=root.querySelectorAll('select');
106
106
  harness.value='claude';harness.dispatchEvent(new Event('change'));
107
107
  const wait=async predicate=>{for(let i=0;i<100;i++){if(predicate())return;await new Promise(r=>setTimeout(r,30));}throw Error('MCP reload timed out');};
@@ -111,7 +111,7 @@ app.whenReady().then(async () => {
111
111
  })()`);
112
112
  await fs.writeFile(path.join(out, 'mcp.png'), (await win.webContents.capturePage()).toPNG());
113
113
  await win.webContents.executeJavaScript(`(async()=>{
114
- const root=document.querySelector('[data-codexhost-settings-shell]').shadowRoot;
114
+ const root=document.querySelector('[data-harnessmix-settings-shell]').shadowRoot;
115
115
  const mcpRow=Array.from(root.querySelectorAll('.settings-integrations-row')).find(r=>r.querySelector('strong')?.textContent?.includes('ui-probe'));
116
116
  mcpRow.querySelector('button').click();
117
117
  const wait=async predicate=>{for(let i=0;i<100;i++){if(predicate())return;await new Promise(r=>setTimeout(r,30));}throw Error('MCP editor timed out');};
@@ -7,16 +7,16 @@ const { isCodexTaskEnvironment, readLiveHostInstance } = require('../src/main/na
7
7
 
8
8
  const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-mix-config-'));
9
9
  try {
10
- const source = { CODEXHOST_DATA_DIR: directory, CODEXHOST_PI_COMMAND: 'C:\\Native tools\\pi.cmd', PRIVATE_TEST_VALUE: 'do-not-persist' };
10
+ const source = { HARNESSMIX_DATA_DIR: directory, HARNESSMIX_PI_COMMAND: 'C:\\Native tools\\pi.cmd', PRIVATE_TEST_VALUE: 'do-not-persist' };
11
11
  const env = nativeEnvironment(source);
12
- assert.equal(source.CODEXHOST_DEFAULT_AGENT, undefined, 'Input environment is not mutated');
13
- assert.equal(env.CODEXHOST_DEFAULT_AGENT, 'codex');
12
+ assert.equal(source.HARNESSMIX_DEFAULT_AGENT, undefined, 'Input environment is not mutated');
13
+ assert.equal(env.HARNESSMIX_DEFAULT_AGENT, 'codex');
14
14
  saveNativeSettings(env);
15
15
  const saved = JSON.parse(fs.readFileSync(path.join(directory, 'harness-mix-settings.json'), 'utf8'));
16
- assert.deepEqual(saved, { CODEXHOST_PI_COMMAND: source.CODEXHOST_PI_COMMAND });
17
- assert.equal(nativeEnvironment({ CODEXHOST_DATA_DIR: directory }).CODEXHOST_PI_COMMAND, source.CODEXHOST_PI_COMMAND,
16
+ assert.deepEqual(saved, { HARNESSMIX_PI_COMMAND: source.HARNESSMIX_PI_COMMAND });
17
+ assert.equal(nativeEnvironment({ HARNESSMIX_DATA_DIR: directory }).HARNESSMIX_PI_COMMAND, source.HARNESSMIX_PI_COMMAND,
18
18
  'AppX child recovers command settings from the data directory');
19
- assert.equal(nativeEnvironment({ CODEXHOST_DATA_DIR: directory, CODEXHOST_PI_COMMAND: 'D:\\other\\pi.cmd' }).CODEXHOST_PI_COMMAND,
19
+ assert.equal(nativeEnvironment({ HARNESSMIX_DATA_DIR: directory, HARNESSMIX_PI_COMMAND: 'D:\\other\\pi.cmd' }).HARNESSMIX_PI_COMMAND,
20
20
  'D:\\other\\pi.cmd', 'Explicit environment takes priority');
21
21
  for (const file of Object.values(nativePaths())) assert.ok(fs.statSync(file).isFile(), file);
22
22
  const runtimeDirectory = path.join(directory, 'runtime');
@@ -54,7 +54,7 @@ const alive = pid => {
54
54
  ...process.env,
55
55
  HARNESS_MIX_HOST_SCRIPT: fixture,
56
56
  HARNESS_MIX_NODE_PATH: process.execPath,
57
- CODEXHOST_STOCK_CODEX_PATH: process.execPath,
57
+ HARNESSMIX_STOCK_CODEX_PATH: process.execPath,
58
58
  FAKE_HOST_PIDS: pidFile,
59
59
  },
60
60
  stdio: ['ignore', 'ignore', 'pipe'],
@@ -74,22 +74,22 @@ async function main() {
74
74
  const schemas = require(schemaPath);
75
75
  const version = await bridge.request('harness-mix/runtime/version');
76
76
  assert.equal(version.version, require('../package.json').version, 'About page reads the installed package version');
77
- const accounts = await bridge.request('codexhost/account/list');
77
+ const accounts = await bridge.request('harnessmix/account/list');
78
78
  schemas.codexAccountListResultSchema.parse(accounts);
79
79
  assert.equal(accounts.accounts[0].email, 'native@example.com', 'Official account/read is projected into Account management');
80
80
  assert.equal(accounts.accounts[0].authenticated, true);
81
81
  assert.equal(accounts.accounts[0].management, 'native');
82
- const accountUsage = await bridge.request('codexhost/account/usage/inspect', { accountId: 'official-codex' });
82
+ const accountUsage = await bridge.request('harnessmix/account/usage/inspect', { accountId: 'official-codex' });
83
83
  schemas.codexAccountUsageResultSchema.parse(accountUsage);
84
84
  assert.equal(accountUsage.usage.planFiveHourUsedPercent, 33);
85
85
  assert.equal(accountUsage.usage.planSevenDayUsedPercent, 29);
86
86
  assert.equal(accountUsage.accountCredits.periodType, 'five_hour');
87
87
  assert.equal(accountUsage.accountCredits.productUsage[0].product, '7-day window');
88
- const login = await bridge.request('codexhost/account/login/start', { accountId: 'official-codex' });
88
+ const login = await bridge.request('harnessmix/account/login/start', { accountId: 'official-codex' });
89
89
  schemas.codexAccountLoginStartResultSchema.parse(login);
90
90
  assert.equal(login.userCode, 'ABCD-EFGH');
91
- assert.deepEqual(await bridge.request('codexhost/account/login/cancel', { accountId: 'official-codex', loginId: 'native-login' }), { cancelled: true });
92
- const loggedOut = await bridge.request('codexhost/account/logout');
91
+ assert.deepEqual(await bridge.request('harnessmix/account/login/cancel', { accountId: 'official-codex', loginId: 'native-login' }), { cancelled: true });
92
+ const loggedOut = await bridge.request('harnessmix/account/logout');
93
93
  schemas.codexAccountMutationResultSchema.parse(loggedOut);
94
94
  assert.equal(loggedOut.account.authenticated, false);
95
95
  let openedCodexThread = null;
@@ -109,30 +109,36 @@ async function main() {
109
109
  },
110
110
  close() {},
111
111
  };
112
- const isolated = await bridge.request('thread/start', { cwd: root, model: 'gpt-test', __codexhostAccountId: 'account-work' });
112
+ const isolated = await bridge.request('thread/start', { cwd: root, model: 'gpt-test', __harnessmixAccountId: 'account-work' });
113
113
  assert.equal(decodeRoute(isolated.thread.model).harnessId, 'codex-harness', 'An isolated Codex Account becomes an owned Codex adapter Thread');
114
114
  assert.equal(openedCodexThread.options.accountId, 'account-work');
115
115
  assert.equal(openedCodexThread.options.codexHome, path.join(root, 'isolated-codex-home'));
116
116
  assert.equal(openedCodexThread.options.model.id, 'gpt-test');
117
117
  const inspection = await bridge.inspect('pi');
118
118
  schemas.harnessInspectionSchema.parse(inspection);
119
+ assert.deepEqual(inspection.capabilities.workspace, { git: true, worktree: true, finalDiff: true, nativeDiff: false, nativePatch: false });
119
120
  assert.equal(inspection.catalog.defaultThinkingOptionId, 'high', 'Declared default thinking level projects to the catalog');
120
121
  assert.ok(inspection.catalog.models.every(m => m.supportedThinkingOptionIds?.join(',') === 'high,low'), 'Every catalog model carries the selectable thinking set');
121
- schemas.harnessPluginListResultSchema.parse(await bridge.request('codexhost/harness/plugins/list'));
122
+ schemas.harnessPluginListResultSchema.parse(await bridge.request('harnessmix/harness/plugins/list'));
122
123
  const started = await bridge.request('thread/start', { cwd: root, model: routeModel('pi') });
123
124
  const threadId = started.thread.id;
125
+ const threadInspection = await bridge.request('harnessmix/thread/inspect', { threadId });
126
+ schemas.threadInspectionSchema.parse(threadInspection);
127
+ assert.equal(threadInspection.workspace.hostManaged, true);
128
+ assert.equal(threadInspection.workspace.finalDiff.source, 'snapshot');
129
+ assert.equal(threadInspection.workspace.worktree.available, true);
124
130
  assert.equal(started.thread.sessionId, threadId, 'Desktop session identity is the host thread, not a native session id');
125
- assert.equal(started.thread.model, 'codexhost/pi-native');
131
+ assert.equal(started.thread.model, 'harnessmix/pi-native');
126
132
  const { includesThread } = require('../src/main/native/thread-list');
127
133
  const storedThread = runtime.threads.find(t => t.id === threadId);
128
- const hostCommands = await bridge.request('codexhost/thread/commands/inspect', { threadId });
134
+ const hostCommands = await bridge.request('harnessmix/thread/commands/inspect', { threadId });
129
135
  assert.ok(hostCommands.commands.some(command => command.id === 'verify'));
130
136
  assert.ok(hostCommands.commands.some(command => command.id === 'gate'));
131
- const gate = await bridge.request('codexhost/thread/verification/configure', { threadId, policy: { mode: 'required', checks: { cleanWorkingTree: false } } });
137
+ const gate = await bridge.request('harnessmix/thread/verification/configure', { threadId, policy: { mode: 'required', checks: { cleanWorkingTree: false } } });
132
138
  assert.equal(gate.policy.mode, 'required');
133
139
  assert.equal(gate.satisfied, false);
134
- assert.equal((await bridge.request('codexhost/thread/verification/get', { threadId })).policy.mode, 'required');
135
- const storage = await bridge.request('codexhost/storage/inspect');
140
+ assert.equal((await bridge.request('harnessmix/thread/verification/get', { threadId })).policy.mode, 'required');
141
+ const storage = await bridge.request('harnessmix/storage/inspect');
136
142
  assert.equal(storage.schemaVersion, 2);
137
143
  assert.ok(storage.threadCount >= 1);
138
144
  assert.equal(includesThread(storedThread, { sectionId: section.id }), false);
@@ -155,7 +161,7 @@ async function main() {
155
161
  await bridge.request('turn/interrupt', { threadId: prewarmed.thread.id });
156
162
  await wait(() => !runtime.threads.find(t => t.id === prewarmed.thread.id).reviewPending && !runtime.sending.has(prewarmed.thread.id));
157
163
  emit = emits[0]; // 恢复主线程的事件源(open 顺序:主线程序,预热线程后)
158
- schemas.threadInspectionSchema.parse(await bridge.request('codexhost/thread/inspect', { threadId }));
164
+ schemas.threadInspectionSchema.parse(await bridge.request('harnessmix/thread/inspect', { threadId }));
159
165
  const turn = await bridge.request('turn/start', { threadId, input: [{ type: 'text', text: 'test' }], approvalPolicy: 'never', sandboxPolicy: { type: 'dangerFullAccess' } });
160
166
  // turn/start 在 currentTurn 建立后即返回,adapter.send 的调用在其后;等待透传到达
161
167
  await wait(() => sendExtras.at(-1)?.turnPermissions != null);
@@ -252,7 +258,7 @@ async function main() {
252
258
  ]) {
253
259
  assert.equal(await bridge.request(method, params), undefined, `Official Codex ${method} passes through`);
254
260
  }
255
- assert.deepEqual(await bridge.request('codexhost/thread/ownership/list', { threadIds: ['official-thread', threadId] }), {
261
+ assert.deepEqual(await bridge.request('harnessmix/thread/ownership/list', { threadIds: ['official-thread', threadId] }), {
256
262
  threads: [
257
263
  { threadId: 'official-thread', owner: 'codex' },
258
264
  { threadId, owner: 'external', harnessId: 'pi' },
@@ -267,25 +273,25 @@ async function main() {
267
273
  hooks.emit({ kind: 'usage', usage: { input: 20, output: 5, cacheRead: 10, tokens: 30, contextWindow: 100, cost: 0.01 } });
268
274
  hooks.emit({ kind: 'completed', finalAnswer: true });
269
275
  };
270
- const command = await bridge.request('codexhost/thread/command/execute', { threadId, commandId: 'compact' });
276
+ const command = await bridge.request('harnessmix/thread/command/execute', { threadId, commandId: 'compact' });
271
277
  schemas.threadCommandExecuteResultSchema.parse(command);
272
278
  await wait(() => compactCalls === 1 && !runtime.threads.find(t => t.id === threadId).reviewPending && !runtime.sending.has(threadId));
273
- const usage = await bridge.request('codexhost/thread/usage/inspect', { threadId });
279
+ const usage = await bridge.request('harnessmix/thread/usage/inspect', { threadId });
274
280
  schemas.threadUsageInspectionSchema.parse(usage);
275
281
  assert.equal(usage.usage.inputTokens, 20);
276
282
  assert.equal(usage.usage.contextUsagePercent, 30);
277
- assert.ok(events.some(e => e.method === 'codexhost/thread/usage/updated' && e.params.usage?.cachedInputTokens === 10));
278
- await assert.rejects(bridge.request('codexhost/thread/command/execute', { threadId, commandId: 'missing' }), /不支持此指令/);
283
+ assert.ok(events.some(e => e.method === 'harnessmix/thread/usage/updated' && e.params.usage?.cachedInputTokens === 10));
284
+ await assert.rejects(bridge.request('harnessmix/thread/command/execute', { threadId, commandId: 'missing' }), /不支持此指令/);
279
285
  // ===== 新 Harness 路由:omp / opencode / grok 的 legacy 传输串解码与投影 =====
280
- assert.equal(routeModel('omp'), 'codexhost/omp-native');
281
- assert.equal(routeModel('opencode'), 'codexhost/opencode-native');
282
- assert.equal(routeModel('grok'), 'codexhost/grok-native');
283
- assert.deepEqual(decodeRoute('codexhost/omp-native'), { harnessId: 'omp' });
284
- assert.deepEqual(decodeRoute('codexhost/omp-native@model-x@high'), { harnessId: 'omp', model: { id: 'model-x' }, thinkingOptionId: 'high' }, 'OMP 两段式 = model@thinking');
285
- assert.deepEqual(decodeRoute('codexhost/omp-native@model-x@approve@high'), { harnessId: 'omp', model: { id: 'model-x' }, permissionModeId: 'approve', thinkingOptionId: 'high' }, 'OMP 三段式 = model@permission@thinking');
286
- assert.deepEqual(decodeRoute('codexhost/opencode-native@m@perm'), { harnessId: 'opencode', model: { id: 'm' }, permissionModeId: 'perm' });
287
- assert.deepEqual(decodeRoute('codexhost/grok-native@m@@think'), { harnessId: 'grok', model: { id: 'm' }, thinkingOptionId: 'think' });
288
- assert.throws(() => decodeRoute('codexhost/omp-native@a@b@c@d'), /Invalid native Harness route/);
286
+ assert.equal(routeModel('omp'), 'harnessmix/omp-native');
287
+ assert.equal(routeModel('opencode'), 'harnessmix/opencode-native');
288
+ assert.equal(routeModel('grok'), 'harnessmix/grok-native');
289
+ assert.deepEqual(decodeRoute('harnessmix/omp-native'), { harnessId: 'omp' });
290
+ assert.deepEqual(decodeRoute('harnessmix/omp-native@model-x@high'), { harnessId: 'omp', model: { id: 'model-x' }, thinkingOptionId: 'high' }, 'OMP 两段式 = model@thinking');
291
+ assert.deepEqual(decodeRoute('harnessmix/omp-native@model-x@approve@high'), { harnessId: 'omp', model: { id: 'model-x' }, permissionModeId: 'approve', thinkingOptionId: 'high' }, 'OMP 三段式 = model@permission@thinking');
292
+ assert.deepEqual(decodeRoute('harnessmix/opencode-native@m@perm'), { harnessId: 'opencode', model: { id: 'm' }, permissionModeId: 'perm' });
293
+ assert.deepEqual(decodeRoute('harnessmix/grok-native@m@@think'), { harnessId: 'grok', model: { id: 'm' }, thinkingOptionId: 'think' });
294
+ assert.throws(() => decodeRoute('harnessmix/omp-native@a@b@c@d'), /Invalid native Harness route/);
289
295
  // ===== 跨 Harness 协作:委派 → 消息 → 等待 → 级联取消 =====
290
296
  const childEmits = [];
291
297
  let childSend;
@@ -298,11 +304,11 @@ async function main() {
298
304
  async close() {} };
299
305
  runtime.adapters.set('claude', childAdapter); runtime.status.claude = { available: true };
300
306
  // Host 级 /delegate 指令出现在命令目录中(insert 型,填入输入框)
301
- const commandList = await bridge.request('codexhost/thread/commands/inspect', { threadId });
307
+ const commandList = await bridge.request('harnessmix/thread/commands/inspect', { threadId });
302
308
  assert.ok(commandList.commands.some(c => c.invocation === '/delegate' && c.argumentMode === 'text'), 'Host 级 /delegate 指令应出现在命令目录');
303
309
  // 委派:协议入口创建子任务线程并挂起父线程协作 Turn
304
310
  childSend = hooks => { hooks.emit({ kind: 'text-delta', text: '子任务结论' }); hooks.emit({ kind: 'completed', finalAnswer: true }); };
305
- const delegated = await bridge.request('codexhost/thread/delegate', { threadId, harnessId: 'claude-code', task: '审查代码' });
311
+ const delegated = await bridge.request('harnessmix/thread/delegate', { threadId, harnessId: 'claude-code', task: '审查代码' });
306
312
  schemas.threadDelegationResultSchema.parse(delegated);
307
313
  assert.equal(delegated.turn.status, 'inProgress', '委派后父线程协作 Turn 保持活动');
308
314
  assert.ok(delegated.turn?.id, 'Delegation starts a parent collaboration Turn');
@@ -322,13 +328,13 @@ async function main() {
322
328
  assert.equal(delegateTool.status, 'completed', '子任务结算后协作工具项完成');
323
329
  assert.ok(String(delegateTool.output).includes('子任务结论'), '协作工具项携带子任务最终答复');
324
330
  // 消息链:向同一子任务跟进(复用既有子线程)
325
- const followUp = await bridge.request('codexhost/thread/message', { threadId, childThreadId: childId, text: '再检查一遍' });
331
+ const followUp = await bridge.request('harnessmix/thread/message', { threadId, childThreadId: childId, text: '再检查一遍' });
326
332
  schemas.threadDelegationResultSchema.parse(followUp);
327
333
  await wait(() => !runtime.execution.isRunning(threadId));
328
334
  assert.deepEqual(childAdapter.sendCalls, ['审查代码', '再检查一遍'], '跟进消息进入同一子任务');
329
335
  assert.equal(followUp.childThreadId, childId);
330
336
  // 循环防护:子任务不能继续委派
331
- await assert.rejects(bridge.request('codexhost/thread/delegate', { threadId: childId, harnessId: 'pi', task: 'x' }), /暂不支持继续委派/);
337
+ await assert.rejects(bridge.request('harnessmix/thread/delegate', { threadId: childId, harnessId: 'pi', task: 'x' }), /暂不支持继续委派/);
332
338
  // 斜杠通道:/delegate 文本走同一委派链路
333
339
  childSend = hooks => { hooks.emit({ kind: 'text-delta', text: '斜杠委派完成' }); hooks.emit({ kind: 'completed', finalAnswer: true }); };
334
340
  const slashTurn = await bridge.request('turn/start', { threadId, input: [{ type: 'text', text: '/delegate claude 用斜杠通道' }] });
@@ -338,7 +344,7 @@ async function main() {
338
344
  await assert.rejects(bridge.request('turn/start', { threadId, input: [{ type: 'text', text: '/delegate' }] }), /用法:\/delegate/);
339
345
  // 级联取消:中断父线程协作 Turn ⇒ 子任务被取消
340
346
  childSend = () => new Promise(() => {}); // 子任务永不自行结算
341
- const stuck = await bridge.request('codexhost/thread/delegate', { threadId, harnessId: 'claude', task: '长跑任务' });
347
+ const stuck = await bridge.request('harnessmix/thread/delegate', { threadId, harnessId: 'claude', task: '长跑任务' });
342
348
  assert.ok(runtime.execution.isRunning(threadId), '父线程协作 Turn 等待子任务');
343
349
  await bridge.request('turn/interrupt', { threadId });
344
350
  await wait(() => !runtime.execution.isRunning(threadId) && !runtime.execution.isRunning(stuck.childThreadId));
@@ -350,8 +356,8 @@ async function main() {
350
356
  await assert.rejects(bridge.request('thread/fork', { threadId, excludeTurns: true }), /Ephemeral fork is not supported/);
351
357
  await assert.rejects(bridge.request('thread/start', { cwd: root, model: routeModel('pi'), ephemeral: true, threadSource: 'thread_description' }), /Ephemeral background thread is not supported/);
352
358
  // Worktree 隔离工作区丢弃与推送协议接口
353
- await assert.rejects(bridge.request('codexhost/thread/workspace/discard', { threadId }), /该任务未使用 Worktree 隔离工作区/);
354
- await assert.rejects(bridge.request('codexhost/thread/workspace/push', { threadId }), /该任务未使用 Worktree 隔离工作区/);
359
+ await assert.rejects(bridge.request('harnessmix/thread/workspace/discard', { threadId }), /该任务未使用 Worktree 隔离工作区/);
360
+ await assert.rejects(bridge.request('harnessmix/thread/workspace/push', { threadId }), /该任务未使用 Worktree 隔离工作区/);
355
361
  const dummyWorktreeThread = await bridge.request('thread/start', { cwd: root, model: routeModel('pi') });
356
362
  const dummyThreadId = dummyWorktreeThread.thread.id;
357
363
  const dummyWorkspaceDir = path.join(root, 'dummy-wt');
@@ -362,12 +368,12 @@ async function main() {
362
368
  root: dummyWorkspaceDir,
363
369
  cwd: dummyWorkspaceDir,
364
370
  source: root,
365
- branch: 'codexhost/test-wt-branch',
371
+ branch: 'harnessmix/test-wt-branch',
366
372
  };
367
- await assert.rejects(bridge.request('codexhost/thread/workspace/push', { threadId: dummyThreadId }), /git/i);
368
- const discardResult = await bridge.request('codexhost/thread/workspace/discard', { threadId: dummyThreadId });
373
+ await assert.rejects(bridge.request('harnessmix/thread/workspace/push', { threadId: dummyThreadId }), /git/i);
374
+ const discardResult = await bridge.request('harnessmix/thread/workspace/discard', { threadId: dummyThreadId });
369
375
  assert.equal(discardResult.discarded, true);
370
- assert.equal(discardResult.branch, 'codexhost/test-wt-branch');
376
+ assert.equal(discardResult.branch, 'harnessmix/test-wt-branch');
371
377
  assert.equal(dummyTargetThread.workspace, undefined, 'Discard deletes thread.workspace');
372
378
 
373
379
  // 消息排队(thread/queue/add, list, update, reorder, delete, start)能力验证
@@ -20,7 +20,7 @@ const wait = async fn => { for (let n = 0; n < 400; n++) { if (fn()) return; awa
20
20
  runtime.adapters.set('pi', adapter); runtime.status.pi = { available: true };
21
21
  const bridge = new NativeProtocol(runtime, () => {});
22
22
  try {
23
- const { thread } = await bridge.request('thread/start', { cwd: root, model: 'codexhost/pi-native' });
23
+ const { thread } = await bridge.request('thread/start', { cwd: root, model: 'harnessmix/pi-native' });
24
24
  for (const text of ['kept', 'removed']) {
25
25
  await bridge.request('turn/start', { threadId: thread.id, input: [{ type: 'text', text }] });
26
26
  await wait(() => !runtime.execution.isRunning(thread.id) && !runtime.threads[0].reviewPending);
@@ -31,7 +31,7 @@ const helper = [
31
31
 
32
32
  // --- real helper: DPAPI vault round-trip on a temp data dir ---
33
33
  const data = fs.mkdtempSync(path.join(os.tmpdir(), 'hm-secret-'));
34
- const env = { ...process.env, CODEXHOST_DATA_DIR: data };
34
+ const env = { ...process.env, HARNESSMIX_DATA_DIR: data };
35
35
  const call = (args, input) => execFileSync(helper, args, { encoding: 'utf8', windowsHide: true, env, input });
36
36
  call(['set', 'demo.token'], 'super-secret-value');
37
37
  assert.equal(call(['get', 'demo.token']), 'super-secret-value');
@@ -12,7 +12,7 @@ async function main() {
12
12
  const host = path.join(work, 'fixture host.cjs');
13
13
  const stockProbe = path.join(work, 'stock probe.cjs');
14
14
  const env = { ...process.env, HARNESS_MIX_NODE_PATH: process.execPath,
15
- CODEXHOST_STOCK_CODEX_PATH: process.execPath, HARNESS_MIX_HOST_SCRIPT: host, CODEX_CLI_PATH: 'must-be-removed' };
15
+ HARNESSMIX_STOCK_CODEX_PATH: process.execPath, HARNESS_MIX_HOST_SCRIPT: host, CODEX_CLI_PATH: 'must-be-removed' };
16
16
  let child;
17
17
  try {
18
18
  fs.writeFileSync(host, `const readline = require('node:readline');
@@ -55,13 +55,13 @@ async function testPrewarm() {
55
55
  const manager = { onNotification() {}, onRequest() {}, dispatchAppServerResponse() {} };
56
56
  const target = {};
57
57
  installDraftPrewarmPolicyBridge(manager, bridge, 'local', target, { discardAllPrewarmedThreads() {} });
58
- const policy = target.__codexhostDraftPrewarmPolicyV1;
58
+ const policy = target.__harnessmixDraftPrewarmPolicyV1;
59
59
  for (const harness of ['pi', 'claude-code', 'deepseek-harness', 'antigravity']) {
60
- policy.select(`codexhost/${harness}-native`);
60
+ policy.select(`harnessmix/${harness}-native`);
61
61
  bridge.prewarmThreadStart({ cwd: 'E:/project', model: 'gpt-test' });
62
62
  bridge.sendRequest('thread/start', { cwd: 'E:/project', model: 'gpt-test' });
63
63
  assert.equal(prewarmed.at(-1).ephemeral, true);
64
- assert.equal(prewarmed.at(-1).model, `codexhost/${harness}-native`);
64
+ assert.equal(prewarmed.at(-1).model, `harnessmix/${harness}-native`);
65
65
  assert.equal(sent.at(-1).params.ephemeral, undefined);
66
66
  }
67
67
  bridge.prewarmThreadStart({ ephemeral: true, model: 'gpt-title' });
@@ -72,7 +72,7 @@ async function testPrewarm() {
72
72
  policy.dispose();
73
73
  console.log('PASS: all four external prewarm routes stay ephemeral; actual starts and Codex internal tasks are preserved');
74
74
  const sidebarFile = path.join(root, 'sidebar.cjs');
75
- await require('esbuild').build({ entryPoints: ['src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts'], outfile: sidebarFile, bundle: true, platform: 'node', format: 'cjs', alias: { '@codexhost/shared-contracts': path.resolve('src/native-ui/shared-contracts/src/index.ts') }, loader: { '.png': 'dataurl', '.svg': 'dataurl' }, logLevel: 'silent' });
75
+ await require('esbuild').build({ entryPoints: ['src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts'], outfile: sidebarFile, bundle: true, platform: 'node', format: 'cjs', alias: { '@harnessmix/shared-contracts': path.resolve('src/native-ui/shared-contracts/src/index.ts') }, loader: { '.png': 'dataurl', '.svg': 'dataurl' }, logLevel: 'silent' });
76
76
  const { installRendererSidebarAgentIcons } = require(sidebarFile);
77
77
  let cleared = 0;
78
78
  let agent = null;
@@ -12,13 +12,13 @@ app.whenReady().then(async () => {
12
12
  const icons = getAllIconsDictionary();
13
13
  icons.harnesses['claude-code'] = icons.harnesses.claude;
14
14
  icons.harnesses['deepseek-harness'] = icons.harnesses.dsh;
15
- const bundle = await esbuild.build({ stdin: { contents: `export { createRendererAgentIcon } from './src/native-ui/renderer-extension/src/renderer-agent-icon.ts'; export { mountRendererAgentPicker, renderRendererAgentPicker } from './src/native-ui/renderer-extension/src/renderer-agent-picker.ts'; export { mountRendererModelPicker, renderRendererModelPicker } from './src/native-ui/renderer-extension/src/renderer-model-picker.ts'; export { mountRendererHarnessHandoff } from './src/native-ui/renderer-extension/src/renderer-harness-handoff.ts'; export { restoredThreadOwnership } from './src/native-ui/renderer-extension/src/renderer-binding-probe.ts'; export { installRendererSidebarAgentIcons } from './src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts'; export { installRendererSettingsLifecycle } from './src/native-ui/renderer-extension/src/harness-mix-settings.ts'; export { createAccountsSettingsPage } from './src/native-ui/renderer-extension/src/settings/accounts-page.ts'; export { createStorageSettingsPage } from './src/native-ui/renderer-extension/src/settings/storage-page.ts'; export { createSkinSettingsPage } from './src/native-ui/renderer-extension/src/settings/skin-market.ts'; export { applyRendererSkin } from './src/native-ui/renderer-extension/src/settings/skin-runtime.ts'; export { aboutPage } from './src/native-ui/renderer-extension/src/settings/pages.ts'; export { rendererSettingsMessages } from './src/native-ui/renderer-extension/src/settings/localization.ts'; export { installRendererSettingsShell } from './src/native-ui/renderer-extension/src/settings/shell.ts';`, resolveDir: process.cwd() }, bundle: true, alias: { '@codexhost/shared-contracts': path.resolve('src/native-ui/shared-contracts/src/index.ts') }, platform: 'browser', format: 'iife', globalName: 'NativeUI', write: false, loader: { '.svg': 'dataurl', '.png': 'dataurl', '.webp': 'dataurl', '.css': 'text' }, logLevel: 'silent' });
15
+ const bundle = await esbuild.build({ stdin: { contents: `export { createRendererAgentIcon } from './src/native-ui/renderer-extension/src/renderer-agent-icon.ts'; export { mountRendererAgentPicker, renderRendererAgentPicker } from './src/native-ui/renderer-extension/src/renderer-agent-picker.ts'; export { mountRendererModelPicker, renderRendererModelPicker } from './src/native-ui/renderer-extension/src/renderer-model-picker.ts'; export { mountRendererHarnessHandoff } from './src/native-ui/renderer-extension/src/renderer-harness-handoff.ts'; export { restoredThreadOwnership } from './src/native-ui/renderer-extension/src/renderer-binding-probe.ts'; export { installRendererSidebarAgentIcons } from './src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts'; export { installRendererSettingsLifecycle } from './src/native-ui/renderer-extension/src/harness-mix-settings.ts'; export { createAccountsSettingsPage } from './src/native-ui/renderer-extension/src/settings/accounts-page.ts'; export { createStorageSettingsPage } from './src/native-ui/renderer-extension/src/settings/storage-page.ts'; export { createSkinSettingsPage } from './src/native-ui/renderer-extension/src/settings/skin-market.ts'; export { applyRendererSkin } from './src/native-ui/renderer-extension/src/settings/skin-runtime.ts'; export { aboutPage } from './src/native-ui/renderer-extension/src/settings/pages.ts'; export { rendererSettingsMessages } from './src/native-ui/renderer-extension/src/settings/localization.ts'; export { installRendererSettingsShell } from './src/native-ui/renderer-extension/src/settings/shell.ts';`, resolveDir: process.cwd() }, bundle: true, alias: { '@harnessmix/shared-contracts': path.resolve('src/native-ui/shared-contracts/src/index.ts') }, platform: 'browser', format: 'iife', globalName: 'NativeUI', write: false, loader: { '.svg': 'dataurl', '.png': 'dataurl', '.webp': 'dataurl', '.css': 'text' }, logLevel: 'silent' });
16
16
  const win = new BrowserWindow({ show: false, width: 900, height: 650, webPreferences: { contextIsolation: true, sandbox: true, offscreen: true, backgroundThrottling: false } });
17
17
  await win.loadURL('data:text/html,<html><head><style>body{background:%2317191d;color:white;font:16px Arial;padding:40px}button{background:%23272a30;color:white;border:0;padding:12px}img{vertical-align:middle}main{display:flex;gap:25px;margin-bottom:40px}</style></head><body><h2>Harness Mix native components</h2><main></main></body></html>');
18
18
  await win.webContents.executeJavaScript(`globalThis.__HARNESS_MIX_ICONS__=${JSON.stringify(icons)};globalThis.__HARNESS_MIX_MODEL_FAMILIES__=${JSON.stringify(MODEL_FAMILIES.map(f => ({ id: f.id, pattern: f.regex.source })))};${bundle.outputFiles[0].text}`);
19
19
  const liveSettingsPages = await win.webContents.executeJavaScript(`(() => {
20
20
  const lifecycle = NativeUI.installRendererSettingsLifecycle(window, {});
21
- const pageIds = globalThis.__codexhostSettingsShellV1.registry.pages.map(page => page.id);
21
+ const pageIds = globalThis.__harnessmixSettingsShellV1.registry.pages.map(page => page.id);
22
22
  lifecycle.dispose();
23
23
  return pageIds;
24
24
  })()`);
@@ -26,7 +26,7 @@ app.whenReady().then(async () => {
26
26
  const { NativeProtocol } = require('../src/main/native/protocol');
27
27
  const nativeThreads = ['pi', 'claude', 'dsh', 'antigravity'].map((harnessId, index) => ({ id: 'sidebar-' + index, harnessId, model: { id: 'model-' + index, provider: 'native' }, options: {} }));
28
28
  const protocol = new NativeProtocol({ threads: nativeThreads, getThread: id => nativeThreads.find(thread => thread.id === id), subscribe: () => () => {}, core: { subscribe: () => () => {} }, describe: async () => ({}), getCapabilities: () => ({}) }, () => {});
29
- const inspections = await Promise.all(nativeThreads.map(thread => protocol.request('codexhost/thread/inspect', { threadId: thread.id })));
29
+ const inspections = await Promise.all(nativeThreads.map(thread => protocol.request('harnessmix/thread/inspect', { threadId: thread.id })));
30
30
  await win.webContents.executeJavaScript(`globalThis.testInspections=${JSON.stringify(inspections)}`);
31
31
  const result = await win.webContents.executeJavaScript(`(async () => {
32
32
  const agents = ['codex','pi','claude-code','deepseek-harness','antigravity','omp','opencode','grok'];
@@ -43,10 +43,10 @@ app.whenReady().then(async () => {
43
43
  }
44
44
  const decoration = NativeUI.installRendererSidebarAgentIcons({ getClient: () => ({ listThreadOwnership: async ({threadIds}) => ({threads: threadIds.map(threadId => { const agent = agents[Number(threadId.slice(4))]; return agent === 'codex' ? {threadId, owner:'codex'} : {threadId, owner:'external', harnessId:agent}; })}) }) });
45
45
  await new Promise(resolve => setTimeout(resolve, 50));
46
- const sidebarIcons = [...sidebar.querySelectorAll('[data-codexhost-sidebar-agent-icon]')].map(icon => icon.getAttribute('data-codexhost-sidebar-agent-icon'));
46
+ const sidebarIcons = [...sidebar.querySelectorAll('[data-harnessmix-sidebar-agent-icon]')].map(icon => icon.getAttribute('data-harnessmix-sidebar-agent-icon'));
47
47
  // Rescan a React-updated row: no duplicate icon and no loss of ownership.
48
48
  decoration.refresh(); await new Promise(resolve => setTimeout(resolve, 50));
49
- const sidebarIconCount = sidebar.querySelectorAll('[data-codexhost-sidebar-agent-icon]').length;
49
+ const sidebarIconCount = sidebar.querySelectorAll('[data-harnessmix-sidebar-agent-icon]').length;
50
50
  globalThis.testSidebarDecoration = decoration;
51
51
  for(const agent of agents) { const el=document.createElement('div'); el.append(NativeUI.createRendererAgentIcon(agent,28),document.createTextNode(' '+agent));document.querySelector('main').append(el); }
52
52
  let selected;
@@ -150,16 +150,16 @@ app.whenReady().then(async () => {
150
150
  assert.equal(settingsResult.addHidden, false, 'multi-account Add Account action remains visible');
151
151
  fs.writeFileSync(path.join(out, 'settings-account.png'), (await win.webContents.capturePage()).toPNG());
152
152
  const storageText = await win.webContents.executeJavaScript(`(async () => {
153
- globalThis.__codexhostSettingsShellV1.openSettings(undefined, 'storage');
153
+ globalThis.__harnessmixSettingsShellV1.openSettings(undefined, 'storage');
154
154
  await new Promise(resolve => setTimeout(resolve, 100));
155
- return globalThis.__codexhostSettingsShellV1.root.shadowRoot.textContent;
155
+ return globalThis.__harnessmixSettingsShellV1.root.shadowRoot.textContent;
156
156
  })()`);
157
157
  assert.match(storageText, /Schema v3/);
158
158
  assert.match(storageText, /12 个任务/);
159
159
  fs.writeFileSync(path.join(out, 'settings-storage.png'), (await win.webContents.capturePage()).toPNG());
160
160
  const skinResult = await win.webContents.executeJavaScript(`(async () => {
161
- globalThis.__codexhostSettingsShellV1.openSettings(undefined, 'skins');
162
- const shadow = globalThis.__codexhostSettingsShellV1.root.shadowRoot;
161
+ globalThis.__harnessmixSettingsShellV1.openSettings(undefined, 'skins');
162
+ const shadow = globalThis.__harnessmixSettingsShellV1.root.shadowRoot;
163
163
  const firstButton = shadow.querySelector('button[data-skin-action="styler-nocturne-studio"]');
164
164
  const mikuButton = shadow.querySelector('button[data-skin-action="miku-488137"]');
165
165
  firstButton.click();
@@ -180,16 +180,16 @@ app.whenReady().then(async () => {
180
180
  assert.equal(skinResult.bundledPreviewCount, 16);
181
181
  fs.writeFileSync(path.join(out, 'settings-skins.png'), (await win.webContents.capturePage()).toPNG());
182
182
  await win.webContents.executeJavaScript(`(() => {
183
- const shadow = globalThis.__codexhostSettingsShellV1.root.shadowRoot;
183
+ const shadow = globalThis.__harnessmixSettingsShellV1.root.shadowRoot;
184
184
  const page = shadow.querySelector('.settings-page');
185
185
  page.scrollTop = page.scrollHeight;
186
186
  })()`);
187
187
  await new Promise(resolve => setTimeout(resolve, 100));
188
188
  fs.writeFileSync(path.join(out, 'settings-skins-discovery.png'), (await win.webContents.capturePage()).toPNG());
189
189
  const aboutText = await win.webContents.executeJavaScript(`(async () => {
190
- globalThis.__codexhostSettingsShellV1.openSettings(undefined, 'about');
190
+ globalThis.__harnessmixSettingsShellV1.openSettings(undefined, 'about');
191
191
  await new Promise(resolve => setTimeout(resolve, 100));
192
- return globalThis.__codexhostSettingsShellV1.root.shadowRoot.textContent;
192
+ return globalThis.__harnessmixSettingsShellV1.root.shadowRoot.textContent;
193
193
  })()`);
194
194
  assert.match(aboutText, /v0\.1\.4/);
195
195
  fs.writeFileSync(path.join(out, 'settings-about.png'), (await win.webContents.capturePage()).toPNG());