harnery 0.33.0 → 0.34.1

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 (657) hide show
  1. package/dist/commander.d.ts.map +1 -1
  2. package/dist/commander.js +4 -0
  3. package/dist/commands/adapter.js +2 -2
  4. package/dist/commands/agents.d.ts +144 -1
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +1237 -590
  7. package/dist/commands/artifacts.d.ts.map +1 -1
  8. package/dist/commands/artifacts.js +7 -6
  9. package/dist/commands/backup.d.ts +1 -1
  10. package/dist/commands/backup.d.ts.map +1 -1
  11. package/dist/commands/backup.js +29 -16
  12. package/dist/commands/browse.d.ts.map +1 -1
  13. package/dist/commands/browse.js +234 -12
  14. package/dist/commands/checkpoint.d.ts.map +1 -1
  15. package/dist/commands/checkpoint.js +3 -2
  16. package/dist/commands/claude-desktop.d.ts +1 -1
  17. package/dist/commands/claude-desktop.d.ts.map +1 -1
  18. package/dist/commands/claude-desktop.js +3 -74
  19. package/dist/commands/context.js +1 -6
  20. package/dist/commands/decision.d.ts.map +1 -1
  21. package/dist/commands/decision.js +22 -38
  22. package/dist/commands/docs.d.ts.map +1 -1
  23. package/dist/commands/docs.js +91 -28
  24. package/dist/commands/doctor.js +10 -1
  25. package/dist/commands/events.d.ts +5 -0
  26. package/dist/commands/events.d.ts.map +1 -0
  27. package/dist/commands/events.js +189 -0
  28. package/dist/commands/governor.d.ts.map +1 -1
  29. package/dist/commands/governor.js +13 -4
  30. package/dist/commands/init.d.ts +9 -2
  31. package/dist/commands/init.d.ts.map +1 -1
  32. package/dist/commands/init.js +223 -51
  33. package/dist/commands/journal.d.ts.map +1 -1
  34. package/dist/commands/journal.js +4 -13
  35. package/dist/commands/ledger-v3.d.ts +5 -0
  36. package/dist/commands/ledger-v3.d.ts.map +1 -0
  37. package/dist/commands/ledger-v3.js +91 -0
  38. package/dist/commands/presence.d.ts.map +1 -1
  39. package/dist/commands/presence.js +11 -5
  40. package/dist/commands/sync.d.ts +1 -1
  41. package/dist/commands/sync.js +1 -1
  42. package/dist/commands/web.d.ts +6 -0
  43. package/dist/commands/web.d.ts.map +1 -1
  44. package/dist/commands/web.js +67 -7
  45. package/dist/commands/work.d.ts.map +1 -1
  46. package/dist/commands/work.js +22 -5
  47. package/dist/core/adapter.d.ts +5 -0
  48. package/dist/core/adapter.d.ts.map +1 -0
  49. package/dist/core/adapter.js +1 -0
  50. package/dist/core/adapters/attest.d.ts +5 -2
  51. package/dist/core/adapters/attest.d.ts.map +1 -1
  52. package/dist/core/adapters/attest.js +8 -3
  53. package/dist/core/adapters/profiles.d.ts +6 -6
  54. package/dist/core/adapters/profiles.d.ts.map +1 -1
  55. package/dist/core/adapters/profiles.js +4 -4
  56. package/dist/core/agents/canonical-emit.d.ts +17 -15
  57. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  58. package/dist/core/agents/canonical-emit.js +22 -22
  59. package/dist/core/agents/cli.js +207 -234
  60. package/dist/core/agents/codex-archive-v3.d.ts +14 -0
  61. package/dist/core/agents/codex-archive-v3.d.ts.map +1 -0
  62. package/dist/core/agents/codex-archive-v3.js +110 -0
  63. package/dist/core/agents/coord-client.d.ts +19 -81
  64. package/dist/core/agents/coord-client.d.ts.map +1 -1
  65. package/dist/core/agents/coord-client.js +65 -155
  66. package/dist/core/agents/finalization.d.ts +4 -1
  67. package/dist/core/agents/finalization.d.ts.map +1 -1
  68. package/dist/core/agents/finalization.js +89 -32
  69. package/dist/core/agents/index.d.ts +4 -5
  70. package/dist/core/agents/index.d.ts.map +1 -1
  71. package/dist/core/agents/index.js +4 -5
  72. package/dist/core/agents/live-authority-v3.d.ts +59 -0
  73. package/dist/core/agents/live-authority-v3.d.ts.map +1 -0
  74. package/dist/core/agents/live-authority-v3.js +233 -0
  75. package/dist/core/agents/live-lifecycle-v3.d.ts +20 -0
  76. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -0
  77. package/dist/core/agents/live-lifecycle-v3.js +91 -0
  78. package/dist/core/agents/live-observation-v3.d.ts +25 -0
  79. package/dist/core/agents/live-observation-v3.d.ts.map +1 -0
  80. package/dist/core/agents/live-observation-v3.js +157 -0
  81. package/dist/core/agents/render/prompt-context.d.ts +4 -4
  82. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  83. package/dist/core/agents/render/prompt-context.js +23 -58
  84. package/dist/core/agents/render/session-context.d.ts +1 -1
  85. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  86. package/dist/core/agents/render/session-context.js +8 -32
  87. package/dist/core/agents/rules/claim-conflict.d.ts +3 -3
  88. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  89. package/dist/core/agents/rules/claim-conflict.js +79 -127
  90. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  91. package/dist/core/agents/rules/commit-conflict.js +3 -18
  92. package/dist/core/agents/rules/stop-hook.d.ts +9 -50
  93. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  94. package/dist/core/agents/rules/stop-hook.js +193 -236
  95. package/dist/core/agents/session-events.d.ts +5 -7
  96. package/dist/core/agents/session-events.d.ts.map +1 -1
  97. package/dist/core/agents/session-events.js +127 -95
  98. package/dist/core/agents/session-finalization-state-v3.d.ts +30 -0
  99. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -0
  100. package/dist/core/agents/session-finalization-state-v3.js +40 -0
  101. package/dist/core/agents/session-finalizer-v3.d.ts +107 -0
  102. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -0
  103. package/dist/core/agents/session-finalizer-v3.js +734 -0
  104. package/dist/core/agents/session-name-display.d.ts +40 -0
  105. package/dist/core/agents/session-name-display.d.ts.map +1 -0
  106. package/dist/core/agents/session-name-display.js +119 -0
  107. package/dist/core/agents/state/activity-log.d.ts +3 -3
  108. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  109. package/dist/core/agents/state/activity-log.js +7 -16
  110. package/dist/core/agents/state/heartbeat-writer.d.ts +23 -55
  111. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  112. package/dist/core/agents/state/heartbeat-writer.js +56 -228
  113. package/dist/core/agents/state/live-coordination-view.d.ts +31 -0
  114. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -0
  115. package/dist/core/agents/state/live-coordination-view.js +209 -0
  116. package/dist/core/agents/state/session-state.d.ts +4 -3
  117. package/dist/core/agents/state/session-state.d.ts.map +1 -1
  118. package/dist/core/agents/state/session-state.js +18 -9
  119. package/dist/core/agents/state/stale-sweep.d.ts +1 -1
  120. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  121. package/dist/core/agents/state/stale-sweep.js +26 -15
  122. package/dist/core/artifacts/index.d.ts.map +1 -1
  123. package/dist/core/artifacts/index.js +5 -7
  124. package/dist/core/config.d.ts +33 -2
  125. package/dist/core/config.d.ts.map +1 -1
  126. package/dist/core/config.js +98 -2
  127. package/dist/core/context/index.d.ts +1 -4
  128. package/dist/core/context/index.d.ts.map +1 -1
  129. package/dist/core/context/index.js +9 -9
  130. package/dist/core/events/span-parent.d.ts +15 -0
  131. package/dist/core/events/span-parent.d.ts.map +1 -0
  132. package/dist/core/events/span-parent.js +34 -0
  133. package/dist/core/events/v3/advance.d.ts +14 -0
  134. package/dist/core/events/v3/advance.d.ts.map +1 -0
  135. package/dist/core/events/v3/advance.js +134 -0
  136. package/dist/core/events/v3/authority-outbox.d.ts +78 -0
  137. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -0
  138. package/dist/core/events/v3/authority-outbox.js +399 -0
  139. package/dist/core/events/v3/base-builder.d.ts +20 -0
  140. package/dist/core/events/v3/base-builder.d.ts.map +1 -0
  141. package/dist/core/events/v3/base-builder.js +29 -0
  142. package/dist/core/events/v3/base-contract.d.ts +7576 -0
  143. package/dist/core/events/v3/base-contract.d.ts.map +1 -0
  144. package/dist/core/events/v3/base-contract.js +647 -0
  145. package/dist/core/events/v3/bootstrap.d.ts +34 -0
  146. package/dist/core/events/v3/bootstrap.d.ts.map +1 -0
  147. package/dist/core/events/v3/bootstrap.js +175 -0
  148. package/dist/core/events/v3/builder.d.ts +20 -0
  149. package/dist/core/events/v3/builder.d.ts.map +1 -0
  150. package/dist/core/events/v3/builder.js +28 -0
  151. package/dist/core/events/v3/canonical.d.ts +31 -0
  152. package/dist/core/events/v3/canonical.d.ts.map +1 -0
  153. package/dist/core/events/v3/canonical.js +100 -0
  154. package/dist/core/events/v3/capabilities.d.ts +31 -0
  155. package/dist/core/events/v3/capabilities.d.ts.map +1 -0
  156. package/dist/core/events/v3/capabilities.js +107 -0
  157. package/dist/core/events/v3/capability-drift.d.ts +22 -0
  158. package/dist/core/events/v3/capability-drift.d.ts.map +1 -0
  159. package/dist/core/events/v3/capability-drift.js +134 -0
  160. package/dist/core/events/v3/catalog.d.ts +38 -0
  161. package/dist/core/events/v3/catalog.d.ts.map +1 -0
  162. package/dist/core/events/v3/catalog.js +135 -0
  163. package/dist/core/events/v3/clock-order.d.ts +34 -0
  164. package/dist/core/events/v3/clock-order.d.ts.map +1 -0
  165. package/dist/core/events/v3/clock-order.js +35 -0
  166. package/dist/core/events/v3/contract.d.ts +171 -0
  167. package/dist/core/events/v3/contract.d.ts.map +1 -0
  168. package/dist/core/events/v3/contract.js +180 -0
  169. package/dist/core/events/v3/control.d.ts +111 -0
  170. package/dist/core/events/v3/control.d.ts.map +1 -0
  171. package/dist/core/events/v3/control.js +419 -0
  172. package/dist/core/events/v3/coordination-view.d.ts +69 -0
  173. package/dist/core/events/v3/coordination-view.d.ts.map +1 -0
  174. package/dist/core/events/v3/coordination-view.js +119 -0
  175. package/dist/core/events/v3/economics.d.ts +77 -0
  176. package/dist/core/events/v3/economics.d.ts.map +1 -0
  177. package/dist/core/events/v3/economics.js +274 -0
  178. package/dist/core/events/v3/finalization-view.d.ts +26 -0
  179. package/dist/core/events/v3/finalization-view.d.ts.map +1 -0
  180. package/dist/core/events/v3/finalization-view.js +37 -0
  181. package/dist/core/events/v3/fingerprint-keys.d.ts +25 -0
  182. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -0
  183. package/dist/core/events/v3/fingerprint-keys.js +217 -0
  184. package/dist/core/events/v3/generated.d.ts +4 -0
  185. package/dist/core/events/v3/generated.d.ts.map +1 -0
  186. package/dist/core/events/v3/generated.js +47 -0
  187. package/dist/core/events/v3/ids.d.ts +9 -0
  188. package/dist/core/events/v3/ids.d.ts.map +1 -0
  189. package/dist/core/events/v3/ids.js +25 -0
  190. package/dist/core/events/v3/index.d.ts +35 -0
  191. package/dist/core/events/v3/index.d.ts.map +1 -0
  192. package/dist/core/events/v3/index.js +33 -0
  193. package/dist/core/events/v3/latency.d.ts +63 -0
  194. package/dist/core/events/v3/latency.d.ts.map +1 -0
  195. package/dist/core/events/v3/latency.js +412 -0
  196. package/dist/core/events/v3/live-feed.d.ts +45 -0
  197. package/dist/core/events/v3/live-feed.d.ts.map +1 -0
  198. package/dist/core/events/v3/live-feed.js +246 -0
  199. package/dist/core/events/v3/live-observation.d.ts +35 -0
  200. package/dist/core/events/v3/live-observation.d.ts.map +1 -0
  201. package/dist/core/events/v3/live-observation.js +1 -0
  202. package/dist/core/events/v3/live-routing.d.ts +57 -0
  203. package/dist/core/events/v3/live-routing.d.ts.map +1 -0
  204. package/dist/core/events/v3/live-routing.js +107 -0
  205. package/dist/core/events/v3/producers/command-recorder.d.ts +67 -0
  206. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -0
  207. package/dist/core/events/v3/producers/command-recorder.js +477 -0
  208. package/dist/core/events/v3/producers/command.d.ts +50 -0
  209. package/dist/core/events/v3/producers/command.d.ts.map +1 -0
  210. package/dist/core/events/v3/producers/command.js +135 -0
  211. package/dist/core/events/v3/producers/coordination-recorder.d.ts +53 -0
  212. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -0
  213. package/dist/core/events/v3/producers/coordination-recorder.js +376 -0
  214. package/dist/core/events/v3/producers/coordination.d.ts +90 -0
  215. package/dist/core/events/v3/producers/coordination.d.ts.map +1 -0
  216. package/dist/core/events/v3/producers/coordination.js +229 -0
  217. package/dist/core/events/v3/producers/hook-base.d.ts +54 -0
  218. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -0
  219. package/dist/core/events/v3/producers/hook-base.js +424 -0
  220. package/dist/core/events/v3/producers/hook.d.ts +29 -0
  221. package/dist/core/events/v3/producers/hook.d.ts.map +1 -0
  222. package/dist/core/events/v3/producers/hook.js +71 -0
  223. package/dist/core/events/v3/producers/intake.d.ts +65 -0
  224. package/dist/core/events/v3/producers/intake.d.ts.map +1 -0
  225. package/dist/core/events/v3/producers/intake.js +244 -0
  226. package/dist/core/events/v3/producers/recorder.d.ts +240 -0
  227. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -0
  228. package/dist/core/events/v3/producers/recorder.js +2176 -0
  229. package/dist/core/events/v3/projection.d.ts +101 -0
  230. package/dist/core/events/v3/projection.d.ts.map +1 -0
  231. package/dist/core/events/v3/projection.js +479 -0
  232. package/dist/core/events/v3/reader.d.ts +75 -0
  233. package/dist/core/events/v3/reader.d.ts.map +1 -0
  234. package/dist/core/events/v3/reader.js +778 -0
  235. package/dist/core/events/v3/recovery-record.d.ts +47 -0
  236. package/dist/core/events/v3/recovery-record.d.ts.map +1 -0
  237. package/dist/core/events/v3/recovery-record.js +167 -0
  238. package/dist/core/events/v3/recovery.d.ts +22 -0
  239. package/dist/core/events/v3/recovery.d.ts.map +1 -0
  240. package/dist/core/events/v3/recovery.js +227 -0
  241. package/dist/core/events/v3/span-state.d.ts +52 -0
  242. package/dist/core/events/v3/span-state.d.ts.map +1 -0
  243. package/dist/core/events/v3/span-state.js +142 -0
  244. package/dist/core/events/v3/targets.d.ts +23 -0
  245. package/dist/core/events/v3/targets.d.ts.map +1 -0
  246. package/dist/core/events/v3/targets.js +134 -0
  247. package/dist/core/events/v3/turn-telemetry.d.ts +41 -0
  248. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -0
  249. package/dist/core/events/v3/turn-telemetry.js +168 -0
  250. package/dist/core/events/v3/validate.d.ts +9 -0
  251. package/dist/core/events/v3/validate.d.ts.map +1 -0
  252. package/dist/core/events/v3/validate.js +281 -0
  253. package/dist/core/events/v3/writer.d.ts +56 -0
  254. package/dist/core/events/v3/writer.d.ts.map +1 -0
  255. package/dist/core/events/v3/writer.js +335 -0
  256. package/dist/core/governor/index.d.ts +1 -1
  257. package/dist/core/governor/index.d.ts.map +1 -1
  258. package/dist/core/governor/index.js +1 -1
  259. package/dist/core/governor/plan-api.d.ts +2 -1
  260. package/dist/core/governor/plan-api.d.ts.map +1 -1
  261. package/dist/core/governor/plan-api.js +6 -3
  262. package/dist/core/governor/read.d.ts +1 -1
  263. package/dist/core/governor/read.d.ts.map +1 -1
  264. package/dist/core/governor/read.js +1 -1
  265. package/dist/core/governor/state.d.ts +9 -0
  266. package/dist/core/governor/state.d.ts.map +1 -1
  267. package/dist/core/governor/state.js +40 -3
  268. package/dist/core/guard/config.d.ts +5 -0
  269. package/dist/core/guard/config.d.ts.map +1 -0
  270. package/dist/core/guard/config.js +157 -0
  271. package/dist/core/guard/coordinator.d.ts +14 -0
  272. package/dist/core/guard/coordinator.d.ts.map +1 -0
  273. package/dist/core/guard/coordinator.js +173 -0
  274. package/dist/core/guard/evaluator.d.ts +4 -0
  275. package/dist/core/guard/evaluator.d.ts.map +1 -0
  276. package/dist/core/guard/evaluator.js +242 -0
  277. package/dist/core/guard/evidence-v3.d.ts +15 -0
  278. package/dist/core/guard/evidence-v3.d.ts.map +1 -0
  279. package/dist/core/guard/evidence-v3.js +171 -0
  280. package/dist/core/guard/index.d.ts +10 -0
  281. package/dist/core/guard/index.d.ts.map +1 -0
  282. package/dist/core/guard/index.js +6 -0
  283. package/dist/core/guard/live-source-v3.d.ts +40 -0
  284. package/dist/core/guard/live-source-v3.d.ts.map +1 -0
  285. package/dist/core/guard/live-source-v3.js +128 -0
  286. package/dist/core/guard/storage.d.ts +27 -0
  287. package/dist/core/guard/storage.d.ts.map +1 -0
  288. package/dist/core/guard/storage.js +140 -0
  289. package/dist/core/guard/types.d.ts +119 -0
  290. package/dist/core/guard/types.d.ts.map +1 -0
  291. package/dist/core/guard/types.js +1 -0
  292. package/dist/core/hooks/adapter/detect.d.ts +18 -1
  293. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  294. package/dist/core/hooks/adapter/detect.js +29 -0
  295. package/dist/core/hooks/adapter/events.d.ts +7 -4
  296. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  297. package/dist/core/hooks/adapter/events.js +12 -4
  298. package/dist/core/hooks/adapter/output.d.ts +2 -2
  299. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  300. package/dist/core/hooks/adapter/parse.d.ts +7 -4
  301. package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
  302. package/dist/core/hooks/adapter/parse.js +63 -25
  303. package/dist/core/hooks/adapter/wiring.d.ts +30 -4
  304. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  305. package/dist/core/hooks/adapter/wiring.js +89 -11
  306. package/dist/core/hooks/cli.d.ts +1 -1
  307. package/dist/core/hooks/cli.js +306 -444
  308. package/dist/core/hooks/effects/image-capture.d.ts +20 -34
  309. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  310. package/dist/core/hooks/effects/image-capture.js +212 -221
  311. package/dist/core/hooks/effects/index.d.ts +1 -9
  312. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  313. package/dist/core/hooks/effects/index.js +1 -24
  314. package/dist/core/hooks/events/input-hash.d.ts +7 -0
  315. package/dist/core/hooks/events/input-hash.d.ts.map +1 -0
  316. package/dist/core/hooks/events/input-hash.js +43 -0
  317. package/dist/core/hooks/index.d.ts +4 -3
  318. package/dist/core/hooks/index.d.ts.map +1 -1
  319. package/dist/core/hooks/index.js +2 -3
  320. package/dist/core/hooks/resolve/coord-root.d.ts +1 -1
  321. package/dist/core/hooks/resolve/coord-root.js +1 -1
  322. package/dist/core/hooks/resolve/owner.d.ts +16 -15
  323. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  324. package/dist/core/hooks/resolve/owner.js +51 -42
  325. package/dist/core/hooks/resolve/transcript.d.ts +33 -3
  326. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  327. package/dist/core/hooks/resolve/transcript.js +161 -14
  328. package/dist/core/hooks/session-name-presence.d.ts +9 -10
  329. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  330. package/dist/core/hooks/session-name-presence.js +15 -15
  331. package/dist/core/hooks/unsafe-cross-shell.d.ts +1 -1
  332. package/dist/core/hooks/unsafe-cross-shell.d.ts.map +1 -1
  333. package/dist/core/journal/index.d.ts +2 -2
  334. package/dist/core/journal/index.d.ts.map +1 -1
  335. package/dist/core/journal/index.js +9 -22
  336. package/dist/core/presence/blob.d.ts +4 -3
  337. package/dist/core/presence/blob.d.ts.map +1 -1
  338. package/dist/core/presence/blob.js +45 -44
  339. package/dist/core/presence/codec-digest.d.ts +29 -0
  340. package/dist/core/presence/codec-digest.d.ts.map +1 -0
  341. package/dist/core/presence/codec-digest.js +170 -0
  342. package/dist/core/presence/relay-client.d.ts +1 -1
  343. package/dist/core/presence/relay-client.d.ts.map +1 -1
  344. package/dist/core/presence/relay-client.js +5 -5
  345. package/dist/core/work/index.d.ts +1 -1
  346. package/dist/core/work/index.d.ts.map +1 -1
  347. package/dist/core/work/index.js +1 -1
  348. package/dist/core/work/read.d.ts +1 -1
  349. package/dist/core/work/read.d.ts.map +1 -1
  350. package/dist/core/work/read.js +1 -1
  351. package/dist/core/work/runner.d.ts.map +1 -1
  352. package/dist/core/work/runner.js +6 -0
  353. package/dist/core/work/state.d.ts +9 -0
  354. package/dist/core/work/state.d.ts.map +1 -1
  355. package/dist/core/work/state.js +17 -3
  356. package/dist/core/workflow/engine.js +24 -25
  357. package/dist/core/workflow/live-session-v3.d.ts +19 -0
  358. package/dist/core/workflow/live-session-v3.d.ts.map +1 -0
  359. package/dist/core/workflow/live-session-v3.js +86 -0
  360. package/dist/core/workflow/scope-id.d.ts +3 -0
  361. package/dist/core/workflow/scope-id.d.ts.map +1 -0
  362. package/dist/core/workflow/scope-id.js +5 -0
  363. package/dist/core/workflow/workspaces/leases.d.ts +4 -0
  364. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  365. package/dist/core/workflow/workspaces/leases.js +53 -19
  366. package/dist/index.d.ts +1 -1
  367. package/dist/index.js +1 -1
  368. package/dist/lib/browser/client.d.ts +41 -0
  369. package/dist/lib/browser/client.d.ts.map +1 -1
  370. package/dist/lib/browser/client.js +203 -0
  371. package/dist/lib/browser/critique.d.ts +28 -2
  372. package/dist/lib/browser/critique.d.ts.map +1 -1
  373. package/dist/lib/browser/critique.js +74 -18
  374. package/dist/lib/browser/geometry.d.ts +1 -1
  375. package/dist/lib/browser/geometry.d.ts.map +1 -1
  376. package/dist/lib/browser/geometry.js +130 -6
  377. package/dist/lib/browser/index.d.ts +3 -0
  378. package/dist/lib/browser/index.d.ts.map +1 -1
  379. package/dist/lib/browser/index.js +3 -0
  380. package/dist/lib/browser/qa-plan.d.ts +174 -0
  381. package/dist/lib/browser/qa-plan.d.ts.map +1 -0
  382. package/dist/lib/browser/qa-plan.js +321 -0
  383. package/dist/lib/browser/qa-reuse.d.ts +99 -0
  384. package/dist/lib/browser/qa-reuse.d.ts.map +1 -0
  385. package/dist/lib/browser/qa-reuse.js +222 -0
  386. package/dist/lib/browser/qa-snapshot.d.ts +64 -0
  387. package/dist/lib/browser/qa-snapshot.d.ts.map +1 -0
  388. package/dist/lib/browser/qa-snapshot.js +171 -0
  389. package/dist/lib/browser/runts.d.ts.map +1 -1
  390. package/dist/lib/browser/runts.js +22 -1
  391. package/dist/lib/browser/tiling.d.ts +71 -0
  392. package/dist/lib/browser/tiling.d.ts.map +1 -0
  393. package/dist/lib/browser/tiling.js +118 -0
  394. package/dist/lib/claude-desktop.d.ts +0 -47
  395. package/dist/lib/claude-desktop.d.ts.map +1 -1
  396. package/dist/lib/claude-desktop.js +1 -169
  397. package/dist/lib/context/index.d.ts +0 -3
  398. package/dist/lib/context/index.d.ts.map +1 -1
  399. package/dist/lib/context/index.js +20 -42
  400. package/dist/lib/council/index.d.ts +2 -2
  401. package/dist/lib/council/index.d.ts.map +1 -1
  402. package/dist/lib/council/index.js +9 -20
  403. package/dist/lib/docs-frontmatter.d.ts +1 -6
  404. package/dist/lib/docs-frontmatter.d.ts.map +1 -1
  405. package/dist/lib/docs-frontmatter.js +12 -78
  406. package/dist/lib/docs-index.d.ts +9 -0
  407. package/dist/lib/docs-index.d.ts.map +1 -1
  408. package/dist/lib/docs-index.js +32 -3
  409. package/dist/lib/docs-lint.d.ts.map +1 -1
  410. package/dist/lib/docs-lint.js +14 -30
  411. package/dist/lib/docs-metadata-audit.d.ts +19 -0
  412. package/dist/lib/docs-metadata-audit.d.ts.map +1 -0
  413. package/dist/lib/docs-metadata-audit.js +132 -0
  414. package/dist/lib/docs-metadata-managed.d.ts +23 -0
  415. package/dist/lib/docs-metadata-managed.d.ts.map +1 -0
  416. package/dist/lib/docs-metadata-managed.js +78 -0
  417. package/dist/lib/docs-metadata-sync.d.ts +20 -0
  418. package/dist/lib/docs-metadata-sync.d.ts.map +1 -0
  419. package/dist/lib/docs-metadata-sync.js +222 -0
  420. package/dist/lib/docs-metadata-v2-schema.d.ts +273 -0
  421. package/dist/lib/docs-metadata-v2-schema.d.ts.map +1 -0
  422. package/dist/lib/docs-metadata-v2-schema.js +134 -0
  423. package/dist/lib/docs-metadata-v2.d.ts +21 -0
  424. package/dist/lib/docs-metadata-v2.d.ts.map +1 -0
  425. package/dist/lib/docs-metadata-v2.js +424 -0
  426. package/dist/lib/docs-new.d.ts +11 -0
  427. package/dist/lib/docs-new.d.ts.map +1 -0
  428. package/dist/lib/docs-new.js +52 -0
  429. package/dist/lib/docs-sweep.d.ts.map +1 -1
  430. package/dist/lib/docs-sweep.js +45 -29
  431. package/dist/lib/headless/index.d.ts +98 -0
  432. package/dist/lib/headless/index.d.ts.map +1 -0
  433. package/dist/lib/headless/index.js +211 -0
  434. package/dist/lib/identities/assume.d.ts +4 -4
  435. package/dist/lib/identities/assume.d.ts.map +1 -1
  436. package/dist/lib/identities/assume.js +52 -68
  437. package/dist/lib/instructions/apply.d.ts +5 -4
  438. package/dist/lib/instructions/apply.d.ts.map +1 -1
  439. package/dist/lib/instructions/apply.js +32 -20
  440. package/dist/lib/instructions/bundle.d.ts +1 -1
  441. package/dist/lib/instructions/bundle.d.ts.map +1 -1
  442. package/dist/lib/instructions/bundle.js +1 -1
  443. package/dist/lib/instructions/splice.d.ts +0 -1
  444. package/dist/lib/instructions/splice.d.ts.map +1 -1
  445. package/dist/lib/instructions/splice.js +22 -6
  446. package/dist/lib/instructions/templates.d.ts +7 -5
  447. package/dist/lib/instructions/templates.d.ts.map +1 -1
  448. package/dist/lib/instructions/templates.js +79 -9
  449. package/package.json +26 -5
  450. package/schemas/config.schema.json +120 -2
  451. package/schemas/docs-metadata-v2.schema.json +441 -0
  452. package/schemas/event-v3.schema.json +24472 -0
  453. package/src/commander.ts +4 -0
  454. package/src/commands/adapter.ts +2 -2
  455. package/src/commands/agents.ts +1530 -593
  456. package/src/commands/artifacts.ts +7 -6
  457. package/src/commands/backup.ts +29 -21
  458. package/src/commands/browse.ts +349 -8
  459. package/src/commands/checkpoint.ts +4 -3
  460. package/src/commands/claude-desktop.ts +2 -101
  461. package/src/commands/context.ts +1 -6
  462. package/src/commands/decision.ts +27 -44
  463. package/src/commands/docs.ts +100 -33
  464. package/src/commands/doctor.ts +14 -1
  465. package/src/commands/events.ts +256 -0
  466. package/src/commands/governor.ts +18 -4
  467. package/src/commands/init.ts +253 -57
  468. package/src/commands/instructions.ts +1 -1
  469. package/src/commands/journal.ts +4 -13
  470. package/src/commands/ledger-v3.ts +111 -0
  471. package/src/commands/presence.ts +11 -10
  472. package/src/commands/sync.ts +1 -1
  473. package/src/commands/web.ts +67 -8
  474. package/src/commands/work.ts +28 -5
  475. package/src/core/adapter.ts +5 -0
  476. package/src/core/adapters/attest.ts +8 -3
  477. package/src/core/adapters/profiles.ts +4 -6
  478. package/src/core/agents/canonical-emit.ts +34 -25
  479. package/src/core/agents/cli.ts +236 -262
  480. package/src/core/agents/codex-archive-v3.ts +138 -0
  481. package/src/core/agents/coord-client.ts +75 -188
  482. package/src/core/agents/finalization.ts +120 -38
  483. package/src/core/agents/index.ts +4 -5
  484. package/src/core/agents/live-authority-v3.ts +375 -0
  485. package/src/core/agents/live-lifecycle-v3.ts +140 -0
  486. package/src/core/agents/live-observation-v3.ts +216 -0
  487. package/src/core/agents/render/prompt-context.ts +29 -60
  488. package/src/core/agents/render/session-context.ts +10 -31
  489. package/src/core/agents/rules/claim-conflict.ts +85 -126
  490. package/src/core/agents/rules/commit-conflict.ts +3 -14
  491. package/src/core/agents/rules/stop-hook.ts +239 -293
  492. package/src/core/agents/session-events.ts +137 -104
  493. package/src/core/agents/session-finalization-state-v3.ts +90 -0
  494. package/src/core/agents/session-finalizer-v3.ts +953 -0
  495. package/src/core/agents/session-name-display.ts +149 -0
  496. package/src/core/agents/state/activity-log.ts +6 -14
  497. package/src/core/agents/state/heartbeat-writer.ts +82 -277
  498. package/src/core/agents/state/live-coordination-view.ts +290 -0
  499. package/src/core/agents/state/session-state.ts +24 -12
  500. package/src/core/agents/state/stale-sweep.ts +40 -17
  501. package/src/core/artifacts/index.ts +4 -5
  502. package/src/core/config.ts +148 -3
  503. package/src/core/context/index.ts +9 -17
  504. package/src/core/events/span-parent.ts +46 -0
  505. package/src/core/events/v3/advance.ts +168 -0
  506. package/src/core/events/v3/authority-outbox.ts +548 -0
  507. package/src/core/events/v3/base-builder.ts +60 -0
  508. package/src/core/events/v3/base-contract.ts +882 -0
  509. package/src/core/events/v3/bootstrap.ts +226 -0
  510. package/src/core/events/v3/builder.ts +59 -0
  511. package/src/core/events/v3/canonical.ts +153 -0
  512. package/src/core/events/v3/capabilities.ts +171 -0
  513. package/src/core/events/v3/capability-drift.ts +177 -0
  514. package/src/core/events/v3/catalog.ts +202 -0
  515. package/src/core/events/v3/clock-order.ts +41 -0
  516. package/src/core/events/v3/contract.ts +365 -0
  517. package/src/core/events/v3/control.ts +576 -0
  518. package/src/core/events/v3/coordination-view.ts +193 -0
  519. package/src/core/events/v3/economics.ts +384 -0
  520. package/src/core/events/v3/finalization-view.ts +67 -0
  521. package/src/core/events/v3/fingerprint-keys.ts +260 -0
  522. package/src/core/events/v3/generated.ts +48 -0
  523. package/src/core/events/v3/ids.ts +33 -0
  524. package/src/core/events/v3/index.ts +322 -0
  525. package/src/core/events/v3/latency.ts +551 -0
  526. package/src/core/events/v3/live-feed.ts +319 -0
  527. package/src/core/events/v3/live-observation.ts +39 -0
  528. package/src/core/events/v3/live-routing.ts +135 -0
  529. package/src/core/events/v3/producers/command-recorder.ts +631 -0
  530. package/src/core/events/v3/producers/command.ts +201 -0
  531. package/src/core/events/v3/producers/coordination-recorder.ts +538 -0
  532. package/src/core/events/v3/producers/coordination.ts +355 -0
  533. package/src/core/events/v3/producers/hook-base.ts +578 -0
  534. package/src/core/events/v3/producers/hook.ts +119 -0
  535. package/src/core/events/v3/producers/intake.ts +319 -0
  536. package/src/core/events/v3/producers/recorder.ts +2805 -0
  537. package/src/core/events/v3/projection.ts +653 -0
  538. package/src/core/events/v3/reader.ts +1127 -0
  539. package/src/core/events/v3/recovery-record.ts +244 -0
  540. package/src/core/events/v3/recovery.ts +271 -0
  541. package/src/core/events/v3/span-state.ts +187 -0
  542. package/src/core/events/v3/targets.ts +182 -0
  543. package/src/core/events/v3/turn-telemetry.ts +259 -0
  544. package/src/core/events/v3/validate.ts +361 -0
  545. package/src/core/events/v3/writer.ts +419 -0
  546. package/src/core/governor/index.ts +3 -0
  547. package/src/core/governor/plan-api.ts +10 -2
  548. package/src/core/governor/read.ts +3 -0
  549. package/src/core/governor/state.ts +52 -5
  550. package/src/core/guard/config.ts +206 -0
  551. package/src/core/guard/coordinator.ts +227 -0
  552. package/src/core/guard/evaluator.ts +343 -0
  553. package/src/core/guard/evidence-v3.ts +227 -0
  554. package/src/core/guard/index.ts +35 -0
  555. package/src/core/guard/live-source-v3.ts +204 -0
  556. package/src/core/guard/storage.ts +188 -0
  557. package/src/core/guard/types.ts +152 -0
  558. package/src/core/hooks/adapter/detect.ts +28 -1
  559. package/src/core/hooks/adapter/events.ts +14 -6
  560. package/src/core/hooks/adapter/output.ts +7 -2
  561. package/src/core/hooks/adapter/parse.ts +80 -38
  562. package/src/core/hooks/adapter/wiring.ts +119 -13
  563. package/src/core/hooks/cli.ts +352 -466
  564. package/src/core/hooks/effects/image-capture.ts +228 -238
  565. package/src/core/hooks/effects/index.ts +1 -36
  566. package/src/core/hooks/events/input-hash.ts +47 -0
  567. package/src/core/hooks/index.ts +4 -11
  568. package/src/core/hooks/resolve/coord-root.ts +1 -1
  569. package/src/core/hooks/resolve/owner.ts +52 -45
  570. package/src/core/hooks/resolve/transcript.ts +171 -14
  571. package/src/core/hooks/session-name-presence.ts +14 -15
  572. package/src/core/hooks/unsafe-cross-shell.ts +1 -1
  573. package/src/core/journal/index.ts +15 -22
  574. package/src/core/presence/blob.ts +48 -41
  575. package/src/core/presence/codec-digest.ts +215 -0
  576. package/src/core/presence/relay-client.ts +5 -5
  577. package/src/core/work/index.ts +3 -0
  578. package/src/core/work/read.ts +3 -0
  579. package/src/core/work/runner.ts +6 -0
  580. package/src/core/work/state.ts +27 -3
  581. package/src/core/workflow/engine.ts +24 -24
  582. package/src/core/workflow/live-session-v3.ts +126 -0
  583. package/src/core/workflow/scope-id.ts +6 -0
  584. package/src/core/workflow/workspaces/leases.ts +56 -19
  585. package/src/index.ts +1 -1
  586. package/src/lib/browser/client.ts +230 -0
  587. package/src/lib/browser/critique.ts +104 -27
  588. package/src/lib/browser/geometry.ts +143 -14
  589. package/src/lib/browser/index.ts +34 -0
  590. package/src/lib/browser/qa-plan.ts +501 -0
  591. package/src/lib/browser/qa-reuse.ts +306 -0
  592. package/src/lib/browser/qa-snapshot.ts +223 -0
  593. package/src/lib/browser/runts.ts +27 -2
  594. package/src/lib/browser/tiling.ts +164 -0
  595. package/src/lib/claude-desktop.ts +1 -232
  596. package/src/lib/context/index.ts +22 -46
  597. package/src/lib/council/index.ts +9 -21
  598. package/src/lib/docs-frontmatter.ts +8 -79
  599. package/src/lib/docs-index.ts +33 -3
  600. package/src/lib/docs-lint.ts +15 -29
  601. package/src/lib/docs-metadata-audit.ts +166 -0
  602. package/src/lib/docs-metadata-managed.ts +83 -0
  603. package/src/lib/docs-metadata-sync.ts +262 -0
  604. package/src/lib/docs-metadata-v2-schema.ts +138 -0
  605. package/src/lib/docs-metadata-v2.ts +646 -0
  606. package/src/lib/docs-new.ts +63 -0
  607. package/src/lib/docs-sweep.ts +42 -28
  608. package/src/lib/headless/index.ts +287 -0
  609. package/src/lib/identities/assume.ts +67 -86
  610. package/src/lib/instructions/apply.ts +33 -20
  611. package/src/lib/instructions/bundle.ts +2 -2
  612. package/src/lib/instructions/splice.ts +21 -7
  613. package/src/lib/instructions/templates.ts +85 -13
  614. package/dist/core/agents/cli-emit.d.ts +0 -27
  615. package/dist/core/agents/cli-emit.d.ts.map +0 -1
  616. package/dist/core/agents/cli-emit.js +0 -57
  617. package/dist/core/agents/codex-replay.d.ts +0 -29
  618. package/dist/core/agents/codex-replay.d.ts.map +0 -1
  619. package/dist/core/agents/codex-replay.js +0 -138
  620. package/dist/core/agents/events/consume.d.ts +0 -82
  621. package/dist/core/agents/events/consume.d.ts.map +0 -1
  622. package/dist/core/agents/events/consume.js +0 -195
  623. package/dist/core/agents/events/emit.d.ts +0 -42
  624. package/dist/core/agents/events/emit.d.ts.map +0 -1
  625. package/dist/core/agents/events/emit.js +0 -75
  626. package/dist/core/agents/events/ulid.d.ts +0 -11
  627. package/dist/core/agents/events/ulid.d.ts.map +0 -1
  628. package/dist/core/agents/events/ulid.js +0 -47
  629. package/dist/core/agents/state/heartbeat-projector.d.ts +0 -76
  630. package/dist/core/agents/state/heartbeat-projector.d.ts.map +0 -1
  631. package/dist/core/agents/state/heartbeat-projector.js +0 -581
  632. package/dist/core/hooks/events/emit.d.ts +0 -31
  633. package/dist/core/hooks/events/emit.d.ts.map +0 -1
  634. package/dist/core/hooks/events/emit.js +0 -93
  635. package/dist/core/hooks/events/rotate.d.ts +0 -43
  636. package/dist/core/hooks/events/rotate.d.ts.map +0 -1
  637. package/dist/core/hooks/events/rotate.js +0 -142
  638. package/dist/core/hooks/events/schema.d.ts +0 -341
  639. package/dist/core/hooks/events/schema.d.ts.map +0 -1
  640. package/dist/core/hooks/events/schema.js +0 -12
  641. package/dist/core/hooks/events/ulid.d.ts +0 -10
  642. package/dist/core/hooks/events/ulid.d.ts.map +0 -1
  643. package/dist/core/hooks/events/ulid.js +0 -47
  644. package/dist/lib/docs-frontmatter-migrate.d.ts +0 -33
  645. package/dist/lib/docs-frontmatter-migrate.d.ts.map +0 -1
  646. package/dist/lib/docs-frontmatter-migrate.js +0 -364
  647. package/src/core/agents/cli-emit.ts +0 -64
  648. package/src/core/agents/codex-replay.ts +0 -163
  649. package/src/core/agents/events/consume.ts +0 -254
  650. package/src/core/agents/events/emit.ts +0 -115
  651. package/src/core/agents/events/ulid.ts +0 -51
  652. package/src/core/agents/state/heartbeat-projector.ts +0 -645
  653. package/src/core/hooks/events/emit.ts +0 -125
  654. package/src/core/hooks/events/rotate.ts +0 -151
  655. package/src/core/hooks/events/schema.ts +0 -582
  656. package/src/core/hooks/events/ulid.ts +0 -51
  657. package/src/lib/docs-frontmatter-migrate.ts +0 -427
@@ -0,0 +1,140 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type { Adapter } from "../adapter.ts";
3
+ import { buildEventV3 } from "../events/v3/builder.ts";
4
+ import { normalizeNativeIdV3 } from "../events/v3/canonical.ts";
5
+ import type { EventV3 } from "../events/v3/contract.ts";
6
+ import { readEventV3ControlState } from "../events/v3/control.ts";
7
+ import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.ts";
8
+ import {
9
+ liveInstanceIdV3,
10
+ livePlatformV3,
11
+ resolveLiveEventLedgerRouteV3,
12
+ } from "../events/v3/live-routing.ts";
13
+ import { readHookProducerStateV3 } from "../events/v3/producers/recorder.ts";
14
+ import { writeEventV3 } from "../events/v3/writer.ts";
15
+ import { LiveCoordinationAuthorityV3Error } from "./live-authority-v3.ts";
16
+ import { liveCoordinationAdapterV3 } from "./state/live-coordination-view.ts";
17
+
18
+ export type LiveLifecycleObservationV3Result = { state: "recorded"; event: EventV3 };
19
+
20
+ interface LiveLifecycleObservationBaseV3 {
21
+ coordRoot: string;
22
+ owner: string;
23
+ nativeSessionId: string;
24
+ adapter: Adapter;
25
+ observedAt?: string;
26
+ }
27
+
28
+ export function recordLiveSweepObservationV3(
29
+ input: LiveLifecycleObservationBaseV3 & {
30
+ observation: "stale_heartbeat" | "killed" | "unparseable_heartbeat" | "missing_timestamp";
31
+ ageMs: number;
32
+ },
33
+ ): LiveLifecycleObservationV3Result {
34
+ return recordObservation(input, "lifecycle.sweep_observed", {
35
+ subject_instance_id: liveInstanceIdV3(input.owner),
36
+ observation: input.observation,
37
+ provisional: true,
38
+ age_ms: Math.max(0, Math.floor(input.ageMs)),
39
+ });
40
+ }
41
+
42
+ export function recordLiveResumeObservationV3(
43
+ input: LiveLifecycleObservationBaseV3,
44
+ ): LiveLifecycleObservationV3Result {
45
+ const normalized = withAttestedAdapter(input);
46
+ const hook = requireHookState(normalized);
47
+ return recordObservation(normalized, "session.resumed", {
48
+ prior_generation_id: hook.generation_id,
49
+ continuity: "native",
50
+ evidence_reference: "heartbeat_recreated",
51
+ });
52
+ }
53
+
54
+ function recordObservation<T extends "lifecycle.sweep_observed" | "session.resumed">(
55
+ input: LiveLifecycleObservationBaseV3,
56
+ eventType: T,
57
+ payload: T extends "lifecycle.sweep_observed"
58
+ ? {
59
+ subject_instance_id: `inst_${string}`;
60
+ observation: string;
61
+ provisional: true;
62
+ age_ms: number;
63
+ }
64
+ : {
65
+ prior_generation_id: `gen_${string}`;
66
+ continuity: "native";
67
+ evidence_reference: string;
68
+ },
69
+ ): LiveLifecycleObservationV3Result {
70
+ const route = resolveLiveEventLedgerRouteV3(input.coordRoot);
71
+ if (route.state === "blocked") throw new LiveCoordinationAuthorityV3Error(route.reason);
72
+ input = withAttestedAdapter(input);
73
+ const control = readEventV3ControlState(input.coordRoot);
74
+ if (control.state !== route.mode) {
75
+ throw new LiveCoordinationAuthorityV3Error("control_state_changed");
76
+ }
77
+ const hook = requireHookState(input);
78
+ if (!hook.last_event_id) throw new LiveCoordinationAuthorityV3Error("generation_has_no_event");
79
+ const rootId = control.genesis.event.scope.root_id as `root_${string}`;
80
+ const context = fingerprintContextV3(
81
+ input.coordRoot,
82
+ rootId,
83
+ hook.generation_id,
84
+ control.genesis.profile.privacy_key_epoch,
85
+ );
86
+ const nativeObservationId = `${eventType}\0${input.owner}\0${input.observedAt ?? "now"}\0${JSON.stringify(payload)}`;
87
+ const common = {
88
+ producer: {
89
+ producer_id: "prd_agent-coord-lifecycle" as const,
90
+ boot_id: `boot_${randomUUID()}` as const,
91
+ sequence: 1,
92
+ component: "agent-coord" as const,
93
+ build_id: route.build_id,
94
+ platform: livePlatformV3(),
95
+ },
96
+ scope: {
97
+ root_id: rootId,
98
+ instance_id: hook.instance_id,
99
+ session_id: hook.session_id,
100
+ generation_id: hook.generation_id,
101
+ },
102
+ attestation_id: hook.attestation_id,
103
+ links: { caused_by: [hook.last_event_id] },
104
+ provenance: {
105
+ source_event: `agent-coord.${eventType}`,
106
+ attestation: "derived" as const,
107
+ confidence: "exact" as const,
108
+ source_record_id: normalizeNativeIdV3(
109
+ context,
110
+ `agent-coord.${eventType}`,
111
+ nativeObservationId,
112
+ ),
113
+ attribution: {
114
+ method: "heartbeat_match" as const,
115
+ state: "verified" as const,
116
+ observer_instance_id: hook.instance_id,
117
+ subject_instance_id: hook.instance_id,
118
+ },
119
+ },
120
+ observed_at: input.observedAt,
121
+ monotonic_ns: process.hrtime.bigint().toString(),
122
+ };
123
+ const event = buildEventV3(eventType, { ...common, payload } as never) as EventV3;
124
+ writeEventV3(input.coordRoot, event);
125
+ return { state: "recorded", event };
126
+ }
127
+
128
+ function withAttestedAdapter<T extends LiveLifecycleObservationBaseV3>(input: T): T {
129
+ const adapter = liveCoordinationAdapterV3(input.coordRoot, input.owner);
130
+ if (!adapter) return input;
131
+ return { ...input, adapter };
132
+ }
133
+
134
+ function requireHookState(input: LiveLifecycleObservationBaseV3) {
135
+ const hook = readHookProducerStateV3(input.coordRoot, input.adapter, input.nativeSessionId);
136
+ if (!hook || hook.instance_id !== liveInstanceIdV3(input.owner)) {
137
+ throw new LiveCoordinationAuthorityV3Error("hook_generation_not_joinable");
138
+ }
139
+ return hook;
140
+ }
@@ -0,0 +1,216 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type { Adapter } from "../adapter.ts";
3
+ import { buildEventV3 } from "../events/v3/builder.ts";
4
+ import {
5
+ canonicalJsonV3,
6
+ fingerprintV3,
7
+ normalizeNativeIdV3,
8
+ sha256V3,
9
+ } from "../events/v3/canonical.ts";
10
+ import type { EventTypeV3, EventV3 } from "../events/v3/contract.ts";
11
+ import { readEventV3ControlState } from "../events/v3/control.ts";
12
+ import { readCoordinationViewV3 } from "../events/v3/coordination-view.ts";
13
+ import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.ts";
14
+ import type { LiveCoordinationObservationV3 } from "../events/v3/live-observation.ts";
15
+ import {
16
+ liveInstanceIdV3,
17
+ livePlatformV3,
18
+ resolveLiveEventLedgerRouteV3,
19
+ } from "../events/v3/live-routing.ts";
20
+ import { readHookProducerStateV3 } from "../events/v3/producers/recorder.ts";
21
+ import { writeEventV3 } from "../events/v3/writer.ts";
22
+ import { LiveCoordinationAuthorityV3Error } from "./live-authority-v3.ts";
23
+ import { liveCoordinationAdapterV3 } from "./state/live-coordination-view.ts";
24
+
25
+ export type { LiveCoordinationObservationV3 } from "../events/v3/live-observation.ts";
26
+
27
+ export interface RecordLiveCoordinationObservationV3Input {
28
+ coordRoot: string;
29
+ owner: string;
30
+ nativeSessionId: string;
31
+ adapter: Adapter;
32
+ observation: LiveCoordinationObservationV3;
33
+ observationId?: string;
34
+ observedAt?: string;
35
+ }
36
+
37
+ export interface RecordLiveCoordinationObservationV3Result {
38
+ state: "recorded";
39
+ event: EventV3;
40
+ }
41
+
42
+ /**
43
+ * Append a non-authority coordination observation against one attested live
44
+ * generation. Raw message and record bodies are used only to derive keyed
45
+ * fingerprints or content digests; they never enter the ledger payload.
46
+ */
47
+ export function recordLiveCoordinationObservationV3(
48
+ input: RecordLiveCoordinationObservationV3Input,
49
+ ): RecordLiveCoordinationObservationV3Result {
50
+ const route = resolveLiveEventLedgerRouteV3(input.coordRoot);
51
+ if (route.state === "blocked") throw new LiveCoordinationAuthorityV3Error(route.reason);
52
+ const control = readEventV3ControlState(input.coordRoot);
53
+ if (control.state !== route.mode) {
54
+ throw new LiveCoordinationAuthorityV3Error("control_state_changed");
55
+ }
56
+ const adapter = liveCoordinationAdapterV3(input.coordRoot, input.owner) ?? input.adapter;
57
+ const hook = readHookProducerStateV3(input.coordRoot, adapter, input.nativeSessionId);
58
+ if (
59
+ !hook ||
60
+ hook.terminal ||
61
+ !hook.last_event_id ||
62
+ hook.instance_id !== liveInstanceIdV3(input.owner)
63
+ ) {
64
+ throw new LiveCoordinationAuthorityV3Error("hook_generation_not_joinable");
65
+ }
66
+
67
+ const rootId = control.genesis.event.scope.root_id as `root_${string}`;
68
+ const fingerprintContext = fingerprintContextV3(
69
+ input.coordRoot,
70
+ rootId,
71
+ hook.generation_id,
72
+ control.genesis.profile.privacy_key_epoch,
73
+ );
74
+ const observationId = input.observationId ?? `${input.observation.event_type}-${randomUUID()}`;
75
+ const subject =
76
+ "subject" in input.observation && input.observation.subject
77
+ ? liveInstanceIdV3(input.observation.subject)
78
+ : hook.instance_id;
79
+ const common = {
80
+ producer: {
81
+ producer_id: "prd_agent-coord-observation" as const,
82
+ boot_id: `boot_${randomUUID()}` as const,
83
+ sequence: 1,
84
+ component: "agent-coord" as const,
85
+ build_id: route.build_id,
86
+ platform: livePlatformV3(),
87
+ },
88
+ scope: {
89
+ root_id: rootId,
90
+ instance_id: hook.instance_id,
91
+ session_id: hook.session_id,
92
+ generation_id: hook.generation_id,
93
+ },
94
+ attestation_id: hook.attestation_id,
95
+ links: { caused_by: [hook.last_event_id] },
96
+ provenance: {
97
+ source_event: `agent-coord.${input.observation.event_type}`,
98
+ attestation: "derived" as const,
99
+ confidence: "exact" as const,
100
+ source_record_id: normalizeNativeIdV3(
101
+ fingerprintContext,
102
+ "agent-coord.observation",
103
+ observationId,
104
+ ),
105
+ attribution: {
106
+ method: "session_env" as const,
107
+ state: "verified" as const,
108
+ observer_instance_id: hook.instance_id,
109
+ subject_instance_id: subject,
110
+ },
111
+ },
112
+ observed_at: input.observedAt,
113
+ monotonic_ns: process.hrtime.bigint().toString(),
114
+ };
115
+
116
+ const observation = input.observation;
117
+ let event: EventV3;
118
+ switch (observation.event_type) {
119
+ case "coord.status_observed":
120
+ event = buildEventV3("coord.status_observed", {
121
+ ...common,
122
+ payload: {
123
+ observer_instance_id: hook.instance_id,
124
+ subject_instance_id: subject,
125
+ status: safeToken(observation.status),
126
+ },
127
+ });
128
+ break;
129
+ case "coord.presence_changed": {
130
+ // The ledger projection, not the independently versioned presence file,
131
+ // owns the canonical prior state. Omitting an unknown first prior keeps
132
+ // the transition honest and avoids manufacturing a history.
133
+ const projectedPrior = readCoordinationViewV3(input.coordRoot).instances[hook.instance_id]
134
+ ?.presence_state;
135
+ event = buildEventV3("coord.presence_changed", {
136
+ ...common,
137
+ payload: {
138
+ actor_instance_id: hook.instance_id,
139
+ subject_instance_id: hook.instance_id,
140
+ ...(projectedPrior ? { prior_state: safeToken(projectedPrior) } : {}),
141
+ new_state: safeToken(observation.new_state),
142
+ reason: reasonCode(observation.reason),
143
+ authority: {},
144
+ },
145
+ });
146
+ break;
147
+ }
148
+ case "coord.message_observed":
149
+ event = buildEventV3("coord.message_observed", {
150
+ ...common,
151
+ payload: {
152
+ message_id: safeToken(observation.message_id ?? `msg_${randomUUID()}`),
153
+ direction: observation.direction,
154
+ peer_instance_id: subject,
155
+ body_length: Buffer.byteLength(observation.body, "utf8"),
156
+ body_fingerprint: fingerprintV3(
157
+ fingerprintContext,
158
+ "coord.message.body",
159
+ observation.body,
160
+ "generation",
161
+ ),
162
+ },
163
+ });
164
+ break;
165
+ case "council.state_changed":
166
+ event = buildEventV3("council.state_changed", {
167
+ ...common,
168
+ payload: {
169
+ council_id: safeToken(observation.council_id),
170
+ ...(observation.prior_state ? { prior_state: safeToken(observation.prior_state) } : {}),
171
+ new_state: safeToken(observation.new_state),
172
+ record_digest: sha256V3(canonicalJsonV3(observation.record)),
173
+ },
174
+ });
175
+ break;
176
+ case "decision.state_changed": {
177
+ const projectedDecisionPrior = readCoordinationViewV3(input.coordRoot).decisions[
178
+ observation.decision_id
179
+ ];
180
+ event = buildEventV3("decision.state_changed", {
181
+ ...common,
182
+ payload: {
183
+ decision_id: safeToken(observation.decision_id),
184
+ ...(projectedDecisionPrior ? { prior_state: safeToken(projectedDecisionPrior) } : {}),
185
+ new_state: safeToken(observation.new_state),
186
+ record_digest: sha256V3(canonicalJsonV3(observation.record)),
187
+ authority: { record_id: safeToken(observation.decision_id) },
188
+ },
189
+ });
190
+ break;
191
+ }
192
+ }
193
+ writeEventV3(input.coordRoot, event);
194
+ return { state: "recorded", event };
195
+ }
196
+
197
+ function safeToken(value: string): string {
198
+ const normalized = value.normalize("NFC");
199
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(normalized)) {
200
+ throw new LiveCoordinationAuthorityV3Error(`invalid_safe_token:${value}`);
201
+ }
202
+ return normalized;
203
+ }
204
+
205
+ function reasonCode(value: string): string {
206
+ const normalized = value.normalize("NFC");
207
+ if (!/^[a-z0-9][a-z0-9._-]{0,79}$/.test(normalized)) {
208
+ throw new LiveCoordinationAuthorityV3Error(`invalid_reason_code:${value}`);
209
+ }
210
+ return normalized;
211
+ }
212
+
213
+ export type LiveCoordinationObservationEventTypeV3 = Extract<
214
+ EventTypeV3,
215
+ LiveCoordinationObservationV3["event_type"]
216
+ >;
@@ -3,7 +3,7 @@
3
3
  * council-pending hash-dedup, the cross-adapter first-session naming nudge,
4
4
  * the Cursor/Codex set-task staleness nudge, and the Codex status-footer
5
5
  * reminder.
6
- * agent-hook's user_prompt.submit post-emit handler calls this
6
+ * agent-hook's turn.started post-emit handler calls this
7
7
  * and forwards the result as the adapter-shaped additionalContext payload.
8
8
  *
9
9
  * Four subsections combined into one additionalContext payload:
@@ -12,9 +12,9 @@
12
12
  * + sorted(files_touched) + platform, sorted by instance_id).
13
13
  * 2. Council pending: pending open-council IDs hashed; re-emits when the
14
14
  * ID set changes.
15
- * 3. Focus nudge. Until the session has produced its suggested name (first
16
- * non-empty set-task), tells every adapter — on every prompt, undeduped —
17
- * to reproduce set-task's suggested session name in a fenced code block.
15
+ * 3. Focus nudge. Until the session has displayed its current suggested
16
+ * name, tells every adapter on every prompt to send the exact fenced block
17
+ * before prose or another tool call.
18
18
  * Cursor/Codex additionally get the existing unset/stale-task reminder
19
19
  * because their Stop hooks do not enforce task declarations as reliably
20
20
  * as Claude Code's.
@@ -45,6 +45,11 @@ import { join } from "node:path";
45
45
  import { coordEnv } from "../../../lib/env.ts";
46
46
  import { endOfTurnStatusCommand, resolveBinName } from "../../config.ts";
47
47
  import { type RemoteMachine, readRemoteMachines } from "../../presence/index.ts";
48
+ import { sessionNameDisplayBlock, sessionNameDisplayPending } from "../session-name-display.ts";
49
+ import {
50
+ readLiveCoordinationRow,
51
+ readLiveCoordinationRows,
52
+ } from "../state/live-coordination-view.ts";
48
53
  import type { AgentActivity, TaskState } from "../state/session-state.ts";
49
54
  import { formatPendingCouncils } from "./session-context.ts";
50
55
 
@@ -55,18 +60,15 @@ interface HeartbeatRow {
55
60
  session_id?: string;
56
61
  started_at?: string;
57
62
  last_heartbeat?: string;
58
- last_tool?: string;
59
- last_tool_target?: string;
60
63
  files_touched?: string[];
61
64
  platform?: string;
62
65
  task?: string;
63
66
  activity?: AgentActivity;
64
67
  task_state?: TaskState;
65
68
  task_state_reason?: string;
66
- task_updated_at?: string;
69
+ task_updated_at?: string | null;
67
70
  suggested_session_name?: string;
68
71
  session_name_seen_for?: string;
69
- turn_summary?: string;
70
72
  workflow_run_id?: string;
71
73
  }
72
74
 
@@ -160,7 +162,7 @@ function renderTurnRitualReminder(
160
162
  selfInstanceId: string,
161
163
  adapter: string,
162
164
  ): string {
163
- const hb = readHeartbeat(join(coordRoot, ".harnery", "active", `${selfInstanceId}.json`));
165
+ const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
164
166
  if (!hb || hb.kind === "subagent" || hb.kind === "transient" || hb.workflow_run_id) return "";
165
167
 
166
168
  const bin = resolveBinName(coordRoot);
@@ -178,7 +180,7 @@ function renderTurnRitualReminder(
178
180
  }
179
181
 
180
182
  function renderStatusFooterReminder(coordRoot: string, selfInstanceId: string): string {
181
- const hb = readHeartbeat(join(coordRoot, ".harnery", "active", `${selfInstanceId}.json`));
183
+ const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
182
184
  if (!hb || hb.kind === "subagent" || hb.kind === "transient" || hb.workflow_run_id) return "";
183
185
 
184
186
  const statusCommand = endOfTurnStatusCommand(coordRoot);
@@ -200,14 +202,8 @@ function computeFocusNudgeIfChanged(
200
202
  selfInstanceId: string,
201
203
  opts: { sessionNameNudge: boolean; taskNudge: boolean },
202
204
  ): string {
203
- const hbPath = join(coordRoot, ".harnery", "active", `${selfInstanceId}.json`);
204
- if (!existsSync(hbPath)) return "";
205
- let hb: HeartbeatRow;
206
- try {
207
- hb = JSON.parse(readFileSync(hbPath, "utf8"));
208
- } catch {
209
- return "";
210
- }
205
+ const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
206
+ if (!hb) return "";
211
207
 
212
208
  const hashFile = join(coordRoot, ".harnery", `.last-task-nudge-hash.${selfInstanceId}`);
213
209
  // Subagents and workflow children have no human-owned session/tab to rename.
@@ -223,20 +219,16 @@ function computeFocusNudgeIfChanged(
223
219
  let message = "";
224
220
  let nudgeKind = "";
225
221
 
226
- if (
227
- opts.sessionNameNudge &&
228
- (!hb.suggested_session_name ||
229
- (hb.session_name_seen_for !== undefined &&
230
- hb.suggested_session_name !== hb.session_name_seen_for))
231
- ) {
222
+ const pendingSessionName = sessionNameDisplayPending(hb);
223
+ if (opts.sessionNameNudge && (!hb.suggested_session_name || pendingSessionName)) {
232
224
  // Keyed on "a name was ever produced", not task_updated_at: a bare clear
233
225
  // as the first declaration must not end the naming window.
234
226
  needsNudge = true;
235
227
  nudgeKind = "session-name";
236
- message = hb.suggested_session_name
237
- ? `This session's lifecycle changed its suggested name. Reproduce this value by itself inside a fenced code block at the very top of your reply so the operator can one-click-copy it as the session/tab title: ${hb.suggested_session_name}`
228
+ message = pendingSessionName
229
+ ? `This session name is still pending display. Before any prose or another tool call, send this exact block as your next assistant text:\n\n${sessionNameDisplayBlock(pendingSessionName)}`
238
230
  : `This session has no name yet: run \`${bin} agents set-task "<2-5 word session topic>"\` as your first tool call. ` +
239
- "When it returns `first_of_session: true`, reproduce its `suggested_session_name` value by itself inside a fenced code block at the very top of your reply so the operator can one-click-copy it as the session/tab title. " +
231
+ "When it returns `first_of_session: true`, send its `suggested_session_name` as the exact fenced block requested by the PostToolUse instruction before any prose or another tool call. " +
240
232
  "Then continue with the task; that `set-task` also satisfies this turn's focus declaration.";
241
233
  } else if (opts.taskNudge && !taskValue) {
242
234
  needsNudge = true;
@@ -287,25 +279,21 @@ function computePeerTableIfChanged(
287
279
  selfInstanceId: string,
288
280
  selfSessionIdFallback: string,
289
281
  ): string {
290
- const activeDir = join(coordRoot, ".harnery", "active");
291
- if (!existsSync(activeDir)) return "";
292
-
293
282
  // Read self heartbeat for session_id (group key); fall back to the caller's hint.
294
283
  let mySessionId = selfSessionIdFallback;
295
- const selfHb = readHeartbeat(join(activeDir, `${selfInstanceId}.json`));
284
+ const rows = readLiveCoordinationRows(coordRoot);
285
+ const selfHb = readLiveCoordinationRow(coordRoot, selfInstanceId);
296
286
  if (selfHb?.session_id) mySessionId = selfHb.session_id;
297
287
  if (!mySessionId) return "";
298
288
 
299
- // Collect peer heartbeats.
300
- const peers: HeartbeatRow[] = [];
301
- for (const f of readdirSync(activeDir)) {
302
- if (!f.endsWith(".json")) continue;
303
- const hb = readHeartbeat(join(activeDir, f));
304
- if (!hb?.instance_id || hb.instance_id === selfInstanceId) continue;
305
- peers.push(hb);
306
- }
289
+ // Collect peers from the selected ledger route. Under V3 this is the
290
+ // canonical projection, never the legacy active directory.
291
+ const peers: HeartbeatRow[] = rows.filter(
292
+ (heartbeat) => heartbeat.instance_id && heartbeat.instance_id !== selfInstanceId,
293
+ );
307
294
  // Cross-machine presence (ADR 0016): sessions on other machines, from the
308
- // locally-fetched presence refs. Advisory (no claim blocking in v1).
295
+ // locally-fetched presence refs. Advisory only; remote presence never grants
296
+ // claim authority.
309
297
  const remote = readRemoteMachinesSafe(coordRoot);
310
298
  if (peers.length === 0 && remote.length === 0) return "";
311
299
 
@@ -448,14 +436,6 @@ function computeCouncilPendingIfChanged(
448
436
 
449
437
  /* ---------- helpers ---------- */
450
438
 
451
- function readHeartbeat(path: string): HeartbeatRow | null {
452
- try {
453
- return JSON.parse(readFileSync(path, "utf8")) as HeartbeatRow;
454
- } catch {
455
- return null;
456
- }
457
- }
458
-
459
439
  function safeRead(path: string): string {
460
440
  try {
461
441
  return readFileSync(path, "utf8").trim();
@@ -555,12 +535,10 @@ function formatRow(r: HeartbeatRow & { display_files: string[] }, nowSec: number
555
535
  const startedSec = parseIsoSec(r.started_at) ?? parseIsoSec(r.last_heartbeat);
556
536
  const ageFrom = startedSec === null ? "age unknown" : fmtAge(nowSec - startedSec);
557
537
  const filesPart = fmtFiles(r.display_files);
558
- const lastActivity = fmtLastActivity(r, nowSec);
559
- const turnSummary = r.turn_summary ? `\n last turn: ${r.turn_summary.slice(0, 80)}` : "";
560
538
  // Prefer a short instance_id over a bare "unknown" so an incomplete row is
561
539
  // still identifiable.
562
540
  const label = r.name ?? (r.instance_id ? r.instance_id.slice(0, 8) : "unknown");
563
- return ` - agent-${label}${taskPart} (${statePart}, ${ageFrom}, ${filesPart}${lastActivity})${turnSummary}`;
541
+ return ` - agent-${label}${taskPart} (${statePart}, ${ageFrom}, ${filesPart})`;
564
542
  }
565
543
 
566
544
  function formatState(r: HeartbeatRow): string {
@@ -577,15 +555,6 @@ function fmtFiles(files: string[]): string {
577
555
  return `holds: ${files.slice(0, 3).join(", ")}, +${files.length - 3} more`;
578
556
  }
579
557
 
580
- function fmtLastActivity(r: HeartbeatRow, nowSec: number): string {
581
- if (!r.last_tool) return "";
582
- const lastTs = parseIsoSec(r.last_heartbeat) ?? parseIsoSec(r.started_at);
583
- const tail = r.last_tool_target ? ` ${r.last_tool_target.slice(0, 60)}` : "";
584
- // No valid timestamp → render the tool without an absurd age.
585
- if (lastTs === null) return `, last: ${r.last_tool}${tail}`;
586
- return `, last: ${r.last_tool}${tail} ${fmtAge(nowSec - lastTs)}`;
587
- }
588
-
589
558
  /** Epoch-seconds for an ISO string, or null when missing/unparseable (so callers
590
559
  * can render "age unknown" instead of an epoch-derived absurd age). */
591
560
  function parseIsoSec(iso: string | undefined): number | null {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * SessionStart UX renderer: combines the peer table, the wiring check, and
3
- * the pending-council formatter so agent-hook session.start can emit the
3
+ * the pending-council formatter so agent-hook session.started can emit the
4
4
  * combined `systemMessage` JSON directly.
5
5
  *
6
6
  * Outputs a Claude Code SessionStart hookSpecificOutput.additionalContext
@@ -13,6 +13,7 @@ import { join } from "node:path";
13
13
  import { resolveBinName, resolveHooksSetupHint } from "../../config.ts";
14
14
  import { harneryVersion, loadAdapterWiring } from "../../hooks/adapter/wiring.ts";
15
15
  import { readRemoteMachines } from "../../presence/index.ts";
16
+ import { readLiveCoordinationRows } from "../state/live-coordination-view.ts";
16
17
  import { readForkParent } from "../state/names.ts";
17
18
  import type { AgentActivity, TaskState } from "../state/session-state.ts";
18
19
 
@@ -23,15 +24,12 @@ interface HeartbeatRow {
23
24
  session_id?: string;
24
25
  started_at?: string;
25
26
  last_heartbeat?: string;
26
- last_tool?: string;
27
- last_tool_target?: string;
28
27
  files_touched?: string[];
29
28
  platform?: string;
30
29
  task?: string;
31
30
  activity?: AgentActivity;
32
31
  task_state?: TaskState;
33
32
  task_state_reason?: string;
34
- turn_summary?: string;
35
33
  }
36
34
 
37
35
  export interface RenderOpts {
@@ -154,22 +152,11 @@ function formatRemoteMachines(coordRoot: string): string {
154
152
  }
155
153
  }
156
154
 
157
- /** Read all peer heartbeats from .harnery/active/, excluding self. */
155
+ /** Read peers from the selected ledger route, excluding self. */
158
156
  function readActivePeers(coordRoot: string, selfInstanceId: string): HeartbeatRow[] {
159
- const out: HeartbeatRow[] = [];
160
- const dir = join(coordRoot, ".harnery", "active");
161
- if (!existsSync(dir)) return out;
162
- for (const f of readdirSync(dir)) {
163
- if (!f.endsWith(".json")) continue;
164
- try {
165
- const hb = JSON.parse(readFileSync(join(dir, f), "utf8")) as HeartbeatRow;
166
- if (!hb.instance_id || hb.instance_id === selfInstanceId) continue;
167
- out.push(hb);
168
- } catch {
169
- /* skip */
170
- }
171
- }
172
- return out;
157
+ return readLiveCoordinationRows(coordRoot).filter(
158
+ (heartbeat) => heartbeat.instance_id && heartbeat.instance_id !== selfInstanceId,
159
+ );
173
160
  }
174
161
 
175
162
  /**
@@ -244,9 +231,7 @@ function formatRow(r: HeartbeatRow & { display_files: string[] }, nowSec: number
244
231
  lifecycle === "blocked" && r.task_state_reason ? `: ${r.task_state_reason.slice(0, 80)}` : "";
245
232
  const ageFrom = fmtAge(nowSec - parseIsoSec(r.started_at));
246
233
  const filesPart = fmtFiles(r.display_files);
247
- const lastActivity = fmtLastActivity(r, nowSec);
248
- const turnSummary = r.turn_summary ? `\n last turn: ${r.turn_summary.slice(0, 80)}` : "";
249
- return ` - agent-${r.name ?? "unknown"}${taskPart} (activity=${activity}, lifecycle=${lifecycle}${reason}, ${ageFrom}, ${filesPart}${lastActivity})${turnSummary}`;
234
+ return ` - agent-${r.name ?? "unknown"}${taskPart} (activity=${activity}, lifecycle=${lifecycle}${reason}, ${ageFrom}, ${filesPart})`;
250
235
  }
251
236
 
252
237
  function fmtFiles(files: string[]): string {
@@ -255,14 +240,6 @@ function fmtFiles(files: string[]): string {
255
240
  return `holds: ${files.slice(0, 3).join(", ")}, +${files.length - 3} more`;
256
241
  }
257
242
 
258
- function fmtLastActivity(r: HeartbeatRow, nowSec: number): string {
259
- if (!r.last_tool) return "";
260
- const lastTs = parseIsoSec(r.last_heartbeat ?? r.started_at);
261
- const ageSec = nowSec - lastTs;
262
- const tail = r.last_tool_target ? ` ${r.last_tool_target.slice(0, 60)}` : "";
263
- return `, last: ${r.last_tool}${tail} ${fmtAge(ageSec)}`;
264
- }
265
-
266
243
  function parseIsoSec(iso: string | undefined): number {
267
244
  if (!iso) return 0;
268
245
  const ms = Date.parse(iso);
@@ -360,7 +337,9 @@ function extractFirstSubmodule(gitmodulesPath: string): string | null {
360
337
  * superproject) via a `git rev-parse --git-dir` vs `--git-common-dir` check.
361
338
  */
362
339
  function isLinkedWorktree(coordRoot: string): boolean {
363
- const dir = spawnSync("git", ["-C", coordRoot, "rev-parse", "--git-dir"], { encoding: "utf8" });
340
+ const dir = spawnSync("git", ["-C", coordRoot, "rev-parse", "--git-dir"], {
341
+ encoding: "utf8",
342
+ });
364
343
  const common = spawnSync("git", ["-C", coordRoot, "rev-parse", "--git-common-dir"], {
365
344
  encoding: "utf8",
366
345
  });