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
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Headless harness calling — run a one-shot prompt (optionally with images)
3
+ * through a locally installed AI coding harness CLI and return its reply.
4
+ *
5
+ * Backends, in default preference order (subscription seats an embedding
6
+ * host already pays for, before any metered API a host might add on top):
7
+ *
8
+ * 1. claude-code `claude -p` JSON envelope on stdout
9
+ * 2. codex `codex exec` last message written to a file
10
+ * 3. cursor `cursor-agent -p` plain text on stdout
11
+ *
12
+ * Design rules, each learned from a live failure:
13
+ *
14
+ * - Every call runs from a NEUTRAL temp cwd holding only the staged images,
15
+ * so the nested session loads no repo instructions, hooks, or coordination
16
+ * rituals from the caller's checkout.
17
+ * - The child's stdin is CLOSED immediately. execFile leaves it open as a
18
+ * pipe, and codex interprets that as "more prompt coming" and blocks on
19
+ * it, then exits with no output.
20
+ * - An empty reply THROWS instead of returning "": a one-shot call that
21
+ * produced nothing was inconclusive, and callers gating on the result must
22
+ * fail closed rather than read silence as success.
23
+ * - `runHeadless` walks the backend chain PER CALL: a backend that is
24
+ * installed but errors (rate limit, timeout, transient exec failure) hands
25
+ * the same request to the next backend instead of failing the call. "On
26
+ * PATH" is not "working", and under parallel load the first backend can
27
+ * flake on a fraction of calls while the second runs clean.
28
+ *
29
+ * Env knobs (read through coordEnv, so the HARNERY_ prefix stays in one
30
+ * place): HARNERY_HEADLESS_BACKEND forces one backend and disables the
31
+ * fallback walk; HARNERY_HEADLESS_MODEL overrides the model passed to
32
+ * whichever backend runs.
33
+ */
34
+ /** Names accepted by `runHeadlessOn`, `runHeadless({backends})`, and the
35
+ * HARNERY_HEADLESS_BACKEND env knob. */
36
+ export type HeadlessBackendName = "claude-code" | "codex" | "cursor";
37
+ /** An image to stage into the call's neutral cwd. `data` is the PNG bytes
38
+ * (Buffer) or their base64 encoding (string). */
39
+ export interface HeadlessImage {
40
+ data: Buffer | string;
41
+ /** Staged filename inside the neutral dir (default `image-<n>.png`). */
42
+ name?: string;
43
+ }
44
+ export interface HeadlessRequest {
45
+ /**
46
+ * The prompt, or a builder receiving the staged image paths. Backends that
47
+ * cannot attach an image natively (claude-code, cursor) rely on the prompt
48
+ * naming the staged paths so the harness reads them with its own tools;
49
+ * codex additionally attaches every image via `-i`.
50
+ */
51
+ prompt: string | ((ctx: {
52
+ imagePaths: string[];
53
+ }) => string);
54
+ images?: HeadlessImage[];
55
+ /** Model override for this call; HARNERY_HEADLESS_MODEL wins over it. */
56
+ model?: string;
57
+ /** Kill the child after this long (default 240_000 ms). */
58
+ timeoutMs?: number;
59
+ /** Agentic turn budget where the backend supports one (default 4). */
60
+ maxTurns?: number;
61
+ }
62
+ export interface HeadlessResult {
63
+ /** The harness's final reply text, never empty (empty replies throw). */
64
+ text: string;
65
+ /** Which backend produced it. */
66
+ backend: HeadlessBackendName;
67
+ }
68
+ export interface RunHeadlessOptions {
69
+ /** Preference order (default: HEADLESS_BACKENDS order). */
70
+ backends?: HeadlessBackendName[];
71
+ /** Walk the chain past a failing backend (default true). Forcing a backend
72
+ * via HARNERY_HEADLESS_BACKEND implies false. */
73
+ fallback?: boolean;
74
+ }
75
+ /** Cross-runtime `which`: walk PATH (and PATHEXT on Windows) for an
76
+ * executable. Node has no built-in and Bun.which only exists under Bun. */
77
+ export declare function whichBin(bin: string): string | undefined;
78
+ /** The backend registry in default preference order. */
79
+ export declare const HEADLESS_BACKENDS: ReadonlyArray<{
80
+ name: HeadlessBackendName;
81
+ bin: string;
82
+ }>;
83
+ /** Backends whose binary is on PATH right now, in preference order. Being
84
+ * listed means installed, not proven working — that is what the per-call
85
+ * fallback in `runHeadless` is for. */
86
+ export declare function availableHeadlessBackends(): HeadlessBackendName[];
87
+ /** Run the request on exactly one named backend. Throws when the backend is
88
+ * not installed or the call fails. */
89
+ export declare function runHeadlessOn(name: HeadlessBackendName, req: HeadlessRequest): Promise<HeadlessResult>;
90
+ /**
91
+ * Run the request on the first backend that succeeds, walking the preference
92
+ * order past installed-but-failing backends (unless fallback is disabled or a
93
+ * backend is forced via HARNERY_HEADLESS_BACKEND). Throws when no backend is
94
+ * installed, or every attempted backend failed — the error message carries
95
+ * each backend's failure so a flaky chain is diagnosable.
96
+ */
97
+ export declare function runHeadless(req: HeadlessRequest, opts?: RunHeadlessOptions): Promise<HeadlessResult>;
98
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/headless/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAoBH;wCACwC;AACxC,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE;iDACiD;AACjD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,MAAM,CAAC,CAAC;IAC7D,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC;qDACiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAMD;2EAC2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgBxD;AA6FD,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAIvF,CAAC;AAaF;;uCAEuC;AACvC,wBAAgB,yBAAyB,IAAI,mBAAmB,EAAE,CAEjE;AAED;sCACsC;AACtC,wBAAsB,aAAa,CACjC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,cAAc,CAAC,CASzB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,eAAe,EACpB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAwBzB"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Headless harness calling — run a one-shot prompt (optionally with images)
3
+ * through a locally installed AI coding harness CLI and return its reply.
4
+ *
5
+ * Backends, in default preference order (subscription seats an embedding
6
+ * host already pays for, before any metered API a host might add on top):
7
+ *
8
+ * 1. claude-code `claude -p` JSON envelope on stdout
9
+ * 2. codex `codex exec` last message written to a file
10
+ * 3. cursor `cursor-agent -p` plain text on stdout
11
+ *
12
+ * Design rules, each learned from a live failure:
13
+ *
14
+ * - Every call runs from a NEUTRAL temp cwd holding only the staged images,
15
+ * so the nested session loads no repo instructions, hooks, or coordination
16
+ * rituals from the caller's checkout.
17
+ * - The child's stdin is CLOSED immediately. execFile leaves it open as a
18
+ * pipe, and codex interprets that as "more prompt coming" and blocks on
19
+ * it, then exits with no output.
20
+ * - An empty reply THROWS instead of returning "": a one-shot call that
21
+ * produced nothing was inconclusive, and callers gating on the result must
22
+ * fail closed rather than read silence as success.
23
+ * - `runHeadless` walks the backend chain PER CALL: a backend that is
24
+ * installed but errors (rate limit, timeout, transient exec failure) hands
25
+ * the same request to the next backend instead of failing the call. "On
26
+ * PATH" is not "working", and under parallel load the first backend can
27
+ * flake on a fraction of calls while the second runs clean.
28
+ *
29
+ * Env knobs (read through coordEnv, so the HARNERY_ prefix stays in one
30
+ * place): HARNERY_HEADLESS_BACKEND forces one backend and disables the
31
+ * fallback walk; HARNERY_HEADLESS_MODEL overrides the model passed to
32
+ * whichever backend runs.
33
+ */
34
+ import { execFile } from "node:child_process";
35
+ import { accessSync, constants, existsSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
36
+ import { tmpdir } from "node:os";
37
+ import { delimiter, isAbsolute, join } from "node:path";
38
+ import { promisify } from "node:util";
39
+ import { coordEnv } from "../env.js";
40
+ const execFileAsync = promisify(execFile);
41
+ const MAX_BUFFER = 32 * 1024 * 1024;
42
+ const DEFAULT_TIMEOUT_MS = 240_000;
43
+ const DEFAULT_MAX_TURNS = 4;
44
+ /** Cross-runtime `which`: walk PATH (and PATHEXT on Windows) for an
45
+ * executable. Node has no built-in and Bun.which only exists under Bun. */
46
+ export function whichBin(bin) {
47
+ if (isAbsolute(bin))
48
+ return isExecutable(bin) ? bin : undefined;
49
+ const paths = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
50
+ const exts = process.platform === "win32" ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";") : [""];
51
+ for (const dir of paths) {
52
+ for (const ext of exts) {
53
+ const candidate = join(dir, bin + ext.toLowerCase());
54
+ if (isExecutable(candidate))
55
+ return candidate;
56
+ if (ext) {
57
+ const upper = join(dir, bin + ext);
58
+ if (isExecutable(upper))
59
+ return upper;
60
+ }
61
+ }
62
+ }
63
+ return undefined;
64
+ }
65
+ function isExecutable(path) {
66
+ try {
67
+ if (!statSync(path).isFile())
68
+ return false;
69
+ accessSync(path, constants.X_OK);
70
+ return true;
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ }
76
+ /** Write the request's images into a fresh neutral dir and resolve the
77
+ * prompt against their staged paths. Caller must clean the dir up. */
78
+ function stageCall(req) {
79
+ const dir = mkdtempSync(join(tmpdir(), "harnery-headless-"));
80
+ const imagePaths = (req.images ?? []).map((img, i) => {
81
+ const path = join(dir, img.name ?? `image-${i + 1}.png`);
82
+ writeFileSync(path, typeof img.data === "string" ? Buffer.from(img.data, "base64") : img.data);
83
+ return path;
84
+ });
85
+ const prompt = typeof req.prompt === "function" ? req.prompt({ imagePaths }) : req.prompt;
86
+ return {
87
+ dir,
88
+ imagePaths,
89
+ prompt,
90
+ model: coordEnv("HEADLESS_MODEL") ?? req.model,
91
+ timeoutMs: req.timeoutMs ?? DEFAULT_TIMEOUT_MS,
92
+ maxTurns: req.maxTurns ?? DEFAULT_MAX_TURNS,
93
+ };
94
+ }
95
+ /** Run a harness CLI from the neutral dir with stdin CLOSED (see module
96
+ * comment: an open stdin pipe deadlocks codex). */
97
+ function execHarness(bin, args, call) {
98
+ const pending = execFileAsync(bin, args, {
99
+ cwd: call.dir,
100
+ timeout: call.timeoutMs,
101
+ maxBuffer: MAX_BUFFER,
102
+ });
103
+ pending.child.stdin?.end();
104
+ return pending;
105
+ }
106
+ function assertReply(text, backend) {
107
+ if (!text.trim())
108
+ throw new Error(`${backend}: empty reply (inconclusive; failing closed)`);
109
+ return { text, backend };
110
+ }
111
+ async function runClaudeCode(bin, call) {
112
+ const args = ["-p", call.prompt, "--output-format", "json", "--max-turns", String(call.maxTurns)];
113
+ if (call.imagePaths.length)
114
+ args.push("--allowedTools", "Read");
115
+ if (call.model)
116
+ args.push("--model", call.model);
117
+ const { stdout } = await execHarness(bin, args, call);
118
+ const envelope = JSON.parse(stdout);
119
+ if (envelope.is_error) {
120
+ throw new Error(typeof envelope.result === "string" ? envelope.result : "claude-code: headless error");
121
+ }
122
+ return assertReply(typeof envelope.result === "string" ? envelope.result : "", "claude-code");
123
+ }
124
+ async function runCodex(bin, call) {
125
+ const outPath = join(call.dir, "last-message.txt");
126
+ const args = ["exec", "--skip-git-repo-check"];
127
+ for (const png of call.imagePaths)
128
+ args.push("-i", png);
129
+ args.push("--output-last-message", outPath);
130
+ if (call.model)
131
+ args.push("-m", call.model);
132
+ args.push(call.prompt);
133
+ await execHarness(bin, args, call);
134
+ return assertReply(existsSync(outPath) ? readFileSync(outPath, "utf-8") : "", "codex");
135
+ }
136
+ /** `-f` trusts the neutral dir so cursor's read tool runs without a prompt. */
137
+ async function runCursor(bin, call) {
138
+ const args = ["-p", call.prompt, "--output-format", "text", "-f"];
139
+ if (call.model)
140
+ args.push("--model", call.model);
141
+ const { stdout } = await execHarness(bin, args, call);
142
+ return assertReply(stdout, "cursor");
143
+ }
144
+ /** The backend registry in default preference order. */
145
+ export const HEADLESS_BACKENDS = [
146
+ { name: "claude-code", bin: "claude" },
147
+ { name: "codex", bin: "codex" },
148
+ { name: "cursor", bin: "cursor-agent" },
149
+ ];
150
+ const RUNNERS = {
151
+ "claude-code": runClaudeCode,
152
+ codex: runCodex,
153
+ cursor: runCursor,
154
+ };
155
+ function backendBin(name) {
156
+ const entry = HEADLESS_BACKENDS.find((b) => b.name === name);
157
+ return entry ? whichBin(entry.bin) : undefined;
158
+ }
159
+ /** Backends whose binary is on PATH right now, in preference order. Being
160
+ * listed means installed, not proven working — that is what the per-call
161
+ * fallback in `runHeadless` is for. */
162
+ export function availableHeadlessBackends() {
163
+ return HEADLESS_BACKENDS.filter((b) => whichBin(b.bin)).map((b) => b.name);
164
+ }
165
+ /** Run the request on exactly one named backend. Throws when the backend is
166
+ * not installed or the call fails. */
167
+ export async function runHeadlessOn(name, req) {
168
+ const bin = backendBin(name);
169
+ if (!bin)
170
+ throw new Error(`headless backend not installed: ${name}`);
171
+ const call = stageCall(req);
172
+ try {
173
+ return await RUNNERS[name](bin, call);
174
+ }
175
+ finally {
176
+ rmSync(call.dir, { recursive: true, force: true });
177
+ }
178
+ }
179
+ /**
180
+ * Run the request on the first backend that succeeds, walking the preference
181
+ * order past installed-but-failing backends (unless fallback is disabled or a
182
+ * backend is forced via HARNERY_HEADLESS_BACKEND). Throws when no backend is
183
+ * installed, or every attempted backend failed — the error message carries
184
+ * each backend's failure so a flaky chain is diagnosable.
185
+ */
186
+ export async function runHeadless(req, opts = {}) {
187
+ const forced = coordEnv("HEADLESS_BACKEND");
188
+ if (forced && !opts.backends) {
189
+ if (!HEADLESS_BACKENDS.some((b) => b.name === forced)) {
190
+ throw new Error(`unknown HARNERY_HEADLESS_BACKEND: ${forced}`);
191
+ }
192
+ return runHeadlessOn(forced, req);
193
+ }
194
+ const order = opts.backends ?? HEADLESS_BACKENDS.map((b) => b.name);
195
+ const installed = order.filter((name) => backendBin(name));
196
+ if (!installed.length) {
197
+ throw new Error(`no headless backend installed (looked for: ${order.join(", ")})`);
198
+ }
199
+ const fallback = opts.fallback ?? true;
200
+ const attempts = fallback ? installed : installed.slice(0, 1);
201
+ const failures = [];
202
+ for (const name of attempts) {
203
+ try {
204
+ return await runHeadlessOn(name, req);
205
+ }
206
+ catch (err) {
207
+ failures.push(`${name}: ${err instanceof Error ? err.message : String(err)}`);
208
+ }
209
+ }
210
+ throw new Error(`every headless backend failed:\n ${failures.join("\n ")}`);
211
+ }
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * The operation is serialized because "is this name live?" and "claim it"
5
5
  * must be one critical section. Authoritative state is written twice on
6
- * purpose: `.name-history` heals a missing heartbeat, while the canonical
7
- * `identity.assumed` event makes replay and derived readers converge.
6
+ * purpose: `.name-history` supplies display metadata, while the canonical
7
+ * `coord.identity_attested` event makes replay and derived readers converge.
8
8
  *
9
9
  * Local collision policy: a fresh heartbeat alone is not enough to block.
10
10
  * If the namesake has no live pid-map process (crashed session, healed
@@ -12,7 +12,7 @@
12
12
  * Refuse only when another process is still alive, or when cached remote
13
13
  * presence reports the name.
14
14
  */
15
- export type IdentityAssumeErrorCode = "identity_busy" | "identity_in_use" | "identity_is_ancestor" | "identity_not_found" | "invalid_identity" | "no_heartbeat" | "not_session" | "projection_failed";
15
+ export type IdentityAssumeErrorCode = "identity_busy" | "identity_in_use" | "identity_is_ancestor" | "identity_not_found" | "invalid_identity" | "no_live_generation" | "not_session" | "projection_failed";
16
16
  export declare class IdentityAssumeError extends Error {
17
17
  readonly code: IdentityAssumeErrorCode;
18
18
  constructor(code: IdentityAssumeErrorCode, message: string);
@@ -38,7 +38,7 @@ export interface IdentityAssumeResult {
38
38
  }
39
39
  /** Best-effort collision read across local heartbeats and cached remote
40
40
  * presence. No network call occurs; absent presence degrades to local-only. */
41
- export declare function findIdentityConflict(coordRoot: string, instanceId: string, name: string, nowMs?: number): IdentityConflict | null;
41
+ export declare function findIdentityConflict(coordRoot: string, instanceId: string, name: string, nowMs?: number, excludedInstanceIds?: ReadonlySet<string>): IdentityConflict | null;
42
42
  /**
43
43
  * Drop a local namesake whose adapter process is gone. Fresh heartbeats can
44
44
  * linger after a crash (or after heartbeat heal without a live pid-map), and
@@ -1 +1 @@
1
- {"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA2BH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf,iBAAiB,GACjB,sBAAsB,GACtB,oBAAoB,GACpB,kBAAkB,GAClB,cAAc,GACd,aAAa,GACb,mBAAmB,CAAC;AAExB,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,uBAAuB;gBAA7B,IAAI,EAAE,uBAAuB,EAC7C,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAOD;+EAC+E;AAC/E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,SAAa,GACjB,gBAAgB,GAAG,IAAI,CAiCzB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CA2CT;AAyED,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,oBAAoB,CA4HtB"}
1
+ {"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuBH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf,iBAAiB,GACjB,sBAAsB,GACtB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,aAAa,GACb,mBAAmB,CAAC;AAExB,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,uBAAuB;gBAA7B,IAAI,EAAE,uBAAuB,EAC7C,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAOD;+EAC+E;AAC/E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,SAAa,EAClB,mBAAmB,GAAE,WAAW,CAAC,MAAM,CAAa,GACnD,gBAAgB,GAAG,IAAI,CA6BzB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAyCT;AAyED,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,oBAAoB,CAkHtB"}
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * The operation is serialized because "is this name live?" and "claim it"
5
5
  * must be one critical section. Authoritative state is written twice on
6
- * purpose: `.name-history` heals a missing heartbeat, while the canonical
7
- * `identity.assumed` event makes replay and derived readers converge.
6
+ * purpose: `.name-history` supplies display metadata, while the canonical
7
+ * `coord.identity_attested` event makes replay and derived readers converge.
8
8
  *
9
9
  * Local collision policy: a fresh heartbeat alone is not enough to block.
10
10
  * If the namesake has no live pid-map process (crashed session, healed
@@ -13,12 +13,12 @@
13
13
  * presence reports the name.
14
14
  */
15
15
  import { randomUUID } from "node:crypto";
16
- import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
16
+ import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
17
17
  import { join } from "node:path";
18
- import { emitAndProject } from "../../core/agents/cli-emit.js";
19
- import { emit } from "../../core/agents/events/emit.js";
20
- import { readHeartbeat } from "../../core/agents/state/heartbeat-writer.js";
21
- import { recordNameAssumption, resolveForkAncestry } from "../../core/agents/state/names.js";
18
+ import { recordLiveIdentityChangeV3 } from "../../core/agents/live-authority-v3.js";
19
+ import { recordLiveSweepObservationV3 } from "../../core/agents/live-lifecycle-v3.js";
20
+ import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../../core/agents/state/live-coordination-view.js";
21
+ import { resolveForkAncestry } from "../../core/agents/state/names.js";
22
22
  import { instanceHasLivePid, removePidmapRowsForInstance } from "../../core/agents/state/pidmap.js";
23
23
  import { coordFreshnessSeconds } from "../../core/config.js";
24
24
  import { readRemoteMachines } from "../../core/presence/index.js";
@@ -40,25 +40,16 @@ function heartbeatIsFresh(hb, cutoffMs) {
40
40
  }
41
41
  /** Best-effort collision read across local heartbeats and cached remote
42
42
  * presence. No network call occurs; absent presence degrades to local-only. */
43
- export function findIdentityConflict(coordRoot, instanceId, name, nowMs = Date.now()) {
43
+ export function findIdentityConflict(coordRoot, instanceId, name, nowMs = Date.now(), excludedInstanceIds = new Set()) {
44
44
  const wanted = name.toLowerCase();
45
45
  const cutoffMs = nowMs - coordFreshnessSeconds(coordRoot) * 1000;
46
- const activeDir = join(coordRoot, ".harnery", "active");
47
- if (existsSync(activeDir)) {
48
- for (const file of readdirSync(activeDir)) {
49
- if (!file.endsWith(".json"))
50
- continue;
51
- try {
52
- const hb = JSON.parse(readFileSync(join(activeDir, file), "utf8"));
53
- if (hb.instance_id === instanceId || !heartbeatIsFresh(hb, cutoffMs))
54
- continue;
55
- if ((hb.name ?? "").toLowerCase() === wanted) {
56
- return { instance_id: hb.instance_id, name: hb.name ?? name, scope: "local" };
57
- }
58
- }
59
- catch {
60
- // Malformed heartbeats are handled by stale sweep, not this command.
61
- }
46
+ for (const row of readLiveCoordinationRows(coordRoot)) {
47
+ if (row.instance_id === instanceId ||
48
+ excludedInstanceIds.has(row.instance_id) ||
49
+ !heartbeatIsFresh(row, cutoffMs))
50
+ continue;
51
+ if ((row.name ?? "").toLowerCase() === wanted) {
52
+ return { instance_id: row.instance_id, name: row.name ?? name, scope: "local" };
62
53
  }
63
54
  }
64
55
  for (const remote of readRemoteMachines(coordRoot)) {
@@ -92,14 +83,21 @@ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
92
83
  let adapter = "claude-code";
93
84
  let sessionId = conflict.instance_id;
94
85
  let ageSecs;
86
+ const liveRow = readLiveCoordinationRow(coordRoot, conflict.instance_id);
87
+ if (liveRow) {
88
+ adapter = adapterOf(liveRow.platform);
89
+ sessionId = liveRow.session_id || conflict.instance_id;
90
+ const ts = Date.parse(liveRow.last_heartbeat);
91
+ if (Number.isFinite(ts))
92
+ ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
93
+ }
95
94
  if (existsSync(hbPath)) {
96
95
  try {
97
96
  const hb = JSON.parse(readFileSync(hbPath, "utf8"));
97
+ // Native producer identity is private cache metadata, not ledger authority.
98
+ // It is required to join the exact producer state when recording the sweep.
98
99
  adapter = adapterOf(hb.platform);
99
100
  sessionId = hb.session_id || conflict.instance_id;
100
- const ts = Date.parse(hb.last_heartbeat);
101
- if (Number.isFinite(ts))
102
- ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
103
101
  }
104
102
  catch {
105
103
  /* content unreadable — still reclaim the file */
@@ -112,24 +110,14 @@ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
112
110
  }
113
111
  }
114
112
  removePidmapRowsForInstance(coordRoot, conflict.instance_id);
115
- try {
116
- emit(coordRoot, {
117
- event_type: "health.heartbeat_swept",
118
- instance_id: conflict.instance_id,
119
- session_id: sessionId,
120
- adapter,
121
- source: "agent-coord",
122
- data: {
123
- reason: "stale",
124
- ...(ageSecs !== undefined ? { age_secs: ageSecs } : {}),
125
- reclaimed_by: "identity.assume",
126
- },
127
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
128
- });
129
- }
130
- catch {
131
- /* telemetry only */
132
- }
113
+ recordLiveSweepObservationV3({
114
+ coordRoot,
115
+ owner: conflict.instance_id,
116
+ nativeSessionId: sessionId,
117
+ adapter,
118
+ observation: "stale_heartbeat",
119
+ ageMs: Math.max(0, (ageSecs ?? 0) * 1_000),
120
+ });
133
121
  return true;
134
122
  }
135
123
  function resolveTarget(coordRoot, input) {
@@ -197,9 +185,9 @@ function adapterOf(platform) {
197
185
  export function assumeIdentity(coordRoot, instanceId, target, opts) {
198
186
  const release = acquireLock(coordRoot);
199
187
  try {
200
- const hb = readHeartbeat(coordRoot, instanceId);
188
+ const hb = readLiveCoordinationRow(coordRoot, instanceId);
201
189
  if (!hb) {
202
- throw new IdentityAssumeError("no_heartbeat", `no live heartbeat for instance '${instanceId}'`);
190
+ throw new IdentityAssumeError("no_live_generation", `no authority-safe live V3 generation for instance '${instanceId}'`);
203
191
  }
204
192
  if (hb.kind && hb.kind !== "session") {
205
193
  throw new IdentityAssumeError("not_session", `identity assumption is limited to main sessions (current kind: ${hb.kind})`);
@@ -222,7 +210,10 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
222
210
  let conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name);
223
211
  if (conflict && reclaimAbandonedLocalConflict(coordRoot, conflict)) {
224
212
  reclaimedInstanceId = conflict.instance_id;
225
- conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name);
213
+ // The V3 sweep is intentionally provisional, so the generation remains
214
+ // replay-visible after its disposable cache is removed. Ignore that one
215
+ // reclaimed holder while still checking for any additional namesake.
216
+ conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name, Date.now(), new Set([reclaimedInstanceId]));
226
217
  }
227
218
  if (conflict) {
228
219
  const where = conflict.scope === "remote" ? ` on ${conflict.machine}` : "";
@@ -232,8 +223,7 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
232
223
  const created = !targetIdentity.identity;
233
224
  const previousName = hb.name || null;
234
225
  const previousAgentId = hb.agent_id || null;
235
- const history = recordNameAssumption(coordRoot, instanceId, identity.name, identity.agent_id, "session");
236
- const changed = history.changed || previousName !== identity.name || previousAgentId !== identity.agent_id;
226
+ const changed = previousName !== identity.name || previousAgentId !== identity.agent_id;
237
227
  if (!changed) {
238
228
  return {
239
229
  changed: false,
@@ -248,25 +238,17 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
248
238
  reclaimed_instance_id: reclaimedInstanceId,
249
239
  };
250
240
  }
251
- const emitted = emitAndProject({
252
- event_type: "identity.assumed",
253
- instance_id: instanceId,
254
- session_id: hb.session_id,
241
+ const emitted = recordLiveIdentityChangeV3({
242
+ coordRoot,
243
+ owner: instanceId,
244
+ nativeSessionId: hb.native_session_id ?? hb.session_id,
255
245
  adapter: adapterOf(hb.platform),
256
- data: {
257
- name: identity.name,
258
- agent_id: identity.agent_id,
259
- ...(previousName ? { previous_name: previousName } : {}),
260
- ...(previousAgentId ? { previous_agent_id: previousAgentId } : {}),
261
- ...(reclaimedInstanceId ? { reclaimed_instance_id: reclaimedInstanceId } : {}),
262
- },
263
- }, { coordRoot });
264
- if (!emitted?.projected) {
265
- throw new IdentityAssumeError("projection_failed", "the durable name binding was recorded but event projection failed; rerun the command to heal it");
266
- }
267
- const projected = readHeartbeat(coordRoot, instanceId);
246
+ name: identity.name,
247
+ identityId: identity.agent_id,
248
+ });
249
+ const projected = readLiveCoordinationRow(coordRoot, instanceId);
268
250
  if (projected?.name !== identity.name || projected.agent_id !== identity.agent_id) {
269
- throw new IdentityAssumeError("projection_failed", "identity.assumed was emitted but the heartbeat did not converge; rerun the command");
251
+ throw new IdentityAssumeError("projection_failed", "coord.identity_attested was emitted but the V3 projection did not converge; rerun the command");
270
252
  }
271
253
  return {
272
254
  changed: true,
@@ -277,7 +259,9 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
277
259
  name: identity.name,
278
260
  agent_id: identity.agent_id,
279
261
  identity_created: created,
280
- event_id: emitted.envelope.event_id,
262
+ event_id: emitted.state === "recorded" && emitted.result.state === "recorded"
263
+ ? emitted.result.event.event_id
264
+ : null,
281
265
  reclaimed_instance_id: reclaimedInstanceId,
282
266
  };
283
267
  }
@@ -14,8 +14,9 @@
14
14
  * so a fresh consumer gets a CLAUDE.md whose managed region imports
15
15
  * `@AGENTS.md`. A CLAUDE.md that already imports AGENTS.md or already carries
16
16
  * the block (a host that generates CLAUDE.md from AGENTS.md) is left alone.
17
- * - `.claude/skills/<skill>/SKILL.md` — claude-code only; fully-owned files,
18
- * honoring `skills.exclude` in `.harnery/config.jsonc`.
17
+ * - `<adapter-skill-dir>/<skill>/SKILL.md` — fully-owned files, honoring
18
+ * `skills.exclude` in `.harnery/config.jsonc`. Claude Code uses
19
+ * `.claude/skills/`; Cursor and Codex use `.agents/skills/`.
19
20
  */
20
21
  /** Read `skills.exclude` from `.harnery/config.jsonc` (absent/unparseable → none). */
21
22
  export declare function readSkillsExclude(projectRoot: string): Set<string>;
@@ -30,7 +31,7 @@ export interface ApplyResult {
30
31
  }
31
32
  /**
32
33
  * Inject / refresh the instructions block, the CLAUDE.md import shim (claude-code),
33
- * and the shipped skills (claude-code). Idempotent: a re-run on current content
34
+ * and the adapter-native shipped skills. Idempotent: a re-run on current content
34
35
  * writes nothing. `dryRun` reports without touching the fs.
35
36
  */
36
37
  export declare function applyInstructions(projectRoot: string, opts: ApplyOpts): ApplyResult;
@@ -51,7 +52,7 @@ export interface CheckResult {
51
52
  }
52
53
  /**
53
54
  * Read-only drift report for `init --check`: the AGENTS.md block and each
54
- * shipped skill (claude-code). Fresh → exit 0; any stale / missing / hand-edit
55
+ * shipped skill for the selected adapter. Fresh → exit 0; stale / missing / hand-edit
55
56
  * → drift (exit 2); an unreadable file → error (exit 1). Mirrors the wiki-theme
56
57
  * `--check-only` contract the first host wires into pre-commit.
57
58
  */
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA8CH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlE;AAiBD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA8GnF;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAiFrF;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CAiDb"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAsDH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlE;AAkBD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA+GnF;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAkFrF;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CAkDb"}