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,6 +1,7 @@
1
1
  import type { Command } from "commander";
2
2
  import type { EmitContext, HarneryProgramContext } from "../commander.ts";
3
- import { monorepoRoot, readHeartbeat, resolveOwner } from "../core/agents/index.ts";
3
+ import { monorepoRoot, resolveOwner } from "../core/agents/index.ts";
4
+ import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.ts";
4
5
  import {
5
6
  type ArtifactActor,
6
7
  cleanArtifacts,
@@ -30,7 +31,7 @@ export function registerArtifactsCommand(
30
31
  .action((slug: string, opts: { purpose: string; days?: string }) => {
31
32
  run(emit, () => {
32
33
  const repoRoot = requireRepoRoot(context);
33
- const actor = currentActor();
34
+ const actor = currentActor(repoRoot);
34
35
  const retentionDays = opts.days
35
36
  ? parseDays(opts.days)
36
37
  : artifactDefaultRetentionDays(repoRoot);
@@ -85,7 +86,7 @@ export function registerArtifactsCommand(
85
86
  run(emit, () => {
86
87
  const repoRoot = requireRepoRoot(context);
87
88
  const manifest = renewArtifact(repoRoot, ref, parseDays(opts.days), opts.reason, {
88
- actor: currentActor(),
89
+ actor: currentActor(repoRoot),
89
90
  });
90
91
  emit.data(manifest);
91
92
  });
@@ -97,7 +98,7 @@ export function registerArtifactsCommand(
97
98
  .action((ref: string) => {
98
99
  run(emit, () => {
99
100
  const repoRoot = requireRepoRoot(context);
100
- emit.data(releaseArtifact(repoRoot, ref, { actor: currentActor() }));
101
+ emit.data(releaseArtifact(repoRoot, ref, { actor: currentActor(repoRoot) }));
101
102
  });
102
103
  });
103
104
 
@@ -117,10 +118,10 @@ export function registerArtifactsCommand(
117
118
  });
118
119
  }
119
120
 
120
- function currentActor(): ArtifactActor | undefined {
121
+ function currentActor(repoRoot: string): ArtifactActor | undefined {
121
122
  const instanceId = resolveOwner();
122
123
  if (!instanceId) return undefined;
123
- const hb = readHeartbeat(instanceId);
124
+ const hb = readLiveCoordinationRow(repoRoot, instanceId);
124
125
  return {
125
126
  instance_id: instanceId,
126
127
  session_id: hb?.session_id,
@@ -6,7 +6,7 @@
6
6
  * paths and are init'd on first `harn backup init`. Subcommands:
7
7
  *
8
8
  * init restic init the repo (one-time)
9
- * snapshot restic backup .harnery/ (working artifacts excluded)
9
+ * snapshot restic backup of the durable, privacy-safe V3 state
10
10
  * list restic snapshots
11
11
  * restore restic restore <id>
12
12
  * prune restic forget --keep-daily 7 --keep-weekly 4 --prune
@@ -134,17 +134,11 @@ export function registerBackupCommand(program: Command, emit: EmitContext): void
134
134
  backup
135
135
  .command("snapshot")
136
136
  .description(
137
- "Take a restic snapshot of .harnery/ (excluding events.ndjson and " +
138
- ".lock files and artifacts/ by default). Pass --target to back up a different path.",
137
+ "Take a restic snapshot of the durable, privacy-safe V3 ledger and coordination state.",
139
138
  )
140
- .option("--target <path>", "Path to snapshot (default: .harnery/ from cwd walk-up)")
141
139
  .option("--tag <tag>", "Restic tag (repeatable)", collect, [] as string[])
142
140
  .option("--repo <path>", "Repository path")
143
141
  .option("--password-file <path>", "Password file")
144
- .option(
145
- "--include-events",
146
- "Don't exclude events.ndjson (default: excluded; large + machine-local)",
147
- )
148
142
  .option(
149
143
  "--include-artifacts",
150
144
  "Include managed working artifacts (default: excluded; potentially large + ephemeral)",
@@ -152,9 +146,7 @@ export function registerBackupCommand(program: Command, emit: EmitContext): void
152
146
  .action(
153
147
  (
154
148
  opts: BaseOpts & {
155
- target?: string;
156
149
  tag: string[];
157
- includeEvents?: boolean;
158
150
  includeArtifacts?: boolean;
159
151
  },
160
152
  ) => {
@@ -162,27 +154,43 @@ export function registerBackupCommand(program: Command, emit: EmitContext): void
162
154
  emit.setExitCode(1);
163
155
  return;
164
156
  }
165
- const target = opts.target ?? findHarneryDir();
166
- if (!target) {
157
+ const harnery = findHarneryDir();
158
+ if (!harnery) {
167
159
  emit.error({
168
160
  code: "target_missing",
169
- message:
170
- "No .harnery/ found above cwd; pass --target explicitly or run from a monorepo with .harnery/",
161
+ message: "No .harnery/ found above cwd; run from an initialized project",
171
162
  });
172
163
  emit.setExitCode(1);
173
164
  return;
174
165
  }
175
166
  const passThrough: string[] = [];
176
- if (!opts.includeEvents) {
177
- passThrough.push("--exclude", "events.ndjson");
178
- passThrough.push("--exclude", ".lock");
179
- passThrough.push("--exclude", ".log.lock");
180
- }
181
- if (!opts.includeArtifacts) passThrough.push("--exclude", "artifacts");
182
167
  for (const t of opts.tag) {
183
168
  passThrough.push("--tag", t);
184
169
  }
185
- const r = runRestic(["backup", target], {
170
+ const safeTargets = [
171
+ "ledgers",
172
+ "councils",
173
+ "journal",
174
+ "work",
175
+ "workflows",
176
+ "decisions",
177
+ "config.jsonc",
178
+ ".name-history",
179
+ ]
180
+ .map((entry) => path.join(harnery, entry))
181
+ .filter(existsSync);
182
+ if (opts.includeArtifacts && existsSync(path.join(harnery, "artifacts"))) {
183
+ safeTargets.push(path.join(harnery, "artifacts"));
184
+ }
185
+ if (safeTargets.length === 0) {
186
+ emit.error({
187
+ code: "backup_empty",
188
+ message: "No durable V3 state is available to back up",
189
+ });
190
+ emit.setExitCode(1);
191
+ return;
192
+ }
193
+ const r = runRestic(["backup", ...safeTargets], {
186
194
  repo: opts.repo,
187
195
  passwordFile: opts.passwordFile,
188
196
  stdio: "inherit",
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
1
+ import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, isAbsolute, resolve } from "node:path";
4
4
  import type { Command } from "commander";
@@ -33,6 +33,24 @@ import {
33
33
  writeNetscapeCookieFile,
34
34
  wslHeadedLaunchArgs,
35
35
  } from "../lib/browser/index.ts";
36
+ import {
37
+ buildQaManifest,
38
+ classifySignatures,
39
+ type QaClassification,
40
+ type QaContext,
41
+ type QaManifest,
42
+ type QaScope,
43
+ type QaSignature,
44
+ } from "../lib/browser/qa-plan.ts";
45
+ import {
46
+ type CritiqueReusePlan,
47
+ DEFAULT_REUSE_MISMATCH_RATIO,
48
+ type PersistedCritique,
49
+ planCritiqueReuse,
50
+ QA_CRITIQUE_CONTRACT_VERSION,
51
+ rubricDigest,
52
+ } from "../lib/browser/qa-reuse.ts";
53
+ import { loadQaSnapshot, resolveQaBaseline, saveQaSnapshot } from "../lib/browser/qa-snapshot.ts";
36
54
  import {
37
55
  type BrowserSessionServer,
38
56
  startBrowserSessionServer,
@@ -181,6 +199,16 @@ interface BrowseOpts {
181
199
  diff?: string;
182
200
  diffThreshold?: string;
183
201
  diffFail?: boolean;
202
+ // Diff-aware QA planning (qa-plan.ts / qa-snapshot.ts)
203
+ qaPlan?: boolean;
204
+ qaSnapshot?: boolean;
205
+ qaTarget?: string;
206
+ qaTheme?: string;
207
+ qaState?: string;
208
+ qaScope?: string[];
209
+ qaStates?: string[];
210
+ qaReuse?: boolean;
211
+ qaReuseThreshold?: string;
184
212
  // Next.js dev-overlay capture (auto-on; --no-dev-overlay opts out)
185
213
  devOverlay?: boolean;
186
214
  }
@@ -590,6 +618,67 @@ export function registerBrowseCommand(
590
618
  "--diff-fail",
591
619
  "Exit non-zero if --diff mismatchRatio exceeds --diff-threshold; requires --diff.",
592
620
  )
621
+ .option(
622
+ "--qa-plan",
623
+ "Classify this render against the persisted QA baseline and emit a review manifest " +
624
+ "(change class, scope selectors, required contexts, provider-call ceiling) under " +
625
+ "`qaPlan` in the JSON envelope — BEFORE any vision spend. Text/data-only edits plan " +
626
+ "zero model calls; ambiguity widens, never narrows. Baseline comes from the snapshot " +
627
+ "store (seed one with --qa-snapshot); no baseline classifies as `unknown`.",
628
+ )
629
+ .option(
630
+ "--qa-snapshot",
631
+ "Persist this render (signature + DOM + full-page screenshot) as the QA baseline for the " +
632
+ "target + context, replacing any prior snapshot atomically. Run it on a page state you " +
633
+ "trust — typically right after a passing QA run — so the next --qa-plan inherits its " +
634
+ "baseline for free.",
635
+ )
636
+ .option(
637
+ "--qa-target <key>",
638
+ "Override the snapshot-store key (default: the url argument). Lets a production render " +
639
+ "seed the baseline for a local file/route: browse the prod URL with --qa-snapshot " +
640
+ "--qa-target <local-target>, then --qa-plan the local target.",
641
+ )
642
+ .option(
643
+ "--qa-theme <theme>",
644
+ "Context label for the QA snapshot store: light | dark (default light). Labels the " +
645
+ "stored/compared context; it does not switch the page's rendered theme.",
646
+ "light",
647
+ )
648
+ .option(
649
+ "--qa-state <name>",
650
+ "Context state label for the QA snapshot store (default 'default').",
651
+ "default",
652
+ )
653
+ .option(
654
+ "--qa-scope <selector>",
655
+ "Explicit scope selector from the producing task (repeatable) — resolution-order rung 1; " +
656
+ "overrides lifted anchors in the --qa-plan manifest.",
657
+ (value: string, previous: string[] = []) => [...previous, value],
658
+ [] as string[],
659
+ )
660
+ .option(
661
+ "--qa-states <names>",
662
+ "Comma-separated interaction states to review (promotes the plan to interaction-state).",
663
+ (value: string) =>
664
+ value
665
+ .split(",")
666
+ .map((s) => s.trim())
667
+ .filter(Boolean),
668
+ )
669
+ .option(
670
+ "--qa-reuse",
671
+ "Reuse the baseline run's critique verdicts for tiles whose pixels provably didn't " +
672
+ "change (band-diff against the persisted --qa-snapshot screenshot; strict mismatch " +
673
+ "threshold). Only clean regions are reused — a region with baseline findings or any " +
674
+ "pixel drift is always re-reviewed. Requires --check-critique; misses degrade to a " +
675
+ "full fresh review, never an error. Stats land under `qaReuse` in the JSON envelope.",
676
+ )
677
+ .option(
678
+ "--qa-reuse-threshold <ratio>",
679
+ "Band-diff mismatch ratio at or below which a clean tile region is reused " +
680
+ `(default ${DEFAULT_REUSE_MISMATCH_RATIO}; lower it toward 0 for stricter reuse).`,
681
+ )
593
682
  .option(
594
683
  "--no-dev-overlay",
595
684
  "Skip auto-capture of Next.js dev-overlay issues. Default: capture every queued error (kind/code/message/stack) when a <nextjs-portal> shadow root is present. Necessary because Next.js 16 + React 19 route hydration errors + most React warnings through onCaughtError → next-devtools' errorQueue, NOT through console.error, so Playwright's standard listener doesn't see them. Surfaces them in the JSON envelope under `devOverlay`.",
@@ -818,18 +907,139 @@ async function runBrowse(
818
907
  opts.checkContrast !== undefined ? { scope: contentScope(opts.checkContrast) } : null,
819
908
  });
820
909
  }
910
+ // Diff-aware QA planning. Signature capture must also happen BEFORE any
911
+ // annotation overlays are injected — an annotation box is a DOM change.
912
+ let qaPlan: QaPlanReport | undefined;
913
+ let qaCapture: QaCaptureState | undefined;
914
+ if (opts.qaPlan || opts.qaSnapshot) {
915
+ const qa = await runQaPlanning(browser, url, navResult.url, opts);
916
+ qaPlan = qa.report;
917
+ qaCapture = qa.capture;
918
+ if (qaPlan?.manifest) {
919
+ const m = qaPlan.manifest;
920
+ emit.log(
921
+ `qa-plan: class=${m.change_class} scopes=${m.scopes.map((s) => s.selector).join(",") || "-"} ` +
922
+ `contexts=${m.contexts.length} model-calls<=${m.predicted.model_calls_ceiling} baseline=${m.baseline_source}`,
923
+ "info",
924
+ );
925
+ }
926
+ }
821
927
  // Vision critique. Capture tiles BEFORE any annotation overlays are injected
822
928
  // so the model sees the real page, not our boxes.
823
929
  let critique: CritiqueResult | undefined;
930
+ let qaReuse: CritiqueReusePlan | undefined;
931
+ let critiqueTiles: CritiqueTile[] | undefined;
932
+ let critiqueFullPage: Buffer | undefined;
824
933
  if (opts.checkCritique !== undefined) {
825
- const tiles = await captureCritiqueTiles(browser, opts);
934
+ const rubric = opts.checkCritiqueRubric ?? DEFAULT_CRITIQUE_RUBRIC;
935
+ const captured = await captureCritiqueTiles(
936
+ browser,
937
+ opts,
938
+ context?.critiqueProvider?.tileBudgetPx,
939
+ );
940
+ critiqueTiles = captured.tiles;
941
+ critiqueFullPage = captured.fullPage;
942
+ let tilesToReview = captured.tiles;
943
+ if (opts.qaReuse) {
944
+ const reuseContext: QaContext = {
945
+ viewport: opts.viewport ?? "desktop",
946
+ theme: opts.qaTheme === "dark" ? "dark" : "light",
947
+ state: opts.qaState ?? "default",
948
+ };
949
+ const stored = loadQaSnapshot(opts.qaTarget ?? url, reuseContext, {});
950
+ if (stored?.screenshotPath && stored.critique) {
951
+ qaReuse = planCritiqueReuse({
952
+ baselineScreenshot: readFileSync(stored.screenshotPath),
953
+ baselineCritique: stored.critique,
954
+ currentScreenshot: captured.fullPage,
955
+ tiles: captured.tiles,
956
+ rubric,
957
+ mismatchThreshold: opts.qaReuseThreshold
958
+ ? Number.parseFloat(opts.qaReuseThreshold)
959
+ : undefined,
960
+ });
961
+ } else {
962
+ qaReuse = {
963
+ mode: "band-diff",
964
+ review: captured.tiles,
965
+ decisions: [],
966
+ tiles_total: captured.tiles.length,
967
+ tiles_reused: 0,
968
+ tiles_reviewed: captured.tiles.length,
969
+ provider_calls_avoided: 0,
970
+ mismatch_threshold: DEFAULT_REUSE_MISMATCH_RATIO,
971
+ invalidation:
972
+ "no persisted baseline snapshot with critique results for this target/context",
973
+ };
974
+ }
975
+ tilesToReview = qaReuse.review;
976
+ emit.log(
977
+ `qa-reuse: ${qaReuse.tiles_reused}/${qaReuse.tiles_total} tiles reused (band-diff), ` +
978
+ `${qaReuse.tiles_reviewed} reviewed fresh${qaReuse.invalidation ? ` — ${qaReuse.invalidation}` : ""}`,
979
+ "info",
980
+ );
981
+ }
826
982
  critique = await runCritique({
827
983
  url: navResult.url,
828
- rubric: opts.checkCritiqueRubric ?? DEFAULT_CRITIQUE_RUBRIC,
829
- tiles,
984
+ rubric,
985
+ tiles: tilesToReview,
830
986
  provider: context?.critiqueProvider,
831
987
  });
832
988
  }
989
+ // Persist the QA baseline AFTER critique so a passing run's verdicts ride
990
+ // along with the snapshot (still before annotations mutate the page).
991
+ if (opts.qaSnapshot && qaCapture) {
992
+ const screenshotPng = critiqueFullPage ?? (await browser.fullPageScreenshotBuffer());
993
+ // Persist critique results only when the full tile set was freshly
994
+ // reviewed — a partially-reused run must never become the next
995
+ // baseline's finding record.
996
+ const fullCoverage =
997
+ critique?.provider &&
998
+ critique.outcome !== "skipped" &&
999
+ critiqueTiles !== undefined &&
1000
+ (!qaReuse || qaReuse.tiles_reused === 0);
1001
+ const persistedCritique: PersistedCritique | undefined =
1002
+ fullCoverage && critique && critiqueTiles
1003
+ ? {
1004
+ contract_version: QA_CRITIQUE_CONTRACT_VERSION,
1005
+ rubric_digest: rubricDigest(opts.checkCritiqueRubric ?? DEFAULT_CRITIQUE_RUBRIC),
1006
+ outcome: critique.outcome as "pass" | "fail",
1007
+ findings: critique.findings,
1008
+ tiles: critiqueTiles.map((t) => ({
1009
+ index: t.index,
1010
+ label: t.label,
1011
+ x: t.x ?? 0,
1012
+ scrollY: t.scrollY,
1013
+ width: t.width,
1014
+ height: t.height,
1015
+ })),
1016
+ }
1017
+ : undefined;
1018
+ const saved = saveQaSnapshot(
1019
+ qaCapture.target,
1020
+ qaCapture.context,
1021
+ {
1022
+ signature: qaCapture.signature,
1023
+ domHtml: qaCapture.domHtml,
1024
+ screenshotPng,
1025
+ ...(persistedCritique ? { critique: persistedCritique } : {}),
1026
+ },
1027
+ {},
1028
+ );
1029
+ if (qaPlan) {
1030
+ qaPlan.snapshotSaved = {
1031
+ path: saved.path,
1032
+ target: qaCapture.target,
1033
+ context: qaCapture.context,
1034
+ };
1035
+ }
1036
+ emit.log(
1037
+ `qa-snapshot: saved baseline for ${qaCapture.target} ` +
1038
+ `[${qaCapture.context.viewport}/${qaCapture.context.theme}/${qaCapture.context.state}]` +
1039
+ `${persistedCritique ? " (with critique results)" : ""}`,
1040
+ "info",
1041
+ );
1042
+ }
833
1043
  let asserts: AssertResult[] | undefined;
834
1044
  if (opts.assert && opts.assert.length > 0) {
835
1045
  const specs = opts.assert.map(parseAssertSpec);
@@ -948,6 +1158,8 @@ async function runBrowse(
948
1158
  asserts,
949
1159
  devOverlay,
950
1160
  batchResult,
1161
+ qaPlan,
1162
+ qaReuse ? summarizeReuse(qaReuse) : undefined,
951
1163
  );
952
1164
  } else {
953
1165
  await runTrioMode(
@@ -966,6 +1178,8 @@ async function runBrowse(
966
1178
  asserts,
967
1179
  devOverlay,
968
1180
  batchResult,
1181
+ qaPlan,
1182
+ qaReuse ? summarizeReuse(qaReuse) : undefined,
969
1183
  );
970
1184
  }
971
1185
 
@@ -1209,6 +1423,8 @@ async function runPrintMode(
1209
1423
  asserts: AssertResult[] | undefined,
1210
1424
  devOverlay: DevOverlayResult | undefined,
1211
1425
  batchResult: BatchResult | undefined,
1426
+ qaPlan: QaPlanReport | undefined,
1427
+ qaReuse: Record<string, unknown> | undefined,
1212
1428
  ): Promise<void> {
1213
1429
  let body: string | null = null;
1214
1430
  if (opts.html) {
@@ -1243,6 +1459,8 @@ async function runPrintMode(
1243
1459
  if (critique) result.critique = critique;
1244
1460
  if (asserts) result.asserts = asserts;
1245
1461
  if (devOverlay) result.devOverlay = devOverlay;
1462
+ if (qaPlan) result.qaPlan = qaPlan;
1463
+ if (qaReuse) result.qaReuse = qaReuse;
1246
1464
  if (batchResult && batchResult.clipboardReads.length > 0) {
1247
1465
  result.batchClipboardReads = batchResult.clipboardReads;
1248
1466
  }
@@ -1279,6 +1497,8 @@ async function runTrioMode(
1279
1497
  asserts: AssertResult[] | undefined,
1280
1498
  devOverlay: DevOverlayResult | undefined,
1281
1499
  batchResult: BatchResult | undefined,
1500
+ qaPlan: QaPlanReport | undefined,
1501
+ qaReuse: Record<string, unknown> | undefined,
1282
1502
  ): Promise<void> {
1283
1503
  const prefix = resolveOutPrefix(opts.out);
1284
1504
  mkdirSync(dirname(prefix), { recursive: true });
@@ -1351,6 +1571,8 @@ async function runTrioMode(
1351
1571
  if (critique) envelope.critique = critique;
1352
1572
  if (asserts) envelope.asserts = asserts;
1353
1573
  if (devOverlay) envelope.devOverlay = devOverlay;
1574
+ if (qaPlan) envelope.qaPlan = qaPlan;
1575
+ if (qaReuse) envelope.qaReuse = qaReuse;
1354
1576
  if (batchResult && batchResult.clipboardReads.length > 0) {
1355
1577
  envelope.batchClipboardReads = batchResult.clipboardReads;
1356
1578
  }
@@ -1812,9 +2034,113 @@ function applyContentFailGates(opts: BrowseOpts, content: ContentChecksResult |
1812
2034
  // Vision critique tiling
1813
2035
  // ---------------------------------------------------------------------------
1814
2036
 
1815
- async function captureCritiqueTiles(browser: Browser, opts: BrowseOpts): Promise<CritiqueTile[]> {
2037
+ /** Envelope-safe reuse stats: everything except the `review` tiles, whose
2038
+ * base64 PNGs would bloat the JSON by megabytes. */
2039
+ function summarizeReuse(plan: CritiqueReusePlan): Record<string, unknown> {
2040
+ const { review: _review, ...rest } = plan;
2041
+ return rest;
2042
+ }
2043
+
2044
+ /** What `--qa-plan` / `--qa-snapshot` put in the JSON envelope. */
2045
+ interface QaPlanReport {
2046
+ manifest?: QaManifest;
2047
+ classification?: QaClassification;
2048
+ snapshotSaved?: { path: string; target: string; context: QaContext };
2049
+ signature: { nodes: number; stylesheets: number; truncated: boolean };
2050
+ }
2051
+
2052
+ /** The captured page state a later --qa-snapshot persist needs. Kept out of
2053
+ * the envelope: domHtml can be megabytes. */
2054
+ interface QaCaptureState {
2055
+ target: string;
2056
+ context: QaContext;
2057
+ signature: QaSignature;
2058
+ domHtml: string;
2059
+ }
2060
+
2061
+ /**
2062
+ * Diff-aware QA planning inside a browse run: capture the page's QA signature
2063
+ * (before any annotation overlay mutates the DOM) and classify against the
2064
+ * persisted baseline. Persistence happens later in the run — after critique —
2065
+ * so a passing run's verdicts ride along with the snapshot; this helper only
2066
+ * supplies the live-page inputs (signature, page height, explicit scope match
2067
+ * counts). Classification and manifest math live in lib/browser/qa-plan.ts.
2068
+ */
2069
+ async function runQaPlanning(
2070
+ browser: Browser,
2071
+ targetArg: string,
2072
+ renderedUrl: string,
2073
+ opts: BrowseOpts,
2074
+ ): Promise<{ report: QaPlanReport; capture: QaCaptureState }> {
2075
+ const context: QaContext = {
2076
+ viewport: opts.viewport ?? "desktop",
2077
+ theme: opts.qaTheme === "dark" ? "dark" : "light",
2078
+ state: opts.qaState ?? "default",
2079
+ };
2080
+ const target = opts.qaTarget ?? targetArg;
2081
+ const captured = await browser.qaSignature();
2082
+ const signature: QaSignature = {
2083
+ url: renderedUrl,
2084
+ capturedAt: new Date().toISOString(),
2085
+ nodes: captured.nodes,
2086
+ stylesheets: captured.stylesheets,
2087
+ ...(captured.truncated ? { truncated: true } : {}),
2088
+ };
2089
+ const report: QaPlanReport = {
2090
+ signature: {
2091
+ nodes: captured.nodes.length,
2092
+ stylesheets: captured.stylesheets.length,
2093
+ truncated: captured.truncated,
2094
+ },
2095
+ };
2096
+
2097
+ if (opts.qaPlan) {
2098
+ const baseline = await resolveQaBaseline({ target, context });
2099
+ const classification = classifySignatures(baseline.signature, signature);
2100
+ // Full-page tile ceiling from the real page height and the critique
2101
+ // tiling knobs, so the predicted cost matches what --check-critique
2102
+ // would actually spend.
2103
+ const pageHeight = await browser.currentPage.evaluate(() =>
2104
+ Math.max(document.documentElement.scrollHeight, document.body?.scrollHeight ?? 0),
2105
+ );
2106
+ const band = Number.parseInt(opts.checkCritiqueBand ?? "1400", 10);
2107
+ const overlap = Number.parseInt(opts.checkCritiqueOverlap ?? "120", 10);
2108
+ const maxTiles = Number.parseInt(opts.checkCritiqueMaxTiles ?? "24", 10);
2109
+ const estimatedFullPageTiles = Math.min(
2110
+ maxTiles,
2111
+ Math.max(1, Math.ceil(pageHeight / Math.max(1, band - overlap))),
2112
+ );
2113
+ const explicitScopes: QaScope[] = [];
2114
+ for (const selector of opts.qaScope ?? []) {
2115
+ const matches = await browser.currentPage.evaluate(
2116
+ (sel) => document.querySelectorAll(sel).length,
2117
+ selector,
2118
+ );
2119
+ explicitScopes.push({ selector, reason: "explicit input (--qa-scope)", matches });
2120
+ }
2121
+ report.classification = classification;
2122
+ report.manifest = buildQaManifest(classification, {
2123
+ baselineSource: baseline.source,
2124
+ ...(explicitScopes.length > 0 ? { explicitScopes } : {}),
2125
+ ...(opts.qaStates?.length ? { states: opts.qaStates } : {}),
2126
+ ...(opts.assert?.length ? { outcomeAssertions: opts.assert } : {}),
2127
+ estimatedFullPageTiles,
2128
+ });
2129
+ }
2130
+
2131
+ return { report, capture: { target, context, signature, domHtml: captured.domHtml } };
2132
+ }
2133
+
2134
+ async function captureCritiqueTiles(
2135
+ browser: Browser,
2136
+ opts: BrowseOpts,
2137
+ tileBudgetPx?: number,
2138
+ ): Promise<{ tiles: CritiqueTile[]; fullPage: Buffer }> {
1816
2139
  const maxTiles = Math.max(1, Number.parseInt(opts.checkCritiqueMaxTiles ?? "24", 10));
1817
- const band = Math.max(200, Number.parseInt(opts.checkCritiqueBand ?? "1400", 10));
2140
+ // The routed provider's vision long-edge budget caps band height so tiles
2141
+ // are never silently downscaled by the model.
2142
+ const bandFlag = Math.max(200, Number.parseInt(opts.checkCritiqueBand ?? "1400", 10));
2143
+ const band = tileBudgetPx ? Math.max(200, Math.min(bandFlag, tileBudgetPx)) : bandFlag;
1818
2144
  const overlap = Math.max(0, Number.parseInt(opts.checkCritiqueOverlap ?? "120", 10));
1819
2145
 
1820
2146
  // Capture the whole page ONCE, then crop tiles from the pixels. Playwright's
@@ -1826,7 +2152,22 @@ async function captureCritiqueTiles(browser: Browser, opts: BrowseOpts): Promise
1826
2152
  typeof opts.checkCritique === "string"
1827
2153
  ? await browser.elementTiles(opts.checkCritique)
1828
2154
  : undefined;
1829
- const tiles = tilesFromFullPage(buffer, { elementRects, bandHeight: band, overlap, maxTiles });
2155
+ // Content-aware seams: atoms let band cuts snap into gaps and over-tall
2156
+ // selector tiles band internally. Extraction failing is never fatal — the
2157
+ // tiler falls back to fixed bands, today's behavior.
2158
+ let atoms: Awaited<ReturnType<Browser["visualAtoms"]>> | undefined;
2159
+ try {
2160
+ atoms = await browser.visualAtoms();
2161
+ } catch {
2162
+ atoms = undefined;
2163
+ }
2164
+ const tiles = tilesFromFullPage(buffer, {
2165
+ elementRects,
2166
+ bandHeight: band,
2167
+ overlap,
2168
+ maxTiles,
2169
+ atoms,
2170
+ });
1830
2171
 
1831
2172
  if (elementRects && elementRects.length > maxTiles) {
1832
2173
  emit.log(
@@ -1839,7 +2180,7 @@ async function captureCritiqueTiles(browser: Browser, opts: BrowseOpts): Promise
1839
2180
  "warn",
1840
2181
  );
1841
2182
  }
1842
- return tiles;
2183
+ return { tiles, fullPage: buffer };
1843
2184
  }
1844
2185
  function logCritiqueSummary(critique: CritiqueResult): void {
1845
2186
  if (critique.outcome === "skipped") {
@@ -1,13 +1,14 @@
1
1
  import type { Command } from "commander";
2
2
  import type { EmitContext, HarneryProgramContext } from "../commander.ts";
3
- import { monorepoRoot, readHeartbeat, resolveOwner } from "../core/agents/index.ts";
3
+ import type { Adapter } from "../core/adapter.ts";
4
+ import { monorepoRoot, resolveOwner } from "../core/agents/index.ts";
5
+ import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.ts";
4
6
  import {
5
7
  type CheckpointReason,
6
8
  checkpointContext,
7
9
  readContextState,
8
10
  readLatestCapsule,
9
11
  } from "../core/context/index.ts";
10
- import type { Adapter } from "../core/hooks/events/schema.ts";
11
12
 
12
13
  /**
13
14
  * `harn checkpoint`: durable context continuity across compaction.
@@ -156,7 +157,7 @@ function resolveContinuityIdentity(
156
157
  if (!instanceId) {
157
158
  throw new Error("could not resolve the current agent; pass --instance and --session");
158
159
  }
159
- const heartbeat = readHeartbeat(instanceId);
160
+ const heartbeat = readLiveCoordinationRow(coordRoot, instanceId);
160
161
  const sessionId = opts.session ?? heartbeat?.session_id ?? instanceId;
161
162
  const adapter = opts.adapter
162
163
  ? parseAdapter(opts.adapter)
@@ -1,5 +1,5 @@
1
1
  import type { Command } from "commander";
2
- import type { EmitContext } from "../commander.ts";
2
+ import type { EmitContext, HarneryProgramContext } from "../commander.ts";
3
3
  import {
4
4
  applyMirror,
5
5
  type DesktopAccount,
@@ -24,12 +24,14 @@ import {
24
24
  * desktop app picks the copies up, and opening one resumes with full
25
25
  * history.
26
26
  */
27
- export function registerClaudeDesktopCommand(program: Command, emit: EmitContext): void {
27
+ export function registerClaudeDesktopCommand(
28
+ program: Command,
29
+ emit: EmitContext,
30
+ _context?: HarneryProgramContext,
31
+ ): void {
28
32
  const cmd = program
29
33
  .command("claude-desktop")
30
- .description(
31
- "Claude desktop-app session index: list accounts/sessions, mirror sessions across accounts",
32
- )
34
+ .description("Claude desktop-app session index: list and mirror sessions across accounts")
33
35
  .action(() => {
34
36
  const dirs = requireDataDirs(emit, undefined);
35
37
  for (const dir of dirs) {
@@ -112,10 +112,6 @@ function renderSelf(s: NonNullable<ContextReport["self"]>): string[] {
112
112
  ` agent-${s.name ?? "?"} (${formatAge(s.session_age_secs)} old, owner=${s.instance_id.slice(0, 8)}…)`,
113
113
  );
114
114
  if (s.task) body.push(` task: "${s.task}"`);
115
- if (s.last_tool) {
116
- const target = s.last_tool_target ? ` ${truncate(s.last_tool_target, 80)}` : "";
117
- body.push(` last: ${s.last_tool}${target}`);
118
- }
119
115
  if (s.files_held.length > 0) {
120
116
  body.push(` holds ${s.files_held.length} file(s):`);
121
117
  for (const f of s.files_held.slice(0, 5)) body.push(` ${f}`);
@@ -175,8 +171,7 @@ function renderPeers(p: NonNullable<ContextReport["peers"]>): string[] {
175
171
  const lines = p.rows.map((peer) => {
176
172
  const taskBit = peer.task ? ` "${truncate(peer.task, 40)}"` : "";
177
173
  const filesBit = peer.files > 0 ? `${peer.files}f` : "0f";
178
- const lastBit = peer.last_tool ? `, last: ${peer.last_tool}` : "";
179
- return ` agent-${peer.name.padEnd(12)}${taskBit} (${peer.age_min}m old, ${filesBit}${lastBit})`;
174
+ return ` agent-${peer.name.padEnd(12)}${taskBit} (${peer.age_min}m old, ${filesBit})`;
180
175
  });
181
176
  return section("peers", lines);
182
177
  }