harnery 0.0.1 → 0.2.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 (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 +494 -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 +32 -0
  316. package/dist/lib/readability/client.d.ts.map +1 -0
  317. package/dist/lib/readability/client.js +119 -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 +564 -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 +156 -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,249 @@
1
+ /**
2
+ * Zsh completion generator. Emits a single `#compdef <bin>` script that uses
3
+ * `_arguments -C` for nested-subcommand parsing and supports descriptions
4
+ * inline (the main zsh-over-bash win). The bin name is injected by the caller.
5
+ *
6
+ * Architecture mirrors bash.ts:
7
+ * - Static tables for subcommands + options keyed by path
8
+ * - `<bin> __complete <provider>` callback for dynamic values
9
+ * - Driver function walks $words to determine the current command path
10
+ */
11
+ /** Derive a valid shell function-name prefix from the bin name. */
12
+ function fnPrefix(binName) {
13
+ return `_${binName.replace(/[^a-zA-Z0-9_]/g, "_")}`;
14
+ }
15
+ function valueSpec(opt) {
16
+ if (opt.dynamicProvider)
17
+ return `DYN:${opt.dynamicProvider}`;
18
+ if (opt.valueChoices && opt.valueChoices.length > 0) {
19
+ return `ENUM:${opt.valueChoices.join(" ")}`;
20
+ }
21
+ return "";
22
+ }
23
+ /** Escape a string for single-quoted zsh string. Same rule as bash. */
24
+ function zshEscape(s) {
25
+ return s.replace(/'/g, `'\\''`);
26
+ }
27
+ function zshPath(path) {
28
+ return path === "" ? "ROOT" : path.replace(/ /g, "__");
29
+ }
30
+ export function generateZsh(root, binName) {
31
+ const fn = fnPrefix(binName);
32
+ const subcommandsByPath = new Map();
33
+ const optionsByPath = new Map();
34
+ const positionalsByPath = new Map();
35
+ const walk = (s) => {
36
+ subcommandsByPath.set(s.path, s.subcommands
37
+ .map((c) => ({ name: c.name, description: c.description }))
38
+ .sort((a, b) => a.name.localeCompare(b.name)));
39
+ optionsByPath.set(s.path, s.options);
40
+ positionalsByPath.set(s.path, s.positionals);
41
+ for (const sub of s.subcommands)
42
+ walk(sub);
43
+ };
44
+ walk(root);
45
+ const out = [];
46
+ out.push(`#compdef ${binName}`);
47
+ out.push(`# ${binName} zsh completion, generated by \`${binName} completion zsh\`. Do not edit.`);
48
+ out.push(`# Source via: eval "$(${binName} completion zsh)"`);
49
+ out.push("");
50
+ out.push(`${fn}_subcommands_with_desc() {`);
51
+ out.push(` case "$1" in`);
52
+ for (const [path, subs] of [...subcommandsByPath.entries()].sort()) {
53
+ if (subs.length === 0)
54
+ continue;
55
+ const lines = subs.map((s) => `'${zshEscape(s.name)}:${zshEscape(truncate(s.description, 80))}'`);
56
+ out.push(` ${zshPath(path)}) print -l ${lines.join(" ")} ;;`);
57
+ }
58
+ out.push(" esac");
59
+ out.push("}");
60
+ out.push("");
61
+ out.push(`${fn}_options_with_desc() {`);
62
+ out.push(` case "$1" in`);
63
+ for (const [path, opts] of [...optionsByPath.entries()].sort()) {
64
+ if (opts.length === 0)
65
+ continue;
66
+ const lines = [];
67
+ for (const o of opts) {
68
+ const flags = [o.long, o.short].filter((f) => f.length > 0);
69
+ for (const flag of flags) {
70
+ lines.push(`'${zshEscape(flag)}:${zshEscape(truncate(o.description, 80))}'`);
71
+ }
72
+ }
73
+ out.push(` ${zshPath(path)}) print -l ${lines.join(" ")} ;;`);
74
+ }
75
+ out.push(" esac");
76
+ out.push("}");
77
+ out.push("");
78
+ out.push(`${fn}_option_takes_value() {`);
79
+ out.push(` case "$1|$2" in`);
80
+ for (const [path, opts] of [...optionsByPath.entries()].sort()) {
81
+ for (const o of opts) {
82
+ if (!o.takesValue)
83
+ continue;
84
+ for (const flag of [o.long, o.short].filter((f) => f.length > 0)) {
85
+ out.push(` ${zshPath(path)}\\|${zshEscape(flag)}) echo 1 ;;`);
86
+ }
87
+ }
88
+ }
89
+ out.push(" esac");
90
+ out.push("}");
91
+ out.push("");
92
+ out.push(`${fn}_option_value_spec() {`);
93
+ out.push(` case "$1|$2" in`);
94
+ for (const [path, opts] of [...optionsByPath.entries()].sort()) {
95
+ for (const o of opts) {
96
+ if (!o.takesValue)
97
+ continue;
98
+ const spec = valueSpec(o);
99
+ if (!spec)
100
+ continue;
101
+ for (const flag of [o.long, o.short].filter((f) => f.length > 0)) {
102
+ out.push(` ${zshPath(path)}\\|${zshEscape(flag)}) echo '${zshEscape(spec)}' ;;`);
103
+ }
104
+ }
105
+ }
106
+ out.push(" esac");
107
+ out.push("}");
108
+ out.push("");
109
+ out.push(`${fn}_positional_value_spec() {`);
110
+ out.push(` case "$1|$2" in`);
111
+ for (const [path, positionals] of [...positionalsByPath.entries()].sort()) {
112
+ positionals.forEach((p, i) => {
113
+ const spec = valueSpec(p);
114
+ if (!spec)
115
+ return;
116
+ out.push(` ${zshPath(path)}\\|${i}) echo '${zshEscape(spec)}' ;;`);
117
+ });
118
+ }
119
+ out.push(" esac");
120
+ out.push("}");
121
+ out.push("");
122
+ out.push(zshDriver(fn, binName));
123
+ out.push("");
124
+ out.push(`compdef ${fn} ${binName}`);
125
+ return `${out.join("\n")}\n`;
126
+ }
127
+ function truncate(s, n) {
128
+ if (!s)
129
+ return "";
130
+ return s.length > n ? `${s.slice(0, n - 1)}…` : s;
131
+ }
132
+ /**
133
+ * The driver walks `$words` to determine the current command path, then
134
+ * dispatches to subcommand / option / value completion. `fn` is the
135
+ * function-name prefix; `binName` is the CLI name for the `__complete` callback.
136
+ */
137
+ function zshDriver(fn, binName) {
138
+ return `${fn}() {
139
+ local cur prev path_str path_parts
140
+ local -a words
141
+ words=( "\${(@)words}" )
142
+ local cword=$CURRENT
143
+ cur="\${words[$cword]}"
144
+ prev="\${words[$((cword-1))]}"
145
+
146
+ # Walk words[2..cword-1] (zsh is 1-indexed; words[1] is the bin) to determine path.
147
+ path_str="ROOT"
148
+ local -a path_parts
149
+ local i=2
150
+ while [ $i -lt $cword ]; do
151
+ local w="\${words[$i]}"
152
+ case "$w" in
153
+ -*)
154
+ if [ "$(${fn}_option_takes_value "$path_str" "$w")" = "1" ]; then
155
+ i=$((i+1))
156
+ fi
157
+ ;;
158
+ *)
159
+ path_parts+=("$w")
160
+ local joined="\${(j:__:)path_parts}"
161
+ local known
162
+ known=$(${fn}_subcommands_with_desc "$path_str" | awk -F: '{print $1}' | tr -d "'")
163
+ if [[ " $known " == *" $w "* ]]; then
164
+ path_str="$joined"
165
+ fi
166
+ ;;
167
+ esac
168
+ i=$((i+1))
169
+ done
170
+
171
+ # Case 1: prev is an option that takes a value.
172
+ if [ -n "$prev" ] && [ "$(${fn}_option_takes_value "$path_str" "$prev")" = "1" ]; then
173
+ local spec=$(${fn}_option_value_spec "$path_str" "$prev")
174
+ ${fn}_emit_values "$spec" "$cur"
175
+ return
176
+ fi
177
+
178
+ # Case 2: completing an option (cur starts with -).
179
+ if [[ "$cur" == -* ]]; then
180
+ local -a opt_descs
181
+ opt_descs=( \${(f)"$(${fn}_options_with_desc "$path_str")"} )
182
+ if [ \${#opt_descs[@]} -gt 0 ]; then
183
+ _describe 'options' opt_descs
184
+ fi
185
+ return
186
+ fi
187
+
188
+ # Case 3: subcommands at this level.
189
+ local -a sub_descs
190
+ sub_descs=( \${(f)"$(${fn}_subcommands_with_desc "$path_str")"} )
191
+ if [ \${#sub_descs[@]} -gt 0 ]; then
192
+ _describe 'subcommands' sub_descs
193
+ return
194
+ fi
195
+
196
+ # Case 4: positional value. Count non-option, non-subcommand words after path.
197
+ local after_cmd=0
198
+ local seen_path="ROOT"
199
+ local j=2
200
+ while [ $j -lt $cword ]; do
201
+ local w="\${words[$j]}"
202
+ case "$w" in
203
+ -*)
204
+ if [ "$(${fn}_option_takes_value "$seen_path" "$w")" = "1" ]; then
205
+ j=$((j+1))
206
+ fi
207
+ ;;
208
+ *)
209
+ local joined
210
+ if [ "$seen_path" = "ROOT" ]; then joined="$w"; else joined="\${seen_path}__\${w}"; fi
211
+ local known
212
+ known=$(${fn}_subcommands_with_desc "$seen_path" | awk -F: '{print $1}' | tr -d "'")
213
+ if [[ " $known " == *" $w "* ]]; then
214
+ seen_path="$joined"
215
+ else
216
+ after_cmd=$((after_cmd+1))
217
+ fi
218
+ ;;
219
+ esac
220
+ j=$((j+1))
221
+ done
222
+
223
+ local pos_spec=$(${fn}_positional_value_spec "$path_str" "$after_cmd")
224
+ if [ -n "$pos_spec" ]; then
225
+ ${fn}_emit_values "$pos_spec" "$cur"
226
+ return
227
+ fi
228
+
229
+ _files
230
+ }
231
+
232
+ ${fn}_emit_values() {
233
+ local spec="$1"
234
+ local cur="$2"
235
+ if [[ "$spec" == DYN:* ]]; then
236
+ local provider="\${spec#DYN:}"
237
+ local -a values
238
+ values=( \${(f)"$(${binName} __complete "$provider" -- "$cur" 2>/dev/null)"} )
239
+ if [ \${#values[@]} -gt 0 ]; then
240
+ compadd -a values
241
+ fi
242
+ elif [[ "$spec" == ENUM:* ]]; then
243
+ local choices="\${spec#ENUM:}"
244
+ local -a values
245
+ values=( \${(s: :)choices} )
246
+ compadd -a values
247
+ fi
248
+ }`;
249
+ }
@@ -0,0 +1,107 @@
1
+ interface SubmoduleStatus {
2
+ name: string;
3
+ branch: string;
4
+ ahead: number;
5
+ behind: number;
6
+ dirty: boolean;
7
+ modifiedFiles: number;
8
+ untrackedFiles: number;
9
+ }
10
+ /**
11
+ * `harn context`: one-shot orientation snapshot for session start / post-compaction
12
+ * recovery / subagent dispatch. Aggregates self / time / repo / commits / submodules
13
+ * / peers, plus opt-in services. Fail-open per section so a missing dependency
14
+ * never blocks the rest from rendering.
15
+ *
16
+ * No process spawns for default sections except git; every other source is
17
+ * filesystem-direct via existing lib helpers.
18
+ */
19
+ export type SectionName = "self" | "time" | "repo" | "commits" | "submodules" | "peers" | "services";
20
+ export declare const DEFAULT_SECTIONS: SectionName[];
21
+ export declare const OPT_IN_SECTIONS: SectionName[];
22
+ export interface ContextOptions {
23
+ sections?: SectionName[];
24
+ include?: SectionName[];
25
+ showClean?: boolean;
26
+ /** Monorepo root for git ops. Defaults to process.cwd() when omitted. */
27
+ repoRoot?: string;
28
+ /** Submodule names relative to repoRoot. When omitted, submodules section reports an error. */
29
+ submodules?: readonly string[];
30
+ }
31
+ export interface ContextReport {
32
+ self?: SelfSection | {
33
+ error: string;
34
+ };
35
+ time?: TimeSection;
36
+ repo?: RepoSection | {
37
+ error: string;
38
+ };
39
+ commits?: CommitsSection | {
40
+ error: string;
41
+ };
42
+ submodules?: SubmodulesSection | {
43
+ error: string;
44
+ };
45
+ peers?: PeersSection | {
46
+ error: string;
47
+ };
48
+ services?: ServicesSection | {
49
+ error: string;
50
+ };
51
+ meta: {
52
+ elapsed_ms: number;
53
+ sections_requested: SectionName[];
54
+ };
55
+ }
56
+ export interface SelfSection {
57
+ name: string | null;
58
+ instance_id: string;
59
+ session_age_secs: number;
60
+ task: string | null;
61
+ last_tool: string | null;
62
+ last_tool_target: string | null;
63
+ files_held: string[];
64
+ }
65
+ export interface TimeSection {
66
+ chicago: string;
67
+ utc: string;
68
+ }
69
+ export interface RepoSection {
70
+ cwd: string;
71
+ branch: string;
72
+ ahead: number;
73
+ behind: number;
74
+ modified: number;
75
+ untracked: number;
76
+ staged: number;
77
+ }
78
+ export interface CommitsSection {
79
+ rows: {
80
+ sha: string;
81
+ subject: string;
82
+ }[];
83
+ }
84
+ export interface SubmodulesSection {
85
+ rows: SubmoduleStatus[];
86
+ clean_omitted: number;
87
+ }
88
+ export interface PeersSection {
89
+ rows: {
90
+ name: string;
91
+ instance_id_short: string;
92
+ age_min: number;
93
+ files: number;
94
+ last_tool: string | null;
95
+ task: string | null;
96
+ }[];
97
+ }
98
+ export interface ServicesSection {
99
+ docker_compose: {
100
+ project: string;
101
+ service: string;
102
+ status: string;
103
+ }[];
104
+ }
105
+ export declare function buildContext(opts?: ContextOptions): Promise<ContextReport>;
106
+ export {};
107
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/context/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,275 @@
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { monorepoRoot, readHeartbeat, resolveOwner, } from "../../core/agents/index.js";
4
+ import { exec } from "../exec.js";
5
+ import { NO_DATA } from "../format.js";
6
+ export const DEFAULT_SECTIONS = [
7
+ "self",
8
+ "time",
9
+ "repo",
10
+ "commits",
11
+ "submodules",
12
+ "peers",
13
+ ];
14
+ export const OPT_IN_SECTIONS = ["services"];
15
+ export async function buildContext(opts = {}) {
16
+ const started = Date.now();
17
+ const requested = new Set(opts.sections ?? DEFAULT_SECTIONS);
18
+ for (const s of opts.include ?? [])
19
+ requested.add(s);
20
+ const report = {
21
+ meta: {
22
+ elapsed_ms: 0,
23
+ sections_requested: Array.from(requested),
24
+ },
25
+ };
26
+ const repoRoot = opts.repoRoot ?? process.cwd();
27
+ const submodules = opts.submodules ?? null;
28
+ if (requested.has("self"))
29
+ report.self = await safe(() => buildSelf());
30
+ if (requested.has("time"))
31
+ report.time = buildTime();
32
+ if (requested.has("repo"))
33
+ report.repo = await safe(() => buildRepo(repoRoot));
34
+ if (requested.has("commits"))
35
+ report.commits = await safe(() => buildCommits(repoRoot));
36
+ if (requested.has("submodules")) {
37
+ report.submodules = await safe(() => buildSubmodules(!!opts.showClean, repoRoot, submodules));
38
+ }
39
+ if (requested.has("peers"))
40
+ report.peers = await safe(() => buildPeers());
41
+ if (requested.has("services"))
42
+ report.services = await safe(() => buildServices(repoRoot));
43
+ report.meta.elapsed_ms = Date.now() - started;
44
+ return report;
45
+ }
46
+ // ─── Sections ──────────────────────────────────────────────────────────────
47
+ function buildSelf() {
48
+ const owner = resolveOwner();
49
+ if (!owner)
50
+ throw new Error("not in an agent session (no pid-map entry)");
51
+ const hb = readHeartbeat(owner);
52
+ if (!hb)
53
+ throw new Error(`pid-map resolved owner=${owner.slice(0, 8)}… but no heartbeat`);
54
+ const startedMs = Date.parse(hb.started_at);
55
+ const ageSecs = Number.isFinite(startedMs)
56
+ ? Math.max(0, Math.floor((Date.now() - startedMs) / 1000))
57
+ : 0;
58
+ return {
59
+ name: hb.name ?? null,
60
+ instance_id: hb.instance_id,
61
+ session_age_secs: ageSecs,
62
+ task: hb.task ?? null,
63
+ last_tool: hb.last_tool ?? null,
64
+ last_tool_target: hb.last_tool_target ?? null,
65
+ files_held: hb.files_touched ?? [],
66
+ };
67
+ }
68
+ function buildTime() {
69
+ const now = new Date();
70
+ return {
71
+ chicago: formatChicago(now),
72
+ utc: now.toISOString(),
73
+ };
74
+ }
75
+ async function buildRepo(repoRoot) {
76
+ const [branchResult, statusResult, aheadBehindResult] = await Promise.all([
77
+ exec(["git", "rev-parse", "--abbrev-ref", "HEAD"], { cwd: repoRoot }),
78
+ // trim:false, since porcelain's first line of ` M PATH` would lose its leading
79
+ // space and shift the X/Y status columns, miscounting staged vs modified.
80
+ exec(["git", "status", "--porcelain"], { cwd: repoRoot, trim: false }),
81
+ exec(["git", "rev-list", "--left-right", "--count", "HEAD...@{upstream}"], { cwd: repoRoot }),
82
+ ]);
83
+ const branch = branchResult.stdout || "detached";
84
+ const statusLines = statusResult.stdout ? statusResult.stdout.split("\n") : [];
85
+ let modified = 0;
86
+ let untracked = 0;
87
+ let staged = 0;
88
+ for (const line of statusLines) {
89
+ if (line.startsWith("??"))
90
+ untracked++;
91
+ else if (line.length >= 2) {
92
+ const x = line[0];
93
+ const y = line[1];
94
+ if (x !== " " && x !== "?")
95
+ staged++;
96
+ if (y !== " " && y !== "?")
97
+ modified++;
98
+ }
99
+ }
100
+ let ahead = 0;
101
+ let behind = 0;
102
+ if (aheadBehindResult.exitCode === 0) {
103
+ const parts = aheadBehindResult.stdout.split(/\s+/);
104
+ ahead = Number.parseInt(parts[0] ?? "0", 10);
105
+ behind = Number.parseInt(parts[1] ?? "0", 10);
106
+ }
107
+ return {
108
+ cwd: process.cwd(),
109
+ branch,
110
+ ahead,
111
+ behind,
112
+ modified,
113
+ untracked,
114
+ staged,
115
+ };
116
+ }
117
+ async function buildCommits(repoRoot) {
118
+ const result = await exec(["git", "log", "--oneline", "-3", "--no-decorate"], { cwd: repoRoot });
119
+ const rows = result.stdout
120
+ .split("\n")
121
+ .filter((l) => l.length > 0)
122
+ .map((l) => {
123
+ const idx = l.indexOf(" ");
124
+ if (idx < 0)
125
+ return { sha: l, subject: "" };
126
+ return { sha: l.slice(0, idx), subject: l.slice(idx + 1) };
127
+ });
128
+ return { rows };
129
+ }
130
+ async function buildSubmodules(showClean, repoRoot, submodules) {
131
+ if (!submodules || submodules.length === 0) {
132
+ throw new Error("no submodules configured (pass submodules via HarneryProgramContext)");
133
+ }
134
+ const all = await Promise.all(submodules.map(async (name) => statusFor(name, resolve(repoRoot, name))));
135
+ const rows = showClean ? all : all.filter((s) => s.dirty || s.ahead > 0 || s.behind > 0);
136
+ const cleanOmitted = showClean ? 0 : all.length - rows.length;
137
+ return { rows, clean_omitted: cleanOmitted };
138
+ }
139
+ async function statusFor(name, cwd) {
140
+ const empty = {
141
+ name,
142
+ branch: NO_DATA,
143
+ ahead: 0,
144
+ behind: 0,
145
+ dirty: false,
146
+ modifiedFiles: 0,
147
+ untrackedFiles: 0,
148
+ };
149
+ if (!existsSync(cwd))
150
+ return empty;
151
+ const [branchR, statusR, abR] = await Promise.all([
152
+ exec(["git", "rev-parse", "--abbrev-ref", "HEAD"], { cwd }),
153
+ exec(["git", "status", "--porcelain"], { cwd, trim: false }),
154
+ exec(["git", "rev-list", "--left-right", "--count", "HEAD...@{upstream}"], { cwd }),
155
+ ]);
156
+ let modified = 0;
157
+ let untracked = 0;
158
+ for (const line of statusR.stdout.split("\n")) {
159
+ if (line.startsWith("??"))
160
+ untracked++;
161
+ else if (line.length >= 2)
162
+ modified++;
163
+ }
164
+ const [aheadS, behindS] = abR.stdout.split("\t");
165
+ return {
166
+ name,
167
+ branch: branchR.stdout || "detached",
168
+ ahead: Number.parseInt(aheadS ?? "0", 10) || 0,
169
+ behind: Number.parseInt(behindS ?? "0", 10) || 0,
170
+ dirty: modified + untracked > 0,
171
+ modifiedFiles: modified,
172
+ untrackedFiles: untracked,
173
+ };
174
+ }
175
+ function buildPeers() {
176
+ const root = monorepoRoot();
177
+ if (!root)
178
+ throw new Error("coord_root() returned null");
179
+ const activeDir = resolve(root, ".harnery", "active");
180
+ if (!existsSync(activeDir))
181
+ return { rows: [] };
182
+ const myOwner = resolveOwner();
183
+ // No freshness filter; matches the SessionStart/UserPromptSubmit snapshot.
184
+ // Stale entries get swept by the SessionStart janitor on the next session start.
185
+ const rows = [];
186
+ for (const f of readdirSync(activeDir)) {
187
+ if (!f.endsWith(".json"))
188
+ continue;
189
+ try {
190
+ const hb = JSON.parse(readFileSync(resolve(activeDir, f), "utf8"));
191
+ if (!hb || typeof hb.instance_id !== "string")
192
+ continue;
193
+ if (hb.instance_id === myOwner)
194
+ continue;
195
+ if ((hb.kind ?? "") === "transient")
196
+ continue;
197
+ const startedMs = Date.parse(hb.started_at);
198
+ const ageMin = Number.isFinite(startedMs) ? Math.floor((Date.now() - startedMs) / 60000) : 0;
199
+ rows.push({
200
+ name: hb.name ?? "unknown",
201
+ instance_id_short: hb.instance_id.slice(0, 8),
202
+ age_min: ageMin,
203
+ files: hb.files_touched?.length ?? 0,
204
+ last_tool: hb.last_tool ?? null,
205
+ task: hb.task ?? null,
206
+ });
207
+ }
208
+ catch {
209
+ // skip
210
+ }
211
+ }
212
+ // Sort: file-holders first (more activity), then by recency (younger age first).
213
+ rows.sort((a, b) => b.files - a.files || a.age_min - b.age_min);
214
+ return { rows };
215
+ }
216
+ async function buildServices(repoRoot) {
217
+ // Probe common compose-file locations at the repo root.
218
+ const candidates = [
219
+ resolve(repoRoot, "docker-compose.yml"),
220
+ resolve(repoRoot, "compose.yml"),
221
+ resolve(repoRoot, "compose.yaml"),
222
+ ];
223
+ const composePath = candidates.find((p) => existsSync(p));
224
+ if (!composePath) {
225
+ return { docker_compose: [] };
226
+ }
227
+ const result = await exec(["docker", "compose", "-f", composePath, "ps", "--format", "json"], {
228
+ cwd: repoRoot,
229
+ timeout: 5000,
230
+ });
231
+ if (result.exitCode !== 0) {
232
+ throw new Error(result.stderr || `docker compose ps exited ${result.exitCode}`);
233
+ }
234
+ // `docker compose ps --format json` emits one JSON object per line.
235
+ const items = [];
236
+ for (const line of result.stdout.split("\n")) {
237
+ if (!line.trim())
238
+ continue;
239
+ try {
240
+ const obj = JSON.parse(line);
241
+ items.push({
242
+ project: obj.Project ?? "",
243
+ service: obj.Service ?? "",
244
+ status: obj.Status ?? obj.State ?? "",
245
+ });
246
+ }
247
+ catch {
248
+ // tolerate non-JSON banner lines
249
+ }
250
+ }
251
+ return { docker_compose: items };
252
+ }
253
+ // ─── Helpers ───────────────────────────────────────────────────────────────
254
+ async function safe(fn) {
255
+ try {
256
+ return await fn();
257
+ }
258
+ catch (err) {
259
+ return { error: err.message };
260
+ }
261
+ }
262
+ const CHICAGO_FORMATTER = new Intl.DateTimeFormat("en-US", {
263
+ weekday: "short",
264
+ year: "numeric",
265
+ month: "short",
266
+ day: "numeric",
267
+ hour: "numeric",
268
+ minute: "2-digit",
269
+ timeZoneName: "short",
270
+ hour12: true,
271
+ timeZone: "America/Chicago",
272
+ });
273
+ function formatChicago(d) {
274
+ return CHICAGO_FORMATTER.format(d);
275
+ }