harnery 0.39.0 → 0.41.0

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 (445) hide show
  1. package/README.md +1 -1
  2. package/dist/commander.js +1 -0
  3. package/dist/commands/agents.d.ts.map +1 -1
  4. package/dist/commands/agents.js +25 -19
  5. package/dist/commands/browse-ai.d.ts.map +1 -1
  6. package/dist/commands/browse-ai.js +4 -0
  7. package/dist/commands/browse.d.ts.map +1 -1
  8. package/dist/commands/browse.js +141 -10
  9. package/dist/commands/checkpoint.js +8 -12
  10. package/dist/commands/deinit.d.ts +1 -1
  11. package/dist/commands/deinit.d.ts.map +1 -1
  12. package/dist/commands/deinit.js +8 -4
  13. package/dist/commands/docs.d.ts.map +1 -1
  14. package/dist/commands/docs.js +2 -0
  15. package/dist/commands/doctor.js +10 -2
  16. package/dist/commands/fetch.d.ts.map +1 -1
  17. package/dist/commands/fetch.js +10 -0
  18. package/dist/commands/init.d.ts +19 -3
  19. package/dist/commands/init.d.ts.map +1 -1
  20. package/dist/commands/init.js +232 -104
  21. package/dist/commands/instructions.js +5 -4
  22. package/dist/commands/ledger-v3.d.ts.map +1 -1
  23. package/dist/commands/ledger-v3.js +2 -1
  24. package/dist/commands/webview.d.ts +4 -0
  25. package/dist/commands/webview.d.ts.map +1 -0
  26. package/dist/commands/webview.js +94 -0
  27. package/dist/core/adapter.d.ts +50 -1
  28. package/dist/core/adapter.d.ts.map +1 -1
  29. package/dist/core/adapter.js +59 -1
  30. package/dist/core/adapters/attestation.d.ts.map +1 -1
  31. package/dist/core/adapters/attestation.js +3 -2
  32. package/dist/core/adapters/profiles.d.ts +20 -3
  33. package/dist/core/adapters/profiles.d.ts.map +1 -1
  34. package/dist/core/adapters/profiles.js +32 -1
  35. package/dist/core/adapters/registry.d.ts.map +1 -1
  36. package/dist/core/adapters/registry.js +33 -0
  37. package/dist/core/agents/canonical-emit.d.ts +1 -1
  38. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  39. package/dist/core/agents/canonical-emit.js +2 -7
  40. package/dist/core/agents/cli.js +30 -19
  41. package/dist/core/agents/coord-client.d.ts.map +1 -1
  42. package/dist/core/agents/coord-client.js +7 -2
  43. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  44. package/dist/core/agents/rules/claim-conflict.js +3 -9
  45. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  46. package/dist/core/agents/rules/commit-conflict.js +2 -8
  47. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  48. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  49. package/dist/core/agents/rules/stop-hook.js +1 -1
  50. package/dist/core/agents/session-events.d.ts +6 -2
  51. package/dist/core/agents/session-events.d.ts.map +1 -1
  52. package/dist/core/agents/session-events.js +105 -26
  53. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
  54. package/dist/core/agents/session-finalization-state-v3.js +2 -1
  55. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  56. package/dist/core/agents/session-finalizer-v3.js +5 -4
  57. package/dist/core/agents/session-name-display.d.ts +28 -0
  58. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  59. package/dist/core/agents/session-name-display.js +43 -0
  60. package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
  61. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
  62. package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
  63. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  64. package/dist/core/agents/state/heartbeat-writer.js +21 -2
  65. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  66. package/dist/core/agents/state/live-coordination-view.js +1 -0
  67. package/dist/core/agents/state/live-coordination-writer.js +3 -0
  68. package/dist/core/agents/state/names.d.ts +4 -4
  69. package/dist/core/agents/state/names.d.ts.map +1 -1
  70. package/dist/core/agents/state/names.js +5 -7
  71. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  72. package/dist/core/agents/state/stale-sweep.js +2 -10
  73. package/dist/core/agents/turn-changes.d.ts +17 -0
  74. package/dist/core/agents/turn-changes.d.ts.map +1 -0
  75. package/dist/core/agents/turn-changes.js +76 -0
  76. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  77. package/dist/core/artifacts/delivery-card.js +2 -1
  78. package/dist/core/artifacts/index.d.ts.map +1 -1
  79. package/dist/core/artifacts/index.js +4 -3
  80. package/dist/core/config.d.ts +5 -0
  81. package/dist/core/config.d.ts.map +1 -1
  82. package/dist/core/config.js +14 -0
  83. package/dist/core/context/index.d.ts.map +1 -1
  84. package/dist/core/context/index.js +2 -1
  85. package/dist/core/conversations/archive.d.ts.map +1 -1
  86. package/dist/core/conversations/archive.js +4 -3
  87. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  88. package/dist/core/diagnostics/bundle.js +3 -2
  89. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
  90. package/dist/core/events/legacy-storage/canary.js +5 -4
  91. package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
  92. package/dist/core/events/legacy-storage/compression.js +2 -1
  93. package/dist/core/events/v3/adapter-id.d.ts +10 -2
  94. package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
  95. package/dist/core/events/v3/adapter-id.js +16 -0
  96. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  97. package/dist/core/events/v3/authority-outbox.js +2 -1
  98. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  99. package/dist/core/events/v3/bootstrap.js +5 -4
  100. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  101. package/dist/core/events/v3/capabilities.js +17 -0
  102. package/dist/core/events/v3/contract.d.ts +5 -0
  103. package/dist/core/events/v3/contract.d.ts.map +1 -1
  104. package/dist/core/events/v3/contract.js +7 -1
  105. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  106. package/dist/core/events/v3/control-witness.js +3 -2
  107. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
  108. package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
  109. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
  110. package/dist/core/events/v3/fingerprint-keys.js +7 -6
  111. package/dist/core/events/v3/generated.d.ts +1 -1
  112. package/dist/core/events/v3/generated.js +1 -1
  113. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  114. package/dist/core/events/v3/live-feed.js +5 -4
  115. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  116. package/dist/core/events/v3/producers/command-recorder.js +8 -7
  117. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  118. package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
  119. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
  120. package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
  121. package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
  122. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  123. package/dist/core/events/v3/producers/hook-base.js +10 -4
  124. package/dist/core/events/v3/producers/hook.d.ts +2 -0
  125. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  126. package/dist/core/events/v3/producers/hook.js +16 -1
  127. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  128. package/dist/core/events/v3/producers/intake.js +16 -6
  129. package/dist/core/events/v3/producers/recorder.d.ts +2 -4
  130. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  131. package/dist/core/events/v3/producers/recorder.js +109 -101
  132. package/dist/core/events/v3/recovery.d.ts.map +1 -1
  133. package/dist/core/events/v3/recovery.js +4 -3
  134. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
  135. package/dist/core/events/v3/support-storage/inventory.js +2 -1
  136. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
  137. package/dist/core/events/v3/support-storage/maintenance.js +4 -3
  138. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
  139. package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
  140. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
  141. package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
  142. package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
  143. package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
  144. package/dist/core/events/v3/tool-line-changes.js +135 -0
  145. package/dist/core/events/v3/writer.d.ts.map +1 -1
  146. package/dist/core/events/v3/writer.js +8 -7
  147. package/dist/core/governor/planning.d.ts.map +1 -1
  148. package/dist/core/governor/planning.js +6 -5
  149. package/dist/core/governor/service.d.ts.map +1 -1
  150. package/dist/core/governor/service.js +12 -11
  151. package/dist/core/governor/state.d.ts.map +1 -1
  152. package/dist/core/governor/state.js +7 -6
  153. package/dist/core/guard/evaluator.js +1 -0
  154. package/dist/core/guard/storage.d.ts.map +1 -1
  155. package/dist/core/guard/storage.js +3 -2
  156. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
  157. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
  158. package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
  159. package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
  160. package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
  161. package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
  162. package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
  163. package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
  164. package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
  165. package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
  166. package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
  167. package/dist/core/hooks/adapter/behaviors/index.js +20 -0
  168. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
  169. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
  170. package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
  171. package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
  172. package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
  173. package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
  174. package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
  175. package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
  176. package/dist/core/hooks/adapter/behaviors/types.js +1 -0
  177. package/dist/core/hooks/adapter/detect.d.ts +1 -1
  178. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  179. package/dist/core/hooks/adapter/detect.js +2 -3
  180. package/dist/core/hooks/adapter/events.d.ts +29 -1
  181. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  182. package/dist/core/hooks/adapter/events.js +31 -0
  183. package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
  184. package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
  185. package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
  186. package/dist/core/hooks/adapter/output.d.ts +7 -0
  187. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  188. package/dist/core/hooks/adapter/output.js +8 -1
  189. package/dist/core/hooks/adapter/wiring.d.ts +15 -1
  190. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  191. package/dist/core/hooks/adapter/wiring.js +74 -11
  192. package/dist/core/hooks/cli.js +640 -531
  193. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  194. package/dist/core/hooks/effects/image-capture.js +2 -1
  195. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
  196. package/dist/core/hooks/prompt-context/contract.js +1 -0
  197. package/dist/core/hooks/resolve/transcript.d.ts +1 -1
  198. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  199. package/dist/core/hooks/resolve/transcript.js +35 -4
  200. package/dist/core/hooks/session-name-presence.d.ts +3 -1
  201. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  202. package/dist/core/hooks/session-name-presence.js +7 -2
  203. package/dist/core/hooks/shell-waiter.d.ts +2 -0
  204. package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
  205. package/dist/core/hooks/shell-waiter.js +173 -0
  206. package/dist/core/resources/service.d.ts.map +1 -1
  207. package/dist/core/resources/service.js +5 -4
  208. package/dist/core/semantic/review.d.ts.map +1 -1
  209. package/dist/core/semantic/review.js +5 -4
  210. package/dist/core/semantic/service.d.ts.map +1 -1
  211. package/dist/core/semantic/service.js +15 -14
  212. package/dist/core/semantic/storage.d.ts.map +1 -1
  213. package/dist/core/semantic/storage.js +5 -4
  214. package/dist/core/storage/atomic-json.d.ts.map +1 -1
  215. package/dist/core/storage/atomic-json.js +7 -3
  216. package/dist/core/storage/durable-history.d.ts.map +1 -1
  217. package/dist/core/storage/durable-history.js +6 -5
  218. package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
  219. package/dist/core/storage/maintenance-providers.js +2 -1
  220. package/dist/core/storage/maintenance.d.ts.map +1 -1
  221. package/dist/core/storage/maintenance.js +7 -6
  222. package/dist/core/storage/metrics.d.ts.map +1 -1
  223. package/dist/core/storage/metrics.js +5 -1
  224. package/dist/core/storage/modes.d.ts +17 -0
  225. package/dist/core/storage/modes.d.ts.map +1 -0
  226. package/dist/core/storage/modes.js +47 -0
  227. package/dist/core/storage/process-log.d.ts.map +1 -1
  228. package/dist/core/storage/process-log.js +3 -2
  229. package/dist/core/storage/receipts.d.ts.map +1 -1
  230. package/dist/core/storage/receipts.js +4 -3
  231. package/dist/core/storage/segments.d.ts.map +1 -1
  232. package/dist/core/storage/segments.js +7 -6
  233. package/dist/core/supervisor/hook-health.d.ts +2 -1
  234. package/dist/core/supervisor/hook-health.d.ts.map +1 -1
  235. package/dist/core/supervisor/hook-health.js +4 -3
  236. package/dist/core/supervisor/service.d.ts.map +1 -1
  237. package/dist/core/supervisor/service.js +7 -6
  238. package/dist/core/work/state.d.ts.map +1 -1
  239. package/dist/core/work/state.js +8 -7
  240. package/dist/core/workflow/adapters.d.ts +7 -0
  241. package/dist/core/workflow/adapters.d.ts.map +1 -1
  242. package/dist/core/workflow/adapters.js +9 -0
  243. package/dist/core/workflow/approvals.d.ts.map +1 -1
  244. package/dist/core/workflow/approvals.js +6 -5
  245. package/dist/core/workflow/billing.d.ts.map +1 -1
  246. package/dist/core/workflow/billing.js +33 -4
  247. package/dist/core/workflow/durable-record.d.ts.map +1 -1
  248. package/dist/core/workflow/durable-record.js +4 -3
  249. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  250. package/dist/core/workflow/live-session-v3.js +6 -4
  251. package/dist/core/workflow/run-state.d.ts.map +1 -1
  252. package/dist/core/workflow/run-state.js +3 -2
  253. package/dist/core/workflow/spawn-opencode.d.ts +36 -0
  254. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
  255. package/dist/core/workflow/spawn-opencode.js +132 -0
  256. package/dist/core/workflow/transcript.d.ts.map +1 -1
  257. package/dist/core/workflow/transcript.js +3 -2
  258. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  259. package/dist/core/workflow/workspaces/leases.js +5 -4
  260. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  261. package/dist/core/workflow/workspaces/local-git.js +3 -2
  262. package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
  263. package/dist/core/workflow/workspaces/paths.js +2 -1
  264. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  265. package/dist/core/workflow/workspaces/state.js +10 -9
  266. package/dist/lazy-commands.js +8 -1
  267. package/dist/lib/agent-browser/client.d.ts +9 -0
  268. package/dist/lib/agent-browser/client.d.ts.map +1 -1
  269. package/dist/lib/agent-browser/client.js +13 -0
  270. package/dist/lib/browser/client.d.ts +35 -1
  271. package/dist/lib/browser/client.d.ts.map +1 -1
  272. package/dist/lib/browser/client.js +117 -8
  273. package/dist/lib/browser/identity.d.ts +25 -0
  274. package/dist/lib/browser/identity.d.ts.map +1 -0
  275. package/dist/lib/browser/identity.js +66 -0
  276. package/dist/lib/browser/index.d.ts +2 -1
  277. package/dist/lib/browser/index.d.ts.map +1 -1
  278. package/dist/lib/browser/index.js +2 -1
  279. package/dist/lib/browser/launch-args.d.ts +26 -0
  280. package/dist/lib/browser/launch-args.d.ts.map +1 -1
  281. package/dist/lib/browser/launch-args.js +41 -1
  282. package/dist/lib/browser/user-agent.d.ts +53 -0
  283. package/dist/lib/browser/user-agent.d.ts.map +1 -0
  284. package/dist/lib/browser/user-agent.js +79 -0
  285. package/dist/lib/docs-metadata-managed.d.ts +1 -0
  286. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  287. package/dist/lib/docs-metadata-managed.js +17 -1
  288. package/dist/lib/identities/assume.d.ts.map +1 -1
  289. package/dist/lib/identities/assume.js +4 -9
  290. package/dist/lib/instructions/apply.d.ts.map +1 -1
  291. package/dist/lib/instructions/apply.js +2 -0
  292. package/dist/lib/pace/index.d.ts +2 -0
  293. package/dist/lib/pace/index.d.ts.map +1 -0
  294. package/dist/lib/pace/index.js +1 -0
  295. package/dist/lib/pace/pace.d.ts +95 -0
  296. package/dist/lib/pace/pace.d.ts.map +1 -0
  297. package/dist/lib/pace/pace.js +313 -0
  298. package/dist/lib/tunnel/forward-headers.d.ts +11 -0
  299. package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
  300. package/dist/lib/tunnel/forward-headers.js +17 -0
  301. package/dist/lib/tunnel/gate.js +15 -10
  302. package/dist/lib/webview/index.d.ts +2 -0
  303. package/dist/lib/webview/index.d.ts.map +1 -0
  304. package/dist/lib/webview/index.js +1 -0
  305. package/dist/lib/webview/webview.d.ts +116 -0
  306. package/dist/lib/webview/webview.d.ts.map +1 -0
  307. package/dist/lib/webview/webview.js +289 -0
  308. package/opencode-plugin/package.json +19 -0
  309. package/opencode-plugin/src/index.ts +791 -0
  310. package/package.json +11 -4
  311. package/schemas/config.schema.json +13 -0
  312. package/schemas/event-v3.schema.json +164 -0
  313. package/src/commander.ts +7 -0
  314. package/src/commands/agents.ts +33 -18
  315. package/src/commands/browse-ai.ts +8 -0
  316. package/src/commands/browse.ts +189 -10
  317. package/src/commands/checkpoint.ts +7 -9
  318. package/src/commands/deinit.ts +9 -4
  319. package/src/commands/docs.ts +2 -0
  320. package/src/commands/doctor.ts +11 -2
  321. package/src/commands/fetch.ts +14 -0
  322. package/src/commands/init.ts +281 -119
  323. package/src/commands/instructions.ts +8 -4
  324. package/src/commands/ledger-v3.ts +2 -1
  325. package/src/commands/webview.ts +159 -0
  326. package/src/core/adapter.ts +102 -1
  327. package/src/core/adapters/attestation.ts +3 -2
  328. package/src/core/adapters/profiles.ts +42 -1
  329. package/src/core/adapters/registry.ts +37 -0
  330. package/src/core/agents/canonical-emit.ts +2 -5
  331. package/src/core/agents/cli.ts +31 -20
  332. package/src/core/agents/coord-client.ts +9 -3
  333. package/src/core/agents/rules/claim-conflict.ts +3 -8
  334. package/src/core/agents/rules/commit-conflict.ts +2 -7
  335. package/src/core/agents/rules/stop-hook.ts +3 -1
  336. package/src/core/agents/session-events.ts +120 -26
  337. package/src/core/agents/session-finalization-state-v3.ts +2 -1
  338. package/src/core/agents/session-finalizer-v3.ts +5 -4
  339. package/src/core/agents/session-name-display.ts +48 -0
  340. package/src/core/agents/state/heartbeat-reader.ts +7 -0
  341. package/src/core/agents/state/heartbeat-writer.ts +24 -2
  342. package/src/core/agents/state/live-coordination-view.ts +1 -0
  343. package/src/core/agents/state/live-coordination-writer.ts +3 -0
  344. package/src/core/agents/state/names.ts +7 -9
  345. package/src/core/agents/state/stale-sweep.ts +2 -9
  346. package/src/core/agents/turn-changes.ts +97 -0
  347. package/src/core/artifacts/delivery-card.ts +2 -1
  348. package/src/core/artifacts/index.ts +4 -3
  349. package/src/core/config.ts +23 -0
  350. package/src/core/context/index.ts +2 -1
  351. package/src/core/conversations/archive.ts +4 -3
  352. package/src/core/diagnostics/bundle.ts +3 -2
  353. package/src/core/events/legacy-storage/canary.ts +5 -4
  354. package/src/core/events/legacy-storage/compression.ts +2 -1
  355. package/src/core/events/v3/adapter-id.ts +29 -1
  356. package/src/core/events/v3/authority-outbox.ts +2 -1
  357. package/src/core/events/v3/bootstrap.ts +5 -4
  358. package/src/core/events/v3/capabilities.ts +17 -0
  359. package/src/core/events/v3/contract.ts +9 -1
  360. package/src/core/events/v3/control-witness.ts +3 -2
  361. package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
  362. package/src/core/events/v3/fingerprint-keys.ts +7 -6
  363. package/src/core/events/v3/generated.ts +1 -1
  364. package/src/core/events/v3/live-feed.ts +5 -4
  365. package/src/core/events/v3/producers/command-recorder.ts +8 -6
  366. package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
  367. package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
  368. package/src/core/events/v3/producers/hook-base.ts +11 -4
  369. package/src/core/events/v3/producers/hook.ts +19 -1
  370. package/src/core/events/v3/producers/intake.ts +18 -6
  371. package/src/core/events/v3/producers/recorder.ts +123 -114
  372. package/src/core/events/v3/recovery.ts +4 -3
  373. package/src/core/events/v3/support-storage/inventory.ts +2 -1
  374. package/src/core/events/v3/support-storage/maintenance.ts +8 -3
  375. package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
  376. package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
  377. package/src/core/events/v3/tool-line-changes.ts +139 -0
  378. package/src/core/events/v3/writer.ts +8 -7
  379. package/src/core/governor/planning.ts +6 -5
  380. package/src/core/governor/service.ts +12 -11
  381. package/src/core/governor/state.ts +7 -6
  382. package/src/core/guard/evaluator.ts +1 -0
  383. package/src/core/guard/storage.ts +3 -2
  384. package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
  385. package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
  386. package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
  387. package/src/core/hooks/adapter/behaviors/index.ts +31 -0
  388. package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
  389. package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
  390. package/src/core/hooks/adapter/behaviors/types.ts +110 -0
  391. package/src/core/hooks/adapter/detect.ts +2 -3
  392. package/src/core/hooks/adapter/events.ts +53 -1
  393. package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
  394. package/src/core/hooks/adapter/output.ts +8 -1
  395. package/src/core/hooks/adapter/wiring.ts +85 -11
  396. package/src/core/hooks/cli.ts +738 -538
  397. package/src/core/hooks/effects/image-capture.ts +2 -1
  398. package/src/core/hooks/prompt-context/contract.ts +1 -0
  399. package/src/core/hooks/resolve/transcript.ts +42 -5
  400. package/src/core/hooks/session-name-presence.ts +10 -3
  401. package/src/core/hooks/shell-waiter.ts +166 -0
  402. package/src/core/resources/service.ts +5 -4
  403. package/src/core/semantic/review.ts +5 -4
  404. package/src/core/semantic/service.ts +15 -14
  405. package/src/core/semantic/storage.ts +5 -4
  406. package/src/core/storage/atomic-json.ts +7 -3
  407. package/src/core/storage/durable-history.ts +6 -5
  408. package/src/core/storage/maintenance-providers.ts +2 -1
  409. package/src/core/storage/maintenance.ts +7 -6
  410. package/src/core/storage/metrics.ts +5 -1
  411. package/src/core/storage/modes.ts +53 -0
  412. package/src/core/storage/process-log.ts +3 -2
  413. package/src/core/storage/receipts.ts +4 -3
  414. package/src/core/storage/segments.ts +7 -6
  415. package/src/core/supervisor/hook-health.ts +4 -4
  416. package/src/core/supervisor/service.ts +7 -6
  417. package/src/core/work/state.ts +8 -7
  418. package/src/core/workflow/adapters.ts +15 -0
  419. package/src/core/workflow/approvals.ts +6 -5
  420. package/src/core/workflow/billing.ts +34 -4
  421. package/src/core/workflow/durable-record.ts +4 -3
  422. package/src/core/workflow/live-session-v3.ts +6 -4
  423. package/src/core/workflow/run-state.ts +3 -2
  424. package/src/core/workflow/spawn-opencode.ts +150 -0
  425. package/src/core/workflow/transcript.ts +3 -2
  426. package/src/core/workflow/workspaces/leases.ts +5 -4
  427. package/src/core/workflow/workspaces/local-git.ts +3 -2
  428. package/src/core/workflow/workspaces/paths.ts +2 -1
  429. package/src/core/workflow/workspaces/state.ts +10 -9
  430. package/src/lazy-commands.ts +11 -1
  431. package/src/lib/agent-browser/client.ts +18 -0
  432. package/src/lib/browser/client.ts +147 -9
  433. package/src/lib/browser/identity.ts +64 -0
  434. package/src/lib/browser/index.ts +15 -1
  435. package/src/lib/browser/launch-args.ts +53 -1
  436. package/src/lib/browser/user-agent.ts +130 -0
  437. package/src/lib/docs-metadata-managed.ts +21 -0
  438. package/src/lib/identities/assume.ts +7 -7
  439. package/src/lib/instructions/apply.ts +2 -0
  440. package/src/lib/pace/index.ts +14 -0
  441. package/src/lib/pace/pace.ts +370 -0
  442. package/src/lib/tunnel/forward-headers.ts +16 -0
  443. package/src/lib/tunnel/gate.ts +18 -10
  444. package/src/lib/webview/index.ts +13 -0
  445. package/src/lib/webview/webview.ts +457 -0
package/README.md CHANGED
@@ -28,7 +28,7 @@
28
28
  - **Standalone web UI.** `harn web up` boots a local Next.js dashboard for the coord layer, councils, per-project state, and a local coding-agent status view (Claude Code / Codex / Cursor usage, backed by `harn devtools`). Ships with the git clone, not the npm package (see [Install](#install)).
29
29
  - **Backup + sync.** `harn backup` snapshots `.harnery/` via [restic](https://restic.net/); `harn sync` keeps a curated subset live across machines via [rclone](https://rclone.org/) (Google Drive or any rclone remote).
30
30
 
31
- The CLI also ships batteries: portable utility commands (`tokens`, `eml`, `env`, `grep` for parallel, ripgrep-accelerated monorepo search, plus `docs`, `browse`, `fetch`, `read`, `devtools`, and more) and the library toolkit they're built from. Useful, cross-platform, and dependency-light, but deliberately not the headline. Coordination is why harnery exists; the toolkit exists because the CLI needed it (see [Public surface tiers](#public-surface-tiers)).
31
+ The CLI also ships batteries: portable utility commands (`tokens`, `eml`, `env`, `grep` for parallel, ripgrep-accelerated monorepo search, plus `docs`, `browse`, `fetch`, `read`, `webview`, `devtools`, and more) and the library toolkit they're built from. Every page loader reads at human pace by default, waiting 3 to 9 seconds between loads of one site through a machine-wide ledger, with `--no-pace` and `HARNERY_PACE=off` to opt out. Useful, cross-platform, and dependency-light, but deliberately not the headline. Coordination is why harnery exists; the toolkit exists because the CLI needed it (see [Public surface tiers](#public-surface-tiers)).
32
32
 
33
33
  ## Install
34
34
 
package/dist/commander.js CHANGED
@@ -113,6 +113,7 @@ function harneryCommandBundles({ emit, context, binName, }) {
113
113
  lazy("admission", "Machine-wide admission control for heavy jobs: `admission run --resource <name> -- <command…>` waits for a FIFO slot then runs the command; `admission status` lists holders and waiters per resource.", async (program) => (await import("./commands/admission.js")).registerAdmissionCommand(program, emit)),
114
114
  lazy("browse-session", "Control an opted-in headed browse session through an owner-only descriptor", async (program) => (await import("./commands/browse-session.js")).registerBrowseSessionCommand(program, emit)),
115
115
  lazy("browse-ai <url>", `agent-browser (Vercel Labs) wrapper: accessibility-tree snapshots with element refs (@e1, @e2) for LLM consumption. Daemon-mode: successive calls reuse the same browser instance. Sister to ${binName} browse (Playwright).`, async (program) => (await import("./commands/browse-ai.js")).registerBrowseAiCommand(program, emit, context), { hasOptions: true }),
116
+ lazy("webview <url>", `Lightweight headless page probe through Bun.WebView (experimental, Bun 1.4+). Fresh ephemeral browser per call; use ${binName} browse for login, cookies, HAR, and QA.`, async (program) => (await import("./commands/webview.js")).registerWebviewCommand(program, emit, binName), { hasOptions: true }),
116
117
  {
117
118
  commands: [
118
119
  {
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
@@ -29,9 +29,10 @@ import { agentDisplayName } from "../core/agents/state/activity-log.js";
29
29
  import { buildLifecycleSuggestedName, buildSuggestedName, readHeartbeat as readHeartbeatCache, } from "../core/agents/state/heartbeat-writer.js";
30
30
  import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../core/agents/state/live-coordination-view.js";
31
31
  import { foldSessionState, } from "../core/agents/state/session-state.js";
32
+ import { turnChangesStatusRow } from "../core/agents/turn-changes.js";
32
33
  import { turnElapsedStatusRow } from "../core/agents/turn-elapsed.js";
33
34
  import { coordFreshnessSeconds, resolveBinName, sessionFinalizationConfig, } from "../core/config.js";
34
- import { EVENT_ADAPTER_IDS_V3 } from "../core/events/v3/adapter-id.js";
35
+ import { EVENT_ADAPTER_IDS_V3, normalizeEventAdapterIdV3, } from "../core/events/v3/adapter-id.js";
35
36
  import { readEventV3ControlState } from "../core/events/v3/control.js";
36
37
  import { projectCoordinationViewV3, readCoordinationViewV3, } from "../core/events/v3/coordination-view.js";
37
38
  import { liveInstanceIdV3 } from "../core/events/v3/live-routing.js";
@@ -337,7 +338,7 @@ export function registerAgentsCommand(program, emitParam, programContext, binNam
337
338
  .option("--kind <kind>", "pidmap | cache. Defaults to cache.")
338
339
  .option("--session-id <id>", "(--kind cache) native session id used to join the authoritative V3 generation.")
339
340
  .option("--adapter <id>", "(--kind cache) adapter used to validate the authoritative V3 generation: " +
340
- "claude-code | cursor | codex.")
341
+ "claude-code | cursor | codex | opencode.")
341
342
  .option("--pid <pid>", "(--kind pidmap) PID to register in pid-map. Default: walk " +
342
343
  "this shell's ppid chain for a claude process. Pass explicitly " +
343
344
  "when calling from outside Claude Code's Bash tool tree (e.g. " +
@@ -813,7 +814,7 @@ function runWhoami(opts) {
813
814
  if (!hb) {
814
815
  emit.error({
815
816
  code: "no_live_generation",
816
- message: noLiveGenerationMessage(myOwner),
817
+ message: noLiveGenerationMessage(root, myOwner),
817
818
  });
818
819
  process.exit(1);
819
820
  }
@@ -994,9 +995,18 @@ function normalizeKind(kind) {
994
995
  * This id is actionable: the reader may pass it to cache repair or explicit
995
996
  * finalization. Abbreviate ids for display elsewhere, never in a diagnostic
996
997
  * whose purpose is to hand the caller a canonical identity.
998
+ *
999
+ * The message also names the recovery. A session whose generation ended while
1000
+ * it sat idle (a stale sweep, or a `done` it has since outlived) still has a
1001
+ * live process, and `agents lifecycle active` is the one command that opens a
1002
+ * fresh generation for it (ADR 0088). Without the pointer every coordination
1003
+ * command refuses in turn and the caller has no way to guess the path back.
997
1004
  */
998
- function noLiveGenerationMessage(owner) {
999
- return `resolved owner=${owner} but no authority-safe live V3 generation exists for it`;
1005
+ function noLiveGenerationMessage(root, owner) {
1006
+ return `resolved owner=${owner} but no authority-safe live V3 generation exists for it; ${lifecycleReopenHint(root)}`;
1007
+ }
1008
+ function lifecycleReopenHint(root) {
1009
+ return `run \`${resolveBinName(root)} agents lifecycle active\` to open a fresh generation for this continuing session`;
1000
1010
  }
1001
1011
  /**
1002
1012
  * The instance_id of a live V3 generation that `prefix` strictly prefixes, or null.
@@ -1470,7 +1480,7 @@ function runLifecycle(rawState, opts) {
1470
1480
  if (state !== "active") {
1471
1481
  emit.error({
1472
1482
  code: "no_live_generation",
1473
- message: `${noLiveGenerationMessage(myOwner)}; run \`${resolveBinName(root)} agents lifecycle active\` to open a fresh generation`,
1483
+ message: noLiveGenerationMessage(root, myOwner),
1474
1484
  });
1475
1485
  process.exitCode = 1;
1476
1486
  return;
@@ -1693,7 +1703,7 @@ function runStatus(opts) {
1693
1703
  if (!hb) {
1694
1704
  emit.error({
1695
1705
  code: "no_live_generation",
1696
- message: noLiveGenerationMessage(myOwner),
1706
+ message: noLiveGenerationMessage(root, myOwner),
1697
1707
  });
1698
1708
  process.exit(1);
1699
1709
  }
@@ -1822,6 +1832,7 @@ function runStatus(opts) {
1822
1832
  // one inside the same session. Best-effort by contract — no turn evidence,
1823
1833
  // no row.
1824
1834
  const turnElapsed = turnElapsedStatusRow({ coordRoot: root, instanceId: hb.instance_id });
1835
+ const turnChanges = turnChangesStatusRow({ coordRoot: root, instanceId: hb.instance_id });
1825
1836
  const resources = readResourceStatus(root);
1826
1837
  const data = {
1827
1838
  name: displayName,
@@ -1830,6 +1841,7 @@ function runStatus(opts) {
1830
1841
  session_age_secs: ageSecs,
1831
1842
  turn_elapsed_secs: turnElapsed ? turnElapsed.elapsed.secs : null,
1832
1843
  turn_complete: turnElapsed ? turnElapsed.elapsed.complete : null,
1844
+ turn_changes: turnChanges.changes,
1833
1845
  activity: activityOf(hb),
1834
1846
  activity_updated_at: hb.activity_updated_at ?? null,
1835
1847
  activity_source: hb.activity_source ?? null,
@@ -1875,6 +1887,7 @@ function runStatus(opts) {
1875
1887
  const rows = [
1876
1888
  ["session", formatAge(ageSecs)],
1877
1889
  ...(turnElapsed ? [["turn", turnElapsed.value]] : []),
1890
+ ["changes", turnChanges.value],
1878
1891
  ["activity", activityOf(hb)],
1879
1892
  ["lifecycle", lifecycleLabel(hb)],
1880
1893
  ["context", ctxStr],
@@ -2112,15 +2125,7 @@ export function readAgentDiagnosticEventsInWindow(root, cutoffMs) {
2112
2125
  }
2113
2126
  /** Normalize adapter event data into the heartbeat platform value. */
2114
2127
  function adapterToPlatform(adapter) {
2115
- if (adapter === "claude-code")
2116
- return "claude-code";
2117
- if (adapter === "cursor")
2118
- return "cursor";
2119
- if (adapter === "codex")
2120
- return "codex";
2121
- if (adapter === "openclaw")
2122
- return "openclaw";
2123
- return "unknown";
2128
+ return normalizeEventAdapterIdV3(adapter) ?? "unknown";
2124
2129
  }
2125
2130
  /** Project a canonical health.* event into the HealEvent shape the aggregators
2126
2131
  * already consume. Returns null for non-heal events. instance_id → display name
@@ -4006,10 +4011,11 @@ function runHeal(opts) {
4006
4011
  if (opts.adapter &&
4007
4012
  opts.adapter !== "claude-code" &&
4008
4013
  opts.adapter !== "cursor" &&
4009
- opts.adapter !== "codex") {
4014
+ opts.adapter !== "codex" &&
4015
+ opts.adapter !== "opencode") {
4010
4016
  emit.error({
4011
4017
  code: "bad_adapter",
4012
- message: "--adapter must be one of: claude-code, cursor, codex",
4018
+ message: "--adapter must be one of: claude-code, cursor, codex, opencode",
4013
4019
  });
4014
4020
  process.exit(1);
4015
4021
  }
@@ -4226,7 +4232,7 @@ function cacheHealAuthorityRefusal(root, owner, sessionId, adapter, currentRow)
4226
4232
  if (producer?.terminal) {
4227
4233
  return {
4228
4234
  reason: "terminal_generation",
4229
- message: "the matching generation is terminal and cannot be repaired or reopened by heal",
4235
+ message: `the matching generation is terminal and cannot be repaired or reopened by heal; ${lifecycleReopenHint(root)}`,
4230
4236
  };
4231
4237
  }
4232
4238
  if (producer && producer.instance_id !== liveInstanceIdV3(owner)) {
@@ -1 +1 @@
1
- {"version":3,"file":"browse-ai.d.ts","sourceRoot":"","sources":["../../src/commands/browse-ai.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAiD1E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA2CN"}
1
+ {"version":3,"file":"browse-ai.d.ts","sourceRoot":"","sources":["../../src/commands/browse-ai.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAmD1E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAgDN"}
@@ -2,6 +2,7 @@ import { homedir } from "node:os";
2
2
  import { resolve } from "node:path";
3
3
  import { AgentBrowser } from "../lib/agent-browser/index.js";
4
4
  import { applyExtraCookies, CookieJar } from "../lib/cookies/index.js";
5
+ import { commandPaceGate } from "../lib/pace/index.js";
5
6
  // Module-scoped emit assigned by registerBrowseAiCommand. Same pattern as
6
7
  // cookies/read/browse: helper functions close over `emit` so action
7
8
  // callbacks stay concise.
@@ -45,6 +46,8 @@ export function registerBrowseAiCommand(program, emitParam, context) {
45
46
  'E.g., --batch "click @e5; wait 1000; snapshot"')
46
47
  .option("--network-har <path>", "Record a HAR file from open() through end of run")
47
48
  .option("--no-cookies", "Skip cookie-jar attach and persist")
49
+ .option("--no-pace", "Skip the human-pace gap (3 to 9 s) between page loads of the same site for this run. " +
50
+ "HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.")
48
51
  .option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
49
52
  .option("--json", "Emit a JSON envelope (snapshot, screenshot path, step results)")
50
53
  .option("--timeout <ms>", "Per-step timeout in ms", "60000")
@@ -68,6 +71,7 @@ function runBrowseAi(url, opts, context) {
68
71
  const ab = new AgentBrowser({
69
72
  jar,
70
73
  timeoutMs: Number.parseInt(opts.timeout, 10),
74
+ pace: commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info")),
71
75
  });
72
76
  const stepLog = [];
73
77
  // 1. Open + optional HAR start.
@@ -1 +1 @@
1
- {"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAkS1E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,EAC/B,OAAO,SAAmB,GACzB,IAAI,CAugBN;AAuzDD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,qCAAqC,CAAC"}
1
+ {"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA2S1E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,EAC/B,OAAO,SAAmB,GACzB,IAAI,CAiiBN;AA61DD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,qCAAqC,CAAC"}
@@ -1,10 +1,12 @@
1
+ import { spawn } from "node:child_process";
1
2
  import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { dirname, isAbsolute, resolve } from "node:path";
5
+ import { chromium } from "playwright";
4
6
  import { PNG } from "pngjs";
5
7
  import { resolveBinName } from "../core/config.js";
6
8
  import { CAPTURE_FIDELITY_MISMATCH_THRESHOLD, compareBand, cropNativePng, decideFidelity, pngDimensions, } from "../lib/browser/capture-fidelity.js";
7
- import { Browser, browserProxyFromEnv, browserProxyGateFromEnv, captureDevOverlay, DEFAULT_CRITIQUE_RUBRIC, extractObservedIp, parseAssertSpec, runCritique, tilesFromFullPage, WEBRTC_PROXY_ONLY_ARG, writeNetscapeCookieFile, wslHeadedLaunchArgs, } from "../lib/browser/index.js";
9
+ import { Browser, browserProxyFromEnv, browserProxyGateFromEnv, captureDevOverlay, chromeMajorFromExecutable, DEFAULT_CRITIQUE_RUBRIC, extractObservedIp, installedChromeChannel, installedChromePath, parseAssertSpec, resolveUserAgent, runCritique, tilesFromFullPage, WEBRTC_PROXY_ONLY_ARG, writeNetscapeCookieFile, wslHeadedLaunchArgs, } from "../lib/browser/index.js";
8
10
  import { allocateTileBudget, validatePageReviewAllocation, } from "../lib/browser/page-review-budget.js";
9
11
  import { PAGE_REVIEW_CAPTURE_PLAN_SCHEMA, } from "../lib/browser/page-review-contracts.js";
10
12
  import { findPackTile, gateHitsFromEnvelope, readPackContext, tileId, writePackContext, writePackExpandedTile, } from "../lib/browser/page-review-pack.js";
@@ -18,6 +20,7 @@ import { captureThumbnailFingerprint, registerCaptureThumbnail, } from "../lib/b
18
20
  import { reviewCandidateRects } from "../lib/browser/tiling.js";
19
21
  import { diffAgainstBaseline, saveBaseline, } from "../lib/browser/visual-diff.js";
20
22
  import { applyExtraCookies, CookieJar } from "../lib/cookies/index.js";
23
+ import { commandPaceGate } from "../lib/pace/index.js";
21
24
  /**
22
25
  * `harn browse <url>`: Playwright-backed page navigation with shared
23
26
  * cookie jar + persistent profile + diagnostics capture for LLM
@@ -72,24 +75,39 @@ export function registerBrowseCommand(program, emitParam, context, binName = res
72
75
  "`click <selector>`, `fill <selector=>value>`, `press <key>`, `wait <selector|ms>`, `eval <js>`, `reload`. " +
73
76
  'Example: `--batch "click button; wait 1500; reload; wait 3000"`. `reload` preserves sessionStorage + cookies, which is how to repro sessionStorage-restored UI state.')
74
77
  .option("--network-har <path>", "Record network traffic to a HAR file (finalized on close)")
75
- .option("--viewport <preset|WxH>", "Viewport: mobile (390x844), tablet (820x1180), desktop (1280x800), hd (1920x1080), or explicit '1920x1080'", "desktop")
78
+ .option("--viewport <preset|WxH>", "Viewport: mobile (390x844), tablet (820x1180), desktop (1280x800), hd (1920x1080), or explicit '1920x1080'. Default: real window in headed mode, desktop in headless mode")
76
79
  .option("--color-scheme <scheme>", "Emulate prefers-color-scheme for the whole session: light | dark. " +
77
80
  "Renders theme-aware pages in that scheme without page-specific toggles. " +
78
81
  "Absent = browser default (unchanged behavior).")
79
82
  .option("--login", "Headed mode for one-time auth flow (cookies persist in profile)")
83
+ .option("--plain", "With --login: open the URL in the installed Google Chrome with nothing attached (no DevTools " +
84
+ "protocol, no Playwright) on the same persistent profile. Use it for sign-in flows whose " +
85
+ "verification step detects automation itself (X does). Sign in, then close the window or " +
86
+ "create the --login-close-file; later browse and browse-session runs reuse the profile's cookies. " +
87
+ "Not compatible with --control-file, because nothing is attached to drive.")
80
88
  .option("--login-close-file <path>", "With --login, wait for this file instead of terminal Enter, then remove it and close cleanly")
81
89
  .option("--control-file <path>", "With --login, publish an owner-only descriptor for repeated browse-session control")
82
90
  .option("--headed", "Headed mode for one-off (no auth-flow framing)")
91
+ .option("--browser-channel <name>", "Browser to launch: chrome | chrome-beta | msedge | chromium. Headed launches (--login, --headed) " +
92
+ "default to the installed Google Chrome with the automation signals removed, because the bundled " +
93
+ '"Chrome for Testing" build advertises itself and sign-in flows refuse clicks; chromium forces the ' +
94
+ "bundled build. HARNERY_BROWSER_CHANNEL sets the default machine-wide.")
95
+ .option("--user-agent <ua|auto|native>", "User agent to present. Default: a normal Windows (or macOS on a Mac) Chrome user agent at the launched " +
96
+ "Chrome's major version, stored at ~/.cache/harnery/user-agent.json and reused by every surface; never " +
97
+ "Linux, never HeadlessChrome. A string rewrites the store, auto refreshes it, native uses the browser's own. " +
98
+ "HARNERY_BROWSER_UA overrides for one environment.")
83
99
  .option("--browser-arg <flag>", "Extra Chromium launch flag, passed straight to the browser (repeatable). " +
84
100
  "e.g. --browser-arg --disable-gpu. Also settable machine-wide via the " +
85
- "HARNERY_BROWSER_ARGS env var (whitespace-separated). Under WSL, headed " +
86
- "launches auto-add --disable-gpu to fix blank-window paint; opt out with " +
87
- "HARNERY_BROWSER_NO_WSL_DEFAULTS=1.", (value, prev = []) => [...prev, value], [])
101
+ "HARNERY_BROWSER_ARGS env var (whitespace-separated). Under WSL, set " +
102
+ "HARNERY_BROWSER_WSL_DISABLE_GPU=1 to add --disable-gpu when a headed window paints blank; " +
103
+ "it is off by default because software WebGL is a bot tell.", (value, prev = []) => [...prev, value], [])
88
104
  .option("--proxy-from-env", "Pass HTTP(S)_PROXY to Playwright as an authenticated browser proxy. " +
89
105
  "Credentials stay in the child environment, never command arguments. " +
90
106
  "When the host also injects the HARNERY_BROWSER_PROXY_* gate variables, " +
91
107
  "the expected IP is verified before the requested URL opens.")
92
108
  .option("--no-cookies", "Skip cookie-jar attach and persist")
109
+ .option("--no-pace", "Skip the human-pace gap (3 to 9 s) between page loads of the same site for this run. " +
110
+ "HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.")
93
111
  .option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
94
112
  .option("--profile <dir>", `Persistent Chromium profile dir (default ${DEFAULT_PROFILE})`)
95
113
  .option("--export-cookies <path>", "Write live profile cookies as an owner-only Netscape cookies.txt file on close")
@@ -332,20 +350,54 @@ async function runBrowse(url, opts, context) {
332
350
  if (loginCloseFile && existsSync(loginCloseFile)) {
333
351
  throw new Error(`Login close signal already exists at ${loginCloseFile}. Remove the stale file before launching.`);
334
352
  }
353
+ const pace = commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info"));
354
+ if (opts.plain) {
355
+ if (!opts.login)
356
+ throw new Error("--plain requires --login.");
357
+ if (opts.controlFile) {
358
+ throw new Error("--plain cannot take --control-file: nothing is attached to drive the window.");
359
+ }
360
+ const plainExecutable = installedChromePath();
361
+ const plainUa = resolveUserAgent({
362
+ requested: opts.userAgent,
363
+ env: process.env.HARNERY_BROWSER_UA,
364
+ chromeMajor: plainExecutable ? chromeMajorFromExecutable(plainExecutable) : undefined,
365
+ });
366
+ await pace?.before(url);
367
+ await runPlainLogin(url, opts.profile ?? DEFAULT_PROFILE, loginCloseFile, plainUa, emit);
368
+ return;
369
+ }
370
+ const channel = resolveBrowserChannel(opts, Boolean(headed));
371
+ const userAgent = resolveUserAgent({
372
+ requested: opts.userAgent,
373
+ env: process.env.HARNERY_BROWSER_UA,
374
+ chromeMajor: launchedChromeMajor(channel),
375
+ });
335
376
  const browser = new Browser({
336
377
  profileDir: opts.profile ?? DEFAULT_PROFILE,
337
378
  headed,
338
379
  jar,
339
- viewport,
380
+ viewport: headed && !opts.viewport ? null : viewport,
340
381
  ...(deviceScaleFactor !== undefined ? { deviceScaleFactor } : {}),
341
382
  ...(colorScheme ? { colorScheme } : {}),
342
383
  navigationTimeout: Number.parseInt(opts.timeout, 10),
343
384
  waitUntil: opts.waitUntil,
344
385
  recordHarPath: opts.networkHar ? resolve(opts.networkHar) : undefined,
345
386
  extraHeaders: context?.extraHeaders,
387
+ pace,
346
388
  launchArgs: resolveLaunchArgs(opts, Boolean(headed), Boolean(proxy)),
389
+ ...(channel ? { channel } : {}),
390
+ hideAutomation: Boolean(headed),
391
+ ...(userAgent ? { userAgent } : {}),
347
392
  proxy,
348
393
  });
394
+ if (userAgent)
395
+ emit.log(`Presenting as: ${userAgent}`, "debug");
396
+ if (headed) {
397
+ emit.log(channel && channel !== "chromium"
398
+ ? `Headed session uses the installed ${channel} channel with automation signals hidden.`
399
+ : "Headed session uses Playwright's bundled Chromium (no Google Chrome found); automation signals hidden.", "info");
400
+ }
349
401
  // Print mode: --snapshot / --html / --json all suppress file writes.
350
402
  const printMode = opts.snapshot || opts.html || opts.json;
351
403
  let controlServer = null;
@@ -2035,15 +2087,50 @@ function summarizeDiagnostics(diag) {
2035
2087
  }
2036
2088
  /**
2037
2089
  * Merge Chromium launch flags from three sources, in order, de-duped:
2038
- * 1. WSLg headed default (`--disable-gpu`) — auto-applied for headed launches
2039
- * under WSL so the window actually paints. Opt out with
2040
- * HARNERY_BROWSER_NO_WSL_DEFAULTS=1.
2090
+ * 1. WSLg `--disable-gpu`, only when HARNERY_BROWSER_WSL_DISABLE_GPU=1. It
2091
+ * was the default for headed launches, but software WebGL (SwiftShader)
2092
+ * is a bot tell that sign-in flows screen for, and current WSLg exposes
2093
+ * the host GPU through D3D12, so the flag is now opt-in for machines
2094
+ * that still paint a blank headed window without it.
2041
2095
  * 2. HARNERY_BROWSER_ARGS env (whitespace-separated) — a machine-wide default.
2042
2096
  * 3. --browser-arg flags on this invocation (repeatable).
2043
2097
  */
2098
+ const BROWSER_CHANNELS = new Set(["chrome", "chrome-beta", "msedge", "chromium"]);
2099
+ /**
2100
+ * Pick the browser channel: `--browser-channel`, then `HARNERY_BROWSER_CHANNEL`,
2101
+ * then (headed only) the installed Google Chrome when one exists. Headless runs
2102
+ * keep the bundled Chromium unless told otherwise, so QA renders stay stable.
2103
+ */
2104
+ function resolveBrowserChannel(opts, headed) {
2105
+ const requested = (opts.browserChannel ?? process.env.HARNERY_BROWSER_CHANNEL)?.trim();
2106
+ if (requested) {
2107
+ if (!BROWSER_CHANNELS.has(requested)) {
2108
+ throw new Error(`Unknown --browser-channel "${requested}". Use chrome, chrome-beta, msedge, or chromium.`);
2109
+ }
2110
+ return requested;
2111
+ }
2112
+ return headed ? installedChromeChannel() : undefined;
2113
+ }
2114
+ /**
2115
+ * Major version of the Chrome that will launch: the installed Chrome for the
2116
+ * `chrome` channel, else Playwright's bundled Chromium. Unknown when neither
2117
+ * answers `--version`; the user-agent store then keeps its last value.
2118
+ */
2119
+ function launchedChromeMajor(channel) {
2120
+ if (channel === "chrome") {
2121
+ const exe = installedChromePath();
2122
+ return exe ? chromeMajorFromExecutable(exe) : undefined;
2123
+ }
2124
+ try {
2125
+ return chromeMajorFromExecutable(chromium.executablePath());
2126
+ }
2127
+ catch {
2128
+ return undefined;
2129
+ }
2130
+ }
2044
2131
  function resolveLaunchArgs(opts, headed, proxyEnabled) {
2045
2132
  const args = [];
2046
- if (headed && !process.env.HARNERY_BROWSER_NO_WSL_DEFAULTS) {
2133
+ if (headed && process.env.HARNERY_BROWSER_WSL_DISABLE_GPU === "1") {
2047
2134
  args.push(...wslHeadedLaunchArgs());
2048
2135
  }
2049
2136
  const envArgs = process.env.HARNERY_BROWSER_ARGS?.trim();
@@ -2067,6 +2154,50 @@ async function verifyBrowserProxyGate(browser, gate) {
2067
2154
  }
2068
2155
  emit.log(`browser proxy gate: ${observedIp} · expected IP confirmed`, "info");
2069
2156
  }
2157
+ /**
2158
+ * `--login --plain`: spawn the installed Google Chrome directly on the shared
2159
+ * persistent profile, with no DevTools protocol attached. Playwright enables
2160
+ * its runtime hooks in every frame it drives, and sign-in verification vendors
2161
+ * (X's is the reported case) detect that and fail the flow with no explanation.
2162
+ * The person signs in here; cookies land in the same profile that later
2163
+ * `browse` and `browse-session` runs open, so read-only captures inherit the
2164
+ * session without ever repeating the sign-in under automation.
2165
+ */
2166
+ async function runPlainLogin(url, profileDir, loginCloseFile, userAgent, emit) {
2167
+ const executable = installedChromePath();
2168
+ if (!executable) {
2169
+ throw new Error("--plain needs an installed Google Chrome at a standard path; none was found on this machine.");
2170
+ }
2171
+ mkdirSync(profileDir, { recursive: true });
2172
+ const child = spawn(executable, [
2173
+ `--user-data-dir=${profileDir}`,
2174
+ "--no-first-run",
2175
+ "--no-default-browser-check",
2176
+ ...(userAgent ? [`--user-agent=${userAgent}`] : []),
2177
+ url,
2178
+ ], { stdio: "ignore" });
2179
+ const exited = new Promise((resolveExit) => {
2180
+ child.once("exit", () => resolveExit());
2181
+ child.once("error", () => resolveExit());
2182
+ });
2183
+ const lifecycleAbort = new AbortController();
2184
+ const waits = [exited];
2185
+ if (loginCloseFile) {
2186
+ emit.log(`[--login --plain] Plain Google Chrome is open with nothing attached. Sign in, then close the window or create ${loginCloseFile}.`, "info");
2187
+ waits.push(waitForLoginCloseFile(loginCloseFile, lifecycleAbort.signal));
2188
+ }
2189
+ else {
2190
+ emit.log("[--login --plain] Plain Google Chrome is open with nothing attached. Sign in, then close the window or press Enter here.", "info");
2191
+ waits.push(waitForTerminalEnter(lifecycleAbort.signal));
2192
+ }
2193
+ await Promise.race(waits);
2194
+ lifecycleAbort.abort();
2195
+ if (child.exitCode === null && child.signalCode === null) {
2196
+ child.kill("SIGTERM");
2197
+ await Promise.race([exited, new Promise((r) => setTimeout(r, 5000))]);
2198
+ }
2199
+ emit.log(`[--login --plain] Chrome closed; cookies persisted in ${profileDir}.`, "info");
2200
+ }
2070
2201
  async function waitForLoginCloseFile(path, signal) {
2071
2202
  while (!existsSync(path) && !signal?.aborted) {
2072
2203
  await new Promise((resolve) => setTimeout(resolve, 250));
@@ -1,3 +1,4 @@
1
+ import { ADAPTERS, normalizeAdapter } from "../core/adapter.js";
1
2
  import { monorepoRoot, resolveOwner } from "../core/agents/index.js";
2
3
  import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.js";
3
4
  import { checkpointContext, readContextState, readLatestCapsule, } from "../core/context/index.js";
@@ -58,7 +59,7 @@ export function registerCheckpointCommand(program, emit, context) {
58
59
  .description("Create a durable context-continuity capsule for the current work")
59
60
  .option("--session <id>", "Session id (defaults to the current agent heartbeat)")
60
61
  .option("--instance <id>", "Agent instance id (defaults to the current owner)")
61
- .option("--adapter <id>", "claude-code, codex, or cursor (inferred from heartbeat)")
62
+ .option("--adapter <id>", `${ADAPTERS.join(", ")} (inferred from heartbeat)`)
62
63
  .option("--reason <reason>", "manual, pressure, pre_compact, or session_end", "manual")
63
64
  .option("--note <text>", "Short continuation note for the recovered agent")
64
65
  .option("--json", "Structured JSON output")
@@ -68,7 +69,7 @@ export function registerCheckpointCommand(program, emit, context) {
68
69
  const reason = parseCheckpointReason(opts.reason);
69
70
  const identity = resolveContinuityIdentity(context, opts);
70
71
  if (!identity.adapter) {
71
- throw new Error("could not infer the adapter; pass --adapter claude-code|codex|cursor");
72
+ throw new Error(`could not infer the adapter; pass --adapter ${ADAPTERS.join("|")}`);
72
73
  }
73
74
  const result = checkpointContext(identity.coordRoot, {
74
75
  sessionId: identity.sessionId,
@@ -135,18 +136,13 @@ function resolveContinuityIdentity(context, opts) {
135
136
  return { coordRoot, instanceId, sessionId, adapter };
136
137
  }
137
138
  function adapterFromPlatform(platform) {
138
- if (platform === "claude-code")
139
- return "claude-code";
140
- if (platform === "cursor")
141
- return "cursor";
142
- if (platform === "codex")
143
- return "codex";
144
- return null;
139
+ return normalizeAdapter(platform);
145
140
  }
146
141
  function parseAdapter(value) {
147
- if (value === "claude-code" || value === "codex" || value === "cursor")
148
- return value;
149
- throw new Error(`invalid adapter "${value}"; expected claude-code, codex, or cursor`);
142
+ const adapter = normalizeAdapter(value);
143
+ if (adapter)
144
+ return adapter;
145
+ throw new Error(`invalid adapter "${value}"; expected one of ${ADAPTERS.join(", ")}`);
150
146
  }
151
147
  function parseCheckpointReason(value) {
152
148
  if (value === "manual" ||
@@ -4,7 +4,7 @@
4
4
  * `init` makes two kinds of change outside the harnery package:
5
5
  * 1. Merges `agent-hook` entries into the adapter settings file
6
6
  * (Claude Code `.claude/settings.json`, Cursor `.cursor/hooks.json`, or
7
- * Codex `.codex/hooks.json`).
7
+ * Codex `.codex/hooks.json`), or installs the OpenCode plugin directory.
8
8
  * 2. Creates the `.harnery/` coord root (runtime state: events, councils,
9
9
  * identities, journal) and stamps the host bin name into
10
10
  * `.harnery/config.jsonc`.
@@ -1 +1 @@
1
- {"version":3,"file":"deinit.d.ts","sourceRoot":"","sources":["../../src/commands/deinit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAgBnD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAwHjG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAEV;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C"}
1
+ {"version":3,"file":"deinit.d.ts","sourceRoot":"","sources":["../../src/commands/deinit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAiBnD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CA4HjG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAEV;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C"}
@@ -4,7 +4,7 @@
4
4
  * `init` makes two kinds of change outside the harnery package:
5
5
  * 1. Merges `agent-hook` entries into the adapter settings file
6
6
  * (Claude Code `.claude/settings.json`, Cursor `.cursor/hooks.json`, or
7
- * Codex `.codex/hooks.json`).
7
+ * Codex `.codex/hooks.json`), or installs the OpenCode plugin directory.
8
8
  * 2. Creates the `.harnery/` coord root (runtime state: events, councils,
9
9
  * identities, journal) and stamps the host bin name into
10
10
  * `.harnery/config.jsonc`.
@@ -31,6 +31,7 @@ import { relative, resolve } from "node:path";
31
31
  import { createInterface } from "node:readline";
32
32
  import { DEFAULT_BIN_NAME } from "../core/config.js";
33
33
  import { ADAPTER_SPECS } from "../core/hooks/adapter/events.js";
34
+ import { removeOpenCodePlugin } from "../core/hooks/adapter/opencode-plugin.js";
34
35
  import { removeIndexerExclusions } from "../lib/indexer-exclusions.js";
35
36
  import { removeInstructions } from "../lib/instructions/apply.js";
36
37
  import { removeGitHooks } from "../lib/instructions/git-hooks.js";
@@ -47,7 +48,7 @@ export function registerDeinitCommand(program, emit, binName) {
47
48
  "settings file (keeps any others). Pass --purge-state to also delete the " +
48
49
  ".harnery/ coord root (on a terminal it asks first). Idempotent; use " +
49
50
  "--dry-run to preview.")
50
- .option("--adapter <id>", "claude-code | cursor | codex", "claude-code")
51
+ .option("--adapter <id>", "claude-code | cursor | codex | opencode", "claude-code")
51
52
  .option("--dry-run", "Show what would change without writing")
52
53
  .option("--project-root <path>", "Project root (default: git toplevel, else cwd)")
53
54
  .option("--purge-state", "Also delete the .harnery/ coord root (runtime state, destructive)")
@@ -55,7 +56,7 @@ export function registerDeinitCommand(program, emit, binName) {
55
56
  const adapter = opts.adapter;
56
57
  const spec = ADAPTER_SPECS[adapter];
57
58
  if (!spec) {
58
- emit.text(`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex.`);
59
+ emit.text(`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex | opencode.`);
59
60
  emit.setExitCode(1);
60
61
  return;
61
62
  }
@@ -77,7 +78,10 @@ export function registerDeinitCommand(program, emit, binName) {
77
78
  }
78
79
  // ── 1. unwire adapter hooks ────────────────────────────────────────────
79
80
  const settingsPath = resolve(projectRoot, spec.settingsFile);
80
- if (!existsSync(settingsPath)) {
81
+ if (spec.installMode === "opencode-plugin") {
82
+ actions.push(...removeOpenCodePlugin(projectRoot, dryRun));
83
+ }
84
+ else if (!existsSync(settingsPath)) {
81
85
  actions.push(`· ${rel(projectRoot, settingsPath)} doesn't exist; no hooks to remove`);
82
86
  }
83
87
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAmC1E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA2ON"}
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAqC1E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA2ON"}
@@ -4,6 +4,7 @@ import { initDocsContext as initDocsLinks, runLinks } from "../lib/docs-links.js
4
4
  import { initDocsContext as initDocsLint, runLint } from "../lib/docs-lint.js";
5
5
  import { readDocsMetadata, readDocsMetadataKey } from "../lib/docs-meta.js";
6
6
  import { initDocsMetadataAuditContext, runDocsMetadataAudit } from "../lib/docs-metadata-audit.js";
7
+ import { initDocsMetadataExclusions } from "../lib/docs-metadata-managed.js";
7
8
  import { initDocsMetadataSyncContext, runDocsMetadataSync } from "../lib/docs-metadata-sync.js";
8
9
  import { createDocsFile } from "../lib/docs-new.js";
9
10
  import { countColdHandoffs, initDocsContext as initDocsSweep, runSweep, } from "../lib/docs-sweep.js";
@@ -20,6 +21,7 @@ function ensureContext(context) {
20
21
  docsRootAllowlist: context.docsRootAllowlist,
21
22
  });
22
23
  initDocsLinks({ ...opts, extraExcludedPrefixes: context.extraDocsExcludedPrefixes });
24
+ initDocsMetadataExclusions(context.extraDocsExcludedPrefixes);
23
25
  initDocsMetadataAuditContext(opts);
24
26
  initDocsMetadataSyncContext(opts);
25
27
  initDocsSweep(opts);
@@ -476,12 +476,20 @@ function checkAdapterHooks(installedAdapters = []) {
476
476
  if (d.invalidEventKeys.length > 0) {
477
477
  bits.push(`unsupported events (${d.invalidEventKeys.join(", ")})`);
478
478
  }
479
+ if (d.pluginIssues && d.pluginIssues.length > 0) {
480
+ // Plugin issues already name their file; render them as-is.
481
+ return d.pluginIssues.join("; ");
482
+ }
479
483
  return `${d.settingsFile}: ${bits.join("; ")}`;
480
484
  });
481
485
  for (const id of unwired) {
482
- parts.push(`${ADAPTER_SPECS[id].settingsFile}: ${id} CLI installed, no harnery hooks wired`);
486
+ const what = ADAPTER_SPECS[id].installMode === "opencode-plugin" ? "plugin" : "hooks";
487
+ parts.push(`${ADAPTER_SPECS[id].settingsFile}: ${id} CLI installed, no harnery ${what} wired`);
483
488
  }
484
- const needsManualRepair = drift.some((d) => d.parseError || d.invalidTopLevelKeys.length > 0 || d.invalidEventKeys.length > 0);
489
+ const needsManualRepair = drift.some((d) => d.parseError ||
490
+ d.invalidTopLevelKeys.length > 0 ||
491
+ d.invalidEventKeys.length > 0 ||
492
+ d.pluginIssues?.some((issue) => issue.includes("without harnery's ownership header")));
485
493
  const wireHints = unwired.map((id) => `\`${bin} init --adapter ${id}\``);
486
494
  let hint;
487
495
  if (needsManualRepair) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA4B1E,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA2BN"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA+B1E,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAgCN"}