harnery 0.40.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 (441) 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 +18 -16
  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/stale-sweep.d.ts.map +1 -1
  69. package/dist/core/agents/state/stale-sweep.js +2 -10
  70. package/dist/core/agents/turn-changes.d.ts +17 -0
  71. package/dist/core/agents/turn-changes.d.ts.map +1 -0
  72. package/dist/core/agents/turn-changes.js +76 -0
  73. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  74. package/dist/core/artifacts/delivery-card.js +2 -1
  75. package/dist/core/artifacts/index.d.ts.map +1 -1
  76. package/dist/core/artifacts/index.js +4 -3
  77. package/dist/core/config.d.ts +5 -0
  78. package/dist/core/config.d.ts.map +1 -1
  79. package/dist/core/config.js +14 -0
  80. package/dist/core/context/index.d.ts.map +1 -1
  81. package/dist/core/context/index.js +2 -1
  82. package/dist/core/conversations/archive.d.ts.map +1 -1
  83. package/dist/core/conversations/archive.js +4 -3
  84. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  85. package/dist/core/diagnostics/bundle.js +3 -2
  86. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
  87. package/dist/core/events/legacy-storage/canary.js +5 -4
  88. package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
  89. package/dist/core/events/legacy-storage/compression.js +2 -1
  90. package/dist/core/events/v3/adapter-id.d.ts +10 -2
  91. package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
  92. package/dist/core/events/v3/adapter-id.js +16 -0
  93. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  94. package/dist/core/events/v3/authority-outbox.js +2 -1
  95. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  96. package/dist/core/events/v3/bootstrap.js +5 -4
  97. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  98. package/dist/core/events/v3/capabilities.js +17 -0
  99. package/dist/core/events/v3/contract.d.ts +5 -0
  100. package/dist/core/events/v3/contract.d.ts.map +1 -1
  101. package/dist/core/events/v3/contract.js +7 -1
  102. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  103. package/dist/core/events/v3/control-witness.js +3 -2
  104. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
  105. package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
  106. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
  107. package/dist/core/events/v3/fingerprint-keys.js +7 -6
  108. package/dist/core/events/v3/generated.d.ts +1 -1
  109. package/dist/core/events/v3/generated.js +1 -1
  110. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  111. package/dist/core/events/v3/live-feed.js +5 -4
  112. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  113. package/dist/core/events/v3/producers/command-recorder.js +8 -7
  114. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  115. package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
  116. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
  117. package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
  118. package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
  119. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  120. package/dist/core/events/v3/producers/hook-base.js +10 -4
  121. package/dist/core/events/v3/producers/hook.d.ts +2 -0
  122. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  123. package/dist/core/events/v3/producers/hook.js +16 -1
  124. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  125. package/dist/core/events/v3/producers/intake.js +16 -6
  126. package/dist/core/events/v3/producers/recorder.d.ts +2 -4
  127. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  128. package/dist/core/events/v3/producers/recorder.js +109 -101
  129. package/dist/core/events/v3/recovery.d.ts.map +1 -1
  130. package/dist/core/events/v3/recovery.js +4 -3
  131. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
  132. package/dist/core/events/v3/support-storage/inventory.js +2 -1
  133. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
  134. package/dist/core/events/v3/support-storage/maintenance.js +4 -3
  135. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
  136. package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
  137. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
  138. package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
  139. package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
  140. package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
  141. package/dist/core/events/v3/tool-line-changes.js +135 -0
  142. package/dist/core/events/v3/writer.d.ts.map +1 -1
  143. package/dist/core/events/v3/writer.js +8 -7
  144. package/dist/core/governor/planning.d.ts.map +1 -1
  145. package/dist/core/governor/planning.js +6 -5
  146. package/dist/core/governor/service.d.ts.map +1 -1
  147. package/dist/core/governor/service.js +12 -11
  148. package/dist/core/governor/state.d.ts.map +1 -1
  149. package/dist/core/governor/state.js +7 -6
  150. package/dist/core/guard/evaluator.js +1 -0
  151. package/dist/core/guard/storage.d.ts.map +1 -1
  152. package/dist/core/guard/storage.js +3 -2
  153. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
  154. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
  155. package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
  156. package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
  157. package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
  158. package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
  159. package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
  160. package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
  161. package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
  162. package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
  163. package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
  164. package/dist/core/hooks/adapter/behaviors/index.js +20 -0
  165. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
  166. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
  167. package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
  168. package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
  169. package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
  170. package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
  171. package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
  172. package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
  173. package/dist/core/hooks/adapter/behaviors/types.js +1 -0
  174. package/dist/core/hooks/adapter/detect.d.ts +1 -1
  175. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  176. package/dist/core/hooks/adapter/detect.js +2 -3
  177. package/dist/core/hooks/adapter/events.d.ts +29 -1
  178. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  179. package/dist/core/hooks/adapter/events.js +31 -0
  180. package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
  181. package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
  182. package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
  183. package/dist/core/hooks/adapter/output.d.ts +7 -0
  184. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  185. package/dist/core/hooks/adapter/output.js +8 -1
  186. package/dist/core/hooks/adapter/wiring.d.ts +15 -1
  187. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  188. package/dist/core/hooks/adapter/wiring.js +74 -11
  189. package/dist/core/hooks/cli.js +635 -529
  190. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  191. package/dist/core/hooks/effects/image-capture.js +2 -1
  192. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
  193. package/dist/core/hooks/prompt-context/contract.js +1 -0
  194. package/dist/core/hooks/resolve/transcript.d.ts +1 -1
  195. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  196. package/dist/core/hooks/resolve/transcript.js +35 -4
  197. package/dist/core/hooks/session-name-presence.d.ts +3 -1
  198. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  199. package/dist/core/hooks/session-name-presence.js +7 -2
  200. package/dist/core/hooks/shell-waiter.d.ts +2 -0
  201. package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
  202. package/dist/core/hooks/shell-waiter.js +173 -0
  203. package/dist/core/resources/service.d.ts.map +1 -1
  204. package/dist/core/resources/service.js +5 -4
  205. package/dist/core/semantic/review.d.ts.map +1 -1
  206. package/dist/core/semantic/review.js +5 -4
  207. package/dist/core/semantic/service.d.ts.map +1 -1
  208. package/dist/core/semantic/service.js +15 -14
  209. package/dist/core/semantic/storage.d.ts.map +1 -1
  210. package/dist/core/semantic/storage.js +5 -4
  211. package/dist/core/storage/atomic-json.d.ts.map +1 -1
  212. package/dist/core/storage/atomic-json.js +7 -3
  213. package/dist/core/storage/durable-history.d.ts.map +1 -1
  214. package/dist/core/storage/durable-history.js +6 -5
  215. package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
  216. package/dist/core/storage/maintenance-providers.js +2 -1
  217. package/dist/core/storage/maintenance.d.ts.map +1 -1
  218. package/dist/core/storage/maintenance.js +7 -6
  219. package/dist/core/storage/metrics.d.ts.map +1 -1
  220. package/dist/core/storage/metrics.js +5 -1
  221. package/dist/core/storage/modes.d.ts +17 -0
  222. package/dist/core/storage/modes.d.ts.map +1 -0
  223. package/dist/core/storage/modes.js +47 -0
  224. package/dist/core/storage/process-log.d.ts.map +1 -1
  225. package/dist/core/storage/process-log.js +3 -2
  226. package/dist/core/storage/receipts.d.ts.map +1 -1
  227. package/dist/core/storage/receipts.js +4 -3
  228. package/dist/core/storage/segments.d.ts.map +1 -1
  229. package/dist/core/storage/segments.js +7 -6
  230. package/dist/core/supervisor/hook-health.d.ts +2 -1
  231. package/dist/core/supervisor/hook-health.d.ts.map +1 -1
  232. package/dist/core/supervisor/hook-health.js +4 -3
  233. package/dist/core/supervisor/service.d.ts.map +1 -1
  234. package/dist/core/supervisor/service.js +7 -6
  235. package/dist/core/work/state.d.ts.map +1 -1
  236. package/dist/core/work/state.js +8 -7
  237. package/dist/core/workflow/adapters.d.ts +7 -0
  238. package/dist/core/workflow/adapters.d.ts.map +1 -1
  239. package/dist/core/workflow/adapters.js +9 -0
  240. package/dist/core/workflow/approvals.d.ts.map +1 -1
  241. package/dist/core/workflow/approvals.js +6 -5
  242. package/dist/core/workflow/billing.d.ts.map +1 -1
  243. package/dist/core/workflow/billing.js +33 -4
  244. package/dist/core/workflow/durable-record.d.ts.map +1 -1
  245. package/dist/core/workflow/durable-record.js +4 -3
  246. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  247. package/dist/core/workflow/live-session-v3.js +2 -3
  248. package/dist/core/workflow/run-state.d.ts.map +1 -1
  249. package/dist/core/workflow/run-state.js +3 -2
  250. package/dist/core/workflow/spawn-opencode.d.ts +36 -0
  251. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
  252. package/dist/core/workflow/spawn-opencode.js +132 -0
  253. package/dist/core/workflow/transcript.d.ts.map +1 -1
  254. package/dist/core/workflow/transcript.js +3 -2
  255. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  256. package/dist/core/workflow/workspaces/leases.js +5 -4
  257. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  258. package/dist/core/workflow/workspaces/local-git.js +3 -2
  259. package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
  260. package/dist/core/workflow/workspaces/paths.js +2 -1
  261. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  262. package/dist/core/workflow/workspaces/state.js +10 -9
  263. package/dist/lazy-commands.js +8 -1
  264. package/dist/lib/agent-browser/client.d.ts +9 -0
  265. package/dist/lib/agent-browser/client.d.ts.map +1 -1
  266. package/dist/lib/agent-browser/client.js +13 -0
  267. package/dist/lib/browser/client.d.ts +35 -1
  268. package/dist/lib/browser/client.d.ts.map +1 -1
  269. package/dist/lib/browser/client.js +117 -8
  270. package/dist/lib/browser/identity.d.ts +25 -0
  271. package/dist/lib/browser/identity.d.ts.map +1 -0
  272. package/dist/lib/browser/identity.js +66 -0
  273. package/dist/lib/browser/index.d.ts +2 -1
  274. package/dist/lib/browser/index.d.ts.map +1 -1
  275. package/dist/lib/browser/index.js +2 -1
  276. package/dist/lib/browser/launch-args.d.ts +26 -0
  277. package/dist/lib/browser/launch-args.d.ts.map +1 -1
  278. package/dist/lib/browser/launch-args.js +41 -1
  279. package/dist/lib/browser/user-agent.d.ts +53 -0
  280. package/dist/lib/browser/user-agent.d.ts.map +1 -0
  281. package/dist/lib/browser/user-agent.js +79 -0
  282. package/dist/lib/docs-metadata-managed.d.ts +1 -0
  283. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  284. package/dist/lib/docs-metadata-managed.js +17 -1
  285. package/dist/lib/identities/assume.d.ts.map +1 -1
  286. package/dist/lib/identities/assume.js +4 -9
  287. package/dist/lib/instructions/apply.d.ts.map +1 -1
  288. package/dist/lib/instructions/apply.js +2 -0
  289. package/dist/lib/pace/index.d.ts +2 -0
  290. package/dist/lib/pace/index.d.ts.map +1 -0
  291. package/dist/lib/pace/index.js +1 -0
  292. package/dist/lib/pace/pace.d.ts +95 -0
  293. package/dist/lib/pace/pace.d.ts.map +1 -0
  294. package/dist/lib/pace/pace.js +313 -0
  295. package/dist/lib/tunnel/forward-headers.d.ts +11 -0
  296. package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
  297. package/dist/lib/tunnel/forward-headers.js +17 -0
  298. package/dist/lib/tunnel/gate.js +15 -10
  299. package/dist/lib/webview/index.d.ts +2 -0
  300. package/dist/lib/webview/index.d.ts.map +1 -0
  301. package/dist/lib/webview/index.js +1 -0
  302. package/dist/lib/webview/webview.d.ts +116 -0
  303. package/dist/lib/webview/webview.d.ts.map +1 -0
  304. package/dist/lib/webview/webview.js +289 -0
  305. package/opencode-plugin/package.json +19 -0
  306. package/opencode-plugin/src/index.ts +791 -0
  307. package/package.json +11 -4
  308. package/schemas/config.schema.json +13 -0
  309. package/schemas/event-v3.schema.json +164 -0
  310. package/src/commander.ts +7 -0
  311. package/src/commands/agents.ts +33 -18
  312. package/src/commands/browse-ai.ts +8 -0
  313. package/src/commands/browse.ts +189 -10
  314. package/src/commands/checkpoint.ts +7 -9
  315. package/src/commands/deinit.ts +9 -4
  316. package/src/commands/docs.ts +2 -0
  317. package/src/commands/doctor.ts +11 -2
  318. package/src/commands/fetch.ts +14 -0
  319. package/src/commands/init.ts +281 -119
  320. package/src/commands/instructions.ts +8 -4
  321. package/src/commands/ledger-v3.ts +2 -1
  322. package/src/commands/webview.ts +159 -0
  323. package/src/core/adapter.ts +102 -1
  324. package/src/core/adapters/attestation.ts +3 -2
  325. package/src/core/adapters/profiles.ts +42 -1
  326. package/src/core/adapters/registry.ts +37 -0
  327. package/src/core/agents/canonical-emit.ts +2 -5
  328. package/src/core/agents/cli.ts +18 -17
  329. package/src/core/agents/coord-client.ts +9 -3
  330. package/src/core/agents/rules/claim-conflict.ts +3 -8
  331. package/src/core/agents/rules/commit-conflict.ts +2 -7
  332. package/src/core/agents/rules/stop-hook.ts +3 -1
  333. package/src/core/agents/session-events.ts +120 -26
  334. package/src/core/agents/session-finalization-state-v3.ts +2 -1
  335. package/src/core/agents/session-finalizer-v3.ts +5 -4
  336. package/src/core/agents/session-name-display.ts +48 -0
  337. package/src/core/agents/state/heartbeat-reader.ts +7 -0
  338. package/src/core/agents/state/heartbeat-writer.ts +24 -2
  339. package/src/core/agents/state/live-coordination-view.ts +1 -0
  340. package/src/core/agents/state/live-coordination-writer.ts +3 -0
  341. package/src/core/agents/state/stale-sweep.ts +2 -9
  342. package/src/core/agents/turn-changes.ts +97 -0
  343. package/src/core/artifacts/delivery-card.ts +2 -1
  344. package/src/core/artifacts/index.ts +4 -3
  345. package/src/core/config.ts +23 -0
  346. package/src/core/context/index.ts +2 -1
  347. package/src/core/conversations/archive.ts +4 -3
  348. package/src/core/diagnostics/bundle.ts +3 -2
  349. package/src/core/events/legacy-storage/canary.ts +5 -4
  350. package/src/core/events/legacy-storage/compression.ts +2 -1
  351. package/src/core/events/v3/adapter-id.ts +29 -1
  352. package/src/core/events/v3/authority-outbox.ts +2 -1
  353. package/src/core/events/v3/bootstrap.ts +5 -4
  354. package/src/core/events/v3/capabilities.ts +17 -0
  355. package/src/core/events/v3/contract.ts +9 -1
  356. package/src/core/events/v3/control-witness.ts +3 -2
  357. package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
  358. package/src/core/events/v3/fingerprint-keys.ts +7 -6
  359. package/src/core/events/v3/generated.ts +1 -1
  360. package/src/core/events/v3/live-feed.ts +5 -4
  361. package/src/core/events/v3/producers/command-recorder.ts +8 -6
  362. package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
  363. package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
  364. package/src/core/events/v3/producers/hook-base.ts +11 -4
  365. package/src/core/events/v3/producers/hook.ts +19 -1
  366. package/src/core/events/v3/producers/intake.ts +18 -6
  367. package/src/core/events/v3/producers/recorder.ts +123 -114
  368. package/src/core/events/v3/recovery.ts +4 -3
  369. package/src/core/events/v3/support-storage/inventory.ts +2 -1
  370. package/src/core/events/v3/support-storage/maintenance.ts +8 -3
  371. package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
  372. package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
  373. package/src/core/events/v3/tool-line-changes.ts +139 -0
  374. package/src/core/events/v3/writer.ts +8 -7
  375. package/src/core/governor/planning.ts +6 -5
  376. package/src/core/governor/service.ts +12 -11
  377. package/src/core/governor/state.ts +7 -6
  378. package/src/core/guard/evaluator.ts +1 -0
  379. package/src/core/guard/storage.ts +3 -2
  380. package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
  381. package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
  382. package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
  383. package/src/core/hooks/adapter/behaviors/index.ts +31 -0
  384. package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
  385. package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
  386. package/src/core/hooks/adapter/behaviors/types.ts +110 -0
  387. package/src/core/hooks/adapter/detect.ts +2 -3
  388. package/src/core/hooks/adapter/events.ts +53 -1
  389. package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
  390. package/src/core/hooks/adapter/output.ts +8 -1
  391. package/src/core/hooks/adapter/wiring.ts +85 -11
  392. package/src/core/hooks/cli.ts +733 -537
  393. package/src/core/hooks/effects/image-capture.ts +2 -1
  394. package/src/core/hooks/prompt-context/contract.ts +1 -0
  395. package/src/core/hooks/resolve/transcript.ts +42 -5
  396. package/src/core/hooks/session-name-presence.ts +10 -3
  397. package/src/core/hooks/shell-waiter.ts +166 -0
  398. package/src/core/resources/service.ts +5 -4
  399. package/src/core/semantic/review.ts +5 -4
  400. package/src/core/semantic/service.ts +15 -14
  401. package/src/core/semantic/storage.ts +5 -4
  402. package/src/core/storage/atomic-json.ts +7 -3
  403. package/src/core/storage/durable-history.ts +6 -5
  404. package/src/core/storage/maintenance-providers.ts +2 -1
  405. package/src/core/storage/maintenance.ts +7 -6
  406. package/src/core/storage/metrics.ts +5 -1
  407. package/src/core/storage/modes.ts +53 -0
  408. package/src/core/storage/process-log.ts +3 -2
  409. package/src/core/storage/receipts.ts +4 -3
  410. package/src/core/storage/segments.ts +7 -6
  411. package/src/core/supervisor/hook-health.ts +4 -4
  412. package/src/core/supervisor/service.ts +7 -6
  413. package/src/core/work/state.ts +8 -7
  414. package/src/core/workflow/adapters.ts +15 -0
  415. package/src/core/workflow/approvals.ts +6 -5
  416. package/src/core/workflow/billing.ts +34 -4
  417. package/src/core/workflow/durable-record.ts +4 -3
  418. package/src/core/workflow/live-session-v3.ts +2 -3
  419. package/src/core/workflow/run-state.ts +3 -2
  420. package/src/core/workflow/spawn-opencode.ts +150 -0
  421. package/src/core/workflow/transcript.ts +3 -2
  422. package/src/core/workflow/workspaces/leases.ts +5 -4
  423. package/src/core/workflow/workspaces/local-git.ts +3 -2
  424. package/src/core/workflow/workspaces/paths.ts +2 -1
  425. package/src/core/workflow/workspaces/state.ts +10 -9
  426. package/src/lazy-commands.ts +11 -1
  427. package/src/lib/agent-browser/client.ts +18 -0
  428. package/src/lib/browser/client.ts +147 -9
  429. package/src/lib/browser/identity.ts +64 -0
  430. package/src/lib/browser/index.ts +15 -1
  431. package/src/lib/browser/launch-args.ts +53 -1
  432. package/src/lib/browser/user-agent.ts +130 -0
  433. package/src/lib/docs-metadata-managed.ts +21 -0
  434. package/src/lib/identities/assume.ts +7 -7
  435. package/src/lib/instructions/apply.ts +2 -0
  436. package/src/lib/pace/index.ts +14 -0
  437. package/src/lib/pace/pace.ts +370 -0
  438. package/src/lib/tunnel/forward-headers.ts +16 -0
  439. package/src/lib/tunnel/gate.ts +18 -10
  440. package/src/lib/webview/index.ts +13 -0
  441. package/src/lib/webview/webview.ts +457 -0
@@ -0,0 +1,94 @@
1
+ import { resolve } from "node:path";
2
+ import { commandPaceGate } from "../lib/pace/index.js";
3
+ import { parseWebViewTypeStep, parseWebViewViewport, runWebView, WebViewUnavailableError, } from "../lib/webview/index.js";
4
+ export function registerWebviewCommand(program, emit, binName) {
5
+ program
6
+ .command("webview <url>")
7
+ .description("Lightweight headless page probe through Bun.WebView (experimental, Bun 1.4+). " +
8
+ `Fresh ephemeral browser per call; use ${binName} browse for login, cookies, HAR, and QA.`)
9
+ .option("--backend <engine>", "Browser engine: auto | chrome | webkit", "auto")
10
+ .option("--user-agent <ua>", "Chrome user agent: shared store by default; auto refreshes, native disables")
11
+ .option("--viewport <WxH>", "Viewport in CSS pixels", "1280x800")
12
+ .option("--profile <dir>", "Persist cookies and local storage in this directory (default is ephemeral)")
13
+ .option("--chrome-path <path>", "Chrome-family executable; implies the Chrome backend")
14
+ .option("--browser-arg <flag>", "Extra Chrome launch flag (repeatable)", collect, [])
15
+ .option("--timeout <ms>", "Navigation and selector timeout in milliseconds", "30000")
16
+ .option("--wait-for <css>", "Wait for a CSS selector after navigation")
17
+ .option("--type <css=>text>", "Focus a selector and insert text (repeatable; runs before clicks)", collect, [])
18
+ .option("--click <css>", "Scroll to and click a CSS selector (repeatable)", collect, [])
19
+ .option("--press <key>", "Press a key in the currently focused element (repeatable)", collect, [])
20
+ .option("--evaluate <expression>", "Evaluate a JavaScript expression after actions")
21
+ .option("--settle <ms>", "Extra delay after actions before capture", "0")
22
+ .option("--screenshot <path>", "Save a viewport PNG (Bun.WebView does not provide full-page capture)")
23
+ .option("--html", "Print the final document HTML instead of body text")
24
+ .option("--json", "Print the full result envelope")
25
+ .option("--no-pace", "Skip the human-pace gap (3 to 9 s) between page loads of the same site for this run. " +
26
+ "HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.")
27
+ .action(async (url, opts) => {
28
+ try {
29
+ await runWebview(url, opts, emit);
30
+ }
31
+ catch (err) {
32
+ const message = err instanceof Error ? err.message : String(err);
33
+ emit.error({
34
+ code: err instanceof WebViewUnavailableError ? err.code : "webview_error",
35
+ message,
36
+ });
37
+ process.exit(1);
38
+ }
39
+ });
40
+ }
41
+ async function runWebview(url, opts, emit) {
42
+ if (!isBackend(opts.backend)) {
43
+ throw new Error(`Invalid backend "${opts.backend}". Expected auto, chrome, or webkit.`);
44
+ }
45
+ const backend = opts.backend === "auto" && opts.chromePath ? "chrome" : opts.backend;
46
+ const result = await runWebView(url, {
47
+ backend,
48
+ viewport: parseWebViewViewport(opts.viewport),
49
+ profileDir: opts.profile ? resolve(opts.profile) : undefined,
50
+ chromePath: opts.chromePath ? resolve(opts.chromePath) : undefined,
51
+ browserArgs: opts.browserArg,
52
+ timeoutMs: parseNonNegativeInteger(opts.timeout, "--timeout", false),
53
+ waitFor: opts.waitFor,
54
+ typeSteps: opts.type.map(parseWebViewTypeStep),
55
+ clicks: opts.click,
56
+ presses: opts.press,
57
+ evaluate: opts.evaluate,
58
+ settleMs: parseNonNegativeInteger(opts.settle, "--settle", true),
59
+ screenshotPath: opts.screenshot ? resolve(opts.screenshot) : undefined,
60
+ captureHtml: opts.html === true,
61
+ pace: commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info")),
62
+ userAgent: opts.userAgent,
63
+ });
64
+ if (opts.json) {
65
+ emit.data(result);
66
+ }
67
+ else if (opts.html) {
68
+ emit.text(result.html?.endsWith("\n") ? result.html : `${result.html ?? ""}\n`);
69
+ }
70
+ else if (opts.evaluate !== undefined) {
71
+ const value = typeof result.evaluation === "string"
72
+ ? result.evaluation
73
+ : JSON.stringify(result.evaluation, null, 2);
74
+ emit.text(`${value ?? "undefined"}\n`);
75
+ }
76
+ else {
77
+ emit.text(result.text.endsWith("\n") ? result.text : `${result.text}\n`);
78
+ }
79
+ }
80
+ function collect(value, previous) {
81
+ return [...previous, value];
82
+ }
83
+ function isBackend(value) {
84
+ return value === "auto" || value === "chrome" || value === "webkit";
85
+ }
86
+ function parseNonNegativeInteger(value, flag, allowZero) {
87
+ if (!/^\d+$/.test(value))
88
+ throw new Error(`${flag} expects an integer, got "${value}".`);
89
+ const parsed = Number.parseInt(value, 10);
90
+ if ((!allowZero && parsed < 1) || (allowZero && parsed < 0)) {
91
+ throw new Error(`${flag} must be ${allowZero ? "zero or greater" : "greater than zero"}.`);
92
+ }
93
+ return parsed;
94
+ }
@@ -1,5 +1,54 @@
1
1
  /** First-party harness adapters supported by Harnery's canonical V3 ledger. */
2
- export type Adapter = "claude-code" | "cursor" | "codex";
2
+ export type Adapter = "claude-code" | "cursor" | "codex" | "opencode";
3
3
  /** Canonical producer classes used by V3 provenance. */
4
4
  export type EventSource = "agent-hooks" | "agent-coord" | "user" | "system";
5
+ /**
6
+ * Runtime census of the workflow adapters. Adding a member to `Adapter`
7
+ * without listing it here is a compile error (see `adaptersComplete`), so a
8
+ * new adapter can never slip past the shared normalizer.
9
+ */
10
+ export declare const ADAPTERS: readonly ["claude-code", "cursor", "codex", "opencode"];
11
+ /** Every adapter falls back to this identity when a platform value carries no usable evidence. */
12
+ export declare const DEFAULT_ADAPTER: Adapter;
13
+ /** Why a platform value could not be normalized to a known adapter. */
14
+ export type AdapterFallbackReason = "missing" | "unknown";
15
+ export interface AdapterFallback {
16
+ /** The raw value that was normalized. */
17
+ value: unknown;
18
+ /** `missing` for null, undefined, or an empty string; `unknown` for anything else. */
19
+ reason: AdapterFallbackReason;
20
+ /** The adapter that was substituted. */
21
+ fallback: string;
22
+ /** Caller-supplied label naming the code path, for the diagnostic line. */
23
+ context?: string;
24
+ }
25
+ export interface AdapterFallbackOptions {
26
+ /** Names the caller in the diagnostic line, e.g. `"claim-conflict"`. */
27
+ context?: string;
28
+ /**
29
+ * Receives every fallback. The default writes one stderr line per unknown
30
+ * value; a missing value is a pre-heartbeat state rather than a
31
+ * misattribution, so it is passed here but not printed.
32
+ */
33
+ onFallback?: (fallback: AdapterFallback) => void;
34
+ }
35
+ /**
36
+ * Generic membership normalizer shared by every adapter census. Returns the
37
+ * matching id or `null`; it never substitutes a default.
38
+ */
39
+ export declare function normalizeAdapterId<T extends string>(value: unknown, census: readonly T[]): T | null;
40
+ /**
41
+ * Normalize with an explicit, reported fallback. Every caller that must end up
42
+ * with *some* adapter routes through here so the substitution is visible.
43
+ */
44
+ export declare function resolveAdapterId<T extends string>(value: unknown, census: readonly T[], fallback: T, options?: AdapterFallbackOptions): T;
45
+ /** Default fallback sink: one stderr line for an unrecognized platform value. */
46
+ export declare function reportAdapterFallback(fallback: AdapterFallback): void;
47
+ /** Strict workflow-adapter normalizer: a known id or `null`. */
48
+ export declare function normalizeAdapter(value: unknown): Adapter | null;
49
+ /**
50
+ * Heartbeat `platform` (or any adapter-shaped string) to a workflow adapter,
51
+ * substituting `DEFAULT_ADAPTER` and reporting the substitution.
52
+ */
53
+ export declare function adapterFromPlatform(value: unknown, options?: AdapterFallbackOptions): Adapter;
5
54
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/core/adapter.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/core/adapter.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAEtE,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,QAAQ,yDAKkB,CAAC;AAMxC,kGAAkG;AAClG,eAAO,MAAM,eAAe,EAAE,OAAuB,CAAC;AAEtD,uEAAuE;AACvE,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,sFAAsF;IACtF,MAAM,EAAE,qBAAqB,CAAC;IAC9B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;CAClD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,CAAC,EAAE,GACnB,CAAC,GAAG,IAAI,CAGV;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAC/C,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,QAAQ,EAAE,CAAC,EACX,OAAO,GAAE,sBAA2B,GACnC,CAAC,CAYH;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAMrE;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAE/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAE7F"}
@@ -1 +1,59 @@
1
- export {};
1
+ /**
2
+ * Runtime census of the workflow adapters. Adding a member to `Adapter`
3
+ * without listing it here is a compile error (see `adaptersComplete`), so a
4
+ * new adapter can never slip past the shared normalizer.
5
+ */
6
+ export const ADAPTERS = [
7
+ "claude-code",
8
+ "cursor",
9
+ "codex",
10
+ "opencode",
11
+ ];
12
+ const adaptersComplete = true;
13
+ void adaptersComplete;
14
+ /** Every adapter falls back to this identity when a platform value carries no usable evidence. */
15
+ export const DEFAULT_ADAPTER = "claude-code";
16
+ /**
17
+ * Generic membership normalizer shared by every adapter census. Returns the
18
+ * matching id or `null`; it never substitutes a default.
19
+ */
20
+ export function normalizeAdapterId(value, census) {
21
+ if (typeof value !== "string")
22
+ return null;
23
+ return census.includes(value) ? value : null;
24
+ }
25
+ /**
26
+ * Normalize with an explicit, reported fallback. Every caller that must end up
27
+ * with *some* adapter routes through here so the substitution is visible.
28
+ */
29
+ export function resolveAdapterId(value, census, fallback, options = {}) {
30
+ const normalized = normalizeAdapterId(value, census);
31
+ if (normalized !== null)
32
+ return normalized;
33
+ const reason = value === undefined || value === null || value === "" ? "missing" : "unknown";
34
+ (options.onFallback ?? reportAdapterFallback)({
35
+ value,
36
+ reason,
37
+ fallback,
38
+ context: options.context,
39
+ });
40
+ return fallback;
41
+ }
42
+ /** Default fallback sink: one stderr line for an unrecognized platform value. */
43
+ export function reportAdapterFallback(fallback) {
44
+ if (fallback.reason !== "unknown")
45
+ return;
46
+ const where = fallback.context ? ` (${fallback.context})` : "";
47
+ process.stderr.write(`harnery: unknown adapter platform ${JSON.stringify(fallback.value)}${where}; treating it as ${fallback.fallback}\n`);
48
+ }
49
+ /** Strict workflow-adapter normalizer: a known id or `null`. */
50
+ export function normalizeAdapter(value) {
51
+ return normalizeAdapterId(value, ADAPTERS);
52
+ }
53
+ /**
54
+ * Heartbeat `platform` (or any adapter-shaped string) to a workflow adapter,
55
+ * substituting `DEFAULT_ADAPTER` and reporting the substitution.
56
+ */
57
+ export function adapterFromPlatform(value, options) {
58
+ return resolveAdapterId(value, ADAPTERS, DEFAULT_ADAPTER, options);
59
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C;;uBAEuB;AACvB,eAAO,MAAM,qBAAqB,2FAMxB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,CAAC;IACnB;kFAC8E;IAC9E,cAAc,EAAE,MAAM,CAAC;IACvB;kDAC8C;IAC9C,cAAc,EAAE,MAAM,CAAC;IACvB;;8DAE0D;IAC1D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB;6DACyD;IACzD,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACtE,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,IAAI,GAAE,uBAA4B,GAAG,MAAM,CAI1E;AAED;wDACwD;AACxD,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAM7D;AAMD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,GAChD,kBAAkB,CAEpB;AASD;;aAEa;AACb,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,kBAAkB,EAC1B,IAAI,GAAE,uBAA4B,GACjC,MAAM,CAmBR;AAED;;kEAEkE;AAClE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,uBAA4B,GACjC,kBAAkB,GAAG,IAAI,CAc3B;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,SAAS,GAClB,kBAAkB,GAAG,IAAI,CAe3B;AAED;uBACuB;AACvB,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,kBAAkB,GAAG,IAAI,EACjC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,OAAO,EAAE,cAAc,EACvB,gBAAgB,CAAC,EAAE,OAAO,GACzB,MAAM,IAAI,kBAAkB,CAK9B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,uBAA4B,GAAG,kBAAkB,EAAE,CAczF;AAED;;;oDAGoD;AACpD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,IAAI,EAAE,uBAAuB,GAAG;IAC9B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAChD;wCACoC;IACpC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GACA;IACD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,YAAY,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,CAAA;KAAE,CAAC,CAAC;IAClG,mBAAmB,EAAE,MAAM,CACzB,MAAM,EACN;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CACvE,CAAC;CACH,CAoCA"}
1
+ {"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAcH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C;;uBAEuB;AACvB,eAAO,MAAM,qBAAqB,2FAMxB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,CAAC;IACnB;kFAC8E;IAC9E,cAAc,EAAE,MAAM,CAAC;IACvB;kDAC8C;IAC9C,cAAc,EAAE,MAAM,CAAC;IACvB;;8DAE0D;IAC1D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB;6DACyD;IACzD,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACtE,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,IAAI,GAAE,uBAA4B,GAAG,MAAM,CAI1E;AAED;wDACwD;AACxD,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAM7D;AAMD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,GAChD,kBAAkB,CAEpB;AASD;;aAEa;AACb,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,kBAAkB,EAC1B,IAAI,GAAE,uBAA4B,GACjC,MAAM,CAmBR;AAED;;kEAEkE;AAClE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,uBAA4B,GACjC,kBAAkB,GAAG,IAAI,CAc3B;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,SAAS,GAClB,kBAAkB,GAAG,IAAI,CAe3B;AAED;uBACuB;AACvB,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,kBAAkB,GAAG,IAAI,EACjC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,OAAO,EAAE,cAAc,EACvB,gBAAgB,CAAC,EAAE,OAAO,GACzB,MAAM,IAAI,kBAAkB,CAK9B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,uBAA4B,GAAG,kBAAkB,EAAE,CAczF;AAED;;;oDAGoD;AACpD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,IAAI,EAAE,uBAAuB,GAAG;IAC9B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAChD;wCACoC;IACpC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GACA;IACD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,YAAY,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,CAAA;KAAE,CAAC,CAAC;IAClG,mBAAmB,EAAE,MAAM,CACzB,MAAM,EACN;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CACvE,CAAC;CACH,CAoCA"}
@@ -14,6 +14,7 @@
14
14
  import { mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
15
15
  import { resolve } from "node:path";
16
16
  import { monorepoRoot } from "../agents/coord-client.js";
17
+ import { stateDirMode, stateFileMode } from "../storage/modes.js";
17
18
  import { stableDigest } from "../workflow/durable-record.js";
18
19
  export const ATTESTATION_SCHEMA_VERSION = 2;
19
20
  /** Dimensions one minimal live turn can honestly establish. Everything else
@@ -58,12 +59,12 @@ function attestationPath(adapter, opts) {
58
59
  * create. */
59
60
  export function writeAttestation(record, opts = {}) {
60
61
  const path = attestationPath(record.adapter, opts);
61
- mkdirSync(attestationsDir(opts), { recursive: true, mode: 0o700 });
62
+ mkdirSync(attestationsDir(opts), { recursive: true, mode: stateDirMode() });
62
63
  const temporary = `${path}.tmp-${process.pid}`;
63
64
  try {
64
65
  writeFileSync(temporary, `${JSON.stringify(record, null, 2)}\n`, {
65
66
  encoding: "utf8",
66
- mode: 0o600,
67
+ mode: stateFileMode(),
67
68
  });
68
69
  renameSync(temporary, path);
69
70
  }
@@ -55,14 +55,31 @@ export declare const BUILTIN_ADAPTER_PROFILES: {
55
55
  readonly modelFamily: "multi";
56
56
  readonly effortValues: readonly [];
57
57
  readonly verified: {
58
- readonly date: "2026-08-18";
59
- readonly version: "2026.08.11-e8db854";
58
+ readonly date: "2026-09-20";
59
+ readonly version: "2026.09.18-9a7762b";
60
+ };
61
+ readonly capabilities: AdapterCapabilities;
62
+ };
63
+ readonly opencode: {
64
+ readonly id: "opencode";
65
+ readonly displayName: "OpenCode";
66
+ readonly binary: "opencode";
67
+ readonly installHint: "curl -fsSL https://opencode.ai/install | bash";
68
+ readonly loginHint: "opencode auth login";
69
+ readonly apiKeyEnv: "OPENCODE_API_KEY";
70
+ readonly integrationMode: "cli-subprocess";
71
+ readonly authModel: "own-auth";
72
+ readonly modelFamily: "multi";
73
+ readonly effortValues: readonly [];
74
+ readonly verified: {
75
+ readonly date: "2026-09-20";
76
+ readonly version: "opencode v2.0.11";
60
77
  };
61
78
  readonly capabilities: AdapterCapabilities;
62
79
  };
63
80
  };
64
81
  export type BuiltinAdapterId = keyof typeof BUILTIN_ADAPTER_PROFILES;
65
- export declare const BUILTIN_ADAPTER_IDS: readonly ("claude-code" | "cursor" | "codex")[];
82
+ export declare const BUILTIN_ADAPTER_IDS: readonly ("claude-code" | "cursor" | "codex" | "opencode")[];
66
83
  export declare function isBuiltinAdapter(id: string): id is BuiltinAdapterId;
67
84
  export declare function builtinAdapterProfile(id: string): AdapterProfile | undefined;
68
85
  export declare function validateAdapterEffort(id: string, effort: string | undefined): void;
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAgCvF;gFACgF;AAChF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFc,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAErE,eAAO,MAAM,mBAAmB,iDAE/B,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,gBAAgB,CAEnE;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAUlF"}
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAgCvF;gFACgF;AAChF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkIc,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAErE,eAAO,MAAM,mBAAmB,8DAE/B,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,gBAAgB,CAEnE;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAUlF"}
@@ -92,17 +92,48 @@ export const BUILTIN_ADAPTER_PROFILES = {
92
92
  authModel: "own-auth",
93
93
  modelFamily: "multi",
94
94
  effortValues: [],
95
- verified: { date: "2026-08-18", version: "2026.08.11-e8db854" },
95
+ verified: { date: "2026-09-20", version: "2026.09.18-9a7762b" },
96
96
  capabilities: capabilities({
97
97
  effortSelection: unsupported("Cursor embeds effort in some parameterized model ids; Harnery does not rewrite model ids."),
98
98
  maxTurns: unsupported("cursor-agent exposes no turn-ceiling flag."),
99
99
  sessionId: supported("Read from the JSON result envelope."),
100
100
  cost: unsupported("The JSON result envelope carries no cost."),
101
+ // Still unknown on 2026-09-20 against cursor-agent 2026.09.18: the live
102
+ // `cursor_composer_context_percent` reader serves IDE hook sessions from
103
+ // the composer `state.vscdb`, and headless `cursor-agent` children (this
104
+ // workflow adapter) leave no composer row and no usage in the JSON result.
101
105
  contextTelemetry: unknown("No stable Cursor context-usage payload has been certified."),
102
106
  preCompactionSignal: supported("Cursor preCompact is wired to a durable checkpoint."),
103
107
  postCompactionSignal: unsupported("Harnery does not wire an unverified Cursor postCompact hook."),
104
108
  }),
105
109
  },
110
+ opencode: {
111
+ id: "opencode",
112
+ displayName: "OpenCode",
113
+ binary: "opencode",
114
+ installHint: "curl -fsSL https://opencode.ai/install | bash",
115
+ loginHint: "opencode auth login",
116
+ apiKeyEnv: "OPENCODE_API_KEY",
117
+ integrationMode: "cli-subprocess",
118
+ authModel: "own-auth",
119
+ modelFamily: "multi",
120
+ // Model reasoning is selected through the `provider/model#variant` id;
121
+ // OpenCode exposes no separate effort dial for Harnery to map.
122
+ effortValues: [],
123
+ verified: { date: "2026-09-20", version: "opencode v2.0.11" },
124
+ capabilities: capabilities({
125
+ effortSelection: unsupported("OpenCode selects reasoning through the model id variant; there is no separate effort flag."),
126
+ maxTurns: unsupported("`opencode run` exposes no turn-ceiling flag."),
127
+ sessionId: supported("Read from the `sessionID` on every `--format json` NDJSON line."),
128
+ cost: unsupported("`opencode run --format json` streams parts without a final cost; cost lives in `session export`."),
129
+ // Tool evidence is delivered on the event axis by the Harnery OpenCode
130
+ // plugin, not by the final-result workflow spawn, which retains no tool
131
+ // events (as with Codex and Cursor).
132
+ contextTelemetry: unknown("OpenCode stores context in SQLite; no context-window bridge is certified yet."),
133
+ preCompactionSignal: supported('OpenCode session.hook("compaction") is bridged to a durable checkpoint.'),
134
+ postCompactionSignal: unsupported("No post-compact hook is wired; OpenCode post-compaction recovery is not yet certified."),
135
+ }),
136
+ },
106
137
  };
107
138
  export const BUILTIN_ADAPTER_IDS = Object.freeze(Object.keys(BUILTIN_ADAPTER_PROFILES));
108
139
  export function isBuiltinAdapter(id) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/registry.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAqErD;+EAC+E;AAC/E,qBAAa,eAAe;;gBAGd,QAAQ,GAAE,QAAQ,CAAC,OAAO,CAAM;IAI5C,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAYhC,GAAG,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS;IAIvC,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO;IAU/B,IAAI,IAAI,OAAO,EAAE;IAIjB,GAAG,IAAI,SAAS,EAAE;IAIlB,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAGhD;AAED,wBAAgB,4BAA4B,IAAI,eAAe,CAE9D"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/registry.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAqGrD;+EAC+E;AAC/E,qBAAa,eAAe;;gBAGd,QAAQ,GAAE,QAAQ,CAAC,OAAO,CAAM;IAI5C,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAYhC,GAAG,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS;IAIvC,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO;IAU/B,IAAI,IAAI,OAAO,EAAE;IAIjB,GAAG,IAAI,SAAS,EAAE;IAIlB,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAGhD;AAED,wBAAgB,4BAA4B,IAAI,eAAe,CAE9D"}
@@ -1,6 +1,7 @@
1
1
  import { buildClaudeInvocation, claudeCodeSpawner, normalizeClaudeResult, } from "../workflow/spawn-claude.js";
2
2
  import { buildCodexInvocation, codexSpawner, normalizeCodexResult, } from "../workflow/spawn-codex.js";
3
3
  import { buildCursorInvocation, cursorSpawner, normalizeCursorResult, } from "../workflow/spawn-cursor.js";
4
+ import { buildOpenCodeInvocation, normalizeOpenCodeResult, openCodeSpawner, } from "../workflow/spawn-opencode.js";
4
5
  import { BUILTIN_ADAPTER_IDS, BUILTIN_ADAPTER_PROFILES, } from "./profiles.js";
5
6
  const BUILTIN_ADAPTERS = {
6
7
  "claude-code": {
@@ -67,6 +68,38 @@ const BUILTIN_ADAPTERS = {
67
68
  },
68
69
  },
69
70
  },
71
+ opencode: {
72
+ profile: BUILTIN_ADAPTER_PROFILES.opencode,
73
+ spawn: openCodeSpawner,
74
+ buildInvocation: buildOpenCodeInvocation,
75
+ normalizeResult: normalizeOpenCodeResult,
76
+ fixture: {
77
+ // `opencode run --format json` streams NDJSON: a step-start line then one
78
+ // or more text parts, each carrying the same sessionID.
79
+ raw: {
80
+ stdout: [
81
+ JSON.stringify({
82
+ type: "step_start",
83
+ sessionID: "opencode-bench-session",
84
+ part: { type: "step-start" },
85
+ }),
86
+ JSON.stringify({
87
+ type: "text",
88
+ sessionID: "opencode-bench-session",
89
+ part: { type: "text", text: "HARNERY_BENCH_OK" },
90
+ }),
91
+ ].join("\n"),
92
+ stderr: "",
93
+ exitCode: 0,
94
+ durationMs: 11,
95
+ },
96
+ expected: {
97
+ ok: true,
98
+ text: "HARNERY_BENCH_OK",
99
+ sessionId: "opencode-bench-session",
100
+ },
101
+ },
102
+ },
70
103
  };
71
104
  /** Mutable registry for embedders, initialized empty unless adapters are
72
105
  * provided. Duplicate ids fail loud instead of silently replacing behavior. */
@@ -9,7 +9,7 @@
9
9
  * a 15-second safety budget; loaded-host checks normally finish in a few
10
10
  * seconds and record the observation before the parent command exits.
11
11
  */
12
- import type { EventAdapterIdV3 } from "../events/v3/adapter-id.js";
12
+ import { type EventAdapterIdV3 } from "../events/v3/adapter-id.js";
13
13
  import type { LiveCoordinationObservationV3 } from "../events/v3/live-observation.js";
14
14
  import type { Heartbeat } from "./state/heartbeat-reader.js";
15
15
  export type EventV3EmitObservation = LiveCoordinationObservationV3 | {
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-emit.d.ts","sourceRoot":"","sources":["../../../src/core/agents/canonical-emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAGtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAC9B,6BAA6B,GAC7B;IACE,UAAU,EAAE,yBAAyB,CAAC;IACtC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,sBAAsB,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAE5E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CA4C5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAK/E;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,mBAAmB,GAAG,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAC3E,QAAQ,EAAE,MAAM,GACf,MAAM,CAQR"}
1
+ {"version":3,"file":"canonical-emit.d.ts","sourceRoot":"","sources":["../../../src/core/agents/canonical-emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,KAAK,gBAAgB,EAAgC,MAAM,4BAA4B,CAAC;AACjG,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAGtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAC9B,6BAA6B,GAC7B;IACE,UAAU,EAAE,yBAAyB,CAAC;IACtC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,sBAAsB,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAE5E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CA4C5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAE/E;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,mBAAmB,GAAG,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAC3E,QAAQ,EAAE,MAAM,GACf,MAAM,CAQR"}
@@ -10,6 +10,7 @@
10
10
  * seconds and record the observation before the parent command exits.
11
11
  */
12
12
  import { spawnSync } from "node:child_process";
13
+ import { eventAdapterIdV3FromPlatform } from "../events/v3/adapter-id.js";
13
14
  import { coordBinPath } from "./coord-bin.js";
14
15
  import { resolveCoordRoot } from "./coord-client.js";
15
16
  /**
@@ -74,13 +75,7 @@ export function emitEventV3(input) {
74
75
  * Normalize the heartbeat's `platform` field to the canonical Adapter type.
75
76
  */
76
77
  export function normalizeAdapter(platform) {
77
- if (platform === "cursor")
78
- return "cursor";
79
- if (platform === "codex")
80
- return "codex";
81
- if (platform === "openclaw")
82
- return "openclaw";
83
- return "claude-code";
78
+ return eventAdapterIdV3FromPlatform(platform, { context: "canonical-emit" });
84
79
  }
85
80
  /** Producer joins use the private native session ID, never its V3 fingerprint. */
86
81
  export function nativeSessionIdentity(row, fallback) {
@@ -12,6 +12,8 @@ import { appendFile, mkdir } from "node:fs/promises";
12
12
  import { hostname } from "node:os";
13
13
  import { dirname, join, resolve } from "node:path";
14
14
  import { coordEnv } from "../../lib/env.js";
15
+ import { normalizeAdapter, adapterFromPlatform as sharedAdapterFromPlatform } from "../adapter.js";
16
+ import { resolveBinName } from "../config.js";
15
17
  import { closeProcessLoggers, legacyLogFields, processLogger } from "../storage/logger.js";
16
18
  import { acquireNoClobberLease } from "../workflow/workspaces/leases.js";
17
19
  function sharedDiagnostic(root, event, fields, error) {
@@ -152,13 +154,6 @@ async function handleProject(root, rest) {
152
154
  process.stdout.write(`${JSON.stringify(report, null, rest.includes("--json") ? 2 : 0)}\n`);
153
155
  return view.authority_safe ? 0 : 1;
154
156
  }
155
- function adapterFromPlatform(platform) {
156
- if (platform === "cursor")
157
- return "cursor";
158
- if (platform === "codex")
159
- return "codex";
160
- return "claude-code";
161
- }
162
157
  const coordinationRetryCell = new Int32Array(new SharedArrayBuffer(4));
163
158
  const COORDINATION_RETRY_ATTEMPTS = 240;
164
159
  const COORDINATION_RETRY_DELAY_MS = 25;
@@ -256,7 +251,7 @@ async function handleStateAction(root, action, rest) {
256
251
  coordRoot: root,
257
252
  owner,
258
253
  nativeSessionId: before?.session_id ?? owner,
259
- adapter: adapterFromPlatform(before?.platform),
254
+ adapter: sharedAdapterFromPlatform(before?.platform, { context: "agent-coord" }),
260
255
  task,
261
256
  });
262
257
  break;
@@ -283,7 +278,14 @@ async function handleStateAction(root, action, rest) {
283
278
  }
284
279
  }
285
280
  catch (error) {
286
- process.stderr.write(`agent-coord set-task: V3 authority refused (${error instanceof Error ? error.message : String(error)})\n`);
281
+ const detail = error instanceof Error ? error.message : String(error);
282
+ // A missing heartbeat here means the session's generation ended
283
+ // while its process lived on. Name the reopen command (ADR 0088);
284
+ // set-task is usually the first thing such a session runs.
285
+ const hint = detail.includes("heartbeat_missing:")
286
+ ? `; run \`${resolveBinName(root)} agents lifecycle active\` to open a fresh generation for this continuing session`
287
+ : "";
288
+ process.stderr.write(`agent-coord set-task: V3 authority refused (${detail})${hint}\n`);
287
289
  return 1;
288
290
  }
289
291
  if (!hb) {
@@ -313,7 +315,7 @@ async function handleStateAction(root, action, rest) {
313
315
  coordRoot: root,
314
316
  owner,
315
317
  nativeSessionId: before?.session_id ?? owner,
316
- adapter: adapterFromPlatform(before?.platform),
318
+ adapter: sharedAdapterFromPlatform(before?.platform, { context: "agent-coord" }),
317
319
  operation: "released",
318
320
  path,
319
321
  access: "write",
@@ -371,11 +373,11 @@ async function handleStateAction(root, action, rest) {
371
373
  coordRoot: root,
372
374
  owner,
373
375
  nativeSessionId: sessionId ?? owner,
374
- adapter: adapterFromPlatform(adapter),
376
+ adapter: sharedAdapterFromPlatform(adapter, { context: "agent-coord" }),
375
377
  });
376
378
  }
377
379
  const { repairLiveCoordinationHeartbeat } = await import("./state/live-coordination-writer.js");
378
- hb = repairLiveCoordinationHeartbeat(root, owner, sessionId ?? owner, adapterFromPlatform(adapter), model);
380
+ hb = repairLiveCoordinationHeartbeat(root, owner, sessionId ?? owner, sharedAdapterFromPlatform(adapter, { context: "agent-coord" }), model);
379
381
  }
380
382
  catch (error) {
381
383
  process.stderr.write(`agent-coord repair-coordination-cache: V3 route refused (${error instanceof Error ? error.message : String(error)})\n`);
@@ -397,7 +399,7 @@ async function handleStateAction(root, action, rest) {
397
399
  liveCoordinationWriteModeV3(root);
398
400
  const { liveInstanceIdV3 } = await import("../events/v3/live-routing.js");
399
401
  const { repairLiveCoordinationHeartbeat } = await import("./state/live-coordination-writer.js");
400
- const heartbeat = repairLiveCoordinationHeartbeat(root, owner, sessionId ?? owner, adapterFromPlatform(adapter));
402
+ const heartbeat = repairLiveCoordinationHeartbeat(root, owner, sessionId ?? owner, sharedAdapterFromPlatform(adapter, { context: "agent-coord" }));
401
403
  if (!heartbeat) {
402
404
  throw new Error("authoritative coordination cache could not be materialized");
403
405
  }
@@ -408,7 +410,7 @@ async function handleStateAction(root, action, rest) {
408
410
  observed_current_state_digest: coordinationAuthorityStateDigestV3(heartbeat),
409
411
  approval_record_id: approvalRecordId,
410
412
  });
411
- const repaired = repairLiveCoordinationHeartbeat(root, owner, sessionId ?? owner, adapterFromPlatform(adapter));
413
+ const repaired = repairLiveCoordinationHeartbeat(root, owner, sessionId ?? owner, sharedAdapterFromPlatform(adapter, { context: "agent-coord" }));
412
414
  process.stdout.write(`${JSON.stringify({
413
415
  instance_id: owner,
414
416
  receipt,
@@ -777,7 +779,7 @@ async function handleEmitEvent(root, rest) {
777
779
  const eventType = args.type;
778
780
  const instanceId = args.owner;
779
781
  const sessionId = args.session;
780
- const adapter = args.adapter;
782
+ const adapter = normalizeAdapter(args.adapter) ?? undefined;
781
783
  const dataJson = args["data-stdin"] === "true" ? await readStdin() : "";
782
784
  if (!eventType || !instanceId || !sessionId || !adapter || !dataJson) {
783
785
  process.stderr.write("agent-coord emit-event --type <V3_TYPE> --owner <id> --session <id> --adapter <h> --data-stdin\n");
@@ -945,7 +947,7 @@ async function handleGitHook(fallbackRoot, rest) {
945
947
  owner,
946
948
  subject: hit.instance_id,
947
949
  nativeSessionId: hit.session_id ?? owner,
948
- adapter: adapterFromPlatform(hit.platform),
950
+ adapter: sharedAdapterFromPlatform(hit.platform, { context: "agent-coord" }),
949
951
  operation: "released",
950
952
  path,
951
953
  access: "write",
@@ -1 +1 @@
1
- {"version":3,"file":"coord-client.d.ts","sourceRoot":"","sources":["../../../src/core/agents/coord-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAWhE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAI5E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CA+B7E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAeD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtD;AAiED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,mFAAmF;AACnF,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2CxD;AAgCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,GAAG,MAAM,CAAC;CAC5F,CAsEA;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsB5C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG;IAClD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,QAAQ,GAAG,iBAAiB,GAAG,MAAM,CAAC;CAC/C,CAyBA;AAqBD,sFAAsF;AACtF;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAEtD;AAuCD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAmB9C;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOpE"}
1
+ {"version":3,"file":"coord-client.d.ts","sourceRoot":"","sources":["../../../src/core/agents/coord-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAWhE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAI5E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CA+B7E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAeD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtD;AAiED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,mFAAmF;AACnF,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2CxD;AAgCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,GAAG,MAAM,CAAC;CAC5F,CAsEA;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsB5C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG;IAClD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,QAAQ,GAAG,iBAAiB,GAAG,MAAM,CAAC;CAC/C,CAyBA;AAyBD,sFAAsF;AACtF;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAEtD;AAuCD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAmB9C;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOpE"}
@@ -506,6 +506,10 @@ const SESSION_ID_ENV_VARS = [
506
506
  "CURSOR_CONVERSATION_ID",
507
507
  "CODEX_SESSION_ID",
508
508
  "CODEX_THREAD_ID",
509
+ // OpenCode exports no session id into the tool shell; the Harnery OpenCode
510
+ // plugin stamps this via shell.hook("create.before") so a coord CLI run as a
511
+ // Bash tool recovers its identity.
512
+ "OPENCODE_SESSION_ID",
509
513
  ];
510
514
  /** Read normalized candidates from the first non-empty adapter session-id env var. */
511
515
  /**
@@ -607,9 +611,10 @@ export function resolveSingleActiveOwner(root) {
607
611
  }
608
612
  function adapterCandidatesFromEnv() {
609
613
  const value = process.env.HARNERY_AGENT_COORD_PLATFORM?.trim();
610
- if (value === "claude-code" || value === "codex" || value === "cursor")
614
+ if (value === "claude-code" || value === "codex" || value === "cursor" || value === "opencode") {
611
615
  return [value];
612
- return ["claude-code", "codex", "cursor"];
616
+ }
617
+ return ["claude-code", "codex", "cursor", "opencode"];
613
618
  }
614
619
  function nativeOwnerForV3Instance(root, instanceId) {
615
620
  const activeDir = resolve(root, ".harnery", "active");
@@ -1 +1 @@
1
- {"version":3,"file":"claim-conflict.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/rules/claim-conflict.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAgBlD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,aAAa,CA4GjF"}
1
+ {"version":3,"file":"claim-conflict.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/rules/claim-conflict.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAgBlD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,aAAa,CA4GjF"}
@@ -16,6 +16,7 @@
16
16
  import { spawnSync } from "node:child_process";
17
17
  import { existsSync } from "node:fs";
18
18
  import { join } from "node:path";
19
+ import { adapterFromPlatform as sharedAdapterFromPlatform } from "../../adapter.js";
19
20
  import { recordLiveClaimChangeV3 } from "../live-authority-v3.js";
20
21
  import { readLiveCoordinationRows } from "../state/live-coordination-view.js";
21
22
  const FRESHNESS_SECS = 600;
@@ -211,7 +212,7 @@ function acquireClaimThroughLedger(coordRoot, req) {
211
212
  coordRoot,
212
213
  owner: req.instance_id,
213
214
  nativeSessionId: req.session_id ?? owner?.session_id ?? req.instance_id,
214
- adapter: adapterFromPlatform(owner?.platform),
215
+ adapter: sharedAdapterFromPlatform(owner?.platform, { context: "claim-conflict" }),
215
216
  operation: "acquired",
216
217
  path: req.path,
217
218
  access: "write",
@@ -230,7 +231,7 @@ function releaseClaimThroughLedger(coordRoot, subjectInstanceId, relPath, actor)
230
231
  owner: actor.instance_id,
231
232
  subject: subjectInstanceId,
232
233
  nativeSessionId: actor.session_id ?? owner?.session_id ?? actor.instance_id,
233
- adapter: adapterFromPlatform(owner?.platform),
234
+ adapter: sharedAdapterFromPlatform(owner?.platform, { context: "claim-conflict" }),
234
235
  operation: "released",
235
236
  path: relPath,
236
237
  access: "write",
@@ -241,13 +242,6 @@ function releaseClaimThroughLedger(coordRoot, subjectInstanceId, relPath, actor)
241
242
  return false;
242
243
  }
243
244
  }
244
- function adapterFromPlatform(platform) {
245
- if (platform === "cursor")
246
- return "cursor";
247
- if (platform === "codex")
248
- return "codex";
249
- return "claude-code";
250
- }
251
245
  function authorityUnavailable(path, operation) {
252
246
  return {
253
247
  allow: false,