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 @@
1
+ {"version":3,"file":"pidmap.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/pidmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,IAAI,CAYN"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Pid-map writer.
3
+ *
4
+ * Per-harness pid-map at `.harnery/pid-map/<pid>` containing
5
+ * `<instance_id>\t<platform>`. `harn agents whoami` walks ppid up 20 hops looking
6
+ * for a matching entry (preferring the harness, falling back to any platform).
7
+ *
8
+ * Atomic temp+rename. Idempotent: re-writing the same row is a no-op.
9
+ */
10
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ function atomicWrite(path, content) {
13
+ mkdirSync(dirname(path), { recursive: true });
14
+ const tmp = `${path}.tmp.${process.pid}`;
15
+ writeFileSync(tmp, content, "utf8");
16
+ renameSync(tmp, path);
17
+ }
18
+ export function writePidmapRow(coordRoot, pid, instanceId, platform) {
19
+ const path = join(coordRoot, ".harnery", "pid-map", String(pid));
20
+ const row = `${instanceId}\t${platform}`;
21
+ // Read-then-write idempotency: skip the rename churn when already current.
22
+ if (existsSync(path)) {
23
+ try {
24
+ if (readFileSync(path, "utf8") === row)
25
+ return;
26
+ }
27
+ catch {
28
+ /* fall through to write */
29
+ }
30
+ }
31
+ atomicWrite(path, row);
32
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Scratchpad mutations: append-only timestamped journal at
3
+ * `.harnery/scratch/<instance_id>.md`.
4
+ *
5
+ * Used by the agents-coord web UI route handlers for both operator-nudge
6
+ * appends and inline edits.
7
+ */
8
+ /**
9
+ * Append a timestamped entry to the owner's scratchpad.
10
+ * Returns true on success, false if validation failed.
11
+ */
12
+ export declare function appendScratch(coordRoot: string, instanceId: string, category: string, body: string): {
13
+ ok: boolean;
14
+ reason?: string;
15
+ path?: string;
16
+ };
17
+ /**
18
+ * Replace the scratchpad with new body, archiving prior contents and
19
+ * appending an "(edited via UI by Ryan)" audit-marker note.
20
+ */
21
+ export declare function editScratchpad(coordRoot: string, instanceId: string, newBody: string, summary: string): {
22
+ ok: boolean;
23
+ reason?: string;
24
+ archivePath?: string;
25
+ path?: string;
26
+ };
27
+ //# sourceMappingURL=scratch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/scratch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2CH;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAqBjD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA8BvE"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Scratchpad mutations: append-only timestamped journal at
3
+ * `.harnery/scratch/<instance_id>.md`.
4
+ *
5
+ * Used by the agents-coord web UI route handlers for both operator-nudge
6
+ * appends and inline edits.
7
+ */
8
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ const ALLOWED_CATEGORIES = new Set([
11
+ "note",
12
+ "plan",
13
+ "decision",
14
+ "blocker",
15
+ "question",
16
+ "done",
17
+ "handoff",
18
+ ]);
19
+ const APPEND_BODY_CAP = 4096;
20
+ function nowIsoSeconds() {
21
+ return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
22
+ }
23
+ function scratchPath(coordRoot, instanceId) {
24
+ return join(coordRoot, ".harnery", "scratch", `${instanceId}.md`);
25
+ }
26
+ function archivePath(coordRoot, instanceId, suffix) {
27
+ return join(coordRoot, ".harnery", "scratch", "archived", `${instanceId}-${suffix}.md`);
28
+ }
29
+ function atomicWriteText(path, content) {
30
+ mkdirSync(dirname(path), { recursive: true });
31
+ const tmp = `${path}.tmp.${process.pid}`;
32
+ writeFileSync(tmp, content, "utf8");
33
+ renameSync(tmp, path);
34
+ }
35
+ /**
36
+ * Append a timestamped entry to the owner's scratchpad.
37
+ * Returns true on success, false if validation failed.
38
+ */
39
+ export function appendScratch(coordRoot, instanceId, category, body) {
40
+ if (!ALLOWED_CATEGORIES.has(category)) {
41
+ return { ok: false, reason: `invalid category "${category}"` };
42
+ }
43
+ if (!body || body.length === 0) {
44
+ return { ok: false, reason: "body required" };
45
+ }
46
+ const trimmedBody = body.length > APPEND_BODY_CAP ? `${body.slice(0, APPEND_BODY_CAP - 3)}...` : body;
47
+ const target = scratchPath(coordRoot, instanceId);
48
+ const ts = nowIsoSeconds();
49
+ let prior = "";
50
+ if (existsSync(target)) {
51
+ prior = readFileSync(target, "utf8");
52
+ if (!prior.endsWith("\n"))
53
+ prior += "\n";
54
+ }
55
+ const entry = `## [${ts}] ${category}\n${trimmedBody}\n`;
56
+ atomicWriteText(target, prior + entry);
57
+ return { ok: true, path: target };
58
+ }
59
+ /**
60
+ * Replace the scratchpad with new body, archiving prior contents and
61
+ * appending an "(edited via UI by Ryan)" audit-marker note.
62
+ */
63
+ export function editScratchpad(coordRoot, instanceId, newBody, summary) {
64
+ if (typeof newBody !== "string") {
65
+ return { ok: false, reason: "newBody required" };
66
+ }
67
+ const target = scratchPath(coordRoot, instanceId);
68
+ const ts = nowIsoSeconds();
69
+ const archiveSuffix = `pre-ui-${ts.replace(/:/g, "-")}`;
70
+ const archive = archivePath(coordRoot, instanceId, archiveSuffix);
71
+ mkdirSync(dirname(archive), { recursive: true });
72
+ let prior = "";
73
+ if (existsSync(target)) {
74
+ try {
75
+ copyFileSync(target, archive);
76
+ }
77
+ catch {
78
+ /* archive optional; continue */
79
+ }
80
+ prior = readFileSync(target, "utf8");
81
+ if (!prior.endsWith("\n"))
82
+ prior += "\n";
83
+ }
84
+ const summaryText = summary && summary.length > 0 ? summary : "(no summary)";
85
+ const auditMarker = `## [${ts}] note (edited via UI by Ryan)\n` +
86
+ `${summaryText}\n` +
87
+ `Pre-edit archived at .harnery/scratch/archived/${instanceId}-${archiveSuffix}.md\n\n`;
88
+ atomicWriteText(target, prior + auditMarker + newBody + (newBody.endsWith("\n") ? "" : "\n"));
89
+ return { ok: true, archivePath: archive, path: target };
90
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A heuristic parser that extracts file paths likely to be mutated by a
3
+ * shell command. Used by
4
+ * the cursor + codex harness adapters to emit SHELL_CLAIM_CANDIDATE log lines
5
+ * (warn-only, never blocks).
6
+ *
7
+ * Two cases:
8
+ * 1. Output redirections: `> path` and `>> path`
9
+ * 2. Common mutators: `sed -i…`, `cp`, `mv`, `touch`: capture the next
10
+ * non-space token after the command name (intentionally single-arg even
11
+ * though `cp src dest` has two args)
12
+ *
13
+ * Caller-supplied `coordRoot` is stripped from absolute paths so the warn
14
+ * log shows monorepo-relative form.
15
+ */
16
+ export declare function shellMutationPaths(cmd: string, coordRoot?: string | null): string[];
17
+ //# sourceMappingURL=shell-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-mutation.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/shell-mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,EAAE,CA2BzF"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * A heuristic parser that extracts file paths likely to be mutated by a
3
+ * shell command. Used by
4
+ * the cursor + codex harness adapters to emit SHELL_CLAIM_CANDIDATE log lines
5
+ * (warn-only, never blocks).
6
+ *
7
+ * Two cases:
8
+ * 1. Output redirections: `> path` and `>> path`
9
+ * 2. Common mutators: `sed -i…`, `cp`, `mv`, `touch`: capture the next
10
+ * non-space token after the command name (intentionally single-arg even
11
+ * though `cp src dest` has two args)
12
+ *
13
+ * Caller-supplied `coordRoot` is stripped from absolute paths so the warn
14
+ * log shows monorepo-relative form.
15
+ */
16
+ export function shellMutationPaths(cmd, coordRoot = null) {
17
+ if (!cmd)
18
+ return [];
19
+ const out = [];
20
+ // Output redirections: > path / >> path
21
+ const redirectRe = />>?[ \t]+([^ \t;|&"'`]+)/g;
22
+ let m = redirectRe.exec(cmd);
23
+ while (m !== null) {
24
+ out.push(m[1]);
25
+ m = redirectRe.exec(cmd);
26
+ }
27
+ // Common mutators. Capture up to the first whitespace after the command
28
+ // name and take the final token. For 1-arg commands (touch, sed -i 'expr',
29
+ // cp WITHOUT a dest) that's the path; for 2-arg commands (`cp src dest`,
30
+ // `mv src dest`) it's the source, intentionally heuristic-only.
31
+ const cmdRe = /\b(?:sed -i\S*|cp|mv|touch)[ \t]+([^ \t;|&]+)/g;
32
+ m = cmdRe.exec(cmd);
33
+ while (m !== null) {
34
+ out.push(m[1]);
35
+ m = cmdRe.exec(cmd);
36
+ }
37
+ return out
38
+ .map((p) => p.replace(/^\.\//, ""))
39
+ .map((p) => (coordRoot && p.startsWith(`${coordRoot}/`) ? p.slice(coordRoot.length + 1) : p))
40
+ .filter((p) => p.length > 0);
41
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Stale-sweep: prune dead heartbeats + orphaned pid-map + .last-peer-hash
3
+ * files.
4
+ *
5
+ * Fires at session.start to clean up crashed-peer detritus before the new
6
+ * session's UX layer reads peer state.
7
+ *
8
+ * Freshness threshold defaults to 600s; configurable via
9
+ * HARNERY_AGENT_COORD_FRESHNESS env var.
10
+ */
11
+ export declare function staleSweep(coordRoot: string): {
12
+ heartbeatsRemoved: string[];
13
+ pidmapsRemoved: number;
14
+ peerHashesRemoved: number;
15
+ };
16
+ //# sourceMappingURL=stale-sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiDH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CA+HA"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Stale-sweep: prune dead heartbeats + orphaned pid-map + .last-peer-hash
3
+ * files.
4
+ *
5
+ * Fires at session.start to clean up crashed-peer detritus before the new
6
+ * session's UX layer reads peer state.
7
+ *
8
+ * Freshness threshold defaults to 600s; configurable via
9
+ * HARNERY_AGENT_COORD_FRESHNESS env var.
10
+ */
11
+ import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { coordEnv } from "../../../lib/env.js";
14
+ import { emit } from "../events/emit.js";
15
+ const DEFAULT_FRESHNESS_SECS = 600;
16
+ /** platform → harness, for the swept-event envelope (mirrors heartbeat-writer's harnessOf). */
17
+ function harnessFromPlatform(platform) {
18
+ if (platform === "cursor")
19
+ return "cursor";
20
+ if (platform === "codex")
21
+ return "codex";
22
+ return "claude-code";
23
+ }
24
+ /** Emit a best-effort health.heartbeat_swept event. Telemetry only, never throws. */
25
+ function emitSwept(coordRoot, instanceId, harness, sessionId, reason, ageSecs) {
26
+ try {
27
+ emit(coordRoot, {
28
+ event_type: "health.heartbeat_swept",
29
+ instance_id: instanceId,
30
+ session_id: sessionId,
31
+ harness,
32
+ source: "agent-coord",
33
+ data: { reason, ...(ageSecs !== undefined ? { age_secs: ageSecs } : {}) },
34
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
35
+ });
36
+ }
37
+ catch {
38
+ /* telemetry only, never break the sweep */
39
+ }
40
+ }
41
+ /** File mtime in epoch-seconds, or +Infinity if it can't be read (treat as fresh → don't reap). */
42
+ function mtimeSecs(path) {
43
+ try {
44
+ return Math.floor(statSync(path).mtimeMs / 1000);
45
+ }
46
+ catch {
47
+ return Number.POSITIVE_INFINITY;
48
+ }
49
+ }
50
+ export function staleSweep(coordRoot) {
51
+ const heartbeatsRemoved = [];
52
+ let pidmapsRemoved = 0;
53
+ let peerHashesRemoved = 0;
54
+ const freshness = Number.parseInt(coordEnv("AGENT_COORD_FRESHNESS") ?? String(DEFAULT_FRESHNESS_SECS), 10);
55
+ const nowSec = Math.floor(Date.now() / 1000);
56
+ const cutoff = nowSec - (Number.isFinite(freshness) && freshness > 0 ? freshness : DEFAULT_FRESHNESS_SECS);
57
+ // 1. Prune stale heartbeats from the canonical `.harnery/active/` dir.
58
+ //
59
+ // Two deletion regimes, deliberately asymmetric:
60
+ // • Valid JSON with an OLD last_heartbeat → the legitimate dead/idle-agent
61
+ // prune. Delete (this is the whole point of stale-sweep; idle agents get
62
+ // healed back on their next tool call).
63
+ // • Can't-trust-content (JSON.parse failed, or no/NaN last_heartbeat) →
64
+ // fall back to file MTIME as the liveness signal. Only delete if the file
65
+ // is also mtime-old. A fresh-mtime file failing to parse is almost always
66
+ // a transient (mid-write / partial read), and deleting it would nuke a
67
+ // LIVE agent's heartbeat, the worst possible outcome. So: never reap a
68
+ // fresh file on a content failure.
69
+ // Every deletion now emits health.heartbeat_swept so the lifecycle is
70
+ // auditable (sweeps used to be silent; see the swept-event schema doc).
71
+ const liveInstanceIds = new Set();
72
+ const d = join(coordRoot, ".harnery", "active");
73
+ if (existsSync(d)) {
74
+ for (const f of readdirSync(d)) {
75
+ if (!f.endsWith(".json"))
76
+ continue;
77
+ const path = join(d, f);
78
+ const idFromFile = f.replace(/\.json$/, "");
79
+ let parsed = null;
80
+ try {
81
+ parsed = JSON.parse(readFileSync(path, "utf8"));
82
+ }
83
+ catch {
84
+ parsed = null;
85
+ }
86
+ if (parsed === null) {
87
+ // Unparseable: only reap if the file itself is mtime-old.
88
+ if (mtimeSecs(path) < cutoff) {
89
+ try {
90
+ unlinkSync(path);
91
+ heartbeatsRemoved.push(f);
92
+ emitSwept(coordRoot, idFromFile, "claude-code", idFromFile, "unparseable");
93
+ }
94
+ catch {
95
+ /* swallow */
96
+ }
97
+ }
98
+ continue;
99
+ }
100
+ const instanceId = parsed.instance_id ?? idFromFile;
101
+ const harness = harnessFromPlatform(parsed.platform);
102
+ const sessionId = parsed.session_id ?? instanceId;
103
+ const ts = parsed.last_heartbeat
104
+ ? Math.floor(Date.parse(parsed.last_heartbeat) / 1000)
105
+ : Number.NaN;
106
+ if (!parsed.last_heartbeat || !Number.isFinite(ts)) {
107
+ // No / NaN last_heartbeat: can't trust content; gate on mtime.
108
+ if (mtimeSecs(path) < cutoff) {
109
+ unlinkSync(path);
110
+ heartbeatsRemoved.push(f);
111
+ emitSwept(coordRoot, instanceId, harness, sessionId, "missing_ts");
112
+ }
113
+ else if (parsed.instance_id) {
114
+ liveInstanceIds.add(parsed.instance_id);
115
+ }
116
+ continue;
117
+ }
118
+ if (ts < cutoff) {
119
+ // Legitimate stale prune (valid timestamp, past the freshness cutoff).
120
+ unlinkSync(path);
121
+ heartbeatsRemoved.push(f);
122
+ emitSwept(coordRoot, instanceId, harness, sessionId, "stale", nowSec - ts);
123
+ continue;
124
+ }
125
+ if (parsed.instance_id)
126
+ liveInstanceIds.add(parsed.instance_id);
127
+ }
128
+ }
129
+ // 2. Prune pid-map entries whose instance has no live heartbeat.
130
+ const pidmapDir = join(coordRoot, ".harnery", "pid-map");
131
+ if (existsSync(pidmapDir)) {
132
+ for (const f of readdirSync(pidmapDir)) {
133
+ const path = join(pidmapDir, f);
134
+ try {
135
+ const row = readFileSync(path, "utf8").trim();
136
+ const ownerId = row.split("\t")[0]?.trim() ?? "";
137
+ if (!ownerId || !liveInstanceIds.has(ownerId)) {
138
+ unlinkSync(path);
139
+ pidmapsRemoved += 1;
140
+ }
141
+ }
142
+ catch {
143
+ /* swallow */
144
+ }
145
+ }
146
+ }
147
+ // 3. Prune .last-peer-hash files for dead owners.
148
+ const agentsDir = join(coordRoot, ".harnery");
149
+ if (existsSync(agentsDir)) {
150
+ for (const f of readdirSync(agentsDir)) {
151
+ if (!f.startsWith(".last-peer-hash."))
152
+ continue;
153
+ const owner = f.slice(".last-peer-hash.".length);
154
+ if (!liveInstanceIds.has(owner)) {
155
+ try {
156
+ unlinkSync(join(agentsDir, f));
157
+ peerHashesRemoved += 1;
158
+ }
159
+ catch {
160
+ /* swallow */
161
+ }
162
+ }
163
+ }
164
+ }
165
+ return { heartbeatsRemoved, pidmapsRemoved, peerHashesRemoved };
166
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `.harnery/config.jsonc` reader: the host-project config the coord/hook layer
3
+ * consults when it can't see the consumer CLI's own process.
4
+ *
5
+ * The single field this module owns today is `binName`: the host CLI's binary
6
+ * name (e.g. `myapp`), used in user-facing strings the agent reads and runs:
7
+ * council prompts, end-of-turn nudges, command help/errors. The coord binaries
8
+ * (`agent-hook`, `agent-coord`) and the web UI run as harnery itself, so they
9
+ * have no other way to learn the consumer's bin name; `harn init` stamps it here
10
+ * for them to read back. The `files` deny/override section is parsed separately
11
+ * by `web/lib/files.ts`.
12
+ *
13
+ * Dependency-free (no jsonc npm dep) so it runs on both Bun and Node, and so the
14
+ * ADR-009 vendored copies stay portable.
15
+ */
16
+ /** The standalone CLI's bin name: the resolution floor when nothing else is set. */
17
+ export declare const DEFAULT_BIN_NAME = "harn";
18
+ /** Strip `//` and `/* *​/` comments from JSONC, ignoring comment-like runs inside strings. */
19
+ export declare function stripJsonComments(input: string): string;
20
+ /**
21
+ * Resolve the host CLI's bin name for user-facing strings. Precedence:
22
+ * 1. `HARNERY_BIN` env (explicit per-process override)
23
+ * 2. `.harnery/config.jsonc` `binName` (stamped by `harn init`)
24
+ * 3. `"harn"` (standalone default)
25
+ *
26
+ * `coordRoot` is resolved via `findCoordRoot()` when not passed.
27
+ */
28
+ export declare function resolveBinName(coordRoot?: string | null): string;
29
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAQvC,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqCvD;AAyBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAShE"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * `.harnery/config.jsonc` reader: the host-project config the coord/hook layer
3
+ * consults when it can't see the consumer CLI's own process.
4
+ *
5
+ * The single field this module owns today is `binName`: the host CLI's binary
6
+ * name (e.g. `myapp`), used in user-facing strings the agent reads and runs:
7
+ * council prompts, end-of-turn nudges, command help/errors. The coord binaries
8
+ * (`agent-hook`, `agent-coord`) and the web UI run as harnery itself, so they
9
+ * have no other way to learn the consumer's bin name; `harn init` stamps it here
10
+ * for them to read back. The `files` deny/override section is parsed separately
11
+ * by `web/lib/files.ts`.
12
+ *
13
+ * Dependency-free (no jsonc npm dep) so it runs on both Bun and Node, and so the
14
+ * ADR-009 vendored copies stay portable.
15
+ */
16
+ import { readFileSync, statSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { coordEnv } from "../lib/env.js";
19
+ import { findCoordRoot } from "./hooks/resolve/coord-root.js";
20
+ /** The standalone CLI's bin name: the resolution floor when nothing else is set. */
21
+ export const DEFAULT_BIN_NAME = "harn";
22
+ /** Strip `//` and `/* *​/` comments from JSONC, ignoring comment-like runs inside strings. */
23
+ export function stripJsonComments(input) {
24
+ let out = "";
25
+ let i = 0;
26
+ let inString = false;
27
+ while (i < input.length) {
28
+ const ch = input[i];
29
+ if (inString) {
30
+ out += ch;
31
+ if (ch === "\\" && i + 1 < input.length) {
32
+ out += input[i + 1];
33
+ i += 2;
34
+ continue;
35
+ }
36
+ if (ch === '"')
37
+ inString = false;
38
+ i++;
39
+ continue;
40
+ }
41
+ if (ch === '"') {
42
+ inString = true;
43
+ out += ch;
44
+ i++;
45
+ continue;
46
+ }
47
+ if (ch === "/" && input[i + 1] === "/") {
48
+ while (i < input.length && input[i] !== "\n")
49
+ i++;
50
+ continue;
51
+ }
52
+ if (ch === "/" && input[i + 1] === "*") {
53
+ i += 2;
54
+ while (i < input.length && !(input[i] === "*" && input[i + 1] === "/"))
55
+ i++;
56
+ i += 2;
57
+ continue;
58
+ }
59
+ out += ch;
60
+ i++;
61
+ }
62
+ return out;
63
+ }
64
+ // mtime-keyed per-process cache: a stat is cheap, a parse on every render isn't.
65
+ let cache = null;
66
+ function readConfig(root) {
67
+ const p = join(root, ".harnery", "config.jsonc");
68
+ let mtimeMs = -1;
69
+ try {
70
+ mtimeMs = statSync(p).mtimeMs;
71
+ }
72
+ catch {
73
+ /* missing → -1; cache still valid until the file appears */
74
+ }
75
+ if (cache && cache.root === root && cache.mtimeMs === mtimeMs)
76
+ return cache.cfg;
77
+ let cfg = {};
78
+ try {
79
+ const parsed = JSON.parse(stripJsonComments(readFileSync(p, "utf8")));
80
+ if (parsed && typeof parsed === "object")
81
+ cfg = parsed;
82
+ }
83
+ catch {
84
+ /* missing or unparseable → defaults (the files-section resolver fails loud; bin name is non-critical) */
85
+ }
86
+ cache = { root, mtimeMs, cfg };
87
+ return cfg;
88
+ }
89
+ /**
90
+ * Resolve the host CLI's bin name for user-facing strings. Precedence:
91
+ * 1. `HARNERY_BIN` env (explicit per-process override)
92
+ * 2. `.harnery/config.jsonc` `binName` (stamped by `harn init`)
93
+ * 3. `"harn"` (standalone default)
94
+ *
95
+ * `coordRoot` is resolved via `findCoordRoot()` when not passed.
96
+ */
97
+ export function resolveBinName(coordRoot) {
98
+ const env = coordEnv("BIN");
99
+ if (env?.trim())
100
+ return env.trim();
101
+ const root = coordRoot ?? findCoordRoot();
102
+ if (root) {
103
+ const binName = readConfig(root).binName;
104
+ if (typeof binName === "string" && binName.trim())
105
+ return binName.trim();
106
+ }
107
+ return DEFAULT_BIN_NAME;
108
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `agent-hook` CLI entry point. Phase 2: real canonical-event emission
3
+ * alongside the legacy stream.
4
+ *
5
+ * Flow:
6
+ * 1. Parse argv → event-name + harness.
7
+ * 2. Read stdin → harness payload (JSON or empty).
8
+ * 3. Find coord root (walk up for .harnery/).
9
+ * 4. Resolve instance_id (env → payload → pid-map walk).
10
+ * 5. Map event-name → canonical event_type.
11
+ * 6. Build event data from payload + resolvers (intent, transcript scan).
12
+ * 7. Append envelope to .harnery/events.ndjson via emit() under flock.
13
+ * 8. (Still also writes a debug breadcrumb to .harnery/debug/ for visibility.)
14
+ *
15
+ * Phase 2 ship criterion: confirms parser correctness across thousands of
16
+ * real events without affecting behavior. Always exits 0. Failures land in
17
+ * `.harnery/debug/agent-hook.errors.ndjson` for audit but never break the
18
+ * harness flow.
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}