harnery 0.40.0 → 0.42.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 (595) hide show
  1. package/README.md +1 -1
  2. package/dist/commander.js +4 -0
  3. package/dist/commands/agents.d.ts.map +1 -1
  4. package/dist/commands/agents.js +34 -20
  5. package/dist/commands/artifacts.d.ts.map +1 -1
  6. package/dist/commands/artifacts.js +113 -12
  7. package/dist/commands/browse-ai.d.ts.map +1 -1
  8. package/dist/commands/browse-ai.js +4 -0
  9. package/dist/commands/browse.d.ts +164 -0
  10. package/dist/commands/browse.d.ts.map +1 -1
  11. package/dist/commands/browse.js +388 -45
  12. package/dist/commands/checkpoint.js +8 -12
  13. package/dist/commands/claude-desktop.d.ts.map +1 -1
  14. package/dist/commands/claude-desktop.js +52 -0
  15. package/dist/commands/deinit.d.ts +1 -1
  16. package/dist/commands/deinit.d.ts.map +1 -1
  17. package/dist/commands/deinit.js +8 -4
  18. package/dist/commands/disk.d.ts +6 -0
  19. package/dist/commands/disk.d.ts.map +1 -0
  20. package/dist/commands/disk.js +80 -0
  21. package/dist/commands/docs.d.ts.map +1 -1
  22. package/dist/commands/docs.js +2 -0
  23. package/dist/commands/doctor.d.ts +8 -0
  24. package/dist/commands/doctor.d.ts.map +1 -1
  25. package/dist/commands/doctor.js +58 -3
  26. package/dist/commands/fetch.d.ts.map +1 -1
  27. package/dist/commands/fetch.js +10 -0
  28. package/dist/commands/files.d.ts +16 -0
  29. package/dist/commands/files.d.ts.map +1 -1
  30. package/dist/commands/files.js +54 -2
  31. package/dist/commands/init.d.ts +21 -5
  32. package/dist/commands/init.d.ts.map +1 -1
  33. package/dist/commands/init.js +271 -109
  34. package/dist/commands/instructions.js +5 -4
  35. package/dist/commands/ledger-v3.d.ts.map +1 -1
  36. package/dist/commands/ledger-v3.js +2 -1
  37. package/dist/commands/rm.d.ts +4 -0
  38. package/dist/commands/rm.d.ts.map +1 -0
  39. package/dist/commands/rm.js +87 -0
  40. package/dist/commands/servers.d.ts +7 -0
  41. package/dist/commands/servers.d.ts.map +1 -0
  42. package/dist/commands/servers.js +394 -0
  43. package/dist/commands/tunnel.d.ts.map +1 -1
  44. package/dist/commands/tunnel.js +82 -2
  45. package/dist/commands/webview.d.ts +4 -0
  46. package/dist/commands/webview.d.ts.map +1 -0
  47. package/dist/commands/webview.js +94 -0
  48. package/dist/core/adapter.d.ts +50 -1
  49. package/dist/core/adapter.d.ts.map +1 -1
  50. package/dist/core/adapter.js +59 -1
  51. package/dist/core/adapters/attestation.d.ts.map +1 -1
  52. package/dist/core/adapters/attestation.js +3 -2
  53. package/dist/core/adapters/profiles.d.ts +29 -3
  54. package/dist/core/adapters/profiles.d.ts.map +1 -1
  55. package/dist/core/adapters/profiles.js +53 -1
  56. package/dist/core/adapters/registry.d.ts.map +1 -1
  57. package/dist/core/adapters/registry.js +33 -0
  58. package/dist/core/adapters/types.d.ts +9 -0
  59. package/dist/core/adapters/types.d.ts.map +1 -1
  60. package/dist/core/agents/canonical-emit.d.ts +1 -1
  61. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  62. package/dist/core/agents/canonical-emit.js +2 -7
  63. package/dist/core/agents/cli.js +25 -16
  64. package/dist/core/agents/coord-client.d.ts.map +1 -1
  65. package/dist/core/agents/coord-client.js +7 -2
  66. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  67. package/dist/core/agents/render/session-context.js +2 -0
  68. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  69. package/dist/core/agents/rules/claim-conflict.js +3 -9
  70. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  71. package/dist/core/agents/rules/commit-conflict.js +2 -8
  72. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  73. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  74. package/dist/core/agents/rules/stop-hook.js +1 -1
  75. package/dist/core/agents/session-events.d.ts +6 -2
  76. package/dist/core/agents/session-events.d.ts.map +1 -1
  77. package/dist/core/agents/session-events.js +105 -26
  78. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
  79. package/dist/core/agents/session-finalization-state-v3.js +2 -1
  80. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  81. package/dist/core/agents/session-finalizer-v3.js +5 -4
  82. package/dist/core/agents/session-name-display.d.ts +28 -0
  83. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  84. package/dist/core/agents/session-name-display.js +43 -0
  85. package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
  86. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
  87. package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
  88. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  89. package/dist/core/agents/state/heartbeat-writer.js +21 -2
  90. package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
  91. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  92. package/dist/core/agents/state/live-coordination-view.js +61 -0
  93. package/dist/core/agents/state/live-coordination-writer.js +3 -0
  94. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  95. package/dist/core/agents/state/stale-sweep.js +2 -10
  96. package/dist/core/agents/turn-changes.d.ts +17 -0
  97. package/dist/core/agents/turn-changes.d.ts.map +1 -0
  98. package/dist/core/agents/turn-changes.js +76 -0
  99. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  100. package/dist/core/artifacts/delivery-card.js +11 -3
  101. package/dist/core/artifacts/index.d.ts +140 -4
  102. package/dist/core/artifacts/index.d.ts.map +1 -1
  103. package/dist/core/artifacts/index.js +526 -52
  104. package/dist/core/config.d.ts +73 -11
  105. package/dist/core/config.d.ts.map +1 -1
  106. package/dist/core/config.js +142 -3
  107. package/dist/core/context/index.d.ts.map +1 -1
  108. package/dist/core/context/index.js +2 -1
  109. package/dist/core/conversations/archive.d.ts.map +1 -1
  110. package/dist/core/conversations/archive.js +4 -3
  111. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  112. package/dist/core/diagnostics/bundle.js +5 -4
  113. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
  114. package/dist/core/events/legacy-storage/canary.js +5 -4
  115. package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
  116. package/dist/core/events/legacy-storage/compression.js +2 -1
  117. package/dist/core/events/v3/adapter-id.d.ts +10 -2
  118. package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
  119. package/dist/core/events/v3/adapter-id.js +16 -0
  120. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  121. package/dist/core/events/v3/authority-outbox.js +2 -1
  122. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  123. package/dist/core/events/v3/bootstrap.js +5 -4
  124. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  125. package/dist/core/events/v3/capabilities.js +17 -0
  126. package/dist/core/events/v3/contract.d.ts +5 -0
  127. package/dist/core/events/v3/contract.d.ts.map +1 -1
  128. package/dist/core/events/v3/contract.js +7 -1
  129. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  130. package/dist/core/events/v3/control-witness.js +3 -2
  131. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
  132. package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
  133. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
  134. package/dist/core/events/v3/fingerprint-keys.js +7 -6
  135. package/dist/core/events/v3/generated.d.ts +1 -1
  136. package/dist/core/events/v3/generated.js +1 -1
  137. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  138. package/dist/core/events/v3/live-feed.js +5 -4
  139. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  140. package/dist/core/events/v3/producers/command-recorder.js +8 -7
  141. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  142. package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
  143. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
  144. package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
  145. package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
  146. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  147. package/dist/core/events/v3/producers/hook-base.js +10 -4
  148. package/dist/core/events/v3/producers/hook.d.ts +2 -0
  149. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  150. package/dist/core/events/v3/producers/hook.js +16 -1
  151. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  152. package/dist/core/events/v3/producers/intake.js +16 -6
  153. package/dist/core/events/v3/producers/recorder.d.ts +2 -4
  154. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  155. package/dist/core/events/v3/producers/recorder.js +125 -101
  156. package/dist/core/events/v3/projection.js +9 -1
  157. package/dist/core/events/v3/recovery.d.ts.map +1 -1
  158. package/dist/core/events/v3/recovery.js +4 -3
  159. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
  160. package/dist/core/events/v3/support-storage/inventory.js +2 -1
  161. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
  162. package/dist/core/events/v3/support-storage/maintenance.js +4 -3
  163. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
  164. package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
  165. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
  166. package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
  167. package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
  168. package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
  169. package/dist/core/events/v3/tool-line-changes.js +135 -0
  170. package/dist/core/events/v3/writer.d.ts.map +1 -1
  171. package/dist/core/events/v3/writer.js +8 -7
  172. package/dist/core/governor/planning.d.ts.map +1 -1
  173. package/dist/core/governor/planning.js +6 -5
  174. package/dist/core/governor/service.d.ts.map +1 -1
  175. package/dist/core/governor/service.js +12 -11
  176. package/dist/core/governor/state.d.ts.map +1 -1
  177. package/dist/core/governor/state.js +7 -6
  178. package/dist/core/guard/evaluator.js +1 -0
  179. package/dist/core/guard/storage.d.ts.map +1 -1
  180. package/dist/core/guard/storage.js +3 -2
  181. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
  182. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
  183. package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
  184. package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
  185. package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
  186. package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
  187. package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
  188. package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
  189. package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
  190. package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
  191. package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
  192. package/dist/core/hooks/adapter/behaviors/index.js +20 -0
  193. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
  194. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
  195. package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
  196. package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
  197. package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
  198. package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
  199. package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
  200. package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
  201. package/dist/core/hooks/adapter/behaviors/types.js +1 -0
  202. package/dist/core/hooks/adapter/detect.d.ts +1 -1
  203. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  204. package/dist/core/hooks/adapter/detect.js +2 -3
  205. package/dist/core/hooks/adapter/events.d.ts +46 -1
  206. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  207. package/dist/core/hooks/adapter/events.js +36 -0
  208. package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
  209. package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
  210. package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
  211. package/dist/core/hooks/adapter/output.d.ts +7 -0
  212. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  213. package/dist/core/hooks/adapter/output.js +8 -1
  214. package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
  215. package/dist/core/hooks/adapter/wiring.d.ts +52 -8
  216. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  217. package/dist/core/hooks/adapter/wiring.js +133 -12
  218. package/dist/core/hooks/cli.js +676 -531
  219. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  220. package/dist/core/hooks/effects/image-capture.js +2 -1
  221. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
  222. package/dist/core/hooks/prompt-context/contract.js +1 -0
  223. package/dist/core/hooks/resolve/transcript.d.ts +1 -1
  224. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  225. package/dist/core/hooks/resolve/transcript.js +35 -4
  226. package/dist/core/hooks/run-markers.d.ts +37 -0
  227. package/dist/core/hooks/run-markers.d.ts.map +1 -0
  228. package/dist/core/hooks/run-markers.js +109 -0
  229. package/dist/core/hooks/session-name-presence.d.ts +3 -1
  230. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  231. package/dist/core/hooks/session-name-presence.js +7 -2
  232. package/dist/core/hooks/shell-waiter.d.ts +2 -0
  233. package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
  234. package/dist/core/hooks/shell-waiter.js +173 -0
  235. package/dist/core/resources/service.d.ts.map +1 -1
  236. package/dist/core/resources/service.js +5 -4
  237. package/dist/core/semantic/review.d.ts.map +1 -1
  238. package/dist/core/semantic/review.js +5 -4
  239. package/dist/core/semantic/service.d.ts.map +1 -1
  240. package/dist/core/semantic/service.js +15 -14
  241. package/dist/core/semantic/storage.d.ts.map +1 -1
  242. package/dist/core/semantic/storage.js +5 -4
  243. package/dist/core/servers/index.d.ts +211 -0
  244. package/dist/core/servers/index.d.ts.map +1 -0
  245. package/dist/core/servers/index.js +560 -0
  246. package/dist/core/servers/net.d.ts +58 -0
  247. package/dist/core/servers/net.d.ts.map +1 -0
  248. package/dist/core/servers/net.js +270 -0
  249. package/dist/core/servers/tunnels.d.ts +14 -0
  250. package/dist/core/servers/tunnels.d.ts.map +1 -0
  251. package/dist/core/servers/tunnels.js +33 -0
  252. package/dist/core/storage/atomic-json.d.ts.map +1 -1
  253. package/dist/core/storage/atomic-json.js +7 -3
  254. package/dist/core/storage/builtins.js +1 -0
  255. package/dist/core/storage/durable-history.d.ts.map +1 -1
  256. package/dist/core/storage/durable-history.js +6 -5
  257. package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
  258. package/dist/core/storage/maintenance-providers.js +2 -1
  259. package/dist/core/storage/maintenance.d.ts.map +1 -1
  260. package/dist/core/storage/maintenance.js +7 -6
  261. package/dist/core/storage/metrics.d.ts.map +1 -1
  262. package/dist/core/storage/metrics.js +5 -1
  263. package/dist/core/storage/modes.d.ts +17 -0
  264. package/dist/core/storage/modes.d.ts.map +1 -0
  265. package/dist/core/storage/modes.js +47 -0
  266. package/dist/core/storage/process-log.d.ts.map +1 -1
  267. package/dist/core/storage/process-log.js +3 -2
  268. package/dist/core/storage/receipts.d.ts.map +1 -1
  269. package/dist/core/storage/receipts.js +4 -3
  270. package/dist/core/storage/segments.d.ts.map +1 -1
  271. package/dist/core/storage/segments.js +7 -6
  272. package/dist/core/supervisor/hook-health.d.ts +2 -1
  273. package/dist/core/supervisor/hook-health.d.ts.map +1 -1
  274. package/dist/core/supervisor/hook-health.js +4 -3
  275. package/dist/core/supervisor/service.d.ts.map +1 -1
  276. package/dist/core/supervisor/service.js +7 -6
  277. package/dist/core/work/state.d.ts.map +1 -1
  278. package/dist/core/work/state.js +8 -7
  279. package/dist/core/workflow/adapters.d.ts +7 -0
  280. package/dist/core/workflow/adapters.d.ts.map +1 -1
  281. package/dist/core/workflow/adapters.js +9 -0
  282. package/dist/core/workflow/approvals.d.ts.map +1 -1
  283. package/dist/core/workflow/approvals.js +6 -5
  284. package/dist/core/workflow/billing.d.ts.map +1 -1
  285. package/dist/core/workflow/billing.js +33 -4
  286. package/dist/core/workflow/durable-record.d.ts.map +1 -1
  287. package/dist/core/workflow/durable-record.js +4 -3
  288. package/dist/core/workflow/engine.d.ts.map +1 -1
  289. package/dist/core/workflow/engine.js +30 -1
  290. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  291. package/dist/core/workflow/live-session-v3.js +2 -3
  292. package/dist/core/workflow/run-state.d.ts.map +1 -1
  293. package/dist/core/workflow/run-state.js +3 -2
  294. package/dist/core/workflow/sandbox-projection.d.ts +13 -2
  295. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  296. package/dist/core/workflow/sandbox-projection.js +23 -0
  297. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  298. package/dist/core/workflow/spawn-claude.js +6 -1
  299. package/dist/core/workflow/spawn-codex.d.ts +2 -0
  300. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  301. package/dist/core/workflow/spawn-codex.js +20 -1
  302. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  303. package/dist/core/workflow/spawn-cursor.js +6 -1
  304. package/dist/core/workflow/spawn-opencode.d.ts +36 -0
  305. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
  306. package/dist/core/workflow/spawn-opencode.js +135 -0
  307. package/dist/core/workflow/transcript.d.ts.map +1 -1
  308. package/dist/core/workflow/transcript.js +3 -2
  309. package/dist/core/workflow/types.d.ts +47 -2
  310. package/dist/core/workflow/types.d.ts.map +1 -1
  311. package/dist/core/workflow/worker-access.d.ts +92 -0
  312. package/dist/core/workflow/worker-access.d.ts.map +1 -0
  313. package/dist/core/workflow/worker-access.js +450 -0
  314. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  315. package/dist/core/workflow/workspaces/leases.js +5 -4
  316. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  317. package/dist/core/workflow/workspaces/local-git.js +3 -2
  318. package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
  319. package/dist/core/workflow/workspaces/paths.js +2 -1
  320. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  321. package/dist/core/workflow/workspaces/state.js +10 -9
  322. package/dist/lazy-commands.js +8 -1
  323. package/dist/lib/agent-browser/client.d.ts +9 -0
  324. package/dist/lib/agent-browser/client.d.ts.map +1 -1
  325. package/dist/lib/agent-browser/client.js +13 -0
  326. package/dist/lib/browser/batch-steps.d.ts +18 -0
  327. package/dist/lib/browser/batch-steps.d.ts.map +1 -0
  328. package/dist/lib/browser/batch-steps.js +82 -0
  329. package/dist/lib/browser/client.d.ts +35 -1
  330. package/dist/lib/browser/client.d.ts.map +1 -1
  331. package/dist/lib/browser/client.js +117 -8
  332. package/dist/lib/browser/collect/collector.d.ts +99 -0
  333. package/dist/lib/browser/collect/collector.d.ts.map +1 -0
  334. package/dist/lib/browser/collect/collector.js +202 -0
  335. package/dist/lib/browser/collect/fields.d.ts +31 -0
  336. package/dist/lib/browser/collect/fields.d.ts.map +1 -0
  337. package/dist/lib/browser/collect/fields.js +75 -0
  338. package/dist/lib/browser/collect/index.d.ts +6 -0
  339. package/dist/lib/browser/collect/index.d.ts.map +1 -0
  340. package/dist/lib/browser/collect/index.js +5 -0
  341. package/dist/lib/browser/collect/page-driver.d.ts +14 -0
  342. package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
  343. package/dist/lib/browser/collect/page-driver.js +306 -0
  344. package/dist/lib/browser/collect/presets.d.ts +52 -0
  345. package/dist/lib/browser/collect/presets.d.ts.map +1 -0
  346. package/dist/lib/browser/collect/presets.js +176 -0
  347. package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
  348. package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
  349. package/dist/lib/browser/collect/scroll-plan.js +118 -0
  350. package/dist/lib/browser/identity.d.ts +25 -0
  351. package/dist/lib/browser/identity.d.ts.map +1 -0
  352. package/dist/lib/browser/identity.js +66 -0
  353. package/dist/lib/browser/index.d.ts +3 -2
  354. package/dist/lib/browser/index.d.ts.map +1 -1
  355. package/dist/lib/browser/index.js +2 -1
  356. package/dist/lib/browser/launch-args.d.ts +26 -0
  357. package/dist/lib/browser/launch-args.d.ts.map +1 -1
  358. package/dist/lib/browser/launch-args.js +41 -1
  359. package/dist/lib/browser/page-review-judge.d.ts +2 -0
  360. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  361. package/dist/lib/browser/page-review-judge.js +13 -0
  362. package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
  363. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  364. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  365. package/dist/lib/browser/qa-run.js +1 -0
  366. package/dist/lib/browser/user-agent.d.ts +53 -0
  367. package/dist/lib/browser/user-agent.d.ts.map +1 -0
  368. package/dist/lib/browser/user-agent.js +79 -0
  369. package/dist/lib/browser/windows-chrome.d.ts +59 -0
  370. package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
  371. package/dist/lib/browser/windows-chrome.js +179 -0
  372. package/dist/lib/claude-desktop-share.d.ts +136 -0
  373. package/dist/lib/claude-desktop-share.d.ts.map +1 -0
  374. package/dist/lib/claude-desktop-share.js +394 -0
  375. package/dist/lib/disk-usage.d.ts +50 -0
  376. package/dist/lib/disk-usage.d.ts.map +1 -0
  377. package/dist/lib/disk-usage.js +303 -0
  378. package/dist/lib/docs-lint.d.ts +6 -0
  379. package/dist/lib/docs-lint.d.ts.map +1 -1
  380. package/dist/lib/docs-lint.js +8 -3
  381. package/dist/lib/docs-metadata-managed.d.ts +1 -0
  382. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  383. package/dist/lib/docs-metadata-managed.js +17 -1
  384. package/dist/lib/guarded-remove.d.ts +34 -0
  385. package/dist/lib/guarded-remove.d.ts.map +1 -0
  386. package/dist/lib/guarded-remove.js +310 -0
  387. package/dist/lib/identities/assume.d.ts.map +1 -1
  388. package/dist/lib/identities/assume.js +4 -9
  389. package/dist/lib/instructions/apply.d.ts.map +1 -1
  390. package/dist/lib/instructions/apply.js +2 -0
  391. package/dist/lib/instructions/templates.js +8 -8
  392. package/dist/lib/pace/index.d.ts +2 -0
  393. package/dist/lib/pace/index.d.ts.map +1 -0
  394. package/dist/lib/pace/index.js +1 -0
  395. package/dist/lib/pace/pace.d.ts +95 -0
  396. package/dist/lib/pace/pace.d.ts.map +1 -0
  397. package/dist/lib/pace/pace.js +313 -0
  398. package/dist/lib/tunnel/error-page.d.ts +1 -1
  399. package/dist/lib/tunnel/error-page.d.ts.map +1 -1
  400. package/dist/lib/tunnel/error-page.js +19 -8
  401. package/dist/lib/tunnel/forward-headers.d.ts +11 -0
  402. package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
  403. package/dist/lib/tunnel/forward-headers.js +17 -0
  404. package/dist/lib/tunnel/gate.js +34 -10
  405. package/dist/lib/tunnel/path-scope.d.ts +22 -0
  406. package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
  407. package/dist/lib/tunnel/path-scope.js +62 -0
  408. package/dist/lib/tunnel/state.d.ts +5 -0
  409. package/dist/lib/tunnel/state.d.ts.map +1 -1
  410. package/dist/lib/tunnel/state.js +17 -3
  411. package/dist/lib/webview/index.d.ts +2 -0
  412. package/dist/lib/webview/index.d.ts.map +1 -0
  413. package/dist/lib/webview/index.js +1 -0
  414. package/dist/lib/webview/webview.d.ts +116 -0
  415. package/dist/lib/webview/webview.d.ts.map +1 -0
  416. package/dist/lib/webview/webview.js +289 -0
  417. package/opencode-plugin/package.json +19 -0
  418. package/opencode-plugin/src/index.ts +791 -0
  419. package/package.json +16 -4
  420. package/schemas/config.schema.json +104 -0
  421. package/schemas/event-v3.schema.json +164 -0
  422. package/src/commander.ts +26 -0
  423. package/src/commands/agents.ts +47 -18
  424. package/src/commands/artifacts.ts +171 -19
  425. package/src/commands/browse-ai.ts +8 -0
  426. package/src/commands/browse.ts +570 -48
  427. package/src/commands/checkpoint.ts +7 -9
  428. package/src/commands/claude-desktop.ts +61 -0
  429. package/src/commands/deinit.ts +9 -4
  430. package/src/commands/disk.ts +114 -0
  431. package/src/commands/docs.ts +2 -0
  432. package/src/commands/doctor.ts +63 -3
  433. package/src/commands/fetch.ts +14 -0
  434. package/src/commands/files.ts +93 -2
  435. package/src/commands/init.ts +334 -122
  436. package/src/commands/instructions.ts +8 -4
  437. package/src/commands/ledger-v3.ts +2 -1
  438. package/src/commands/rm.ts +115 -0
  439. package/src/commands/servers.ts +506 -0
  440. package/src/commands/tunnel.ts +102 -2
  441. package/src/commands/webview.ts +159 -0
  442. package/src/core/adapter.ts +102 -1
  443. package/src/core/adapters/attestation.ts +3 -2
  444. package/src/core/adapters/profiles.ts +63 -1
  445. package/src/core/adapters/registry.ts +37 -0
  446. package/src/core/adapters/types.ts +10 -0
  447. package/src/core/agents/canonical-emit.ts +2 -5
  448. package/src/core/agents/cli.ts +26 -17
  449. package/src/core/agents/coord-client.ts +9 -3
  450. package/src/core/agents/render/session-context.ts +1 -0
  451. package/src/core/agents/rules/claim-conflict.ts +3 -8
  452. package/src/core/agents/rules/commit-conflict.ts +2 -7
  453. package/src/core/agents/rules/stop-hook.ts +3 -1
  454. package/src/core/agents/session-events.ts +120 -26
  455. package/src/core/agents/session-finalization-state-v3.ts +2 -1
  456. package/src/core/agents/session-finalizer-v3.ts +5 -4
  457. package/src/core/agents/session-name-display.ts +48 -0
  458. package/src/core/agents/state/heartbeat-reader.ts +7 -0
  459. package/src/core/agents/state/heartbeat-writer.ts +24 -2
  460. package/src/core/agents/state/live-coordination-view.ts +74 -0
  461. package/src/core/agents/state/live-coordination-writer.ts +3 -0
  462. package/src/core/agents/state/stale-sweep.ts +2 -9
  463. package/src/core/agents/turn-changes.ts +97 -0
  464. package/src/core/artifacts/delivery-card.ts +12 -3
  465. package/src/core/artifacts/index.ts +701 -47
  466. package/src/core/config.ts +206 -4
  467. package/src/core/context/index.ts +2 -1
  468. package/src/core/conversations/archive.ts +4 -3
  469. package/src/core/diagnostics/bundle.ts +5 -3
  470. package/src/core/events/legacy-storage/canary.ts +5 -4
  471. package/src/core/events/legacy-storage/compression.ts +2 -1
  472. package/src/core/events/v3/adapter-id.ts +29 -1
  473. package/src/core/events/v3/authority-outbox.ts +2 -1
  474. package/src/core/events/v3/bootstrap.ts +5 -4
  475. package/src/core/events/v3/capabilities.ts +17 -0
  476. package/src/core/events/v3/contract.ts +9 -1
  477. package/src/core/events/v3/control-witness.ts +3 -2
  478. package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
  479. package/src/core/events/v3/fingerprint-keys.ts +7 -6
  480. package/src/core/events/v3/generated.ts +1 -1
  481. package/src/core/events/v3/live-feed.ts +5 -4
  482. package/src/core/events/v3/producers/command-recorder.ts +8 -6
  483. package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
  484. package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
  485. package/src/core/events/v3/producers/hook-base.ts +11 -4
  486. package/src/core/events/v3/producers/hook.ts +19 -1
  487. package/src/core/events/v3/producers/intake.ts +18 -6
  488. package/src/core/events/v3/producers/recorder.ts +139 -114
  489. package/src/core/events/v3/projection.ts +11 -1
  490. package/src/core/events/v3/recovery.ts +4 -3
  491. package/src/core/events/v3/support-storage/inventory.ts +2 -1
  492. package/src/core/events/v3/support-storage/maintenance.ts +8 -3
  493. package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
  494. package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
  495. package/src/core/events/v3/tool-line-changes.ts +139 -0
  496. package/src/core/events/v3/writer.ts +8 -7
  497. package/src/core/governor/planning.ts +6 -5
  498. package/src/core/governor/service.ts +12 -11
  499. package/src/core/governor/state.ts +7 -6
  500. package/src/core/guard/evaluator.ts +1 -0
  501. package/src/core/guard/storage.ts +3 -2
  502. package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
  503. package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
  504. package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
  505. package/src/core/hooks/adapter/behaviors/index.ts +31 -0
  506. package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
  507. package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
  508. package/src/core/hooks/adapter/behaviors/types.ts +110 -0
  509. package/src/core/hooks/adapter/detect.ts +2 -3
  510. package/src/core/hooks/adapter/events.ts +72 -1
  511. package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
  512. package/src/core/hooks/adapter/output.ts +8 -1
  513. package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
  514. package/src/core/hooks/adapter/wiring.ts +198 -16
  515. package/src/core/hooks/cli.ts +776 -539
  516. package/src/core/hooks/effects/image-capture.ts +2 -1
  517. package/src/core/hooks/prompt-context/contract.ts +1 -0
  518. package/src/core/hooks/resolve/transcript.ts +42 -5
  519. package/src/core/hooks/run-markers.ts +132 -0
  520. package/src/core/hooks/session-name-presence.ts +10 -3
  521. package/src/core/hooks/shell-waiter.ts +166 -0
  522. package/src/core/resources/service.ts +5 -4
  523. package/src/core/semantic/review.ts +5 -4
  524. package/src/core/semantic/service.ts +15 -14
  525. package/src/core/semantic/storage.ts +5 -4
  526. package/src/core/servers/index.ts +712 -0
  527. package/src/core/servers/net.ts +283 -0
  528. package/src/core/servers/tunnels.ts +39 -0
  529. package/src/core/storage/atomic-json.ts +7 -3
  530. package/src/core/storage/builtins.ts +1 -0
  531. package/src/core/storage/durable-history.ts +6 -5
  532. package/src/core/storage/maintenance-providers.ts +2 -1
  533. package/src/core/storage/maintenance.ts +7 -6
  534. package/src/core/storage/metrics.ts +5 -1
  535. package/src/core/storage/modes.ts +53 -0
  536. package/src/core/storage/process-log.ts +3 -2
  537. package/src/core/storage/receipts.ts +4 -3
  538. package/src/core/storage/segments.ts +7 -6
  539. package/src/core/supervisor/hook-health.ts +4 -4
  540. package/src/core/supervisor/service.ts +7 -6
  541. package/src/core/work/state.ts +8 -7
  542. package/src/core/workflow/adapters.ts +15 -0
  543. package/src/core/workflow/approvals.ts +6 -5
  544. package/src/core/workflow/billing.ts +34 -4
  545. package/src/core/workflow/durable-record.ts +4 -3
  546. package/src/core/workflow/engine.ts +38 -1
  547. package/src/core/workflow/live-session-v3.ts +2 -3
  548. package/src/core/workflow/run-state.ts +3 -2
  549. package/src/core/workflow/sandbox-projection.ts +38 -2
  550. package/src/core/workflow/spawn-claude.ts +5 -1
  551. package/src/core/workflow/spawn-codex.ts +18 -1
  552. package/src/core/workflow/spawn-cursor.ts +5 -1
  553. package/src/core/workflow/spawn-opencode.ts +153 -0
  554. package/src/core/workflow/transcript.ts +3 -2
  555. package/src/core/workflow/types.ts +62 -2
  556. package/src/core/workflow/worker-access.ts +525 -0
  557. package/src/core/workflow/workspaces/leases.ts +5 -4
  558. package/src/core/workflow/workspaces/local-git.ts +3 -2
  559. package/src/core/workflow/workspaces/paths.ts +2 -1
  560. package/src/core/workflow/workspaces/state.ts +10 -9
  561. package/src/lazy-commands.ts +11 -1
  562. package/src/lib/agent-browser/client.ts +18 -0
  563. package/src/lib/browser/batch-steps.ts +79 -0
  564. package/src/lib/browser/client.ts +147 -9
  565. package/src/lib/browser/collect/collector.ts +306 -0
  566. package/src/lib/browser/collect/fields.ts +87 -0
  567. package/src/lib/browser/collect/index.ts +47 -0
  568. package/src/lib/browser/collect/page-driver.ts +327 -0
  569. package/src/lib/browser/collect/presets.ts +237 -0
  570. package/src/lib/browser/collect/scroll-plan.ts +179 -0
  571. package/src/lib/browser/identity.ts +64 -0
  572. package/src/lib/browser/index.ts +16 -1
  573. package/src/lib/browser/launch-args.ts +53 -1
  574. package/src/lib/browser/page-review-judge.ts +16 -0
  575. package/src/lib/browser/qa-run-contracts.ts +11 -0
  576. package/src/lib/browser/qa-run.ts +1 -0
  577. package/src/lib/browser/user-agent.ts +130 -0
  578. package/src/lib/browser/windows-chrome.ts +227 -0
  579. package/src/lib/claude-desktop-share.ts +511 -0
  580. package/src/lib/disk-usage.ts +347 -0
  581. package/src/lib/docs-lint.ts +8 -3
  582. package/src/lib/docs-metadata-managed.ts +21 -0
  583. package/src/lib/guarded-remove.ts +376 -0
  584. package/src/lib/identities/assume.ts +7 -7
  585. package/src/lib/instructions/apply.ts +2 -0
  586. package/src/lib/instructions/templates.ts +8 -8
  587. package/src/lib/pace/index.ts +14 -0
  588. package/src/lib/pace/pace.ts +370 -0
  589. package/src/lib/tunnel/error-page.ts +25 -9
  590. package/src/lib/tunnel/forward-headers.ts +16 -0
  591. package/src/lib/tunnel/gate.ts +39 -10
  592. package/src/lib/tunnel/path-scope.ts +73 -0
  593. package/src/lib/tunnel/state.ts +20 -3
  594. package/src/lib/webview/index.ts +13 -0
  595. package/src/lib/webview/webview.ts +457 -0
@@ -0,0 +1,791 @@
1
+ /**
2
+ * Harnery OpenCode plugin: bridges OpenCode V2 in-process lifecycle hooks to
3
+ * `agent-hook <subcommand> --adapter opencode`, so an interactive OpenCode
4
+ * session (TUI, `opencode run`, the desktop app) produces the same Event Ledger
5
+ * V3 evidence as a Claude Code, Cursor, or Codex session.
6
+ *
7
+ * OpenCode V2 has no settings-file command hooks; its only interception point
8
+ * is a plugin loaded into the shared background service. `harn init --adapter
9
+ * opencode` copies this file, verbatim under a hash-stamped ownership header,
10
+ * to `.opencode/plugins/harnery/index.ts` with a sibling `harnery.json` that
11
+ * names the `agent-hook` launcher. OpenCode auto-discovers that directory, so
12
+ * no `opencode.json` edit is needed.
13
+ *
14
+ * Contract this file keeps, because it is copied into consumer repositories:
15
+ * - self-contained: `node:*` imports only, no relative imports, no Harnery
16
+ * package imports (the consumer may not have Harnery resolvable from here);
17
+ * - fail-open: a hook that cannot reach `agent-hook` logs and returns, so a
18
+ * broken bridge never breaks the operator's OpenCode session;
19
+ * - observe-only at turn end: OpenCode has no blocking Stop channel, so the
20
+ * `stop` verdict is recorded but never re-prompts.
21
+ *
22
+ * Event map (OpenCode → agent-hook subcommand), kept in sync with
23
+ * `OPENCODE_EVENTS` in `src/core/hooks/adapter/events.ts`:
24
+ * event session.created → session-start (child → sub-agent-start)
25
+ * session.hook("prompt") → user-prompt-submit
26
+ * tool.hook("execute.before") → pre-tool-use (deny → throw)
27
+ * tool.hook("execute.after") → post-tool-use | post-tool-use-failure
28
+ * permission.hook("evaluate") → permission-request
29
+ * session.hook("compaction") → pre-compact
30
+ * event session.execution.succeeded → stop (child → sub-agent-stop)
31
+ * event session.execution.failed → stop-failure (child → sub-agent-stop)
32
+ * event session.execution.interrupted → stop-failure (child → sub-agent-stop)
33
+ * event session.deleted → session-end
34
+ * shell.hook("create.before") → stamps OPENCODE_SESSION_ID into the tool shell
35
+ */
36
+
37
+ import { spawn } from "node:child_process";
38
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
39
+ import { homedir } from "node:os";
40
+ import { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
41
+ import { fileURLToPath } from "node:url";
42
+
43
+ export const HARNERY_OPENCODE_PLUGIN_ID = "harnery";
44
+ export const HARNERY_OPENCODE_CONFIG_FILE = "harnery.json";
45
+ export const HARNERY_OPENCODE_CONFIG_SCHEMA = "harnery-opencode-plugin/v1";
46
+ /** Env var the shell hook stamps so a coord CLI run as a tool recovers its session. */
47
+ export const OPENCODE_SESSION_ENV = "OPENCODE_SESSION_ID";
48
+ const ADAPTER = "opencode";
49
+ const DEFAULT_TIMEOUT_MS = 20_000;
50
+ const CONTEXT_DESCRIPTION = "Harnery coordination context";
51
+
52
+ // ── OpenCode plugin API (the subset this plugin touches) ─────────────────────
53
+
54
+ export interface OpenCodeRegistration {
55
+ dispose(): Promise<void>;
56
+ }
57
+ export interface OpenCodeToolBefore {
58
+ tool: string;
59
+ readonly sessionID: string;
60
+ readonly agent?: string;
61
+ readonly messageID?: string;
62
+ readonly id: string;
63
+ input: unknown;
64
+ }
65
+ export type OpenCodeToolAfter = {
66
+ readonly tool: string;
67
+ readonly sessionID: string;
68
+ readonly agent?: string;
69
+ readonly messageID?: string;
70
+ readonly id: string;
71
+ readonly input: unknown;
72
+ } & (
73
+ | { readonly status: "completed"; result: unknown }
74
+ | { readonly status: "error"; error: unknown }
75
+ );
76
+ export interface OpenCodeSessionPrompt {
77
+ readonly sessionID: string;
78
+ readonly messageID?: string;
79
+ prompt: { text?: string; [k: string]: unknown };
80
+ metadata?: Record<string, unknown>;
81
+ delivery?: string;
82
+ }
83
+ export interface OpenCodeSystemPart {
84
+ type: "text";
85
+ text: string;
86
+ [k: string]: unknown;
87
+ }
88
+ export interface OpenCodeSessionRequest {
89
+ readonly sessionID: string;
90
+ readonly agent?: string;
91
+ readonly model?: { providerID?: string; id?: string; variant?: string };
92
+ system: OpenCodeSystemPart[];
93
+ [k: string]: unknown;
94
+ }
95
+ export interface OpenCodePermissionEvaluation {
96
+ readonly sessionID: string;
97
+ readonly agent?: string;
98
+ readonly action: string;
99
+ readonly resources: ReadonlyArray<string>;
100
+ readonly metadata?: Record<string, unknown>;
101
+ readonly source?: { type?: string; messageID?: string; id?: string };
102
+ effect: "allow" | "ask" | "deny";
103
+ message?: string;
104
+ }
105
+ export interface OpenCodeShellCreateBefore {
106
+ command: string;
107
+ cwd: string;
108
+ timeout?: number;
109
+ shell?: string;
110
+ env: Record<string, string | undefined>;
111
+ }
112
+ export interface OpenCodeBusEvent {
113
+ id?: string;
114
+ created?: number;
115
+ type: string;
116
+ location?: { directory?: string };
117
+ data?: Record<string, unknown>;
118
+ }
119
+ type Hook<T> = (
120
+ name: string,
121
+ callback: (event: T) => Promise<void> | void,
122
+ ) => Promise<OpenCodeRegistration>;
123
+ export interface OpenCodePluginContext {
124
+ readonly location: { directory: string; project?: { id?: string; directory?: string } };
125
+ readonly options?: Record<string, unknown>;
126
+ readonly session: {
127
+ hook: Hook<OpenCodeSessionPrompt | OpenCodeSessionRequest>;
128
+ synthetic(input: { sessionID: string; text: string; description?: string }): Promise<unknown>;
129
+ };
130
+ readonly tool: { hook: Hook<OpenCodeToolBefore | OpenCodeToolAfter> };
131
+ readonly permission: { hook: Hook<OpenCodePermissionEvaluation> };
132
+ readonly shell: { hook: Hook<OpenCodeShellCreateBefore> };
133
+ readonly event: {
134
+ subscribe(options?: { signal?: AbortSignal }): AsyncIterable<OpenCodeBusEvent>;
135
+ };
136
+ }
137
+
138
+ // ── Configuration ────────────────────────────────────────────────────────────
139
+
140
+ export interface HarneryOpenCodeConfig {
141
+ schema: string;
142
+ /** `agent-hook` launcher: repo-relative path (run through `bash`) or the bare `agent-hook` on PATH. */
143
+ agentHook: string;
144
+ /** Project root that `agent-hook` resolves its coord root from (its cwd). */
145
+ projectRoot: string;
146
+ timeoutMs: number;
147
+ }
148
+
149
+ /**
150
+ * Resolve the plugin's config from the sibling `harnery.json`. The plugin lives
151
+ * at `<root>/.opencode/plugins/harnery/index.ts`, so the project root is three
152
+ * directories up; `agentHook` is relative to that root, as `harn init` writes it.
153
+ */
154
+ export function loadHarneryOpenCodeConfig(pluginDir: string): HarneryOpenCodeConfig {
155
+ const projectRoot = resolve(pluginDir, "..", "..", "..");
156
+ let agentHook = "agent-hook";
157
+ let timeoutMs = DEFAULT_TIMEOUT_MS;
158
+ const path = resolve(pluginDir, HARNERY_OPENCODE_CONFIG_FILE);
159
+ if (existsSync(path)) {
160
+ try {
161
+ const parsed = JSON.parse(readFileSync(path, "utf8")) as {
162
+ agentHook?: unknown;
163
+ timeoutMs?: unknown;
164
+ };
165
+ if (typeof parsed.agentHook === "string" && parsed.agentHook.length > 0) {
166
+ agentHook = parsed.agentHook;
167
+ }
168
+ if (typeof parsed.timeoutMs === "number" && parsed.timeoutMs > 0) {
169
+ timeoutMs = parsed.timeoutMs;
170
+ }
171
+ } catch {
172
+ /* unreadable config → PATH launcher, default timeout */
173
+ }
174
+ }
175
+ return { schema: HARNERY_OPENCODE_CONFIG_SCHEMA, agentHook, projectRoot, timeoutMs };
176
+ }
177
+
178
+ /** argv for one bridge call, mirroring `hookCommand` in `src/core/hooks/adapter/wiring.ts`. */
179
+ export function agentHookArgv(config: HarneryOpenCodeConfig, subcommand: string): string[] {
180
+ const tail = [subcommand, "--adapter", ADAPTER];
181
+ if (config.agentHook === "agent-hook") return ["agent-hook", ...tail];
182
+ const launcher = isAbsolute(config.agentHook)
183
+ ? config.agentHook
184
+ : resolve(config.projectRoot, config.agentHook);
185
+ return ["bash", launcher, ...tail];
186
+ }
187
+
188
+ /**
189
+ * Directories a tool shell needs so the project's bare launchers resolve: its
190
+ * own `bin/`, plus whichever Bun install directory exists (a project launcher is
191
+ * commonly a shim that execs `bun`). Only existing directories are returned, so
192
+ * a PATH is never padded with dead entries.
193
+ */
194
+ export function shellPathDirs(projectRoot: string, home = homedir()): string[] {
195
+ const dirs = [join(projectRoot, "bin")];
196
+ for (const bin of [join(home, ".bun", "bin"), "/usr/local/bin", "/opt/homebrew/bin"]) {
197
+ if (existsSync(join(bin, "bun"))) dirs.push(bin);
198
+ }
199
+ return dirs.filter((dir) => existsSync(dir));
200
+ }
201
+
202
+ /**
203
+ * Prepend {@link shellPathDirs} to a tool shell's PATH, preserving order and
204
+ * skipping entries already present. An OpenCode server can start from a
205
+ * GUI-launched environment whose PATH lacks the project's own tools, which would
206
+ * make an otherwise-valid `bin/<launcher>` call fail as "command not found".
207
+ */
208
+ export function prependShellPath(
209
+ env: Record<string, string | undefined>,
210
+ projectRoot: string,
211
+ home = homedir(),
212
+ ): void {
213
+ const current = env.PATH ?? process.env.PATH ?? "";
214
+ const parts = current.split(delimiter).filter((part) => part.length > 0);
215
+ const additions = shellPathDirs(projectRoot, home).filter((dir) => !parts.includes(dir));
216
+ env.PATH = [...additions, ...parts].join(delimiter);
217
+ }
218
+
219
+ // ── Payload translation (pure; unit-tested) ──────────────────────────────────
220
+
221
+ export type HookPayload = Record<string, unknown>;
222
+
223
+ /**
224
+ * OpenCode names tools in lowercase (`shell`, `read`, `edit`); Harnery's
225
+ * parsers key command extraction on `Bash`/`Shell` and target hashing on the
226
+ * capitalized Claude Code names, so capitalize and map `shell` → `Shell`.
227
+ */
228
+ export function harneryToolName(tool: string | undefined): string {
229
+ if (!tool) return "unknown";
230
+ if (tool === "shell" || tool === "bash") return tool === "shell" ? "Shell" : "Bash";
231
+ return tool.charAt(0).toUpperCase() + tool.slice(1);
232
+ }
233
+
234
+ function modelLabel(model: unknown): string | undefined {
235
+ if (!model || typeof model !== "object") return undefined;
236
+ const m = model as { providerID?: unknown; id?: unknown; variant?: unknown };
237
+ if (typeof m.id !== "string") return undefined;
238
+ const base = typeof m.providerID === "string" ? `${m.providerID}/${m.id}` : m.id;
239
+ return typeof m.variant === "string" && m.variant ? `${base}#${m.variant}` : base;
240
+ }
241
+
242
+ function str(value: unknown): string | undefined {
243
+ return typeof value === "string" && value.length > 0 ? value : undefined;
244
+ }
245
+
246
+ export function sessionStartPayload(data: Record<string, unknown>, cwd: string): HookPayload {
247
+ return {
248
+ hook_event_name: "SessionStart",
249
+ session_id: data.sessionID,
250
+ cwd: str(data.directory) ?? cwd,
251
+ source: "startup",
252
+ ...(str(data.parentID) ? { parent_session_id: data.parentID } : {}),
253
+ ...(modelLabel(data.model) ? { model: modelLabel(data.model) } : {}),
254
+ };
255
+ }
256
+
257
+ export function subagentStartPayload(data: Record<string, unknown>, cwd: string): HookPayload {
258
+ return {
259
+ hook_event_name: "SubagentStart",
260
+ session_id: data.parentID,
261
+ parent_session_id: data.parentID,
262
+ subagent_id: data.sessionID,
263
+ agent_type: str(data.agent) ?? "subagent",
264
+ cwd: str(data.directory) ?? cwd,
265
+ };
266
+ }
267
+
268
+ export function promptPayload(event: OpenCodeSessionPrompt, cwd: string): HookPayload {
269
+ return {
270
+ hook_event_name: "UserPromptSubmit",
271
+ session_id: event.sessionID,
272
+ cwd,
273
+ ...(event.messageID ? { turn_id: event.messageID } : {}),
274
+ ...(typeof event.prompt?.text === "string" ? { prompt: event.prompt.text } : {}),
275
+ };
276
+ }
277
+
278
+ export function toolBeforePayload(event: OpenCodeToolBefore, cwd: string): HookPayload {
279
+ return {
280
+ hook_event_name: "PreToolUse",
281
+ session_id: event.sessionID,
282
+ cwd,
283
+ ...(event.messageID ? { turn_id: event.messageID } : {}),
284
+ tool_name: harneryToolName(event.tool),
285
+ tool_input: event.input ?? null,
286
+ tool_use_id: event.id,
287
+ };
288
+ }
289
+
290
+ export function toolAfterPayload(
291
+ event: OpenCodeToolAfter,
292
+ cwd: string,
293
+ ): { subcommand: "post-tool-use" | "post-tool-use-failure"; payload: HookPayload } {
294
+ const base = {
295
+ session_id: event.sessionID,
296
+ cwd,
297
+ ...(event.messageID ? { turn_id: event.messageID } : {}),
298
+ tool_name: harneryToolName(event.tool),
299
+ tool_input: event.input ?? null,
300
+ tool_use_id: event.id,
301
+ };
302
+ if (event.status === "error") {
303
+ return {
304
+ subcommand: "post-tool-use-failure",
305
+ payload: {
306
+ hook_event_name: "PostToolUseFailure",
307
+ ...base,
308
+ tool_response: errorText(event.error),
309
+ reason: errorText(event.error),
310
+ },
311
+ };
312
+ }
313
+ return {
314
+ subcommand: "post-tool-use",
315
+ payload: {
316
+ hook_event_name: "PostToolUse",
317
+ ...base,
318
+ tool_response: toolResultText(event.result),
319
+ },
320
+ };
321
+ }
322
+
323
+ /** Flatten an OpenCode `Tool.Result` to the text agent-hook summarizes. */
324
+ export function toolResultText(result: unknown): unknown {
325
+ if (!result || typeof result !== "object") return result;
326
+ const r = result as { output?: unknown; content?: unknown };
327
+ if (typeof r.output === "string") return r.output;
328
+ if (typeof r.content === "string") return r.content;
329
+ if (Array.isArray(r.content)) {
330
+ const texts = r.content
331
+ .map((part) =>
332
+ part && typeof part === "object" ? (part as { text?: unknown }).text : undefined,
333
+ )
334
+ .filter((t): t is string => typeof t === "string");
335
+ if (texts.length > 0) return texts.join("\n");
336
+ }
337
+ return result;
338
+ }
339
+
340
+ function errorText(error: unknown): string {
341
+ if (error instanceof Error) return error.message;
342
+ if (
343
+ error &&
344
+ typeof error === "object" &&
345
+ typeof (error as { message?: unknown }).message === "string"
346
+ ) {
347
+ return (error as { message: string }).message;
348
+ }
349
+ return typeof error === "string" ? error : JSON.stringify(error ?? null);
350
+ }
351
+
352
+ export function permissionPayload(event: OpenCodePermissionEvaluation, cwd: string): HookPayload {
353
+ return {
354
+ hook_event_name: "PermissionRequest",
355
+ session_id: event.sessionID,
356
+ cwd,
357
+ tool_name: harneryToolName(event.action),
358
+ tool_input: {
359
+ resources: [...event.resources],
360
+ ...(event.message ? { description: event.message } : {}),
361
+ effect: event.effect,
362
+ },
363
+ ...(event.source?.id ? { tool_use_id: event.source.id } : {}),
364
+ };
365
+ }
366
+
367
+ export function compactionPayload(event: OpenCodeSessionRequest, cwd: string): HookPayload {
368
+ return {
369
+ hook_event_name: "PreCompact",
370
+ session_id: event.sessionID,
371
+ cwd,
372
+ trigger: "auto",
373
+ ...(modelLabel(event.model) ? { model: modelLabel(event.model) } : {}),
374
+ };
375
+ }
376
+
377
+ export function turnEndPayload(
378
+ type:
379
+ | "session.execution.succeeded"
380
+ | "session.execution.failed"
381
+ | "session.execution.interrupted",
382
+ data: Record<string, unknown>,
383
+ cwd: string,
384
+ child: boolean,
385
+ ): { subcommand: "stop" | "stop-failure" | "sub-agent-stop"; payload: HookPayload } {
386
+ const ok = type === "session.execution.succeeded";
387
+ const status = ok ? "ok" : type === "session.execution.failed" ? "error" : "interrupted";
388
+ const reason = ok ? undefined : (str(data.reason) ?? errorText(data.error));
389
+ if (child) {
390
+ return {
391
+ subcommand: "sub-agent-stop",
392
+ payload: {
393
+ hook_event_name: "SubagentStop",
394
+ session_id: data.sessionID,
395
+ cwd,
396
+ exit_status: status,
397
+ ...(reason ? { reason } : {}),
398
+ },
399
+ };
400
+ }
401
+ if (ok) {
402
+ return {
403
+ subcommand: "stop",
404
+ payload: {
405
+ hook_event_name: "Stop",
406
+ session_id: data.sessionID,
407
+ cwd,
408
+ stop_hook_active: false,
409
+ },
410
+ };
411
+ }
412
+ return {
413
+ subcommand: "stop-failure",
414
+ payload: {
415
+ hook_event_name: "StopFailure",
416
+ session_id: data.sessionID,
417
+ cwd,
418
+ ...(reason ? { reason } : {}),
419
+ },
420
+ };
421
+ }
422
+
423
+ export function sessionEndPayload(data: Record<string, unknown>, cwd: string): HookPayload {
424
+ return {
425
+ hook_event_name: "SessionEnd",
426
+ session_id: data.sessionID,
427
+ cwd,
428
+ clean_exit: true,
429
+ reason: "deleted",
430
+ };
431
+ }
432
+
433
+ // ── agent-hook stdout interpretation (pure; unit-tested) ─────────────────────
434
+
435
+ export interface HookOutcome {
436
+ /** `additionalContext` text agent-hook asked to inject, if any. */
437
+ context?: string;
438
+ /** A PreToolUse deny reason, if agent-hook blocked the call. */
439
+ deny?: string;
440
+ }
441
+
442
+ /** Read the Claude-shaped `hookSpecificOutput` envelope agent-hook writes for this adapter. */
443
+ export function interpretHookStdout(stdout: string): HookOutcome {
444
+ const outcome: HookOutcome = {};
445
+ for (const line of stdout.split("\n")) {
446
+ const trimmed = line.trim();
447
+ if (!trimmed.startsWith("{")) continue;
448
+ let json: { hookSpecificOutput?: Record<string, unknown> };
449
+ try {
450
+ json = JSON.parse(trimmed) as typeof json;
451
+ } catch {
452
+ continue;
453
+ }
454
+ const out = json.hookSpecificOutput;
455
+ if (!out) continue;
456
+ if (typeof out.additionalContext === "string" && out.additionalContext) {
457
+ outcome.context = outcome.context
458
+ ? `${outcome.context}\n\n${out.additionalContext}`
459
+ : out.additionalContext;
460
+ }
461
+ if (out.permissionDecision === "deny") {
462
+ outcome.deny =
463
+ typeof out.permissionDecisionReason === "string" && out.permissionDecisionReason
464
+ ? out.permissionDecisionReason
465
+ : "Blocked by Harnery coordination guard.";
466
+ }
467
+ }
468
+ return outcome;
469
+ }
470
+
471
+ // ── Bridge runtime ───────────────────────────────────────────────────────────
472
+
473
+ export interface BridgeResult {
474
+ exitCode: number | null;
475
+ stdout: string;
476
+ stderr: string;
477
+ timedOut: boolean;
478
+ error?: string;
479
+ }
480
+ export type Bridge = (subcommand: string, payload: HookPayload) => Promise<BridgeResult>;
481
+
482
+ /** Spawn `agent-hook` with the payload on stdin. Never throws. */
483
+ export function createAgentHookBridge(config: HarneryOpenCodeConfig): Bridge {
484
+ return (subcommand, payload) =>
485
+ new Promise<BridgeResult>((resolvePromise) => {
486
+ const [bin, ...args] = agentHookArgv(config, subcommand);
487
+ let stdout = "";
488
+ let stderr = "";
489
+ let settled = false;
490
+ let timedOut = false;
491
+ const finish = (result: BridgeResult): void => {
492
+ if (settled) return;
493
+ settled = true;
494
+ clearTimeout(timer);
495
+ resolvePromise(result);
496
+ };
497
+ let child: ReturnType<typeof spawn>;
498
+ try {
499
+ child = spawn(bin!, args, {
500
+ cwd: config.projectRoot,
501
+ env: { ...process.env, HARNERY_AGENT_COORD_PLATFORM: ADAPTER },
502
+ stdio: ["pipe", "pipe", "pipe"],
503
+ });
504
+ } catch (error) {
505
+ finish({ exitCode: null, stdout, stderr, timedOut, error: errorText(error) });
506
+ return;
507
+ }
508
+ const timer = setTimeout(() => {
509
+ timedOut = true;
510
+ try {
511
+ child.kill("SIGKILL");
512
+ } catch {
513
+ /* already gone */
514
+ }
515
+ }, config.timeoutMs);
516
+ child.stdout?.on("data", (chunk: Buffer) => {
517
+ stdout += chunk.toString("utf8");
518
+ });
519
+ child.stderr?.on("data", (chunk: Buffer) => {
520
+ stderr += chunk.toString("utf8");
521
+ });
522
+ child.on("error", (error) =>
523
+ finish({ exitCode: null, stdout, stderr, timedOut, error: errorText(error) }),
524
+ );
525
+ child.on("close", (code) => finish({ exitCode: code, stdout, stderr, timedOut }));
526
+ try {
527
+ child.stdin?.on("error", () => undefined);
528
+ child.stdin?.end(JSON.stringify(payload));
529
+ } catch (error) {
530
+ finish({ exitCode: null, stdout, stderr, timedOut, error: errorText(error) });
531
+ }
532
+ });
533
+ }
534
+
535
+ export interface PluginDependencies {
536
+ bridge?: Bridge;
537
+ config?: HarneryOpenCodeConfig;
538
+ log?: (event: string, detail?: Record<string, unknown>) => void;
539
+ /** Override the plugin directory (tests); defaults to this file's directory. */
540
+ pluginDir?: string;
541
+ }
542
+
543
+ function defaultPluginDir(): string {
544
+ try {
545
+ return dirname(fileURLToPath(import.meta.url));
546
+ } catch {
547
+ return process.cwd();
548
+ }
549
+ }
550
+
551
+ function fileLogger(
552
+ projectRoot: string,
553
+ ): (event: string, detail?: Record<string, unknown>) => void {
554
+ const dir = resolve(projectRoot, ".harnery", "debug");
555
+ const file = resolve(dir, "opencode-plugin.ndjson");
556
+ return (event, detail) => {
557
+ try {
558
+ mkdirSync(dir, { recursive: true });
559
+ appendFileSync(
560
+ file,
561
+ `${JSON.stringify({ ts: new Date().toISOString(), event, ...detail })}\n`,
562
+ );
563
+ } catch {
564
+ /* logging is best-effort */
565
+ }
566
+ };
567
+ }
568
+
569
+ /**
570
+ * Build the plugin definition. `deps` exist for tests: a fake bridge records
571
+ * the payloads instead of spawning `agent-hook`.
572
+ */
573
+ export function createHarneryOpenCodePlugin(deps: PluginDependencies = {}) {
574
+ return {
575
+ id: HARNERY_OPENCODE_PLUGIN_ID,
576
+ async setup(ctx: OpenCodePluginContext): Promise<() => Promise<void>> {
577
+ const pluginDir = deps.pluginDir ?? defaultPluginDir();
578
+ const config = deps.config ?? loadHarneryOpenCodeConfig(pluginDir);
579
+ // agent-hook resolves its coord root from cwd, so the bridge runs from
580
+ // the project root. Prefer OpenCode's own location for the payload cwd.
581
+ const cwd = ctx.location?.directory || config.projectRoot;
582
+ const log = deps.log ?? fileLogger(config.projectRoot);
583
+ const bridge = deps.bridge ?? createAgentHookBridge(config);
584
+ /** Child (subagent) sessions seen on the bus, so turn ends map to sub-agent-stop. */
585
+ const children = new Set<string>();
586
+ /** Per-turn context agent-hook asked to inject, pushed into every model call's system prompt. */
587
+ const turnContext = new Map<string, string>();
588
+ /** shell command → session id, so the shell hook (which carries no session) can stamp the env. */
589
+ const pendingShells = new Map<string, string>();
590
+ let lastToolSession: string | undefined;
591
+
592
+ const run = async (subcommand: string, payload: HookPayload): Promise<HookOutcome> => {
593
+ const result = await bridge(subcommand, payload);
594
+ if (result.error || result.timedOut || (result.exitCode !== 0 && result.exitCode !== 2)) {
595
+ log("bridge_failure", {
596
+ subcommand,
597
+ exit_code: result.exitCode,
598
+ timed_out: result.timedOut,
599
+ error: result.error,
600
+ stderr: result.stderr.slice(0, 2000),
601
+ });
602
+ return {};
603
+ }
604
+ // Exit 2 is Claude Code's Stop-block channel. OpenCode cannot block a
605
+ // turn, so the verdict is recorded (agent-hook already wrote it) and
606
+ // the reason is kept in the plugin log only.
607
+ if (result.exitCode === 2) {
608
+ log("stop_verdict_observed", { subcommand, stderr: result.stderr.slice(0, 2000) });
609
+ }
610
+ return interpretHookStdout(result.stdout);
611
+ };
612
+
613
+ const inject = async (sessionID: string, text: string): Promise<void> => {
614
+ if (!text) return;
615
+ try {
616
+ await ctx.session.synthetic({ sessionID, text, description: CONTEXT_DESCRIPTION });
617
+ } catch (error) {
618
+ log("synthetic_failure", { session_id: sessionID, error: errorText(error) });
619
+ }
620
+ };
621
+
622
+ const registrations: OpenCodeRegistration[] = [];
623
+ const register = async <T>(
624
+ hook: Hook<T>,
625
+ name: string,
626
+ cb: (event: T) => Promise<void> | void,
627
+ ) => {
628
+ registrations.push(
629
+ await hook(name, async (event) => {
630
+ try {
631
+ await cb(event);
632
+ } catch (error) {
633
+ if (error instanceof HarneryDeny) throw error;
634
+ log("handler_failure", { hook: name, error: errorText(error) });
635
+ }
636
+ }),
637
+ );
638
+ };
639
+
640
+ await register<OpenCodeSessionPrompt>(
641
+ ctx.session.hook as Hook<OpenCodeSessionPrompt>,
642
+ "prompt",
643
+ async (event) => {
644
+ const outcome = await run("user-prompt-submit", promptPayload(event, cwd));
645
+ if (outcome.context) turnContext.set(event.sessionID, outcome.context);
646
+ else turnContext.delete(event.sessionID);
647
+ },
648
+ );
649
+ await register<OpenCodeSessionRequest>(
650
+ ctx.session.hook as Hook<OpenCodeSessionRequest>,
651
+ "context",
652
+ (event) => {
653
+ const text = turnContext.get(event.sessionID);
654
+ if (text && Array.isArray(event.system)) event.system.push({ type: "text", text });
655
+ },
656
+ );
657
+ await register<OpenCodeSessionRequest>(
658
+ ctx.session.hook as Hook<OpenCodeSessionRequest>,
659
+ "compaction",
660
+ async (event) => {
661
+ await run("pre-compact", compactionPayload(event, cwd));
662
+ },
663
+ );
664
+ await register<OpenCodeToolBefore>(
665
+ ctx.tool.hook as Hook<OpenCodeToolBefore>,
666
+ "execute.before",
667
+ async (event) => {
668
+ lastToolSession = event.sessionID;
669
+ const command =
670
+ event.input && typeof event.input === "object"
671
+ ? (event.input as { command?: unknown }).command
672
+ : undefined;
673
+ if (typeof command === "string") pendingShells.set(command, event.sessionID);
674
+ const outcome = await run("pre-tool-use", toolBeforePayload(event, cwd));
675
+ if (outcome.deny) throw new HarneryDeny(outcome.deny);
676
+ },
677
+ );
678
+ await register<OpenCodeToolAfter>(
679
+ ctx.tool.hook as Hook<OpenCodeToolAfter>,
680
+ "execute.after",
681
+ async (event) => {
682
+ const { subcommand, payload } = toolAfterPayload(event, cwd);
683
+ await run(subcommand, payload);
684
+ },
685
+ );
686
+ await register<OpenCodePermissionEvaluation>(
687
+ ctx.permission.hook,
688
+ "evaluate",
689
+ async (event) => {
690
+ await run("permission-request", permissionPayload(event, cwd));
691
+ },
692
+ );
693
+ await register<OpenCodeShellCreateBefore>(ctx.shell.hook, "create.before", (event) => {
694
+ const sessionID = pendingShells.get(event.command) ?? lastToolSession;
695
+ if (typeof event.command === "string") pendingShells.delete(event.command);
696
+ if (!event.env) return;
697
+ // PATH is session-independent, so stamp it even for a shell the plugin
698
+ // cannot attribute to a session.
699
+ prependShellPath(event.env, config.projectRoot);
700
+ if (!sessionID) return;
701
+ event.env[OPENCODE_SESSION_ENV] = sessionID;
702
+ event.env.HARNERY_AGENT_COORD_PLATFORM = ADAPTER;
703
+ });
704
+
705
+ const controller = new AbortController();
706
+ const handleBus = async (event: OpenCodeBusEvent): Promise<void> => {
707
+ if (
708
+ event.location?.directory &&
709
+ ctx.location?.directory &&
710
+ event.location.directory !== ctx.location.directory
711
+ ) {
712
+ return;
713
+ }
714
+ const data = event.data ?? {};
715
+ const sessionID = str(data.sessionID);
716
+ if (!sessionID) return;
717
+ switch (event.type) {
718
+ case "session.created": {
719
+ if (str(data.parentID)) {
720
+ children.add(sessionID);
721
+ const outcome = await run("sub-agent-start", subagentStartPayload(data, cwd));
722
+ if (outcome.context) await inject(sessionID, outcome.context);
723
+ return;
724
+ }
725
+ const outcome = await run("session-start", sessionStartPayload(data, cwd));
726
+ if (outcome.context) await inject(sessionID, outcome.context);
727
+ return;
728
+ }
729
+ case "session.execution.succeeded":
730
+ case "session.execution.failed":
731
+ case "session.execution.interrupted": {
732
+ turnContext.delete(sessionID);
733
+ const { subcommand, payload } = turnEndPayload(
734
+ event.type,
735
+ data,
736
+ cwd,
737
+ children.has(sessionID),
738
+ );
739
+ await run(subcommand, payload);
740
+ return;
741
+ }
742
+ case "session.deleted": {
743
+ turnContext.delete(sessionID);
744
+ children.delete(sessionID);
745
+ await run("session-end", sessionEndPayload(data, cwd));
746
+ return;
747
+ }
748
+ default:
749
+ return;
750
+ }
751
+ };
752
+ void (async () => {
753
+ try {
754
+ for await (const event of ctx.event.subscribe({ signal: controller.signal })) {
755
+ try {
756
+ await handleBus(event);
757
+ } catch (error) {
758
+ log("bus_handler_failure", { type: event.type, error: errorText(error) });
759
+ }
760
+ }
761
+ } catch (error) {
762
+ if (!controller.signal.aborted)
763
+ log("bus_subscription_ended", { error: errorText(error) });
764
+ }
765
+ })();
766
+
767
+ log("plugin_ready", { project_root: config.projectRoot, agent_hook: config.agentHook, cwd });
768
+
769
+ return async () => {
770
+ controller.abort();
771
+ for (const registration of registrations.splice(0)) {
772
+ try {
773
+ await registration.dispose();
774
+ } catch {
775
+ /* disposing on shutdown */
776
+ }
777
+ }
778
+ };
779
+ },
780
+ };
781
+ }
782
+
783
+ /** Thrown from `execute.before` to reject a tool call; OpenCode surfaces the message to the model. */
784
+ export class HarneryDeny extends Error {
785
+ constructor(reason: string) {
786
+ super(reason);
787
+ this.name = "HarneryDeny";
788
+ }
789
+ }
790
+
791
+ export default createHarneryOpenCodePlugin();