harnery 0.0.1 → 0.2.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 (445) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -2
  3. package/bin/agent-coord +42 -0
  4. package/bin/agent-hook +44 -0
  5. package/bin/harn +40 -0
  6. package/dist/cli.d.ts +9 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +18 -0
  9. package/dist/commander.d.ts +128 -0
  10. package/dist/commander.d.ts.map +1 -0
  11. package/dist/commander.js +126 -0
  12. package/dist/commands/agents.d.ts +18 -0
  13. package/dist/commands/agents.d.ts.map +1 -0
  14. package/dist/commands/agents.js +3946 -0
  15. package/dist/commands/backup.d.ts +22 -0
  16. package/dist/commands/backup.d.ts.map +1 -0
  17. package/dist/commands/backup.js +262 -0
  18. package/dist/commands/browse-ai.d.ts +4 -0
  19. package/dist/commands/browse-ai.d.ts.map +1 -0
  20. package/dist/commands/browse-ai.js +156 -0
  21. package/dist/commands/browse.d.ts +4 -0
  22. package/dist/commands/browse.d.ts.map +1 -0
  23. package/dist/commands/browse.js +590 -0
  24. package/dist/commands/callers.d.ts +4 -0
  25. package/dist/commands/callers.d.ts.map +1 -0
  26. package/dist/commands/callers.js +276 -0
  27. package/dist/commands/completion.d.ts +17 -0
  28. package/dist/commands/completion.d.ts.map +1 -0
  29. package/dist/commands/completion.js +158 -0
  30. package/dist/commands/config-get.d.ts +4 -0
  31. package/dist/commands/config-get.d.ts.map +1 -0
  32. package/dist/commands/config-get.js +131 -0
  33. package/dist/commands/context.d.ts +11 -0
  34. package/dist/commands/context.d.ts.map +1 -0
  35. package/dist/commands/context.js +185 -0
  36. package/dist/commands/cookies.d.ts +4 -0
  37. package/dist/commands/cookies.d.ts.map +1 -0
  38. package/dist/commands/cookies.js +140 -0
  39. package/dist/commands/docs.d.ts +4 -0
  40. package/dist/commands/docs.d.ts.map +1 -0
  41. package/dist/commands/docs.js +137 -0
  42. package/dist/commands/doctor.d.ts +25 -0
  43. package/dist/commands/doctor.d.ts.map +1 -0
  44. package/dist/commands/doctor.js +200 -0
  45. package/dist/commands/edit-batch.d.ts +18 -0
  46. package/dist/commands/edit-batch.d.ts.map +1 -0
  47. package/dist/commands/edit-batch.js +172 -0
  48. package/dist/commands/eml.d.ts +4 -0
  49. package/dist/commands/eml.d.ts.map +1 -0
  50. package/dist/commands/eml.js +428 -0
  51. package/dist/commands/env.d.ts +4 -0
  52. package/dist/commands/env.d.ts.map +1 -0
  53. package/dist/commands/env.js +201 -0
  54. package/dist/commands/fetch.d.ts +4 -0
  55. package/dist/commands/fetch.d.ts.map +1 -0
  56. package/dist/commands/fetch.js +99 -0
  57. package/dist/commands/file-history.d.ts +4 -0
  58. package/dist/commands/file-history.d.ts.map +1 -0
  59. package/dist/commands/file-history.js +152 -0
  60. package/dist/commands/grep.d.ts +4 -0
  61. package/dist/commands/grep.d.ts.map +1 -0
  62. package/dist/commands/grep.js +317 -0
  63. package/dist/commands/init.d.ts +82 -0
  64. package/dist/commands/init.d.ts.map +1 -0
  65. package/dist/commands/init.js +288 -0
  66. package/dist/commands/outline.d.ts +4 -0
  67. package/dist/commands/outline.d.ts.map +1 -0
  68. package/dist/commands/outline.js +509 -0
  69. package/dist/commands/presence.d.ts +12 -0
  70. package/dist/commands/presence.d.ts.map +1 -0
  71. package/dist/commands/presence.js +123 -0
  72. package/dist/commands/read.d.ts +7 -0
  73. package/dist/commands/read.d.ts.map +1 -0
  74. package/dist/commands/read.js +46 -0
  75. package/dist/commands/scratch.d.ts +4 -0
  76. package/dist/commands/scratch.d.ts.map +1 -0
  77. package/dist/commands/scratch.js +426 -0
  78. package/dist/commands/session.d.ts +4 -0
  79. package/dist/commands/session.d.ts.map +1 -0
  80. package/dist/commands/session.js +162 -0
  81. package/dist/commands/sync.d.ts +24 -0
  82. package/dist/commands/sync.d.ts.map +1 -0
  83. package/dist/commands/sync.js +275 -0
  84. package/dist/commands/toc.d.ts +5 -0
  85. package/dist/commands/toc.d.ts.map +1 -0
  86. package/dist/commands/toc.js +153 -0
  87. package/dist/commands/tokens.d.ts +4 -0
  88. package/dist/commands/tokens.d.ts.map +1 -0
  89. package/dist/commands/tokens.js +48 -0
  90. package/dist/commands/tunnel.d.ts +4 -0
  91. package/dist/commands/tunnel.d.ts.map +1 -0
  92. package/dist/commands/tunnel.js +513 -0
  93. package/dist/commands/uninstall.d.ts +22 -0
  94. package/dist/commands/uninstall.d.ts.map +1 -0
  95. package/dist/commands/uninstall.js +126 -0
  96. package/dist/commands/web.d.ts +4 -0
  97. package/dist/commands/web.d.ts.map +1 -0
  98. package/dist/commands/web.js +165 -0
  99. package/dist/core/agents/canonical-emit.d.ts +27 -0
  100. package/dist/core/agents/canonical-emit.d.ts.map +1 -0
  101. package/dist/core/agents/canonical-emit.js +72 -0
  102. package/dist/core/agents/cli-emit.d.ts +27 -0
  103. package/dist/core/agents/cli-emit.d.ts.map +1 -0
  104. package/dist/core/agents/cli-emit.js +57 -0
  105. package/dist/core/agents/cli.d.ts +10 -0
  106. package/dist/core/agents/cli.d.ts.map +1 -0
  107. package/dist/core/agents/cli.js +757 -0
  108. package/dist/core/agents/codex-replay.d.ts +29 -0
  109. package/dist/core/agents/codex-replay.d.ts.map +1 -0
  110. package/dist/core/agents/codex-replay.js +138 -0
  111. package/dist/core/agents/coord-client.d.ts +98 -0
  112. package/dist/core/agents/coord-client.d.ts.map +1 -0
  113. package/dist/core/agents/coord-client.js +212 -0
  114. package/dist/core/agents/events/consume.d.ts +59 -0
  115. package/dist/core/agents/events/consume.d.ts.map +1 -0
  116. package/dist/core/agents/events/consume.js +147 -0
  117. package/dist/core/agents/events/emit.d.ts +42 -0
  118. package/dist/core/agents/events/emit.d.ts.map +1 -0
  119. package/dist/core/agents/events/emit.js +70 -0
  120. package/dist/core/agents/events/ulid.d.ts +11 -0
  121. package/dist/core/agents/events/ulid.d.ts.map +1 -0
  122. package/dist/core/agents/events/ulid.js +47 -0
  123. package/dist/core/agents/index.d.ts +14 -0
  124. package/dist/core/agents/index.d.ts.map +1 -0
  125. package/dist/core/agents/index.js +13 -0
  126. package/dist/core/agents/paths.d.ts +6 -0
  127. package/dist/core/agents/paths.d.ts.map +1 -0
  128. package/dist/core/agents/paths.js +17 -0
  129. package/dist/core/agents/render/prompt-context.d.ts +43 -0
  130. package/dist/core/agents/render/prompt-context.d.ts.map +1 -0
  131. package/dist/core/agents/render/prompt-context.js +335 -0
  132. package/dist/core/agents/render/session-context.d.ts +39 -0
  133. package/dist/core/agents/render/session-context.d.ts.map +1 -0
  134. package/dist/core/agents/render/session-context.js +283 -0
  135. package/dist/core/agents/rules/claim-conflict.d.ts +35 -0
  136. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -0
  137. package/dist/core/agents/rules/claim-conflict.js +244 -0
  138. package/dist/core/agents/rules/commit-conflict.d.ts +59 -0
  139. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -0
  140. package/dist/core/agents/rules/commit-conflict.js +244 -0
  141. package/dist/core/agents/rules/stop-hook.d.ts +44 -0
  142. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -0
  143. package/dist/core/agents/rules/stop-hook.js +161 -0
  144. package/dist/core/agents/session-events.d.ts +41 -0
  145. package/dist/core/agents/session-events.d.ts.map +1 -0
  146. package/dist/core/agents/session-events.js +205 -0
  147. package/dist/core/agents/state/activity-log.d.ts +18 -0
  148. package/dist/core/agents/state/activity-log.d.ts.map +1 -0
  149. package/dist/core/agents/state/activity-log.js +34 -0
  150. package/dist/core/agents/state/council.d.ts +39 -0
  151. package/dist/core/agents/state/council.d.ts.map +1 -0
  152. package/dist/core/agents/state/council.js +216 -0
  153. package/dist/core/agents/state/heartbeat-projector.d.ts +59 -0
  154. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -0
  155. package/dist/core/agents/state/heartbeat-projector.js +436 -0
  156. package/dist/core/agents/state/heartbeat-writer.d.ts +64 -0
  157. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -0
  158. package/dist/core/agents/state/heartbeat-writer.js +271 -0
  159. package/dist/core/agents/state/names.d.ts +35 -0
  160. package/dist/core/agents/state/names.d.ts.map +1 -0
  161. package/dist/core/agents/state/names.js +376 -0
  162. package/dist/core/agents/state/pidmap.d.ts +11 -0
  163. package/dist/core/agents/state/pidmap.d.ts.map +1 -0
  164. package/dist/core/agents/state/pidmap.js +32 -0
  165. package/dist/core/agents/state/scratch.d.ts +27 -0
  166. package/dist/core/agents/state/scratch.d.ts.map +1 -0
  167. package/dist/core/agents/state/scratch.js +90 -0
  168. package/dist/core/agents/state/shell-mutation.d.ts +17 -0
  169. package/dist/core/agents/state/shell-mutation.d.ts.map +1 -0
  170. package/dist/core/agents/state/shell-mutation.js +41 -0
  171. package/dist/core/agents/state/stale-sweep.d.ts +16 -0
  172. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -0
  173. package/dist/core/agents/state/stale-sweep.js +166 -0
  174. package/dist/core/config.d.ts +29 -0
  175. package/dist/core/config.d.ts.map +1 -0
  176. package/dist/core/config.js +108 -0
  177. package/dist/core/hooks/cli.d.ts +21 -0
  178. package/dist/core/hooks/cli.d.ts.map +1 -0
  179. package/dist/core/hooks/cli.js +1123 -0
  180. package/dist/core/hooks/effects/image-capture.d.ts +43 -0
  181. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -0
  182. package/dist/core/hooks/effects/image-capture.js +288 -0
  183. package/dist/core/hooks/effects/index.d.ts +64 -0
  184. package/dist/core/hooks/effects/index.d.ts.map +1 -0
  185. package/dist/core/hooks/effects/index.js +197 -0
  186. package/dist/core/hooks/events/emit.d.ts +31 -0
  187. package/dist/core/hooks/events/emit.d.ts.map +1 -0
  188. package/dist/core/hooks/events/emit.js +89 -0
  189. package/dist/core/hooks/events/schema.d.ts +235 -0
  190. package/dist/core/hooks/events/schema.d.ts.map +1 -0
  191. package/dist/core/hooks/events/schema.js +12 -0
  192. package/dist/core/hooks/events/ulid.d.ts +10 -0
  193. package/dist/core/hooks/events/ulid.d.ts.map +1 -0
  194. package/dist/core/hooks/events/ulid.js +47 -0
  195. package/dist/core/hooks/harness/detect.d.ts +9 -0
  196. package/dist/core/hooks/harness/detect.d.ts.map +1 -0
  197. package/dist/core/hooks/harness/detect.js +29 -0
  198. package/dist/core/hooks/harness/events.d.ts +45 -0
  199. package/dist/core/hooks/harness/events.d.ts.map +1 -0
  200. package/dist/core/hooks/harness/events.js +71 -0
  201. package/dist/core/hooks/harness/output.d.ts +46 -0
  202. package/dist/core/hooks/harness/output.d.ts.map +1 -0
  203. package/dist/core/hooks/harness/output.js +87 -0
  204. package/dist/core/hooks/harness/parse.d.ts +67 -0
  205. package/dist/core/hooks/harness/parse.d.ts.map +1 -0
  206. package/dist/core/hooks/harness/parse.js +132 -0
  207. package/dist/core/hooks/index.d.ts +8 -0
  208. package/dist/core/hooks/index.d.ts.map +1 -0
  209. package/dist/core/hooks/index.js +7 -0
  210. package/dist/core/hooks/resolve/anchor.d.ts +37 -0
  211. package/dist/core/hooks/resolve/anchor.d.ts.map +1 -0
  212. package/dist/core/hooks/resolve/anchor.js +48 -0
  213. package/dist/core/hooks/resolve/coord-root.d.ts +6 -0
  214. package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -0
  215. package/dist/core/hooks/resolve/coord-root.js +27 -0
  216. package/dist/core/hooks/resolve/intent.d.ts +33 -0
  217. package/dist/core/hooks/resolve/intent.d.ts.map +1 -0
  218. package/dist/core/hooks/resolve/intent.js +79 -0
  219. package/dist/core/hooks/resolve/owner.d.ts +42 -0
  220. package/dist/core/hooks/resolve/owner.d.ts.map +1 -0
  221. package/dist/core/hooks/resolve/owner.js +140 -0
  222. package/dist/core/hooks/resolve/transcript.d.ts +26 -0
  223. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -0
  224. package/dist/core/hooks/resolve/transcript.js +73 -0
  225. package/dist/index.d.ts +15 -0
  226. package/dist/index.d.ts.map +1 -0
  227. package/dist/index.js +13 -0
  228. package/dist/lib/agent-browser/client.d.ts +99 -0
  229. package/dist/lib/agent-browser/client.d.ts.map +1 -0
  230. package/dist/lib/agent-browser/client.js +177 -0
  231. package/dist/lib/agent-browser/index.d.ts +2 -0
  232. package/dist/lib/agent-browser/index.d.ts.map +1 -0
  233. package/dist/lib/agent-browser/index.js +1 -0
  234. package/dist/lib/browser/client.d.ts +193 -0
  235. package/dist/lib/browser/client.d.ts.map +1 -0
  236. package/dist/lib/browser/client.js +325 -0
  237. package/dist/lib/browser/dev-overlay.d.ts +23 -0
  238. package/dist/lib/browser/dev-overlay.d.ts.map +1 -0
  239. package/dist/lib/browser/dev-overlay.js +153 -0
  240. package/dist/lib/browser/index.d.ts +5 -0
  241. package/dist/lib/browser/index.d.ts.map +1 -0
  242. package/dist/lib/browser/index.js +2 -0
  243. package/dist/lib/browser/layout.d.ts +79 -0
  244. package/dist/lib/browser/layout.d.ts.map +1 -0
  245. package/dist/lib/browser/layout.js +220 -0
  246. package/dist/lib/browser/visibility.d.ts +86 -0
  247. package/dist/lib/browser/visibility.d.ts.map +1 -0
  248. package/dist/lib/browser/visibility.js +333 -0
  249. package/dist/lib/browser/visual-diff.d.ts +38 -0
  250. package/dist/lib/browser/visual-diff.d.ts.map +1 -0
  251. package/dist/lib/browser/visual-diff.js +107 -0
  252. package/dist/lib/completion/bash.d.ts +25 -0
  253. package/dist/lib/completion/bash.d.ts.map +1 -0
  254. package/dist/lib/completion/bash.js +284 -0
  255. package/dist/lib/completion/fish.d.ts +16 -0
  256. package/dist/lib/completion/fish.d.ts.map +1 -0
  257. package/dist/lib/completion/fish.js +118 -0
  258. package/dist/lib/completion/index.d.ts +5 -0
  259. package/dist/lib/completion/index.d.ts.map +1 -0
  260. package/dist/lib/completion/index.js +4 -0
  261. package/dist/lib/completion/walk.d.ts +68 -0
  262. package/dist/lib/completion/walk.d.ts.map +1 -0
  263. package/dist/lib/completion/walk.js +102 -0
  264. package/dist/lib/completion/zsh.d.ts +13 -0
  265. package/dist/lib/completion/zsh.d.ts.map +1 -0
  266. package/dist/lib/completion/zsh.js +249 -0
  267. package/dist/lib/context/index.d.ts +107 -0
  268. package/dist/lib/context/index.d.ts.map +1 -0
  269. package/dist/lib/context/index.js +275 -0
  270. package/dist/lib/cookies/client.d.ts +131 -0
  271. package/dist/lib/cookies/client.d.ts.map +1 -0
  272. package/dist/lib/cookies/client.js +239 -0
  273. package/dist/lib/cookies/index.d.ts +2 -0
  274. package/dist/lib/cookies/index.d.ts.map +1 -0
  275. package/dist/lib/cookies/index.js +1 -0
  276. package/dist/lib/council/index.d.ts +266 -0
  277. package/dist/lib/council/index.d.ts.map +1 -0
  278. package/dist/lib/council/index.js +674 -0
  279. package/dist/lib/docs-index.d.ts +28 -0
  280. package/dist/lib/docs-index.d.ts.map +1 -0
  281. package/dist/lib/docs-index.js +169 -0
  282. package/dist/lib/docs-lint.d.ts +26 -0
  283. package/dist/lib/docs-lint.d.ts.map +1 -0
  284. package/dist/lib/docs-lint.js +378 -0
  285. package/dist/lib/docs-sweep.d.ts +34 -0
  286. package/dist/lib/docs-sweep.d.ts.map +1 -0
  287. package/dist/lib/docs-sweep.js +304 -0
  288. package/dist/lib/docs.d.ts +27 -0
  289. package/dist/lib/docs.d.ts.map +1 -0
  290. package/dist/lib/docs.js +142 -0
  291. package/dist/lib/env.d.ts +11 -0
  292. package/dist/lib/env.d.ts.map +1 -0
  293. package/dist/lib/env.js +12 -0
  294. package/dist/lib/exec.d.ts +32 -0
  295. package/dist/lib/exec.d.ts.map +1 -0
  296. package/dist/lib/exec.js +54 -0
  297. package/dist/lib/format.d.ts +29 -0
  298. package/dist/lib/format.d.ts.map +1 -0
  299. package/dist/lib/format.js +139 -0
  300. package/dist/lib/http/client.d.ts +56 -0
  301. package/dist/lib/http/client.d.ts.map +1 -0
  302. package/dist/lib/http/client.js +160 -0
  303. package/dist/lib/http/index.d.ts +2 -0
  304. package/dist/lib/http/index.d.ts.map +1 -0
  305. package/dist/lib/http/index.js +1 -0
  306. package/dist/lib/identities/index.d.ts +77 -0
  307. package/dist/lib/identities/index.d.ts.map +1 -0
  308. package/dist/lib/identities/index.js +190 -0
  309. package/dist/lib/machine.d.ts +19 -0
  310. package/dist/lib/machine.d.ts.map +1 -0
  311. package/dist/lib/machine.js +61 -0
  312. package/dist/lib/presence.d.ts +48 -0
  313. package/dist/lib/presence.d.ts.map +1 -0
  314. package/dist/lib/presence.js +123 -0
  315. package/dist/lib/readability/client.d.ts +39 -0
  316. package/dist/lib/readability/client.d.ts.map +1 -0
  317. package/dist/lib/readability/client.js +121 -0
  318. package/dist/lib/readability/index.d.ts +2 -0
  319. package/dist/lib/readability/index.d.ts.map +1 -0
  320. package/dist/lib/readability/index.js +1 -0
  321. package/dist/lib/scratch/index.d.ts +74 -0
  322. package/dist/lib/scratch/index.d.ts.map +1 -0
  323. package/dist/lib/scratch/index.js +393 -0
  324. package/dist/lib/tunnel/gate.d.ts +12 -0
  325. package/dist/lib/tunnel/gate.d.ts.map +1 -0
  326. package/dist/lib/tunnel/gate.js +101 -0
  327. package/dist/lib/tunnel/state.d.ts +34 -0
  328. package/dist/lib/tunnel/state.d.ts.map +1 -0
  329. package/dist/lib/tunnel/state.js +132 -0
  330. package/package.json +160 -8
  331. package/schemas/.gitkeep +0 -0
  332. package/schemas/config.schema.json +109 -0
  333. package/src/cli.ts +22 -0
  334. package/src/commander.ts +242 -0
  335. package/src/commands/.gitkeep +0 -0
  336. package/src/commands/agents.ts +4567 -0
  337. package/src/commands/backup.ts +305 -0
  338. package/src/commands/browse-ai.ts +198 -0
  339. package/src/commands/browse.ts +849 -0
  340. package/src/commands/callers.ts +363 -0
  341. package/src/commands/completion.ts +193 -0
  342. package/src/commands/config-get.ts +161 -0
  343. package/src/commands/context.ts +209 -0
  344. package/src/commands/cookies.ts +198 -0
  345. package/src/commands/docs.ts +174 -0
  346. package/src/commands/doctor.ts +231 -0
  347. package/src/commands/edit-batch.ts +233 -0
  348. package/src/commands/eml.ts +519 -0
  349. package/src/commands/env.ts +254 -0
  350. package/src/commands/fetch.ts +136 -0
  351. package/src/commands/file-history.ts +202 -0
  352. package/src/commands/grep.ts +371 -0
  353. package/src/commands/init.ts +335 -0
  354. package/src/commands/outline.ts +583 -0
  355. package/src/commands/presence.ts +152 -0
  356. package/src/commands/read.ts +64 -0
  357. package/src/commands/scratch.ts +445 -0
  358. package/src/commands/session.ts +187 -0
  359. package/src/commands/sync.ts +306 -0
  360. package/src/commands/toc.ts +218 -0
  361. package/src/commands/tokens.ts +79 -0
  362. package/src/commands/tunnel.ts +633 -0
  363. package/src/commands/uninstall.ts +144 -0
  364. package/src/commands/web.ts +193 -0
  365. package/src/core/agents/canonical-emit.ts +77 -0
  366. package/src/core/agents/cli-emit.ts +64 -0
  367. package/src/core/agents/cli.ts +838 -0
  368. package/src/core/agents/codex-replay.ts +163 -0
  369. package/src/core/agents/coord-client.ts +249 -0
  370. package/src/core/agents/events/consume.ts +196 -0
  371. package/src/core/agents/events/emit.ts +108 -0
  372. package/src/core/agents/events/ulid.ts +51 -0
  373. package/src/core/agents/index.ts +14 -0
  374. package/src/core/agents/paths.ts +16 -0
  375. package/src/core/agents/render/prompt-context.ts +401 -0
  376. package/src/core/agents/render/session-context.ts +341 -0
  377. package/src/core/agents/rules/claim-conflict.ts +282 -0
  378. package/src/core/agents/rules/commit-conflict.ts +303 -0
  379. package/src/core/agents/rules/stop-hook.ts +229 -0
  380. package/src/core/agents/session-events.ts +228 -0
  381. package/src/core/agents/state/activity-log.ts +33 -0
  382. package/src/core/agents/state/council.ts +265 -0
  383. package/src/core/agents/state/heartbeat-projector.ts +488 -0
  384. package/src/core/agents/state/heartbeat-writer.ts +333 -0
  385. package/src/core/agents/state/names.ts +399 -0
  386. package/src/core/agents/state/pidmap.ts +38 -0
  387. package/src/core/agents/state/scratch.ts +121 -0
  388. package/src/core/agents/state/shell-mutation.ts +44 -0
  389. package/src/core/agents/state/stale-sweep.ts +190 -0
  390. package/src/core/config.ts +111 -0
  391. package/src/core/hooks/cli.ts +1247 -0
  392. package/src/core/hooks/effects/image-capture.ts +330 -0
  393. package/src/core/hooks/effects/index.ts +210 -0
  394. package/src/core/hooks/events/emit.ts +120 -0
  395. package/src/core/hooks/events/schema.ts +430 -0
  396. package/src/core/hooks/events/ulid.ts +51 -0
  397. package/src/core/hooks/harness/detect.ts +30 -0
  398. package/src/core/hooks/harness/events.ts +102 -0
  399. package/src/core/hooks/harness/output.ts +100 -0
  400. package/src/core/hooks/harness/parse.ts +180 -0
  401. package/src/core/hooks/index.ts +16 -0
  402. package/src/core/hooks/resolve/anchor.ts +51 -0
  403. package/src/core/hooks/resolve/coord-root.ts +25 -0
  404. package/src/core/hooks/resolve/intent.ts +89 -0
  405. package/src/core/hooks/resolve/owner.ts +140 -0
  406. package/src/core/hooks/resolve/transcript.ts +72 -0
  407. package/src/hooks/.gitkeep +0 -0
  408. package/src/index.ts +15 -0
  409. package/src/lib/agent-browser/client.ts +239 -0
  410. package/src/lib/agent-browser/index.ts +1 -0
  411. package/src/lib/browser/client.ts +449 -0
  412. package/src/lib/browser/dev-overlay.ts +207 -0
  413. package/src/lib/browser/index.ts +24 -0
  414. package/src/lib/browser/layout.ts +288 -0
  415. package/src/lib/browser/visibility.ts +419 -0
  416. package/src/lib/browser/visual-diff.ts +150 -0
  417. package/src/lib/completion/bash.ts +291 -0
  418. package/src/lib/completion/fish.ts +134 -0
  419. package/src/lib/completion/index.ts +10 -0
  420. package/src/lib/completion/walk.ts +184 -0
  421. package/src/lib/completion/zsh.ts +262 -0
  422. package/src/lib/context/index.ts +386 -0
  423. package/src/lib/cookies/client.ts +301 -0
  424. package/src/lib/cookies/index.ts +13 -0
  425. package/src/lib/council/index.ts +803 -0
  426. package/src/lib/docs-index.ts +216 -0
  427. package/src/lib/docs-lint.ts +413 -0
  428. package/src/lib/docs-sweep.ts +348 -0
  429. package/src/lib/docs.ts +199 -0
  430. package/src/lib/env.ts +12 -0
  431. package/src/lib/exec.ts +74 -0
  432. package/src/lib/format.ts +147 -0
  433. package/src/lib/http/client.ts +211 -0
  434. package/src/lib/http/index.ts +1 -0
  435. package/src/lib/identities/index.ts +210 -0
  436. package/src/lib/machine.ts +61 -0
  437. package/src/lib/presence.ts +154 -0
  438. package/src/lib/readability/client.ts +169 -0
  439. package/src/lib/readability/index.ts +5 -0
  440. package/src/lib/readability/turndown-plugin-gfm.d.ts +10 -0
  441. package/src/lib/scratch/index.ts +470 -0
  442. package/src/lib/tunnel/gate.ts +113 -0
  443. package/src/lib/tunnel/state.ts +167 -0
  444. package/src/web/.gitkeep +0 -0
  445. package/index.js +0 -1
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Codex JSONL → canonical event replay.
3
+ *
4
+ * Production codex sessions emit canonical events from each `harn` invocation
5
+ * via the in-process session-tee middleware (which calls `agent-coord
6
+ * emit-event` for state.task_set / state.status_checked). But the codex
7
+ * harness itself doesn't wire agent-hook on preToolUse, so user_prompt.submit
8
+ * + tool.pre_use + turn.stop aren't emitted live.
9
+ *
10
+ * This module parses the Codex JSONL transcript at stop time and emits the
11
+ * missing canonical events so the verdict has a complete turn-window view.
12
+ *
13
+ * Scope: just the events the stop-hook verdict reads: user_prompt.submit,
14
+ * tool.pre_use (for exec_command function calls), state.status_checked
15
+ * (when the cmd contains `<bin> agents status`), state.task_set (when the cmd
16
+ * contains `<bin> agents set-task`), turn.stop (with status_box_present derived
17
+ * from the last_assistant_message).
18
+ */
19
+ export interface CodexReplayOpts {
20
+ coordRoot: string;
21
+ sessionId: string;
22
+ instanceId: string;
23
+ jsonlPath: string;
24
+ lastAssistantMessage?: string;
25
+ }
26
+ export declare function replayCodexJsonl(opts: CodexReplayOpts): {
27
+ emitted: number;
28
+ };
29
+ //# sourceMappingURL=codex-replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-replay.d.ts","sourceRoot":"","sources":["../../../src/core/agents/codex-replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAkBH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAkH3E"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Codex JSONL → canonical event replay.
3
+ *
4
+ * Production codex sessions emit canonical events from each `harn` invocation
5
+ * via the in-process session-tee middleware (which calls `agent-coord
6
+ * emit-event` for state.task_set / state.status_checked). But the codex
7
+ * harness itself doesn't wire agent-hook on preToolUse, so user_prompt.submit
8
+ * + tool.pre_use + turn.stop aren't emitted live.
9
+ *
10
+ * This module parses the Codex JSONL transcript at stop time and emits the
11
+ * missing canonical events so the verdict has a complete turn-window view.
12
+ *
13
+ * Scope: just the events the stop-hook verdict reads: user_prompt.submit,
14
+ * tool.pre_use (for exec_command function calls), state.status_checked
15
+ * (when the cmd contains `<bin> agents status`), state.task_set (when the cmd
16
+ * contains `<bin> agents set-task`), turn.stop (with status_box_present derived
17
+ * from the last_assistant_message).
18
+ */
19
+ import { existsSync, readFileSync } from "node:fs";
20
+ import { emit } from "./events/emit.js";
21
+ const STATUS_BOX_PREFIX = "┌─ agent-";
22
+ export function replayCodexJsonl(opts) {
23
+ const { coordRoot, sessionId, instanceId, jsonlPath, lastAssistantMessage } = opts;
24
+ if (!existsSync(jsonlPath))
25
+ return { emitted: 0 };
26
+ let raw;
27
+ try {
28
+ raw = readFileSync(jsonlPath, "utf8");
29
+ }
30
+ catch {
31
+ return { emitted: 0 };
32
+ }
33
+ let emitted = 0;
34
+ const lines = raw.split("\n");
35
+ for (const line of lines) {
36
+ if (!line.trim())
37
+ continue;
38
+ let entry;
39
+ try {
40
+ entry = JSON.parse(line);
41
+ }
42
+ catch {
43
+ continue;
44
+ }
45
+ const ts = entry.timestamp;
46
+ const t = entry.type;
47
+ if (t === "event_msg" && entry.payload?.type === "user_message") {
48
+ emit(coordRoot, {
49
+ event_type: "user_prompt.submit",
50
+ instance_id: instanceId,
51
+ session_id: sessionId,
52
+ harness: "codex",
53
+ ts,
54
+ data: {
55
+ prompt_text: clamp(entry.payload.message ?? "", 4000),
56
+ },
57
+ });
58
+ emitted += 1;
59
+ continue;
60
+ }
61
+ if (t === "response_item" && entry.payload?.type === "function_call") {
62
+ const name = entry.payload.name ?? "";
63
+ let cmd = "";
64
+ if (entry.payload.arguments) {
65
+ try {
66
+ const parsed = JSON.parse(entry.payload.arguments);
67
+ cmd = parsed.cmd ?? "";
68
+ }
69
+ catch {
70
+ /* skip */
71
+ }
72
+ }
73
+ // Emit tool.pre_use for every function call.
74
+ emit(coordRoot, {
75
+ event_type: "tool.pre_use",
76
+ instance_id: instanceId,
77
+ session_id: sessionId,
78
+ harness: "codex",
79
+ ts,
80
+ data: {
81
+ tool_name: name === "exec_command" ? "Bash" : name,
82
+ tool_input: JSON.stringify({ command: cmd }),
83
+ intent: "",
84
+ intent_source: "codex-replay",
85
+ },
86
+ });
87
+ emitted += 1;
88
+ // Match `<bin> agents status` / `<bin> agents set-task`, bin-agnostic, so
89
+ // it works for harn or any host CLI that composes harnery (a consumer's own
90
+ // binary). Wrapped invocations (cd && <bin> ...; PATH=... <bin> ...) pass
91
+ // because we scan the whole cmd string and anchor on the token before `agents`.
92
+ if (/(^|\s|;|&&)[\w./-]+\s+agents\s+status(\b|$)/.test(cmd)) {
93
+ emit(coordRoot, {
94
+ event_type: "state.status_checked",
95
+ instance_id: instanceId,
96
+ session_id: sessionId,
97
+ harness: "codex",
98
+ ts,
99
+ data: { source: "codex-replay" },
100
+ });
101
+ emitted += 1;
102
+ }
103
+ if (/(^|\s|;|&&)[\w./-]+\s+agents\s+set-task(\b|$)/.test(cmd)) {
104
+ emit(coordRoot, {
105
+ event_type: "state.task_set",
106
+ instance_id: instanceId,
107
+ session_id: sessionId,
108
+ harness: "codex",
109
+ ts,
110
+ data: { source: "codex-replay" },
111
+ });
112
+ emitted += 1;
113
+ }
114
+ }
115
+ }
116
+ // Finally, emit turn.stop with status_box_present derived from the last
117
+ // assistant message (codex's stop payload carries the assistant text
118
+ // directly, unlike CC which only has transcript_path).
119
+ const boxPresent = !!lastAssistantMessage && lastAssistantMessage.includes(STATUS_BOX_PREFIX);
120
+ emit(coordRoot, {
121
+ event_type: "turn.stop",
122
+ instance_id: instanceId,
123
+ session_id: sessionId,
124
+ harness: "codex",
125
+ data: {
126
+ status_box_present: boxPresent,
127
+ tool_call_count: -1,
128
+ text_length: lastAssistantMessage?.length ?? 0,
129
+ },
130
+ });
131
+ emitted += 1;
132
+ return { emitted };
133
+ }
134
+ function clamp(s, max) {
135
+ if (s.length <= max)
136
+ return s;
137
+ return s.slice(0, max);
138
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * The coordination helpers.
3
+ *
4
+ * Both surfaces (bash hooks + this TS module) write into the same
5
+ * `.harnery/active/<owner>.json` heartbeat files and `.harnery/pid-map/`
6
+ * ppid map, so a single coord state can be observed and mutated from
7
+ * either side without divergence.
8
+ */
9
+ export interface Heartbeat {
10
+ instance_id: string;
11
+ name?: string;
12
+ kind?: string;
13
+ session_id: string;
14
+ agent_id: string;
15
+ model: string;
16
+ started_at: string;
17
+ last_heartbeat: string;
18
+ files_touched: string[];
19
+ agent_type?: string;
20
+ /** Most recent tool name stamped by the PostToolUse hook. Phase 1. */
21
+ last_tool?: string;
22
+ /** Short string identifying what the last tool acted on (file path, command head, URL). Phase 1. */
23
+ last_tool_target?: string;
24
+ /** Free-form task/intent string set via `harn agents set-task`. Phase 2. */
25
+ task?: string;
26
+ /** UTC ISO-8601 timestamp when task was last set/cleared. Used by harnesses without Stop enforcement to compute staleness. 2026-05-24. */
27
+ task_updated_at?: string | null;
28
+ /** Auto-generated per-turn summary written by the Stop hook via Haiku. 2026-05-23. */
29
+ turn_summary?: string | null;
30
+ /** UTC ISO-8601 timestamp when turn_summary was last refreshed. */
31
+ turn_summary_updated_at?: string | null;
32
+ /** Hook client: `claude_code` (default) or `cursor`. Cursor Phase 1. */
33
+ platform?: string;
34
+ }
35
+ /**
36
+ * Resolve the monorepo root for coord-state purposes.
37
+ *
38
+ * Resolves the coordination root,
39
+ * including the `--git-common-dir` fallback that strips
40
+ * `<superproject>/.git/modules/<name>/` to recover the superproject for
41
+ * submodule worktrees. Without that fallback, a TS coord caller running
42
+ * inside a `harn worktree add-submodule` checkout would resolve a different
43
+ * `.harnery/` than the bash hooks and the two layers would silently diverge.
44
+ */
45
+ export declare function monorepoRoot(): string | null;
46
+ /** Parse owner from a pid-map row (`owner` or `owner\tplatform`). */
47
+ export declare function parsePidmapRowOwner(row: string): string;
48
+ /** Parse platform from a pid-map row; legacy rows default to `claude_code`. */
49
+ export declare function parsePidmapRowPlatform(row: string): string;
50
+ /**
51
+ * Walk up the ppid chain looking for a pid-map entry. Returns
52
+ * the resolved instance_id or null.
53
+ *
54
+ * Pid-map files are `instance_id` or `instance_id\tplatform` (Cursor Phase 1).
55
+ * Prefer a row whose platform matches `HARNERY_AGENT_COORD_PLATFORM` (default
56
+ * `claude_code`); otherwise return the first owner seen on the walk.
57
+ *
58
+ * Subagents intentionally do not write pid-map entries; a Bash-tool ppid-walk
59
+ * from inside a subagent therefore resolves to the *parent's* pid-map entry.
60
+ * v1 ships this behavior; a real subagent-aware bridge is out of scope.
61
+ */
62
+ export declare function resolveOwner(): string | null;
63
+ /**
64
+ * Like `resolveOwner` but also reports which resolution path matched.
65
+ * Used by `harn agents whoami` to surface the path (`env` / `pidmap`) in
66
+ * the diagnostic output. Operators trying to debug "why doesn't my
67
+ * Codex session see itself?" need to know whether `HARNERY_AGENT_COORD_OWNER`
68
+ * is propagating or the ppid-walk is the load-bearing path.
69
+ */
70
+ export declare function resolveOwnerWithSource(): {
71
+ owner: string | null;
72
+ source: "env" | "pidmap" | "pidmap_fallback" | "none";
73
+ };
74
+ /**
75
+ * Read and parse a heartbeat file. Returns null if the file is missing,
76
+ * unreadable, or contains malformed JSON. Does not throw.
77
+ *
78
+ * Phase 8 cleanup (2026-05-27): the v1/v2 dual-write bridge is gone; the
79
+ * projector writes additively-merged heartbeats directly to
80
+ * `.harnery/active/<id>.json` (the canonical location every reader expects).
81
+ */
82
+ export declare function readHeartbeat(instanceId: string): Heartbeat | null;
83
+ /**
84
+ * Render the display form for an instance_id: `agent-<Name>` if the heartbeat
85
+ * carries a non-empty `.name`, else `agent-<8-char-hex-prefix>`.
86
+ *
87
+ * Hex fallback handles three cases cleanly:
88
+ * - heartbeat written before this feature shipped (no `name` field)
89
+ * - heartbeat pruned but instance_id still appears in older log lines
90
+ * - the narrow window between instance_id resolution and heartbeat read
91
+ */
92
+ export declare function displayName(instanceId: string): string;
93
+ /**
94
+ * Convenience: resolve self via ppid walk, then render. Returns
95
+ * `agent-unknown` when the walk fails.
96
+ */
97
+ export declare function selfDisplayName(): string;
98
+ //# sourceMappingURL=coord-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coord-client.d.ts","sourceRoot":"","sources":["../../../src/core/agents/coord-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oGAAoG;IACpG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0IAA0I;IAC1I,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mEAAmE;IACnE,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CA0C5C;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI1D;AAaD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,iBAAiB,GAAG,MAAM,CAAC;CACvD,CAgCA;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAKlE;AAgBD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * The coordination helpers.
3
+ *
4
+ * Both surfaces (bash hooks + this TS module) write into the same
5
+ * `.harnery/active/<owner>.json` heartbeat files and `.harnery/pid-map/`
6
+ * ppid map, so a single coord state can be observed and mutated from
7
+ * either side without divergence.
8
+ */
9
+ import { spawnSync } from "node:child_process";
10
+ import { existsSync, readFileSync } from "node:fs";
11
+ import { resolve } from "node:path";
12
+ /**
13
+ * Resolve the monorepo root for coord-state purposes.
14
+ *
15
+ * Resolves the coordination root,
16
+ * including the `--git-common-dir` fallback that strips
17
+ * `<superproject>/.git/modules/<name>/` to recover the superproject for
18
+ * submodule worktrees. Without that fallback, a TS coord caller running
19
+ * inside a `harn worktree add-submodule` checkout would resolve a different
20
+ * `.harnery/` than the bash hooks and the two layers would silently diverge.
21
+ */
22
+ export function monorepoRoot() {
23
+ // Test-only override (matches bash HARNERY_COORD_ROOT_OVERRIDE). Lets tests
24
+ // seed `.harnery/pid-map/<pid>` + `.harnery/active/<owner>.json` fixtures
25
+ // in a tmpdir without needing a real git repo.
26
+ const rootOverride = process.env.HARNERY_COORD_ROOT_OVERRIDE;
27
+ if (rootOverride) {
28
+ return rootOverride;
29
+ }
30
+ // 1. Superproject working tree (when running from inside a submodule).
31
+ const sup = spawnSync("git", ["rev-parse", "--show-superproject-working-tree"], {
32
+ encoding: "utf8",
33
+ });
34
+ if (sup.status === 0 && sup.stdout.trim() !== "") {
35
+ return sup.stdout.trim();
36
+ }
37
+ // 2. --git-common-dir fallback for submodule worktrees. `git worktree add`
38
+ // inside a submodule produces a worktree whose --show-superproject-working-
39
+ // tree is empty (the worktree has no submodule relationship of its own),
40
+ // but --git-common-dir points at <superproject>/.git/modules/<name>/, so
41
+ // we recover the superproject by stripping that suffix.
42
+ const common = spawnSync("git", ["rev-parse", "--git-common-dir"], {
43
+ encoding: "utf8",
44
+ });
45
+ if (common.status === 0) {
46
+ const cd = common.stdout.trim();
47
+ const idx = cd.indexOf("/.git/modules/");
48
+ if (idx !== -1) {
49
+ return cd.substring(0, idx);
50
+ }
51
+ }
52
+ // 3. Top-level fallback (regular checkout).
53
+ const top = spawnSync("git", ["rev-parse", "--show-toplevel"], {
54
+ encoding: "utf8",
55
+ });
56
+ if (top.status === 0 && top.stdout.trim() !== "") {
57
+ return top.stdout.trim();
58
+ }
59
+ return null;
60
+ }
61
+ /** Parse owner from a pid-map row (`owner` or `owner\tplatform`). */
62
+ export function parsePidmapRowOwner(row) {
63
+ const trimmed = row.trim();
64
+ const tab = trimmed.indexOf("\t");
65
+ return tab >= 0 ? trimmed.slice(0, tab) : trimmed;
66
+ }
67
+ /** Parse platform from a pid-map row; legacy rows default to `claude_code`. */
68
+ export function parsePidmapRowPlatform(row) {
69
+ const trimmed = row.trim();
70
+ const tab = trimmed.indexOf("\t");
71
+ return tab >= 0 ? trimmed.slice(tab + 1).trim() : "claude_code";
72
+ }
73
+ function readPidmapRow(pidmapDir, pid) {
74
+ const candidate = resolve(pidmapDir, String(pid));
75
+ if (!existsSync(candidate))
76
+ return null;
77
+ try {
78
+ const row = readFileSync(candidate, "utf8").trim();
79
+ return row || null;
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * Walk up the ppid chain looking for a pid-map entry. Returns
87
+ * the resolved instance_id or null.
88
+ *
89
+ * Pid-map files are `instance_id` or `instance_id\tplatform` (Cursor Phase 1).
90
+ * Prefer a row whose platform matches `HARNERY_AGENT_COORD_PLATFORM` (default
91
+ * `claude_code`); otherwise return the first owner seen on the walk.
92
+ *
93
+ * Subagents intentionally do not write pid-map entries; a Bash-tool ppid-walk
94
+ * from inside a subagent therefore resolves to the *parent's* pid-map entry.
95
+ * v1 ships this behavior; a real subagent-aware bridge is out of scope.
96
+ */
97
+ export function resolveOwner() {
98
+ return resolveOwnerWithSource().owner;
99
+ }
100
+ /**
101
+ * Like `resolveOwner` but also reports which resolution path matched.
102
+ * Used by `harn agents whoami` to surface the path (`env` / `pidmap`) in
103
+ * the diagnostic output. Operators trying to debug "why doesn't my
104
+ * Codex session see itself?" need to know whether `HARNERY_AGENT_COORD_OWNER`
105
+ * is propagating or the ppid-walk is the load-bearing path.
106
+ */
107
+ export function resolveOwnerWithSource() {
108
+ const envOwner = process.env.HARNERY_AGENT_COORD_OWNER?.trim();
109
+ if (envOwner) {
110
+ return { owner: envOwner, source: "env" };
111
+ }
112
+ const root = monorepoRoot();
113
+ if (!root)
114
+ return { owner: null, source: "none" };
115
+ const pidmapDir = resolve(root, ".harnery", "pid-map");
116
+ if (!existsSync(pidmapDir))
117
+ return { owner: null, source: "none" };
118
+ const prefer = process.env.HARNERY_AGENT_COORD_PLATFORM?.trim() || "claude_code";
119
+ let fallbackOwner = null;
120
+ let pid = process.pid;
121
+ for (let hop = 0; hop < 20; hop++) {
122
+ if (pid === null)
123
+ break;
124
+ const row = readPidmapRow(pidmapDir, pid);
125
+ if (row) {
126
+ const rowOwner = parsePidmapRowOwner(row);
127
+ const rowPlat = parsePidmapRowPlatform(row);
128
+ if (rowPlat === prefer) {
129
+ return { owner: rowOwner || null, source: "pidmap" };
130
+ }
131
+ if (!fallbackOwner && rowOwner)
132
+ fallbackOwner = rowOwner;
133
+ }
134
+ pid = readPpid(pid);
135
+ }
136
+ return {
137
+ owner: fallbackOwner,
138
+ source: fallbackOwner ? "pidmap_fallback" : "none",
139
+ };
140
+ }
141
+ /**
142
+ * Read and parse a heartbeat file. Returns null if the file is missing,
143
+ * unreadable, or contains malformed JSON. Does not throw.
144
+ *
145
+ * Phase 8 cleanup (2026-05-27): the v1/v2 dual-write bridge is gone; the
146
+ * projector writes additively-merged heartbeats directly to
147
+ * `.harnery/active/<id>.json` (the canonical location every reader expects).
148
+ */
149
+ export function readHeartbeat(instanceId) {
150
+ if (!instanceId)
151
+ return null;
152
+ const root = monorepoRoot();
153
+ if (!root)
154
+ return null;
155
+ return readJsonHeartbeatFile(resolve(root, ".harnery", "active", `${instanceId}.json`));
156
+ }
157
+ function readJsonHeartbeatFile(path) {
158
+ if (!existsSync(path))
159
+ return null;
160
+ try {
161
+ const raw = readFileSync(path, "utf8");
162
+ const parsed = JSON.parse(raw);
163
+ if (parsed && typeof parsed === "object" && typeof parsed.instance_id === "string") {
164
+ return parsed;
165
+ }
166
+ return null;
167
+ }
168
+ catch {
169
+ return null;
170
+ }
171
+ }
172
+ /**
173
+ * Render the display form for an instance_id: `agent-<Name>` if the heartbeat
174
+ * carries a non-empty `.name`, else `agent-<8-char-hex-prefix>`.
175
+ *
176
+ * Hex fallback handles three cases cleanly:
177
+ * - heartbeat written before this feature shipped (no `name` field)
178
+ * - heartbeat pruned but instance_id still appears in older log lines
179
+ * - the narrow window between instance_id resolution and heartbeat read
180
+ */
181
+ export function displayName(instanceId) {
182
+ if (!instanceId)
183
+ return "agent-unknown";
184
+ const hb = readHeartbeat(instanceId);
185
+ if (hb && typeof hb.name === "string" && hb.name.length > 0) {
186
+ return `agent-${hb.name}`;
187
+ }
188
+ return `agent-${instanceId.slice(0, 8)}`;
189
+ }
190
+ /**
191
+ * Convenience: resolve self via ppid walk, then render. Returns
192
+ * `agent-unknown` when the walk fails.
193
+ */
194
+ export function selfDisplayName() {
195
+ const owner = resolveOwner();
196
+ if (!owner)
197
+ return "agent-unknown";
198
+ return displayName(owner);
199
+ }
200
+ function readPpid(pid) {
201
+ try {
202
+ const status = readFileSync(`/proc/${pid}/status`, "utf8");
203
+ const m = status.match(/^PPid:\s+(\d+)/m);
204
+ if (!m)
205
+ return null;
206
+ const parsed = Number.parseInt(m[1], 10);
207
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Incremental consumer for the canonical event stream at
3
+ * `.harnery/events.ndjson`.
4
+ *
5
+ * A small `.harnery/.events-cursor` file persists the last-projected event_id;
6
+ * subsequent runs skip everything up to and including that id and return only
7
+ * the new tail.
8
+ *
9
+ * Read strategy: the global cursor is advanced on every agent's turn.stop, so
10
+ * it almost always sits within the last few KB of the stream. We exploit that
11
+ * with a bounded **tail read** (reading only the last `tailBytes` of the file
12
+ * and locating the cursor there) which turns an O(file-size) read into
13
+ * O(window). If the cursor is older than the window (a long-idle system, or a
14
+ * cursor that's been rotated out) we fall back to a full read. The fallback is
15
+ * always correct, just slower, so undersizing the window can never lose events.
16
+ *
17
+ * Idempotency: projectors are idempotent by `event_id`. The
18
+ * cursor file makes this cheap (we never replay an already-projected event by
19
+ * accident) and the projector tolerates the rare full-replay (cursor rotated
20
+ * out) without double-applying.
21
+ */
22
+ export interface CanonicalEvent {
23
+ schema_version: number;
24
+ event_id: string;
25
+ event_type: string;
26
+ ts: string;
27
+ instance_id: string;
28
+ session_id: string;
29
+ parent_session_id?: string;
30
+ turn_id?: string;
31
+ parent_turn_id?: string;
32
+ harness: string;
33
+ source: string;
34
+ data: Record<string, unknown>;
35
+ }
36
+ export interface ConsumeResult {
37
+ events: CanonicalEvent[];
38
+ /** event_id of the last event the caller successfully projected. */
39
+ lastEventId: string | null;
40
+ /** Total bytes in the stream file at read time (for diagnostics). */
41
+ streamBytes: number;
42
+ }
43
+ export interface ConsumeOpts {
44
+ /** Ignore the cursor and return everything, useful for backfill. */
45
+ replayAll?: boolean;
46
+ /**
47
+ * Tail-window size in bytes for the fast-path read. Defaults to
48
+ * `HARNERY_AGENT_COORD_TAIL_BYTES` env or 2 MiB. Mainly a test seam; production
49
+ * callers should leave it unset.
50
+ */
51
+ tailBytes?: number;
52
+ }
53
+ /**
54
+ * Read all events after the persisted cursor, in chronological (file) order.
55
+ */
56
+ export declare function consumeSince(coordRoot: string, opts?: ConsumeOpts): ConsumeResult;
57
+ export declare function readCursor(coordRoot: string): string | null;
58
+ export declare function writeCursor(coordRoot: string, eventId: string): void;
59
+ //# sourceMappingURL=consume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/events/consume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAmBH,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,oEAAoE;IACpE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,aAAa,CA4CrF;AAwDD,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS3D;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQpE"}