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,305 @@
1
+ /**
2
+ * `harn backup`: restic-backed snapshots of `.harnery/`.
3
+ *
4
+ * Wraps `restic` with sensible defaults so single-user use doesn't require
5
+ * remembering env vars. Repo path + password file live under XDG-style
6
+ * paths and are init'd on first `harn backup init`. Subcommands:
7
+ *
8
+ * init restic init the repo (one-time)
9
+ * snapshot restic backup .harnery/
10
+ * list restic snapshots
11
+ * restore restic restore <id>
12
+ * prune restic forget --keep-daily 7 --keep-weekly 4 --prune
13
+ *
14
+ * Power users override via env vars (HARNERY_RESTIC_REPO, HARNERY_RESTIC_PASSWORD_FILE)
15
+ * or by passing through any restic args after `--`. The wrapper deliberately
16
+ * doesn't try to abstract restic; it surfaces it, with opinionated defaults plus
17
+ * passthrough.
18
+ */
19
+
20
+ import { spawnSync } from "node:child_process";
21
+ import { randomBytes } from "node:crypto";
22
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
23
+ import os from "node:os";
24
+ import path from "node:path";
25
+ import type { Command } from "commander";
26
+ import type { EmitContext } from "../commander.ts";
27
+
28
+ function defaultRepo(): string {
29
+ const home = os.homedir();
30
+ return process.env.HARNERY_RESTIC_REPO ?? path.join(home, ".cache", "harnery", "restic-repo");
31
+ }
32
+
33
+ function defaultPasswordFile(): string {
34
+ const home = os.homedir();
35
+ return (
36
+ process.env.HARNERY_RESTIC_PASSWORD_FILE ??
37
+ path.join(home, ".config", "harnery", "restic-password")
38
+ );
39
+ }
40
+
41
+ function findHarneryDir(): string | null {
42
+ let dir = process.cwd();
43
+ for (let i = 0; i < 8; i++) {
44
+ if (existsSync(path.join(dir, ".harnery"))) {
45
+ return path.join(dir, ".harnery");
46
+ }
47
+ const parent = path.dirname(dir);
48
+ if (parent === dir) break;
49
+ dir = parent;
50
+ }
51
+ return null;
52
+ }
53
+
54
+ function ensurePasswordFile(file: string): void {
55
+ if (existsSync(file)) return;
56
+ mkdirSync(path.dirname(file), { recursive: true });
57
+ const pw = randomBytes(24).toString("base64");
58
+ writeFileSync(file, `${pw}\n`, { encoding: "utf-8", mode: 0o600 });
59
+ }
60
+
61
+ interface RunOpts {
62
+ repo?: string;
63
+ passwordFile?: string;
64
+ passThrough?: string[];
65
+ stdio?: "inherit" | "pipe";
66
+ }
67
+
68
+ function runRestic(args: string[], opts: RunOpts = {}): { exitCode: number; stdout: string } {
69
+ const repo = opts.repo ?? defaultRepo();
70
+ const pwFile = opts.passwordFile ?? defaultPasswordFile();
71
+ const wantInherit = opts.stdio === "inherit";
72
+ const r = spawnSync("restic", [...args, ...(opts.passThrough ?? [])], {
73
+ env: {
74
+ ...process.env,
75
+ RESTIC_REPOSITORY: repo,
76
+ RESTIC_PASSWORD_FILE: pwFile,
77
+ },
78
+ encoding: "utf-8",
79
+ stdio: wantInherit ? "inherit" : "pipe",
80
+ });
81
+ return {
82
+ exitCode: r.status ?? 1,
83
+ stdout: wantInherit ? "" : (r.stdout ?? "") + (r.stderr ?? ""),
84
+ };
85
+ }
86
+
87
+ function checkRestic(emit: EmitContext): boolean {
88
+ const r = spawnSync("restic", ["version"], { encoding: "utf-8" });
89
+ if (r.status !== 0) {
90
+ emit.error({
91
+ code: "restic_missing",
92
+ message: "restic is not on PATH",
93
+ hint: "brew install restic (mac) / apt-get install restic (ubuntu) / https://restic.readthedocs.io/en/stable/020_installation.html",
94
+ });
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+
100
+ interface BaseOpts {
101
+ repo?: string;
102
+ passwordFile?: string;
103
+ json?: boolean;
104
+ }
105
+
106
+ export function registerBackupCommand(program: Command, emit: EmitContext): void {
107
+ const backup = program
108
+ .command("backup")
109
+ .description("restic-backed snapshots of .harnery/ (multi-machine recovery insurance)");
110
+
111
+ // -- init --
112
+ backup
113
+ .command("init")
114
+ .description("Create the restic repository + password file (one-time).")
115
+ .option("--repo <path>", `Repository path (default: ${defaultRepo()})`)
116
+ .option(
117
+ "--password-file <path>",
118
+ `Password file (default: ${defaultPasswordFile()}, autogenerated)`,
119
+ )
120
+ .action((opts: BaseOpts) => {
121
+ if (!checkRestic(emit)) {
122
+ emit.setExitCode(1);
123
+ return;
124
+ }
125
+ const repo = opts.repo ?? defaultRepo();
126
+ const pwFile = opts.passwordFile ?? defaultPasswordFile();
127
+ ensurePasswordFile(pwFile);
128
+ mkdirSync(path.dirname(repo), { recursive: true });
129
+ const r = runRestic(["init"], { repo, passwordFile: pwFile, stdio: "inherit" });
130
+ if (r.exitCode === 0) {
131
+ emit.text(`restic repo initialized at ${repo}\npassword file: ${pwFile}`);
132
+ } else {
133
+ emit.setExitCode(r.exitCode);
134
+ }
135
+ });
136
+
137
+ // -- snapshot --
138
+ backup
139
+ .command("snapshot")
140
+ .description(
141
+ "Take a restic snapshot of .harnery/ (excluding events.ndjson and " +
142
+ ".lock files by default). Pass --target to back up a different path.",
143
+ )
144
+ .option("--target <path>", "Path to snapshot (default: .harnery/ from cwd walk-up)")
145
+ .option("--tag <tag>", "Restic tag (repeatable)", collect, [] as string[])
146
+ .option("--repo <path>", "Repository path")
147
+ .option("--password-file <path>", "Password file")
148
+ .option(
149
+ "--include-events",
150
+ "Don't exclude events.ndjson (default: excluded; large + machine-local)",
151
+ )
152
+ .action((opts: BaseOpts & { target?: string; tag: string[]; includeEvents?: boolean }) => {
153
+ if (!checkRestic(emit)) {
154
+ emit.setExitCode(1);
155
+ return;
156
+ }
157
+ const target = opts.target ?? findHarneryDir();
158
+ if (!target) {
159
+ emit.error({
160
+ code: "target_missing",
161
+ message:
162
+ "No .harnery/ found above cwd; pass --target explicitly or run from a monorepo with .harnery/",
163
+ });
164
+ emit.setExitCode(1);
165
+ return;
166
+ }
167
+ const passThrough: string[] = [];
168
+ if (!opts.includeEvents) {
169
+ passThrough.push("--exclude", "events.ndjson");
170
+ passThrough.push("--exclude", ".lock");
171
+ passThrough.push("--exclude", ".log.lock");
172
+ }
173
+ for (const t of opts.tag) {
174
+ passThrough.push("--tag", t);
175
+ }
176
+ const r = runRestic(["backup", target], {
177
+ repo: opts.repo,
178
+ passwordFile: opts.passwordFile,
179
+ stdio: "inherit",
180
+ passThrough,
181
+ });
182
+ emit.setExitCode(r.exitCode);
183
+ });
184
+
185
+ // -- list --
186
+ backup
187
+ .command("list")
188
+ .description("List snapshots in the repo.")
189
+ .option("--repo <path>", "Repository path")
190
+ .option("--password-file <path>", "Password file")
191
+ .option("--json", "JSON output")
192
+ .action((opts: BaseOpts) => {
193
+ if (!checkRestic(emit)) {
194
+ emit.setExitCode(1);
195
+ return;
196
+ }
197
+ const args = ["snapshots"];
198
+ if (opts.json) args.push("--json");
199
+ const r = runRestic(args, {
200
+ repo: opts.repo,
201
+ passwordFile: opts.passwordFile,
202
+ stdio: opts.json ? "pipe" : "inherit",
203
+ });
204
+ if (opts.json && r.exitCode === 0) {
205
+ try {
206
+ emit.data(JSON.parse(r.stdout));
207
+ } catch {
208
+ emit.text(r.stdout);
209
+ }
210
+ }
211
+ emit.setExitCode(r.exitCode);
212
+ });
213
+
214
+ // -- restore --
215
+ backup
216
+ .command("restore <snapshotId>")
217
+ .description("Restore a snapshot to a target directory (default: ./restore-<timestamp>).")
218
+ .option("--target <path>", "Restore destination")
219
+ .option("--repo <path>", "Repository path")
220
+ .option("--password-file <path>", "Password file")
221
+ .action((snapshotId: string, opts: BaseOpts & { target?: string }) => {
222
+ if (!checkRestic(emit)) {
223
+ emit.setExitCode(1);
224
+ return;
225
+ }
226
+ const target = opts.target ?? path.join(process.cwd(), `restore-${Date.now()}`);
227
+ mkdirSync(target, { recursive: true });
228
+ const r = runRestic(["restore", snapshotId, "--target", target], {
229
+ repo: opts.repo,
230
+ passwordFile: opts.passwordFile,
231
+ stdio: "inherit",
232
+ });
233
+ if (r.exitCode === 0) {
234
+ emit.text(`restored to: ${target}`);
235
+ }
236
+ emit.setExitCode(r.exitCode);
237
+ });
238
+
239
+ // -- prune --
240
+ backup
241
+ .command("prune")
242
+ .description("Forget + prune snapshots (default policy: keep 7 daily / 4 weekly / 6 monthly).")
243
+ .option("--keep-daily <n>", "Daily snapshots to keep", "7")
244
+ .option("--keep-weekly <n>", "Weekly snapshots to keep", "4")
245
+ .option("--keep-monthly <n>", "Monthly snapshots to keep", "6")
246
+ .option("--dry-run", "Show what would be pruned without actually pruning")
247
+ .option("--repo <path>", "Repository path")
248
+ .option("--password-file <path>", "Password file")
249
+ .action(
250
+ (
251
+ opts: BaseOpts & {
252
+ keepDaily: string;
253
+ keepWeekly: string;
254
+ keepMonthly: string;
255
+ dryRun?: boolean;
256
+ },
257
+ ) => {
258
+ if (!checkRestic(emit)) {
259
+ emit.setExitCode(1);
260
+ return;
261
+ }
262
+ const args = [
263
+ "forget",
264
+ "--keep-daily",
265
+ opts.keepDaily,
266
+ "--keep-weekly",
267
+ opts.keepWeekly,
268
+ "--keep-monthly",
269
+ opts.keepMonthly,
270
+ ];
271
+ if (!opts.dryRun) args.push("--prune");
272
+ else args.push("--dry-run");
273
+ const r = runRestic(args, {
274
+ repo: opts.repo,
275
+ passwordFile: opts.passwordFile,
276
+ stdio: "inherit",
277
+ });
278
+ emit.setExitCode(r.exitCode);
279
+ },
280
+ );
281
+
282
+ // -- check --
283
+ backup
284
+ .command("check")
285
+ .description("restic check: verify repo integrity")
286
+ .option("--repo <path>", "Repository path")
287
+ .option("--password-file <path>", "Password file")
288
+ .action((opts: BaseOpts) => {
289
+ if (!checkRestic(emit)) {
290
+ emit.setExitCode(1);
291
+ return;
292
+ }
293
+ const r = runRestic(["check"], {
294
+ repo: opts.repo,
295
+ passwordFile: opts.passwordFile,
296
+ stdio: "inherit",
297
+ });
298
+ emit.setExitCode(r.exitCode);
299
+ });
300
+ }
301
+
302
+ function collect(value: string, acc: string[]): string[] {
303
+ acc.push(value);
304
+ return acc;
305
+ }
@@ -0,0 +1,198 @@
1
+ import { homedir } from "node:os";
2
+ import { resolve } from "node:path";
3
+ import type { Command } from "commander";
4
+ import type { EmitContext } from "../commander.ts";
5
+ import { AgentBrowser, type ExecResult } from "../lib/agent-browser/index.ts";
6
+ import { CookieJar } from "../lib/cookies/index.ts";
7
+
8
+ // Module-scoped emit assigned by registerBrowseAiCommand. Same pattern as
9
+ // cookies/read/browse: helper functions close over `emit` so action
10
+ // callbacks stay concise.
11
+ let emit: EmitContext;
12
+
13
+ /**
14
+ * `harn browse-ai <url>`: wraps Vercel Labs' agent-browser Rust CLI.
15
+ *
16
+ * Sister command to `harn browse` (which uses Playwright). Differences:
17
+ *
18
+ * - **Output shape.** `agent-browser` returns an accessibility-tree
19
+ * snapshot with element refs (`@e1`, `@e2`), purpose-built for LLM
20
+ * consumption. `harn browse` returns DOM/HTML/innerText.
21
+ * - **Process model.** `agent-browser` runs as a daemon: successive
22
+ * calls reuse the same Chrome instance until something explicitly
23
+ * closes it. `harn browse` opens + closes per call.
24
+ * - **Auth model.** `harn browse-ai` doesn't have a `--login` flow; use
25
+ * `harn browse --login` for one-time auth, then both tools share the
26
+ * same cookie jar.
27
+ *
28
+ * Mirrors the agent-side `browse` wrapper (sandbox side) so a script written for one
29
+ * works on the other modulo path differences.
30
+ */
31
+
32
+ const DEFAULT_STORE = resolve(homedir(), ".cache", "harnery", "cookies.json");
33
+
34
+ interface BrowseAiOpts {
35
+ snapshot?: boolean;
36
+ interactive?: boolean;
37
+ screenshot?: string;
38
+ fullPage?: boolean;
39
+ annotate?: string;
40
+ click?: string;
41
+ fill?: string;
42
+ press?: string;
43
+ waitFor?: string;
44
+ evaluate?: string;
45
+ batch?: string;
46
+ networkHar?: string;
47
+ store?: string;
48
+ cookies?: boolean;
49
+ json?: boolean;
50
+ timeout: string;
51
+ }
52
+
53
+ export function registerBrowseAiCommand(program: Command, emitParam: EmitContext): void {
54
+ emit = emitParam;
55
+ program
56
+ .command("browse-ai <url>")
57
+ .description(
58
+ "agent-browser (Vercel Labs) wrapper: accessibility-tree snapshots with element refs (@e1, @e2) for LLM consumption. " +
59
+ "Daemon-mode: successive calls reuse the same browser instance. Sister to harn browse (Playwright).",
60
+ )
61
+ .option("--snapshot", "Print accessibility tree (default action when no other output flag)")
62
+ .option("-i, --interactive", "Snapshot interactive elements only (with --snapshot)")
63
+ .option("--screenshot <path>", "Save a screenshot to the given path")
64
+ .option("--no-full-page", "Capture only the viewport (with --screenshot)")
65
+ .option(
66
+ "--annotate <path>",
67
+ "Save an annotated screenshot with numbered labels (vision-model friendly)",
68
+ )
69
+ .option("--click <ref>", "Click an element ref (@e5) or CSS selector after open")
70
+ .option(
71
+ "--fill <ref=>value>",
72
+ "Fill input: '@e3=>hello' (separator is `=>` so attribute selectors don't collide)",
73
+ )
74
+ .option("--press <key>", "Press a key after open/fill (Enter, Tab, etc.)")
75
+ .option("--wait-for <selector|ms>", "Wait for selector OR a number of ms before output")
76
+ .option("--evaluate <js>", "Run JS in the page context (escape-hatch for power users)")
77
+ .option(
78
+ "--batch <commands>",
79
+ "Run multiple agent-browser steps in one session, semicolon-separated. " +
80
+ 'E.g., --batch "click @e5; wait 1000; snapshot"',
81
+ )
82
+ .option("--network-har <path>", "Record a HAR file from open() through end of run")
83
+ .option("--no-cookies", "Skip cookie-jar attach and persist")
84
+ .option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
85
+ .option("--json", "Emit a JSON envelope (snapshot, screenshot path, step results)")
86
+ .option("--timeout <ms>", "Per-step timeout in ms", "60000")
87
+ .action((url: string, opts: BrowseAiOpts) => {
88
+ try {
89
+ runBrowseAi(url, opts);
90
+ } catch (err: unknown) {
91
+ const msg = err instanceof Error ? err.message : String(err);
92
+ emit.error({ code: "browse_ai_error", message: msg });
93
+ process.exit(1);
94
+ }
95
+ });
96
+ }
97
+
98
+ function runBrowseAi(url: string, opts: BrowseAiOpts): void {
99
+ const jar =
100
+ opts.cookies === false
101
+ ? null
102
+ : new CookieJar({ path: opts.store ?? DEFAULT_STORE, source: "bp-browse-ai" });
103
+ const ab = new AgentBrowser({
104
+ jar,
105
+ timeoutMs: Number.parseInt(opts.timeout, 10),
106
+ });
107
+
108
+ const stepLog: { step: string; ok: boolean; output: string }[] = [];
109
+
110
+ // 1. Open + optional HAR start.
111
+ if (opts.networkHar) ab.harStart(opts.networkHar);
112
+ ab.open(url);
113
+ stepLog.push({ step: `open ${url}`, ok: true, output: "" });
114
+
115
+ // 2. Pre-output actions, in the order they make sense for typical flows.
116
+ if (opts.fill) {
117
+ const sep = opts.fill.indexOf("=>");
118
+ if (sep < 0) {
119
+ throw new Error(
120
+ `--fill expects 'ref=>value' (got: ${opts.fill}). Separator is '=>' (not '=').`,
121
+ );
122
+ }
123
+ const ref = opts.fill.slice(0, sep);
124
+ const value = opts.fill.slice(sep + 2);
125
+ const r = ab.fill(ref, value);
126
+ stepLog.push({ step: `fill ${ref}`, ok: r.ok, output: r.stdout.trim() });
127
+ }
128
+ if (opts.click) {
129
+ const r = ab.click(opts.click);
130
+ stepLog.push({ step: `click ${opts.click}`, ok: r.ok, output: r.stdout.trim() });
131
+ }
132
+ if (opts.press) {
133
+ const r = ab.press(opts.press);
134
+ stepLog.push({ step: `press ${opts.press}`, ok: r.ok, output: r.stdout.trim() });
135
+ }
136
+ if (opts.waitFor) {
137
+ const r = ab.wait(opts.waitFor);
138
+ stepLog.push({ step: `wait ${opts.waitFor}`, ok: r.ok, output: r.stdout.trim() });
139
+ }
140
+ if (opts.batch) {
141
+ const steps = opts.batch
142
+ .split(";")
143
+ .map((s) => s.trim())
144
+ .filter(Boolean);
145
+ const results = ab.batch(steps);
146
+ steps.forEach((step, i) => {
147
+ const r = results[i] as ExecResult | undefined;
148
+ stepLog.push({ step, ok: r?.ok ?? false, output: r?.stdout.trim() ?? "" });
149
+ });
150
+ }
151
+ if (opts.evaluate) {
152
+ const out = ab.evaluate(opts.evaluate);
153
+ stepLog.push({ step: "eval", ok: true, output: out });
154
+ }
155
+
156
+ // 3. Output capture.
157
+ let snapshot: string | null = null;
158
+ if (opts.snapshot || (!opts.screenshot && !opts.annotate && !opts.evaluate)) {
159
+ snapshot = ab.snapshot({ interactive: opts.interactive });
160
+ }
161
+
162
+ if (opts.screenshot) {
163
+ ab.screenshot(opts.screenshot, { full: opts.fullPage !== false });
164
+ }
165
+ if (opts.annotate) {
166
+ ab.screenshot(opts.annotate, { annotate: true });
167
+ }
168
+
169
+ if (opts.networkHar) ab.harStop(opts.networkHar);
170
+
171
+ // 4. Cookie sync back to jar.
172
+ const cookieStats = ab.syncCookiesToJar();
173
+
174
+ // 5. Output.
175
+ if (opts.json) {
176
+ const envelope: Record<string, unknown> = {
177
+ url,
178
+ steps: stepLog,
179
+ cookiesSaved: cookieStats.saved,
180
+ };
181
+ if (snapshot !== null) envelope.snapshot = snapshot;
182
+ if (opts.screenshot) envelope.screenshot = opts.screenshot;
183
+ if (opts.annotate) envelope.annotated = opts.annotate;
184
+ if (opts.networkHar) envelope.har = opts.networkHar;
185
+ emit.data(envelope);
186
+ return;
187
+ }
188
+
189
+ if (snapshot !== null) emit.text(snapshot);
190
+ if (opts.screenshot) emit.log(`screenshot: ${opts.screenshot}`, "info");
191
+ if (opts.annotate) emit.log(`annotated: ${opts.annotate}`, "info");
192
+ if (cookieStats.saved > 0) {
193
+ emit.log(
194
+ `saved ${cookieStats.saved} cookie${cookieStats.saved === 1 ? "" : "s"} to ${jar?.path}`,
195
+ "info",
196
+ );
197
+ }
198
+ }