harnery 0.32.0 → 0.34.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 (665) hide show
  1. package/README.md +2 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +7 -1
  4. package/dist/commands/adapter.js +2 -2
  5. package/dist/commands/agents.d.ts +144 -1
  6. package/dist/commands/agents.d.ts.map +1 -1
  7. package/dist/commands/agents.js +1408 -565
  8. package/dist/commands/artifacts.d.ts.map +1 -1
  9. package/dist/commands/artifacts.js +7 -6
  10. package/dist/commands/backup.d.ts +1 -1
  11. package/dist/commands/backup.d.ts.map +1 -1
  12. package/dist/commands/backup.js +29 -16
  13. package/dist/commands/browse.d.ts.map +1 -1
  14. package/dist/commands/browse.js +234 -12
  15. package/dist/commands/checkpoint.d.ts.map +1 -1
  16. package/dist/commands/checkpoint.js +3 -2
  17. package/dist/commands/claude-desktop.d.ts +2 -2
  18. package/dist/commands/claude-desktop.d.ts.map +1 -1
  19. package/dist/commands/claude-desktop.js +2 -2
  20. package/dist/commands/context.js +1 -6
  21. package/dist/commands/decision.d.ts.map +1 -1
  22. package/dist/commands/decision.js +22 -38
  23. package/dist/commands/docs.d.ts.map +1 -1
  24. package/dist/commands/docs.js +91 -28
  25. package/dist/commands/doctor.d.ts +4 -2
  26. package/dist/commands/doctor.d.ts.map +1 -1
  27. package/dist/commands/doctor.js +55 -7
  28. package/dist/commands/events.d.ts +5 -0
  29. package/dist/commands/events.d.ts.map +1 -0
  30. package/dist/commands/events.js +189 -0
  31. package/dist/commands/governor.d.ts.map +1 -1
  32. package/dist/commands/governor.js +13 -4
  33. package/dist/commands/init.d.ts +10 -2
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +233 -51
  36. package/dist/commands/instructions.d.ts +4 -0
  37. package/dist/commands/instructions.d.ts.map +1 -0
  38. package/dist/commands/instructions.js +100 -0
  39. package/dist/commands/journal.d.ts.map +1 -1
  40. package/dist/commands/journal.js +4 -13
  41. package/dist/commands/ledger-v3.d.ts +5 -0
  42. package/dist/commands/ledger-v3.d.ts.map +1 -0
  43. package/dist/commands/ledger-v3.js +91 -0
  44. package/dist/commands/presence.d.ts.map +1 -1
  45. package/dist/commands/presence.js +15 -6
  46. package/dist/commands/sync.d.ts +1 -1
  47. package/dist/commands/sync.js +1 -1
  48. package/dist/commands/web.d.ts +6 -0
  49. package/dist/commands/web.d.ts.map +1 -1
  50. package/dist/commands/web.js +67 -7
  51. package/dist/commands/work.d.ts.map +1 -1
  52. package/dist/commands/work.js +22 -5
  53. package/dist/core/adapter.d.ts +5 -0
  54. package/dist/core/adapter.d.ts.map +1 -0
  55. package/dist/core/adapter.js +1 -0
  56. package/dist/core/adapters/attest.d.ts +5 -2
  57. package/dist/core/adapters/attest.d.ts.map +1 -1
  58. package/dist/core/adapters/attest.js +8 -3
  59. package/dist/core/adapters/profiles.d.ts +6 -6
  60. package/dist/core/adapters/profiles.d.ts.map +1 -1
  61. package/dist/core/adapters/profiles.js +4 -4
  62. package/dist/core/agents/canonical-emit.d.ts +17 -15
  63. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  64. package/dist/core/agents/canonical-emit.js +27 -25
  65. package/dist/core/agents/cli.js +212 -235
  66. package/dist/core/agents/codex-archive-v3.d.ts +14 -0
  67. package/dist/core/agents/codex-archive-v3.d.ts.map +1 -0
  68. package/dist/core/agents/codex-archive-v3.js +110 -0
  69. package/dist/core/agents/coord-client.d.ts +19 -70
  70. package/dist/core/agents/coord-client.d.ts.map +1 -1
  71. package/dist/core/agents/coord-client.js +65 -155
  72. package/dist/core/agents/finalization.d.ts +4 -1
  73. package/dist/core/agents/finalization.d.ts.map +1 -1
  74. package/dist/core/agents/finalization.js +89 -32
  75. package/dist/core/agents/index.d.ts +5 -5
  76. package/dist/core/agents/index.d.ts.map +1 -1
  77. package/dist/core/agents/index.js +5 -5
  78. package/dist/core/agents/live-authority-v3.d.ts +59 -0
  79. package/dist/core/agents/live-authority-v3.d.ts.map +1 -0
  80. package/dist/core/agents/live-authority-v3.js +233 -0
  81. package/dist/core/agents/live-lifecycle-v3.d.ts +20 -0
  82. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -0
  83. package/dist/core/agents/live-lifecycle-v3.js +91 -0
  84. package/dist/core/agents/live-observation-v3.d.ts +25 -0
  85. package/dist/core/agents/live-observation-v3.d.ts.map +1 -0
  86. package/dist/core/agents/live-observation-v3.js +157 -0
  87. package/dist/core/agents/render/prompt-context.d.ts +10 -4
  88. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  89. package/dist/core/agents/render/prompt-context.js +61 -55
  90. package/dist/core/agents/render/session-context.d.ts +1 -1
  91. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  92. package/dist/core/agents/render/session-context.js +15 -33
  93. package/dist/core/agents/rules/claim-conflict.d.ts +3 -3
  94. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  95. package/dist/core/agents/rules/claim-conflict.js +79 -127
  96. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  97. package/dist/core/agents/rules/commit-conflict.js +3 -18
  98. package/dist/core/agents/rules/stop-hook.d.ts +9 -50
  99. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  100. package/dist/core/agents/rules/stop-hook.js +193 -236
  101. package/dist/core/agents/session-events.d.ts +5 -7
  102. package/dist/core/agents/session-events.d.ts.map +1 -1
  103. package/dist/core/agents/session-events.js +127 -95
  104. package/dist/core/agents/session-finalization-state-v3.d.ts +30 -0
  105. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -0
  106. package/dist/core/agents/session-finalization-state-v3.js +40 -0
  107. package/dist/core/agents/session-finalizer-v3.d.ts +107 -0
  108. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -0
  109. package/dist/core/agents/session-finalizer-v3.js +734 -0
  110. package/dist/core/agents/session-name-display.d.ts +40 -0
  111. package/dist/core/agents/session-name-display.d.ts.map +1 -0
  112. package/dist/core/agents/session-name-display.js +119 -0
  113. package/dist/core/agents/state/activity-log.d.ts +3 -3
  114. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  115. package/dist/core/agents/state/activity-log.js +7 -16
  116. package/dist/core/agents/state/heartbeat-writer.d.ts +29 -46
  117. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  118. package/dist/core/agents/state/heartbeat-writer.js +59 -199
  119. package/dist/core/agents/state/live-coordination-view.d.ts +31 -0
  120. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -0
  121. package/dist/core/agents/state/live-coordination-view.js +209 -0
  122. package/dist/core/agents/state/session-state.d.ts +45 -0
  123. package/dist/core/agents/state/session-state.d.ts.map +1 -0
  124. package/dist/core/agents/state/session-state.js +90 -0
  125. package/dist/core/agents/state/stale-sweep.d.ts +1 -1
  126. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  127. package/dist/core/agents/state/stale-sweep.js +26 -15
  128. package/dist/core/artifacts/index.d.ts.map +1 -1
  129. package/dist/core/artifacts/index.js +5 -7
  130. package/dist/core/config.d.ts +33 -2
  131. package/dist/core/config.d.ts.map +1 -1
  132. package/dist/core/config.js +98 -2
  133. package/dist/core/context/index.d.ts +1 -4
  134. package/dist/core/context/index.d.ts.map +1 -1
  135. package/dist/core/context/index.js +9 -9
  136. package/dist/core/events/span-parent.d.ts +15 -0
  137. package/dist/core/events/span-parent.d.ts.map +1 -0
  138. package/dist/core/events/span-parent.js +34 -0
  139. package/dist/core/events/v3/advance.d.ts +14 -0
  140. package/dist/core/events/v3/advance.d.ts.map +1 -0
  141. package/dist/core/events/v3/advance.js +134 -0
  142. package/dist/core/events/v3/authority-outbox.d.ts +78 -0
  143. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -0
  144. package/dist/core/events/v3/authority-outbox.js +399 -0
  145. package/dist/core/events/v3/base-builder.d.ts +20 -0
  146. package/dist/core/events/v3/base-builder.d.ts.map +1 -0
  147. package/dist/core/events/v3/base-builder.js +29 -0
  148. package/dist/core/events/v3/base-contract.d.ts +7576 -0
  149. package/dist/core/events/v3/base-contract.d.ts.map +1 -0
  150. package/dist/core/events/v3/base-contract.js +647 -0
  151. package/dist/core/events/v3/bootstrap.d.ts +34 -0
  152. package/dist/core/events/v3/bootstrap.d.ts.map +1 -0
  153. package/dist/core/events/v3/bootstrap.js +175 -0
  154. package/dist/core/events/v3/builder.d.ts +20 -0
  155. package/dist/core/events/v3/builder.d.ts.map +1 -0
  156. package/dist/core/events/v3/builder.js +28 -0
  157. package/dist/core/events/v3/canonical.d.ts +31 -0
  158. package/dist/core/events/v3/canonical.d.ts.map +1 -0
  159. package/dist/core/events/v3/canonical.js +100 -0
  160. package/dist/core/events/v3/capabilities.d.ts +31 -0
  161. package/dist/core/events/v3/capabilities.d.ts.map +1 -0
  162. package/dist/core/events/v3/capabilities.js +107 -0
  163. package/dist/core/events/v3/capability-drift.d.ts +22 -0
  164. package/dist/core/events/v3/capability-drift.d.ts.map +1 -0
  165. package/dist/core/events/v3/capability-drift.js +134 -0
  166. package/dist/core/events/v3/catalog.d.ts +38 -0
  167. package/dist/core/events/v3/catalog.d.ts.map +1 -0
  168. package/dist/core/events/v3/catalog.js +135 -0
  169. package/dist/core/events/v3/clock-order.d.ts +34 -0
  170. package/dist/core/events/v3/clock-order.d.ts.map +1 -0
  171. package/dist/core/events/v3/clock-order.js +35 -0
  172. package/dist/core/events/v3/contract.d.ts +171 -0
  173. package/dist/core/events/v3/contract.d.ts.map +1 -0
  174. package/dist/core/events/v3/contract.js +180 -0
  175. package/dist/core/events/v3/control.d.ts +111 -0
  176. package/dist/core/events/v3/control.d.ts.map +1 -0
  177. package/dist/core/events/v3/control.js +419 -0
  178. package/dist/core/events/v3/coordination-view.d.ts +69 -0
  179. package/dist/core/events/v3/coordination-view.d.ts.map +1 -0
  180. package/dist/core/events/v3/coordination-view.js +119 -0
  181. package/dist/core/events/v3/economics.d.ts +77 -0
  182. package/dist/core/events/v3/economics.d.ts.map +1 -0
  183. package/dist/core/events/v3/economics.js +274 -0
  184. package/dist/core/events/v3/finalization-view.d.ts +26 -0
  185. package/dist/core/events/v3/finalization-view.d.ts.map +1 -0
  186. package/dist/core/events/v3/finalization-view.js +37 -0
  187. package/dist/core/events/v3/fingerprint-keys.d.ts +25 -0
  188. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -0
  189. package/dist/core/events/v3/fingerprint-keys.js +217 -0
  190. package/dist/core/events/v3/generated.d.ts +4 -0
  191. package/dist/core/events/v3/generated.d.ts.map +1 -0
  192. package/dist/core/events/v3/generated.js +47 -0
  193. package/dist/core/events/v3/ids.d.ts +9 -0
  194. package/dist/core/events/v3/ids.d.ts.map +1 -0
  195. package/dist/core/events/v3/ids.js +25 -0
  196. package/dist/core/events/v3/index.d.ts +35 -0
  197. package/dist/core/events/v3/index.d.ts.map +1 -0
  198. package/dist/core/events/v3/index.js +33 -0
  199. package/dist/core/events/v3/latency.d.ts +63 -0
  200. package/dist/core/events/v3/latency.d.ts.map +1 -0
  201. package/dist/core/events/v3/latency.js +412 -0
  202. package/dist/core/events/v3/live-feed.d.ts +45 -0
  203. package/dist/core/events/v3/live-feed.d.ts.map +1 -0
  204. package/dist/core/events/v3/live-feed.js +246 -0
  205. package/dist/core/events/v3/live-observation.d.ts +35 -0
  206. package/dist/core/events/v3/live-observation.d.ts.map +1 -0
  207. package/dist/core/events/v3/live-observation.js +1 -0
  208. package/dist/core/events/v3/live-routing.d.ts +57 -0
  209. package/dist/core/events/v3/live-routing.d.ts.map +1 -0
  210. package/dist/core/events/v3/live-routing.js +107 -0
  211. package/dist/core/events/v3/producers/command-recorder.d.ts +67 -0
  212. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -0
  213. package/dist/core/events/v3/producers/command-recorder.js +477 -0
  214. package/dist/core/events/v3/producers/command.d.ts +50 -0
  215. package/dist/core/events/v3/producers/command.d.ts.map +1 -0
  216. package/dist/core/events/v3/producers/command.js +135 -0
  217. package/dist/core/events/v3/producers/coordination-recorder.d.ts +53 -0
  218. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -0
  219. package/dist/core/events/v3/producers/coordination-recorder.js +376 -0
  220. package/dist/core/events/v3/producers/coordination.d.ts +90 -0
  221. package/dist/core/events/v3/producers/coordination.d.ts.map +1 -0
  222. package/dist/core/events/v3/producers/coordination.js +229 -0
  223. package/dist/core/events/v3/producers/hook-base.d.ts +54 -0
  224. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -0
  225. package/dist/core/events/v3/producers/hook-base.js +424 -0
  226. package/dist/core/events/v3/producers/hook.d.ts +29 -0
  227. package/dist/core/events/v3/producers/hook.d.ts.map +1 -0
  228. package/dist/core/events/v3/producers/hook.js +71 -0
  229. package/dist/core/events/v3/producers/intake.d.ts +65 -0
  230. package/dist/core/events/v3/producers/intake.d.ts.map +1 -0
  231. package/dist/core/events/v3/producers/intake.js +244 -0
  232. package/dist/core/events/v3/producers/recorder.d.ts +240 -0
  233. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -0
  234. package/dist/core/events/v3/producers/recorder.js +2176 -0
  235. package/dist/core/events/v3/projection.d.ts +101 -0
  236. package/dist/core/events/v3/projection.d.ts.map +1 -0
  237. package/dist/core/events/v3/projection.js +479 -0
  238. package/dist/core/events/v3/reader.d.ts +75 -0
  239. package/dist/core/events/v3/reader.d.ts.map +1 -0
  240. package/dist/core/events/v3/reader.js +778 -0
  241. package/dist/core/events/v3/recovery-record.d.ts +47 -0
  242. package/dist/core/events/v3/recovery-record.d.ts.map +1 -0
  243. package/dist/core/events/v3/recovery-record.js +167 -0
  244. package/dist/core/events/v3/recovery.d.ts +22 -0
  245. package/dist/core/events/v3/recovery.d.ts.map +1 -0
  246. package/dist/core/events/v3/recovery.js +227 -0
  247. package/dist/core/events/v3/span-state.d.ts +52 -0
  248. package/dist/core/events/v3/span-state.d.ts.map +1 -0
  249. package/dist/core/events/v3/span-state.js +142 -0
  250. package/dist/core/events/v3/targets.d.ts +23 -0
  251. package/dist/core/events/v3/targets.d.ts.map +1 -0
  252. package/dist/core/events/v3/targets.js +134 -0
  253. package/dist/core/events/v3/turn-telemetry.d.ts +41 -0
  254. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -0
  255. package/dist/core/events/v3/turn-telemetry.js +168 -0
  256. package/dist/core/events/v3/validate.d.ts +9 -0
  257. package/dist/core/events/v3/validate.d.ts.map +1 -0
  258. package/dist/core/events/v3/validate.js +281 -0
  259. package/dist/core/events/v3/writer.d.ts +56 -0
  260. package/dist/core/events/v3/writer.d.ts.map +1 -0
  261. package/dist/core/events/v3/writer.js +335 -0
  262. package/dist/core/governor/index.d.ts +1 -1
  263. package/dist/core/governor/index.d.ts.map +1 -1
  264. package/dist/core/governor/index.js +1 -1
  265. package/dist/core/governor/plan-api.d.ts +2 -1
  266. package/dist/core/governor/plan-api.d.ts.map +1 -1
  267. package/dist/core/governor/plan-api.js +6 -3
  268. package/dist/core/governor/read.d.ts +1 -1
  269. package/dist/core/governor/read.d.ts.map +1 -1
  270. package/dist/core/governor/read.js +1 -1
  271. package/dist/core/governor/state.d.ts +9 -0
  272. package/dist/core/governor/state.d.ts.map +1 -1
  273. package/dist/core/governor/state.js +40 -3
  274. package/dist/core/guard/config.d.ts +5 -0
  275. package/dist/core/guard/config.d.ts.map +1 -0
  276. package/dist/core/guard/config.js +157 -0
  277. package/dist/core/guard/coordinator.d.ts +14 -0
  278. package/dist/core/guard/coordinator.d.ts.map +1 -0
  279. package/dist/core/guard/coordinator.js +173 -0
  280. package/dist/core/guard/evaluator.d.ts +4 -0
  281. package/dist/core/guard/evaluator.d.ts.map +1 -0
  282. package/dist/core/guard/evaluator.js +242 -0
  283. package/dist/core/guard/evidence-v3.d.ts +15 -0
  284. package/dist/core/guard/evidence-v3.d.ts.map +1 -0
  285. package/dist/core/guard/evidence-v3.js +171 -0
  286. package/dist/core/guard/index.d.ts +10 -0
  287. package/dist/core/guard/index.d.ts.map +1 -0
  288. package/dist/core/guard/index.js +6 -0
  289. package/dist/core/guard/live-source-v3.d.ts +40 -0
  290. package/dist/core/guard/live-source-v3.d.ts.map +1 -0
  291. package/dist/core/guard/live-source-v3.js +128 -0
  292. package/dist/core/guard/storage.d.ts +27 -0
  293. package/dist/core/guard/storage.d.ts.map +1 -0
  294. package/dist/core/guard/storage.js +140 -0
  295. package/dist/core/guard/types.d.ts +119 -0
  296. package/dist/core/guard/types.d.ts.map +1 -0
  297. package/dist/core/guard/types.js +1 -0
  298. package/dist/core/hooks/adapter/detect.d.ts +18 -1
  299. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  300. package/dist/core/hooks/adapter/detect.js +29 -0
  301. package/dist/core/hooks/adapter/events.d.ts +7 -4
  302. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  303. package/dist/core/hooks/adapter/events.js +13 -4
  304. package/dist/core/hooks/adapter/output.d.ts +2 -2
  305. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  306. package/dist/core/hooks/adapter/parse.d.ts +7 -4
  307. package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
  308. package/dist/core/hooks/adapter/parse.js +64 -24
  309. package/dist/core/hooks/adapter/wiring.d.ts +30 -4
  310. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  311. package/dist/core/hooks/adapter/wiring.js +89 -11
  312. package/dist/core/hooks/cli.d.ts +1 -1
  313. package/dist/core/hooks/cli.js +345 -400
  314. package/dist/core/hooks/codex-authorization.d.ts +30 -0
  315. package/dist/core/hooks/codex-authorization.d.ts.map +1 -0
  316. package/dist/core/hooks/codex-authorization.js +199 -0
  317. package/dist/core/hooks/effects/image-capture.d.ts +20 -34
  318. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  319. package/dist/core/hooks/effects/image-capture.js +212 -221
  320. package/dist/core/hooks/effects/index.d.ts +1 -9
  321. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  322. package/dist/core/hooks/effects/index.js +1 -24
  323. package/dist/core/hooks/events/input-hash.d.ts +7 -0
  324. package/dist/core/hooks/events/input-hash.d.ts.map +1 -0
  325. package/dist/core/hooks/events/input-hash.js +43 -0
  326. package/dist/core/hooks/index.d.ts +4 -3
  327. package/dist/core/hooks/index.d.ts.map +1 -1
  328. package/dist/core/hooks/index.js +2 -3
  329. package/dist/core/hooks/resolve/coord-root.d.ts +1 -1
  330. package/dist/core/hooks/resolve/coord-root.js +1 -1
  331. package/dist/core/hooks/resolve/owner.d.ts +16 -15
  332. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  333. package/dist/core/hooks/resolve/owner.js +51 -42
  334. package/dist/core/hooks/resolve/transcript.d.ts +33 -3
  335. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  336. package/dist/core/hooks/resolve/transcript.js +155 -14
  337. package/dist/core/hooks/session-name-presence.d.ts +9 -10
  338. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  339. package/dist/core/hooks/session-name-presence.js +15 -15
  340. package/dist/core/hooks/unsafe-cross-shell.d.ts +1 -1
  341. package/dist/core/hooks/unsafe-cross-shell.d.ts.map +1 -1
  342. package/dist/core/journal/index.d.ts +2 -2
  343. package/dist/core/journal/index.d.ts.map +1 -1
  344. package/dist/core/journal/index.js +9 -22
  345. package/dist/core/presence/blob.d.ts +8 -3
  346. package/dist/core/presence/blob.d.ts.map +1 -1
  347. package/dist/core/presence/blob.js +54 -41
  348. package/dist/core/presence/codec-digest.d.ts +29 -0
  349. package/dist/core/presence/codec-digest.d.ts.map +1 -0
  350. package/dist/core/presence/codec-digest.js +170 -0
  351. package/dist/core/presence/index.js +15 -1
  352. package/dist/core/presence/relay-client.d.ts +1 -1
  353. package/dist/core/presence/relay-client.d.ts.map +1 -1
  354. package/dist/core/presence/relay-client.js +5 -5
  355. package/dist/core/work/index.d.ts +1 -1
  356. package/dist/core/work/index.d.ts.map +1 -1
  357. package/dist/core/work/index.js +1 -1
  358. package/dist/core/work/read.d.ts +1 -1
  359. package/dist/core/work/read.d.ts.map +1 -1
  360. package/dist/core/work/read.js +1 -1
  361. package/dist/core/work/runner.d.ts.map +1 -1
  362. package/dist/core/work/runner.js +6 -0
  363. package/dist/core/work/state.d.ts +9 -0
  364. package/dist/core/work/state.d.ts.map +1 -1
  365. package/dist/core/work/state.js +17 -3
  366. package/dist/core/workflow/engine.js +24 -25
  367. package/dist/core/workflow/live-session-v3.d.ts +19 -0
  368. package/dist/core/workflow/live-session-v3.d.ts.map +1 -0
  369. package/dist/core/workflow/live-session-v3.js +86 -0
  370. package/dist/core/workflow/scope-id.d.ts +3 -0
  371. package/dist/core/workflow/scope-id.d.ts.map +1 -0
  372. package/dist/core/workflow/scope-id.js +5 -0
  373. package/dist/core/workflow/workspaces/leases.d.ts +4 -0
  374. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  375. package/dist/core/workflow/workspaces/leases.js +53 -19
  376. package/dist/index.d.ts +1 -1
  377. package/dist/index.js +1 -1
  378. package/dist/lib/browser/client.d.ts +41 -0
  379. package/dist/lib/browser/client.d.ts.map +1 -1
  380. package/dist/lib/browser/client.js +203 -0
  381. package/dist/lib/browser/critique.d.ts +28 -2
  382. package/dist/lib/browser/critique.d.ts.map +1 -1
  383. package/dist/lib/browser/critique.js +74 -18
  384. package/dist/lib/browser/geometry.d.ts +1 -1
  385. package/dist/lib/browser/geometry.d.ts.map +1 -1
  386. package/dist/lib/browser/geometry.js +130 -6
  387. package/dist/lib/browser/index.d.ts +3 -0
  388. package/dist/lib/browser/index.d.ts.map +1 -1
  389. package/dist/lib/browser/index.js +3 -0
  390. package/dist/lib/browser/qa-plan.d.ts +174 -0
  391. package/dist/lib/browser/qa-plan.d.ts.map +1 -0
  392. package/dist/lib/browser/qa-plan.js +321 -0
  393. package/dist/lib/browser/qa-reuse.d.ts +99 -0
  394. package/dist/lib/browser/qa-reuse.d.ts.map +1 -0
  395. package/dist/lib/browser/qa-reuse.js +222 -0
  396. package/dist/lib/browser/qa-snapshot.d.ts +64 -0
  397. package/dist/lib/browser/qa-snapshot.d.ts.map +1 -0
  398. package/dist/lib/browser/qa-snapshot.js +171 -0
  399. package/dist/lib/browser/runts.d.ts.map +1 -1
  400. package/dist/lib/browser/runts.js +22 -1
  401. package/dist/lib/browser/tiling.d.ts +71 -0
  402. package/dist/lib/browser/tiling.d.ts.map +1 -0
  403. package/dist/lib/browser/tiling.js +118 -0
  404. package/dist/lib/context/index.d.ts +0 -3
  405. package/dist/lib/context/index.d.ts.map +1 -1
  406. package/dist/lib/context/index.js +20 -42
  407. package/dist/lib/council/index.d.ts +2 -2
  408. package/dist/lib/council/index.d.ts.map +1 -1
  409. package/dist/lib/council/index.js +9 -20
  410. package/dist/lib/docs-frontmatter.d.ts +1 -6
  411. package/dist/lib/docs-frontmatter.d.ts.map +1 -1
  412. package/dist/lib/docs-frontmatter.js +12 -78
  413. package/dist/lib/docs-index.d.ts +9 -0
  414. package/dist/lib/docs-index.d.ts.map +1 -1
  415. package/dist/lib/docs-index.js +32 -3
  416. package/dist/lib/docs-lint.d.ts.map +1 -1
  417. package/dist/lib/docs-lint.js +14 -30
  418. package/dist/lib/docs-metadata-audit.d.ts +19 -0
  419. package/dist/lib/docs-metadata-audit.d.ts.map +1 -0
  420. package/dist/lib/docs-metadata-audit.js +132 -0
  421. package/dist/lib/docs-metadata-managed.d.ts +23 -0
  422. package/dist/lib/docs-metadata-managed.d.ts.map +1 -0
  423. package/dist/lib/docs-metadata-managed.js +78 -0
  424. package/dist/lib/docs-metadata-sync.d.ts +20 -0
  425. package/dist/lib/docs-metadata-sync.d.ts.map +1 -0
  426. package/dist/lib/docs-metadata-sync.js +222 -0
  427. package/dist/lib/docs-metadata-v2-schema.d.ts +273 -0
  428. package/dist/lib/docs-metadata-v2-schema.d.ts.map +1 -0
  429. package/dist/lib/docs-metadata-v2-schema.js +134 -0
  430. package/dist/lib/docs-metadata-v2.d.ts +21 -0
  431. package/dist/lib/docs-metadata-v2.d.ts.map +1 -0
  432. package/dist/lib/docs-metadata-v2.js +424 -0
  433. package/dist/lib/docs-new.d.ts +11 -0
  434. package/dist/lib/docs-new.d.ts.map +1 -0
  435. package/dist/lib/docs-new.js +52 -0
  436. package/dist/lib/docs-sweep.d.ts.map +1 -1
  437. package/dist/lib/docs-sweep.js +45 -29
  438. package/dist/lib/headless/index.d.ts +98 -0
  439. package/dist/lib/headless/index.d.ts.map +1 -0
  440. package/dist/lib/headless/index.js +211 -0
  441. package/dist/lib/identities/assume.d.ts +4 -4
  442. package/dist/lib/identities/assume.d.ts.map +1 -1
  443. package/dist/lib/identities/assume.js +52 -68
  444. package/dist/lib/instructions/apply.d.ts +5 -4
  445. package/dist/lib/instructions/apply.d.ts.map +1 -1
  446. package/dist/lib/instructions/apply.js +32 -20
  447. package/dist/lib/instructions/bundle.d.ts +33 -0
  448. package/dist/lib/instructions/bundle.d.ts.map +1 -0
  449. package/dist/lib/instructions/bundle.js +149 -0
  450. package/dist/lib/instructions/splice.d.ts +0 -1
  451. package/dist/lib/instructions/splice.d.ts.map +1 -1
  452. package/dist/lib/instructions/splice.js +22 -6
  453. package/dist/lib/instructions/templates.d.ts +7 -5
  454. package/dist/lib/instructions/templates.d.ts.map +1 -1
  455. package/dist/lib/instructions/templates.js +79 -9
  456. package/package.json +27 -6
  457. package/schemas/config.schema.json +120 -2
  458. package/schemas/docs-metadata-v2.schema.json +441 -0
  459. package/schemas/event-v3.schema.json +24472 -0
  460. package/src/commander.ts +7 -1
  461. package/src/commands/adapter.ts +2 -2
  462. package/src/commands/agents.ts +1737 -570
  463. package/src/commands/artifacts.ts +7 -6
  464. package/src/commands/backup.ts +29 -21
  465. package/src/commands/browse.ts +349 -8
  466. package/src/commands/checkpoint.ts +4 -3
  467. package/src/commands/claude-desktop.ts +7 -5
  468. package/src/commands/context.ts +1 -6
  469. package/src/commands/decision.ts +27 -44
  470. package/src/commands/docs.ts +100 -33
  471. package/src/commands/doctor.ts +73 -8
  472. package/src/commands/events.ts +256 -0
  473. package/src/commands/governor.ts +18 -4
  474. package/src/commands/init.ts +264 -57
  475. package/src/commands/instructions.ts +129 -0
  476. package/src/commands/journal.ts +4 -13
  477. package/src/commands/ledger-v3.ts +111 -0
  478. package/src/commands/presence.ts +18 -11
  479. package/src/commands/sync.ts +1 -1
  480. package/src/commands/web.ts +67 -8
  481. package/src/commands/work.ts +28 -5
  482. package/src/core/adapter.ts +5 -0
  483. package/src/core/adapters/attest.ts +8 -3
  484. package/src/core/adapters/profiles.ts +4 -6
  485. package/src/core/agents/canonical-emit.ts +39 -28
  486. package/src/core/agents/cli.ts +242 -263
  487. package/src/core/agents/codex-archive-v3.ts +138 -0
  488. package/src/core/agents/coord-client.ts +75 -177
  489. package/src/core/agents/finalization.ts +120 -38
  490. package/src/core/agents/index.ts +5 -5
  491. package/src/core/agents/live-authority-v3.ts +375 -0
  492. package/src/core/agents/live-lifecycle-v3.ts +140 -0
  493. package/src/core/agents/live-observation-v3.ts +216 -0
  494. package/src/core/agents/render/prompt-context.ts +89 -55
  495. package/src/core/agents/render/session-context.ts +23 -32
  496. package/src/core/agents/rules/claim-conflict.ts +85 -126
  497. package/src/core/agents/rules/commit-conflict.ts +3 -14
  498. package/src/core/agents/rules/stop-hook.ts +239 -293
  499. package/src/core/agents/session-events.ts +137 -104
  500. package/src/core/agents/session-finalization-state-v3.ts +90 -0
  501. package/src/core/agents/session-finalizer-v3.ts +953 -0
  502. package/src/core/agents/session-name-display.ts +149 -0
  503. package/src/core/agents/state/activity-log.ts +6 -14
  504. package/src/core/agents/state/heartbeat-writer.ts +98 -242
  505. package/src/core/agents/state/live-coordination-view.ts +290 -0
  506. package/src/core/agents/state/session-state.ts +143 -0
  507. package/src/core/agents/state/stale-sweep.ts +40 -17
  508. package/src/core/artifacts/index.ts +4 -5
  509. package/src/core/config.ts +148 -3
  510. package/src/core/context/index.ts +9 -17
  511. package/src/core/events/span-parent.ts +46 -0
  512. package/src/core/events/v3/advance.ts +168 -0
  513. package/src/core/events/v3/authority-outbox.ts +548 -0
  514. package/src/core/events/v3/base-builder.ts +60 -0
  515. package/src/core/events/v3/base-contract.ts +882 -0
  516. package/src/core/events/v3/bootstrap.ts +226 -0
  517. package/src/core/events/v3/builder.ts +59 -0
  518. package/src/core/events/v3/canonical.ts +153 -0
  519. package/src/core/events/v3/capabilities.ts +171 -0
  520. package/src/core/events/v3/capability-drift.ts +177 -0
  521. package/src/core/events/v3/catalog.ts +202 -0
  522. package/src/core/events/v3/clock-order.ts +41 -0
  523. package/src/core/events/v3/contract.ts +365 -0
  524. package/src/core/events/v3/control.ts +576 -0
  525. package/src/core/events/v3/coordination-view.ts +193 -0
  526. package/src/core/events/v3/economics.ts +384 -0
  527. package/src/core/events/v3/finalization-view.ts +67 -0
  528. package/src/core/events/v3/fingerprint-keys.ts +260 -0
  529. package/src/core/events/v3/generated.ts +48 -0
  530. package/src/core/events/v3/ids.ts +33 -0
  531. package/src/core/events/v3/index.ts +322 -0
  532. package/src/core/events/v3/latency.ts +551 -0
  533. package/src/core/events/v3/live-feed.ts +319 -0
  534. package/src/core/events/v3/live-observation.ts +39 -0
  535. package/src/core/events/v3/live-routing.ts +135 -0
  536. package/src/core/events/v3/producers/command-recorder.ts +631 -0
  537. package/src/core/events/v3/producers/command.ts +201 -0
  538. package/src/core/events/v3/producers/coordination-recorder.ts +538 -0
  539. package/src/core/events/v3/producers/coordination.ts +355 -0
  540. package/src/core/events/v3/producers/hook-base.ts +578 -0
  541. package/src/core/events/v3/producers/hook.ts +119 -0
  542. package/src/core/events/v3/producers/intake.ts +319 -0
  543. package/src/core/events/v3/producers/recorder.ts +2805 -0
  544. package/src/core/events/v3/projection.ts +653 -0
  545. package/src/core/events/v3/reader.ts +1127 -0
  546. package/src/core/events/v3/recovery-record.ts +244 -0
  547. package/src/core/events/v3/recovery.ts +271 -0
  548. package/src/core/events/v3/span-state.ts +187 -0
  549. package/src/core/events/v3/targets.ts +182 -0
  550. package/src/core/events/v3/turn-telemetry.ts +259 -0
  551. package/src/core/events/v3/validate.ts +361 -0
  552. package/src/core/events/v3/writer.ts +419 -0
  553. package/src/core/governor/index.ts +3 -0
  554. package/src/core/governor/plan-api.ts +10 -2
  555. package/src/core/governor/read.ts +3 -0
  556. package/src/core/governor/state.ts +52 -5
  557. package/src/core/guard/config.ts +206 -0
  558. package/src/core/guard/coordinator.ts +227 -0
  559. package/src/core/guard/evaluator.ts +343 -0
  560. package/src/core/guard/evidence-v3.ts +227 -0
  561. package/src/core/guard/index.ts +35 -0
  562. package/src/core/guard/live-source-v3.ts +204 -0
  563. package/src/core/guard/storage.ts +188 -0
  564. package/src/core/guard/types.ts +152 -0
  565. package/src/core/hooks/adapter/detect.ts +28 -1
  566. package/src/core/hooks/adapter/events.ts +15 -6
  567. package/src/core/hooks/adapter/output.ts +7 -2
  568. package/src/core/hooks/adapter/parse.ts +81 -36
  569. package/src/core/hooks/adapter/wiring.ts +119 -13
  570. package/src/core/hooks/cli.ts +398 -422
  571. package/src/core/hooks/codex-authorization.ts +253 -0
  572. package/src/core/hooks/effects/image-capture.ts +228 -238
  573. package/src/core/hooks/effects/index.ts +1 -36
  574. package/src/core/hooks/events/input-hash.ts +47 -0
  575. package/src/core/hooks/index.ts +4 -11
  576. package/src/core/hooks/resolve/coord-root.ts +1 -1
  577. package/src/core/hooks/resolve/owner.ts +52 -45
  578. package/src/core/hooks/resolve/transcript.ts +165 -14
  579. package/src/core/hooks/session-name-presence.ts +14 -15
  580. package/src/core/hooks/unsafe-cross-shell.ts +1 -1
  581. package/src/core/journal/index.ts +15 -22
  582. package/src/core/presence/blob.ts +63 -38
  583. package/src/core/presence/codec-digest.ts +215 -0
  584. package/src/core/presence/index.ts +18 -1
  585. package/src/core/presence/relay-client.ts +5 -5
  586. package/src/core/work/index.ts +3 -0
  587. package/src/core/work/read.ts +3 -0
  588. package/src/core/work/runner.ts +6 -0
  589. package/src/core/work/state.ts +27 -3
  590. package/src/core/workflow/engine.ts +24 -24
  591. package/src/core/workflow/live-session-v3.ts +126 -0
  592. package/src/core/workflow/scope-id.ts +6 -0
  593. package/src/core/workflow/workspaces/leases.ts +56 -19
  594. package/src/index.ts +1 -1
  595. package/src/lib/browser/client.ts +230 -0
  596. package/src/lib/browser/critique.ts +104 -27
  597. package/src/lib/browser/geometry.ts +143 -14
  598. package/src/lib/browser/index.ts +34 -0
  599. package/src/lib/browser/qa-plan.ts +501 -0
  600. package/src/lib/browser/qa-reuse.ts +306 -0
  601. package/src/lib/browser/qa-snapshot.ts +223 -0
  602. package/src/lib/browser/runts.ts +27 -2
  603. package/src/lib/browser/tiling.ts +164 -0
  604. package/src/lib/context/index.ts +22 -46
  605. package/src/lib/council/index.ts +9 -21
  606. package/src/lib/docs-frontmatter.ts +8 -79
  607. package/src/lib/docs-index.ts +33 -3
  608. package/src/lib/docs-lint.ts +15 -29
  609. package/src/lib/docs-metadata-audit.ts +166 -0
  610. package/src/lib/docs-metadata-managed.ts +83 -0
  611. package/src/lib/docs-metadata-sync.ts +262 -0
  612. package/src/lib/docs-metadata-v2-schema.ts +138 -0
  613. package/src/lib/docs-metadata-v2.ts +646 -0
  614. package/src/lib/docs-new.ts +63 -0
  615. package/src/lib/docs-sweep.ts +42 -28
  616. package/src/lib/headless/index.ts +287 -0
  617. package/src/lib/identities/assume.ts +67 -86
  618. package/src/lib/instructions/apply.ts +33 -20
  619. package/src/lib/instructions/bundle.ts +199 -0
  620. package/src/lib/instructions/splice.ts +21 -7
  621. package/src/lib/instructions/templates.ts +85 -13
  622. package/dist/core/agents/cli-emit.d.ts +0 -27
  623. package/dist/core/agents/cli-emit.d.ts.map +0 -1
  624. package/dist/core/agents/cli-emit.js +0 -57
  625. package/dist/core/agents/codex-replay.d.ts +0 -29
  626. package/dist/core/agents/codex-replay.d.ts.map +0 -1
  627. package/dist/core/agents/codex-replay.js +0 -138
  628. package/dist/core/agents/events/consume.d.ts +0 -82
  629. package/dist/core/agents/events/consume.d.ts.map +0 -1
  630. package/dist/core/agents/events/consume.js +0 -195
  631. package/dist/core/agents/events/emit.d.ts +0 -42
  632. package/dist/core/agents/events/emit.d.ts.map +0 -1
  633. package/dist/core/agents/events/emit.js +0 -75
  634. package/dist/core/agents/events/ulid.d.ts +0 -11
  635. package/dist/core/agents/events/ulid.d.ts.map +0 -1
  636. package/dist/core/agents/events/ulid.js +0 -47
  637. package/dist/core/agents/state/heartbeat-projector.d.ts +0 -65
  638. package/dist/core/agents/state/heartbeat-projector.d.ts.map +0 -1
  639. package/dist/core/agents/state/heartbeat-projector.js +0 -527
  640. package/dist/core/hooks/events/emit.d.ts +0 -31
  641. package/dist/core/hooks/events/emit.d.ts.map +0 -1
  642. package/dist/core/hooks/events/emit.js +0 -93
  643. package/dist/core/hooks/events/rotate.d.ts +0 -43
  644. package/dist/core/hooks/events/rotate.d.ts.map +0 -1
  645. package/dist/core/hooks/events/rotate.js +0 -142
  646. package/dist/core/hooks/events/schema.d.ts +0 -312
  647. package/dist/core/hooks/events/schema.d.ts.map +0 -1
  648. package/dist/core/hooks/events/schema.js +0 -12
  649. package/dist/core/hooks/events/ulid.d.ts +0 -10
  650. package/dist/core/hooks/events/ulid.d.ts.map +0 -1
  651. package/dist/core/hooks/events/ulid.js +0 -47
  652. package/dist/lib/docs-frontmatter-migrate.d.ts +0 -33
  653. package/dist/lib/docs-frontmatter-migrate.d.ts.map +0 -1
  654. package/dist/lib/docs-frontmatter-migrate.js +0 -364
  655. package/src/core/agents/cli-emit.ts +0 -64
  656. package/src/core/agents/codex-replay.ts +0 -163
  657. package/src/core/agents/events/consume.ts +0 -254
  658. package/src/core/agents/events/emit.ts +0 -115
  659. package/src/core/agents/events/ulid.ts +0 -51
  660. package/src/core/agents/state/heartbeat-projector.ts +0 -582
  661. package/src/core/hooks/events/emit.ts +0 -125
  662. package/src/core/hooks/events/rotate.ts +0 -151
  663. package/src/core/hooks/events/schema.ts +0 -538
  664. package/src/core/hooks/events/ulid.ts +0 -51
  665. package/src/lib/docs-frontmatter-migrate.ts +0 -427
@@ -1,170 +1,116 @@
1
1
  /**
2
- * Image-feed capture: a non-coordination side effect fired from the normalized
3
- * `agent-hook` tool handlers (see effects/index.ts for the family rationale).
2
+ * Privacy-safe image artifact capture for normalized tool hooks.
4
3
  *
5
- * When an agent VIEWS an image (Read tool on a `.png`/`.jpg`/…) or PRODUCES one
6
- * (a Bash command writes an image file via `harn browse`, `harn image`, `--diff`, …),
7
- * we content-address the bytes into `.harnery/images/<sha256>.<ext>` (dedup:
8
- * identical bytes collapse to one blob) and emit an `image.captured` event into
9
- * the canonical stream. The web image feed (`/images`) groups those events by
10
- * hash and streams them live over the existing SSE infra.
11
- *
12
- * Why this lives at the hook layer: it's the single adapter-agnostic chokepoint
13
- * that sees every tool call across Claude Code / Cursor / Codex with the full
14
- * `tool_input` (file paths) and `tool_response`. No per-command code needed.
15
- *
16
- * Everything here is best-effort and MUST NOT throw; callers wrap it in
17
- * try/catch + logError, matching every other effect.
4
+ * Image bytes are content-addressed under `.harnery/images/`. The canonical V3
5
+ * ledger receives an `artifact.observed` record after the source tool event is
6
+ * durable, so the web feed can recover provenance without retaining command,
7
+ * output, intent, or absolute paths.
18
8
  */
19
- import { createHash } from "node:crypto";
9
+ import { createHash, randomUUID } from "node:crypto";
20
10
  import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
21
- import { isAbsolute, join, resolve } from "node:path";
22
- import { emit } from "../events/emit.js";
23
- /** Raster + vector image extensions the feed accepts. PDF is intentionally
24
- * excluded: book renders aren't an "image feed" and don't thumbnail inline. */
11
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
12
+ import { buildEventV3 } from "../../events/v3/builder.js";
13
+ import { writeEventV3 } from "../../events/v3/writer.js";
25
14
  const IMAGE_EXTS = new Set(["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"]);
26
- /** Skip hashing files larger than this; screenshots are tens of KB; a huge
27
- * file mentioned in passing isn't worth the read. */
15
+ const MEDIA_TYPES = {
16
+ png: "image/png",
17
+ jpg: "image/jpeg",
18
+ jpeg: "image/jpeg",
19
+ gif: "image/gif",
20
+ webp: "image/webp",
21
+ bmp: "image/bmp",
22
+ svg: "image/svg+xml",
23
+ };
28
24
  const MAX_CAPTURE_BYTES = 25 * 1024 * 1024;
29
- /** A produced image must have been written within this window of the command
30
- * finishing, otherwise a path merely *mentioned* in output (an old baseline,
31
- * a doc reference) would be captured. Viewed images skip this gate. */
32
25
  const PRODUCED_MTIME_WINDOW_MS = 120_000;
33
- /** Matches image-ish paths in a command string or its output. Deliberately
34
- * permissive on the path body (`~`, `@`, `.`, `-`, `/`); existence + ext + the
35
- * mtime gate do the real filtering. */
36
- const IMAGE_PATH_RE = /[\w./~@+-]+\.(?:png|jpe?g|gif|webp|bmp|svg)\b/gi;
37
- /**
38
- * Inspect one tool event for image references and capture any that resolve to
39
- * a real image on disk. Emits zero or more `image.captured` events.
40
- */
41
- export function captureImages(coordRoot, ctx) {
42
- const imagesDir = join(coordRoot, ".harnery", "images");
43
- const cwd = resolveCwd(ctx.payload);
44
- const toolName = String(ctx.data.tool_name ?? "");
45
- const candidates = ctx.eventType === "tool.pre_use"
46
- ? collectViewed(toolName, ctx.data, cwd)
47
- : collectProduced(toolName, ctx.payload, cwd);
48
- if (candidates.length === 0)
49
- return;
50
- for (const cand of candidates) {
51
- // Never re-capture our own blob store (would loop on Reads of the gallery).
52
- if (cand.path.startsWith(`${imagesDir}/`))
26
+ const IMAGE_PATH_RE = /[\w./~@:+-]+\.(?:png|jpe?g|gif|webp|bmp|svg)\b/gi;
27
+ /** Copy every qualifying image referenced by one tool hook into the blob store. */
28
+ export function captureImages(coordRoot, eventType, payload) {
29
+ const images = join(coordRoot, ".harnery", "images");
30
+ const cwd = payload?.cwd ? resolve(payload.cwd) : process.cwd();
31
+ const toolName = payload?.tool_name ?? "";
32
+ const candidates = eventType === "tool.requested"
33
+ ? collectViewed(toolName, payload?.tool_input, cwd)
34
+ : collectProduced(toolName, payload, cwd);
35
+ const captured = [];
36
+ const seen = new Set();
37
+ for (const candidate of candidates) {
38
+ if (candidate.path.startsWith(`${images}${sep}`))
53
39
  continue;
54
- const captured = captureOne(imagesDir, cand);
55
- if (!captured)
40
+ const blob = captureOne(images, candidate);
41
+ if (!blob)
56
42
  continue;
57
- emit(coordRoot, {
58
- event_type: "image.captured",
59
- instance_id: ctx.instanceId,
60
- session_id: ctx.sessionId,
61
- adapter: ctx.adapter,
62
- data: {
63
- hash: captured.hash,
64
- ext: captured.ext,
65
- bytes: captured.bytes,
66
- role: cand.role,
67
- source_path: canonicalize(coordRoot, cand.path),
68
- tool_name: toolName,
69
- tool_use_id: ctx.data.tool_use_id,
70
- ...(cand.intent ? { intent: cand.intent } : {}),
71
- ...(cand.commandHead ? { command_head: cand.commandHead } : {}),
72
- },
73
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
74
- });
75
- }
76
- }
77
- /** Read tool → the file_path it's about to show (the "agent saw this" signal). */
78
- function collectViewed(toolName, data, cwd) {
79
- if (toolName !== "Read")
80
- return [];
81
- const input = parseToolInput(data.tool_input);
82
- const filePath = input?.file_path;
83
- if (typeof filePath !== "string" || !filePath)
84
- return [];
85
- if (!hasImageExt(filePath))
86
- return [];
87
- return [
88
- {
89
- path: toAbsolute(filePath, cwd),
90
- role: "viewed",
91
- intent: typeof data.intent === "string" ? data.intent : undefined,
92
- requireRecentMtime: false,
93
- },
94
- ];
95
- }
96
- /** Bash tool → scan the command + its output for freshly-written image files. */
97
- function collectProduced(toolName, payload, cwd) {
98
- if (toolName !== "Bash")
99
- return [];
100
- const command = bashCommand(payload);
101
- const responseText = stringifyResponse(payload?.tool_response);
102
- const commandHead = command ? command.slice(0, 120) : undefined;
103
- const seen = new Set();
104
- const out = [];
105
- for (const text of [command, responseText]) {
106
- if (!text)
43
+ const dedupeKey = `${blob.hash}:${candidate.role}`;
44
+ if (seen.has(dedupeKey))
107
45
  continue;
108
- for (const m of text.matchAll(IMAGE_PATH_RE)) {
109
- const raw = m[0];
110
- const abs = toAbsolute(raw, cwd);
111
- if (seen.has(abs))
112
- continue;
113
- seen.add(abs);
114
- out.push({ path: abs, role: "produced", commandHead, requireRecentMtime: true });
115
- }
46
+ seen.add(dedupeKey);
47
+ const workspacePath = safeWorkspacePath(coordRoot, candidate.path);
48
+ captured.push({
49
+ ...blob,
50
+ role: candidate.role,
51
+ ...(workspacePath ? { workspace_path: workspacePath } : {}),
52
+ });
116
53
  }
117
- return out;
54
+ return captured;
118
55
  }
119
56
  /**
120
- * Validate the candidate on disk, hash it, and copy into the content-addressed
121
- * store (skipping the copy when the blob already exists). Returns null when the
122
- * candidate doesn't qualify.
57
+ * Emit content-addressed image references as canonical V3 artifact events.
58
+ * Each observation uses a one-event producer boot, which preserves independent
59
+ * producer sequence continuity while the ledger writer serializes appends.
123
60
  */
124
- function captureOne(imagesDir, cand) {
125
- let st;
126
- try {
127
- st = statSync(cand.path);
128
- }
129
- catch {
130
- return null; // path doesn't exist (common for "produced" false-positives)
131
- }
132
- if (!st.isFile() || st.size === 0 || st.size > MAX_CAPTURE_BYTES)
133
- return null;
134
- if (cand.requireRecentMtime && Date.now() - st.mtimeMs > PRODUCED_MTIME_WINDOW_MS) {
135
- return null; // mentioned but not freshly produced by this command
136
- }
137
- const ext = extOf(cand.path);
138
- if (!ext || !IMAGE_EXTS.has(ext))
139
- return null;
140
- let bytes;
141
- try {
142
- bytes = readFileSync(cand.path);
143
- }
144
- catch {
145
- return null;
61
+ export function recordImageArtifactsV3(coordRoot, sourceEvent, artifacts) {
62
+ if (!("generation_id" in sourceEvent.scope) || !sourceEvent.attestation_id)
63
+ return;
64
+ for (const artifact of artifacts) {
65
+ writeEventV3(coordRoot, buildImageArtifactEventV3(sourceEvent, artifact));
146
66
  }
147
- const hash = createHash("sha256").update(bytes).digest("hex");
148
- const dest = join(imagesDir, `${hash}.${ext}`);
149
- if (!existsSync(dest)) {
150
- try {
151
- mkdirSync(imagesDir, { recursive: true });
152
- const tmp = `${dest}.tmp.${process.pid}`;
153
- writeFileSync(tmp, bytes);
154
- renameSync(tmp, dest);
155
- }
156
- catch {
157
- return null; // couldn't store, don't emit a dangling event
158
- }
67
+ }
68
+ export function buildImageArtifactEventV3(sourceEvent, artifact) {
69
+ if (!("generation_id" in sourceEvent.scope) || !sourceEvent.attestation_id) {
70
+ throw new Error("image artifacts require a generation-scoped source event");
159
71
  }
160
- return { hash, ext, bytes: st.size };
72
+ return buildEventV3("artifact.observed", {
73
+ producer: {
74
+ producer_id: "prd_agent-hook-image-capture",
75
+ boot_id: `boot_${randomUUID()}`,
76
+ sequence: 1,
77
+ component: "agent-hook",
78
+ build_id: sourceEvent.producer.build_id,
79
+ platform: sourceEvent.producer.platform,
80
+ ...(sourceEvent.producer.bridge ? { bridge: sourceEvent.producer.bridge } : {}),
81
+ },
82
+ scope: {
83
+ root_id: sourceEvent.scope.root_id,
84
+ instance_id: sourceEvent.scope.instance_id,
85
+ session_id: sourceEvent.scope.session_id,
86
+ generation_id: sourceEvent.scope.generation_id,
87
+ ...(sourceEvent.scope.run_id ? { run_id: sourceEvent.scope.run_id } : {}),
88
+ ...(sourceEvent.scope.workflow_id ? { workflow_id: sourceEvent.scope.workflow_id } : {}),
89
+ ...(sourceEvent.scope.workflow_agent_id
90
+ ? { workflow_agent_id: sourceEvent.scope.workflow_agent_id }
91
+ : {}),
92
+ },
93
+ attestation_id: sourceEvent.attestation_id,
94
+ links: { caused_by: [sourceEvent.event_id] },
95
+ provenance: {
96
+ ...sourceEvent.provenance,
97
+ attestation: "derived",
98
+ confidence: "high",
99
+ },
100
+ payload: {
101
+ artifact: {
102
+ artifact_id: `art_${artifact.hash}`,
103
+ kind: "image",
104
+ media_type: MEDIA_TYPES[artifact.ext] ?? "image/png",
105
+ bytes: artifact.bytes,
106
+ retention_class: "bounded_local",
107
+ ...(artifact.workspace_path ? { workspace_path: artifact.workspace_path } : {}),
108
+ },
109
+ operation: artifact.role === "viewed" ? "viewed" : "created",
110
+ },
111
+ });
161
112
  }
162
- /**
163
- * Prune `.harnery/images/` past a size cap (default 2 GB) and an age cap
164
- * (default 30 days), oldest-mtime-first. Fired on session.start next to
165
- * journalJanitor. Pure-fs, fail-soft. Orphaned `image.captured` events whose
166
- * blob was pruned render as an "expired" placeholder in the gallery.
167
- */
113
+ /** Prune the bounded blob store by age and total size, oldest first. */
168
114
  export function imageJanitor(coordRoot) {
169
115
  try {
170
116
  const dir = join(coordRoot, ".harnery", "images");
@@ -176,113 +122,158 @@ export function imageJanitor(coordRoot) {
176
122
  const entries = [];
177
123
  for (const name of readdirSync(dir)) {
178
124
  if (name.endsWith(".tmp") || name.includes(".tmp.")) {
179
- // Orphaned temp from a crashed copy; sweep it.
180
125
  rmSync(join(dir, name), { force: true });
181
126
  continue;
182
127
  }
183
128
  const full = join(dir, name);
184
- let st;
185
129
  try {
186
- st = statSync(full);
130
+ const stat = statSync(full);
131
+ if (stat.isFile())
132
+ entries.push({ path: full, size: stat.size, mtimeMs: stat.mtimeMs });
187
133
  }
188
134
  catch {
189
- continue;
135
+ // A concurrent cleanup or write can make one entry disappear.
190
136
  }
191
- if (!st.isFile())
192
- continue;
193
- entries.push({ path: full, size: st.size, mtimeMs: st.mtimeMs });
194
137
  }
195
- // Age cap.
196
138
  let total = 0;
197
139
  const survivors = [];
198
- for (const e of entries) {
199
- if (now - e.mtimeMs > maxAgeMs) {
200
- rmSync(e.path, { force: true });
201
- continue;
140
+ for (const entry of entries) {
141
+ if (now - entry.mtimeMs > maxAgeMs) {
142
+ rmSync(entry.path, { force: true });
202
143
  }
203
- total += e.size;
204
- survivors.push(e);
205
- }
206
- // Size cap: drop oldest first until under.
207
- if (total > maxBytes) {
208
- survivors.sort((a, b) => a.mtimeMs - b.mtimeMs);
209
- for (const e of survivors) {
210
- if (total <= maxBytes)
211
- break;
212
- rmSync(e.path, { force: true });
213
- total -= e.size;
144
+ else {
145
+ total += entry.size;
146
+ survivors.push(entry);
214
147
  }
215
148
  }
149
+ survivors.sort((a, b) => a.mtimeMs - b.mtimeMs);
150
+ for (const entry of survivors) {
151
+ if (total <= maxBytes)
152
+ break;
153
+ rmSync(entry.path, { force: true });
154
+ total -= entry.size;
155
+ }
216
156
  }
217
157
  catch {
218
- // best-effort
158
+ // Hook effects are always best-effort.
219
159
  }
220
160
  }
221
- /* ── helpers ─────────────────────────────────────────────────────────────── */
222
- function envInt(name, fallback) {
223
- const v = process.env[name];
224
- if (!v)
225
- return fallback;
226
- const n = Number(v);
227
- return Number.isFinite(n) && n > 0 ? n : fallback;
161
+ function collectViewed(toolName, toolInput, cwd) {
162
+ const name = normalizedToolName(toolName);
163
+ if (name !== "read" && name !== "view_image" && name !== "image")
164
+ return [];
165
+ const input = objectInput(toolInput);
166
+ const filePath = input?.file_path ?? input?.path ?? input?.image_path;
167
+ if (typeof filePath !== "string" || !hasImageExt(filePath))
168
+ return [];
169
+ return [{ path: toAbsolute(filePath, cwd), role: "viewed", requireRecentMtime: false }];
228
170
  }
229
- function parseToolInput(raw) {
230
- if (typeof raw !== "string")
231
- return null;
171
+ function collectProduced(toolName, payload, cwd) {
172
+ const name = normalizedToolName(toolName);
173
+ const producerTools = new Set([
174
+ "bash",
175
+ "shell",
176
+ "exec_command",
177
+ "imagegen",
178
+ "image_gen",
179
+ "browse",
180
+ "browse_ai",
181
+ "screenshot",
182
+ ]);
183
+ if (!producerTools.has(name))
184
+ return [];
185
+ const input = objectInput(payload?.tool_input);
186
+ const command = [input?.command, input?.cmd].find((value) => typeof value === "string") ?? "";
187
+ const response = stringify(payload?.tool_response).slice(0, 2_000_000);
188
+ const seen = new Set();
189
+ const out = [];
190
+ for (const text of [String(command), response]) {
191
+ for (const match of text.matchAll(IMAGE_PATH_RE)) {
192
+ const absolute = toAbsolute(match[0], cwd);
193
+ if (seen.has(absolute))
194
+ continue;
195
+ seen.add(absolute);
196
+ out.push({ path: absolute, role: "produced", requireRecentMtime: true });
197
+ }
198
+ }
199
+ return out;
200
+ }
201
+ function captureOne(imagesDir, candidate) {
232
202
  try {
233
- const parsed = JSON.parse(raw);
234
- return parsed && typeof parsed === "object" ? parsed : null;
203
+ const stat = statSync(candidate.path);
204
+ if (!stat.isFile() || stat.size === 0 || stat.size > MAX_CAPTURE_BYTES)
205
+ return null;
206
+ if (candidate.requireRecentMtime && Date.now() - stat.mtimeMs > PRODUCED_MTIME_WINDOW_MS) {
207
+ return null;
208
+ }
209
+ const ext = extOf(candidate.path);
210
+ if (!IMAGE_EXTS.has(ext))
211
+ return null;
212
+ const bytes = readFileSync(candidate.path);
213
+ const hash = createHash("sha256").update(bytes).digest("hex");
214
+ const destination = join(imagesDir, `${hash}.${ext}`);
215
+ if (!existsSync(destination)) {
216
+ mkdirSync(imagesDir, { recursive: true });
217
+ const temporary = `${destination}.tmp.${process.pid}.${randomUUID().slice(0, 8)}`;
218
+ writeFileSync(temporary, bytes, { mode: 0o600 });
219
+ renameSync(temporary, destination);
220
+ }
221
+ return { hash, ext, bytes: stat.size };
235
222
  }
236
223
  catch {
237
224
  return null;
238
225
  }
239
226
  }
240
- /** The un-clamped Bash command from the raw payload (falls back to clamped). */
241
- function bashCommand(payload) {
242
- const ti = payload?.raw?.tool_input;
243
- const cmd = ti?.command;
244
- return typeof cmd === "string" ? cmd : "";
227
+ function normalizedToolName(value) {
228
+ return (value.split(/[.:/]/).pop() ?? value).toLowerCase().replaceAll("-", "_");
245
229
  }
246
- function stringifyResponse(value) {
247
- if (value == null)
248
- return "";
230
+ function objectInput(value) {
231
+ if (value && typeof value === "object" && !Array.isArray(value)) {
232
+ return value;
233
+ }
234
+ if (typeof value !== "string")
235
+ return null;
236
+ try {
237
+ const parsed = JSON.parse(value);
238
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
239
+ ? parsed
240
+ : null;
241
+ }
242
+ catch {
243
+ return null;
244
+ }
245
+ }
246
+ function stringify(value) {
249
247
  if (typeof value === "string")
250
248
  return value;
251
249
  try {
252
- return JSON.stringify(value);
250
+ return JSON.stringify(value ?? "");
253
251
  }
254
252
  catch {
255
253
  return "";
256
254
  }
257
255
  }
258
- function resolveCwd(payload) {
259
- const raw = payload?.raw;
260
- const cwd = raw?.cwd;
261
- return typeof cwd === "string" && cwd ? cwd : process.cwd();
256
+ function toAbsolute(value, cwd) {
257
+ if (value.startsWith("~/") && process.env.HOME)
258
+ return resolve(process.env.HOME, value.slice(2));
259
+ return isAbsolute(value) ? resolve(value) : resolve(cwd, value);
262
260
  }
263
- function hasImageExt(p) {
264
- const ext = extOf(p);
265
- return !!ext && IMAGE_EXTS.has(ext);
261
+ function safeWorkspacePath(coordRoot, value) {
262
+ const rel = relative(resolve(coordRoot), resolve(value));
263
+ if (!rel || isAbsolute(rel) || rel === ".." || rel.startsWith(`..${sep}`))
264
+ return undefined;
265
+ const normalized = rel.split(sep).join("/");
266
+ return normalized.length <= 240 && !normalized.startsWith("/") ? normalized : undefined;
266
267
  }
267
- function extOf(p) {
268
- const clean = p.split(/[?#]/)[0] ?? p; // drop any query/fragment
269
- const dot = clean.lastIndexOf(".");
270
- if (dot < 0)
271
- return "";
272
- return clean.slice(dot + 1).toLowerCase();
268
+ function hasImageExt(value) {
269
+ return IMAGE_EXTS.has(extOf(value));
273
270
  }
274
- function toAbsolute(p, cwd) {
275
- let path = p;
276
- if (path.startsWith("~/")) {
277
- const home = process.env.HOME;
278
- if (home)
279
- path = join(home, path.slice(2));
280
- }
281
- return isAbsolute(path) ? path : resolve(cwd, path);
271
+ function extOf(value) {
272
+ const clean = value.split(/[?#]/)[0] ?? value;
273
+ const dot = clean.lastIndexOf(".");
274
+ return dot < 0 ? "" : clean.slice(dot + 1).toLowerCase();
282
275
  }
283
- /** Strip the coordRoot prefix so the feed shows repo-relative paths. */
284
- function canonicalize(coordRoot, p) {
285
- if (p.startsWith(`${coordRoot}/`))
286
- return p.slice(coordRoot.length + 1);
287
- return p;
276
+ function envInt(name, fallback) {
277
+ const parsed = Number(process.env[name]);
278
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
288
279
  }
@@ -11,8 +11,7 @@
11
11
  * Everything here is best-effort: it never throws and never blocks the hook on a
12
12
  * slow dependency (telemetry runs detached).
13
13
  */
14
- export type { CaptureContext } from "./image-capture.js";
15
- export { captureImages, imageJanitor } from "./image-capture.js";
14
+ export { captureImages, imageJanitor, recordImageArtifactsV3 } from "./image-capture.js";
16
15
  /**
17
16
  * Play a notification sound via the cross-platform utility
18
17
  * (afplay on macOS, powershell.exe on WSL). The
@@ -49,13 +48,6 @@ export declare function journalArchive(repoRoot: string, owner: string): void;
49
48
  * adapter.
50
49
  */
51
50
  export declare function runSessionSyncExtension(repoRoot: string, force: boolean): void;
52
- /**
53
- * Fire the turn-summary extension (Haiku auto-summary of the turn → heartbeat
54
- * `turn_summary`). Detached + unref'd; it makes an Anthropic API call and must
55
- * never block the Stop hook. Claude-Code-only. The
56
- * script self-guards on ANTHROPIC_API_KEY / curl / jq / matching session.
57
- */
58
- export declare function runTurnSummary(repoRoot: string, owner: string, sessionId: string, transcriptPath: string | undefined): void;
59
51
  /** Reset per-turn sound rate-limit counters at the start of a new turn. */
60
52
  export declare function resetSoundCounters(sessionId: string): void;
61
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/effects/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAI,GACX,IAAI,CAYN;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAW3F;AAMD,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAYrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAYpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAqB9E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,IAAI,CAqBN;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAa1D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOnD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/effects/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAI,GACX,IAAI,CAYN;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAW3F;AAMD,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAYrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAYpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAqB9E;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAa1D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOnD"}
@@ -17,7 +17,7 @@ import os from "node:os";
17
17
  import { join } from "node:path";
18
18
  import { applyDetection } from "../../../lib/presence.js";
19
19
  import { coordBinPath } from "../../agents/coord-bin.js";
20
- export { captureImages, imageJanitor } from "./image-capture.js";
20
+ export { captureImages, imageJanitor, recordImageArtifactsV3 } from "./image-capture.js";
21
21
  /**
22
22
  * Play a notification sound via the cross-platform utility
23
23
  * (afplay on macOS, powershell.exe on WSL). The
@@ -137,29 +137,6 @@ export function runSessionSyncExtension(repoRoot, force) {
137
137
  // best-effort
138
138
  }
139
139
  }
140
- /**
141
- * Fire the turn-summary extension (Haiku auto-summary of the turn → heartbeat
142
- * `turn_summary`). Detached + unref'd; it makes an Anthropic API call and must
143
- * never block the Stop hook. Claude-Code-only. The
144
- * script self-guards on ANTHROPIC_API_KEY / curl / jq / matching session.
145
- */
146
- export function runTurnSummary(repoRoot, owner, sessionId, transcriptPath) {
147
- try {
148
- if (!transcriptPath || !existsSync(transcriptPath))
149
- return;
150
- const script = join(repoRoot, "scripts", "hooks", "harness", "claude-code", "extensions", "turn-summary.sh");
151
- if (!existsSync(script))
152
- return;
153
- const child = spawn("bash", [script, owner, sessionId, transcriptPath], {
154
- detached: true,
155
- stdio: "ignore",
156
- });
157
- child.unref();
158
- }
159
- catch {
160
- // best-effort
161
- }
162
- }
163
140
  /** Reset per-turn sound rate-limit counters at the start of a new turn. */
164
141
  export function resetSoundCounters(sessionId) {
165
142
  try {
@@ -0,0 +1,7 @@
1
+ /** Canonical JSON for hashing adapter input before any event-payload clamp. */
2
+ export declare function canonicalToolInput(value: unknown): string;
3
+ /** Exact-input digest used by the report-only run-quality evaluator. */
4
+ export declare function toolInputHash(toolName: string, input: unknown): string;
5
+ /** Hash a semantic target without persisting its path, URL, or query. */
6
+ export declare function toolTargetHash(toolName: string, input: unknown): string | undefined;
7
+ //# sourceMappingURL=input-hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-hash.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/events/input-hash.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEzD;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAMtE;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAgBnF"}
@@ -0,0 +1,43 @@
1
+ import { createHash } from "node:crypto";
2
+ /** Canonical JSON for hashing adapter input before any event-payload clamp. */
3
+ export function canonicalToolInput(value) {
4
+ return JSON.stringify(canonicalize(value));
5
+ }
6
+ /** Exact-input digest used by the report-only run-quality evaluator. */
7
+ export function toolInputHash(toolName, input) {
8
+ return createHash("sha256")
9
+ .update(toolName)
10
+ .update("\n")
11
+ .update(canonicalToolInput(input))
12
+ .digest("hex");
13
+ }
14
+ /** Hash a semantic target without persisting its path, URL, or query. */
15
+ export function toolTargetHash(toolName, input) {
16
+ if (!input || typeof input !== "object" || Array.isArray(input))
17
+ return undefined;
18
+ const record = input;
19
+ const target = record.file_path ??
20
+ record.path ??
21
+ record.target ??
22
+ record.url ??
23
+ record.notebook_path ??
24
+ record.pattern;
25
+ if (target === undefined)
26
+ return undefined;
27
+ return createHash("sha256")
28
+ .update(toolName)
29
+ .update("\n")
30
+ .update(canonicalToolInput(target))
31
+ .digest("hex");
32
+ }
33
+ function canonicalize(value) {
34
+ if (Array.isArray(value))
35
+ return value.map(canonicalize);
36
+ if (value && typeof value === "object") {
37
+ const record = value;
38
+ return Object.fromEntries(Object.keys(record)
39
+ .sort()
40
+ .map((key) => [key, canonicalize(record[key])]));
41
+ }
42
+ return value;
43
+ }
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * agent-hooks library exports.
3
3
  *
4
- * Phase 1 (skeleton): exposes only the canonical event schema types. Parsers,
5
- * resolvers, and emit helpers ship in Phase 2.
4
+ * Public hook types for the canonical V3 ledger.
6
5
  */
7
- export { type Adapter, type Event, type EventEnvelope, type EventType, type RedactionMarker, SCHEMA_VERSION, type Source, } from "./events/schema.js";
6
+ export type { Adapter } from "../adapter.js";
7
+ export type { EventV3 as Event } from "../events/v3/contract.js";
8
+ export { EventV3Schema } from "../events/v3/contract.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,cAAc,EACd,KAAK,MAAM,GACZ,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}