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,161 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { extname, resolve } from "node:path";
3
+ import type { Command } from "commander";
4
+ import yaml from "js-yaml";
5
+ import type { EmitContext } from "../commander.ts";
6
+
7
+ /**
8
+ * `config-get <file> <key>`: extract one value from a JSON or YAML config
9
+ * file by dotted-path. Avoids reading the whole file or shelling out to jq
10
+ * (which doesn't stream well through session-tee). Bracket notation supported
11
+ * for hyphenated keys and arrays: `compilerOptions.paths["@/*"][0]`.
12
+ */
13
+
14
+ interface ConfigGetOpts {
15
+ json?: boolean;
16
+ raw?: boolean;
17
+ }
18
+
19
+ interface ConfigGetResult {
20
+ file: string;
21
+ format: string;
22
+ key: string;
23
+ value: unknown;
24
+ type: string;
25
+ found: boolean;
26
+ }
27
+
28
+ export function registerConfigGetCommand(program: Command, emit: EmitContext): void {
29
+ program
30
+ .command("config-get <file> <key>")
31
+ .description(
32
+ "Extract a single value from a JSON/YAML config file by dotted-path. " +
33
+ "Bracket notation supported: `config-get tsconfig.json compilerOptions.paths`.",
34
+ )
35
+ .option("--json", "Structured JSON envelope {file, format, key, value, type, found}")
36
+ .option("--raw", "Print raw string value (no JSON encoding wrapper)")
37
+ .action(async (file: string, key: string, opts: ConfigGetOpts) => {
38
+ try {
39
+ const result = await runConfigGet(file, key);
40
+ if (opts.json) {
41
+ emit.config({ format: "json" });
42
+ emit.data(result);
43
+ return;
44
+ }
45
+ if (!result.found) {
46
+ emit.error({ code: "key_not_found", message: `key "${key}" not found in ${file}` });
47
+ process.exit(1);
48
+ }
49
+ emit.text(`${renderValue(result.value)}\n`);
50
+ } catch (err) {
51
+ emit.error({ code: "config_get_failed", message: (err as Error).message });
52
+ process.exit(1);
53
+ }
54
+ });
55
+ }
56
+
57
+ async function runConfigGet(file: string, key: string): Promise<ConfigGetResult> {
58
+ const absPath = resolve(file);
59
+ if (!existsSync(absPath)) throw new Error(`no such file: ${file}`);
60
+ const content = readFileSync(absPath, "utf8");
61
+ const ext = extname(absPath).toLowerCase();
62
+
63
+ let format: string;
64
+ let parsed: unknown;
65
+
66
+ if (ext === ".json") {
67
+ format = "json";
68
+ try {
69
+ parsed = JSON.parse(content);
70
+ } catch (err) {
71
+ throw new Error(`json parse failed: ${(err as Error).message}`);
72
+ }
73
+ } else if (ext === ".yaml" || ext === ".yml") {
74
+ format = "yaml";
75
+ try {
76
+ parsed = yaml.load(content);
77
+ } catch (err) {
78
+ throw new Error(`yaml parse failed: ${(err as Error).message}`);
79
+ }
80
+ } else {
81
+ throw new Error(
82
+ `unsupported file type: ${ext || "(no extension)"} (supported: .json, .yaml, .yml)`,
83
+ );
84
+ }
85
+
86
+ const parts = parseDottedPath(key);
87
+ let cur: unknown = parsed;
88
+ let found = true;
89
+
90
+ for (const p of parts) {
91
+ if (cur == null || typeof cur !== "object") {
92
+ found = false;
93
+ cur = undefined;
94
+ break;
95
+ }
96
+ const obj = cur as Record<string, unknown>;
97
+ if (!(p in obj)) {
98
+ found = false;
99
+ cur = undefined;
100
+ break;
101
+ }
102
+ cur = obj[p];
103
+ }
104
+
105
+ const type =
106
+ cur === null
107
+ ? "null"
108
+ : Array.isArray(cur)
109
+ ? "array"
110
+ : cur === undefined
111
+ ? "undefined"
112
+ : typeof cur;
113
+
114
+ return {
115
+ file,
116
+ format,
117
+ key,
118
+ value: cur,
119
+ type,
120
+ found,
121
+ };
122
+ }
123
+
124
+ function parseDottedPath(path: string): string[] {
125
+ const parts: string[] = [];
126
+ let i = 0;
127
+ while (i < path.length) {
128
+ if (path[i] === ".") {
129
+ i++;
130
+ continue;
131
+ }
132
+ if (path[i] === "[") {
133
+ const end = path.indexOf("]", i);
134
+ if (end < 0) throw new Error(`unmatched [ in key: ${path}`);
135
+ let inner = path.slice(i + 1, end);
136
+ if (
137
+ (inner.startsWith('"') && inner.endsWith('"')) ||
138
+ (inner.startsWith("'") && inner.endsWith("'"))
139
+ ) {
140
+ inner = inner.slice(1, -1);
141
+ }
142
+ parts.push(inner);
143
+ i = end + 1;
144
+ continue;
145
+ }
146
+ let end = i;
147
+ while (end < path.length && path[end] !== "." && path[end] !== "[") end++;
148
+ parts.push(path.slice(i, end));
149
+ i = end;
150
+ }
151
+ return parts;
152
+ }
153
+
154
+ function renderValue(value: unknown): string {
155
+ if (value === undefined) return "";
156
+ if (typeof value === "string") return value;
157
+ if (value === null || typeof value === "boolean" || typeof value === "number") {
158
+ return String(value);
159
+ }
160
+ return JSON.stringify(value, null, 2);
161
+ }
@@ -0,0 +1,209 @@
1
+ import type { Command } from "commander";
2
+ import type { EmitContext, HarneryProgramContext } from "../commander.ts";
3
+ import {
4
+ buildContext,
5
+ type ContextReport,
6
+ DEFAULT_SECTIONS,
7
+ OPT_IN_SECTIONS,
8
+ type SectionName,
9
+ } from "../lib/context/index.ts";
10
+
11
+ /**
12
+ * `harn context`: one-shot orientation snapshot.
13
+ *
14
+ * Aggregates self / time / repo / commits / submodules / peers (default) plus
15
+ * opt-in services. Useful at session start, post-compaction, or before
16
+ * dispatching subagents. Fail-open per section.
17
+ */
18
+ export function registerContextCommand(
19
+ program: Command,
20
+ emit: EmitContext,
21
+ context?: HarneryProgramContext,
22
+ ): void {
23
+ program
24
+ .command("context")
25
+ .description(
26
+ `One-shot orientation snapshot: self, repo, submodules, peers, recent commits. Default sections: ${DEFAULT_SECTIONS.join(" / ")}. Opt-in: ${OPT_IN_SECTIONS.join(" / ")}.`,
27
+ )
28
+ .option(
29
+ "--section <name>",
30
+ `Limit to specific sections (comma-list or repeated; valid: ${[...DEFAULT_SECTIONS, ...OPT_IN_SECTIONS].join(", ")})`,
31
+ collectSections,
32
+ [] as SectionName[],
33
+ )
34
+ .option(
35
+ "--include <name>",
36
+ "Add an opt-in section (e.g. services)",
37
+ collectSections,
38
+ [] as SectionName[],
39
+ )
40
+ .option("--show-clean", "Don't hide clean submodules")
41
+ .option("--json", "Structured JSON envelope")
42
+ .action(
43
+ async (opts: {
44
+ section: SectionName[];
45
+ include: SectionName[];
46
+ showClean?: boolean;
47
+ json?: boolean;
48
+ }) => {
49
+ try {
50
+ const sections = opts.section.length > 0 ? opts.section : DEFAULT_SECTIONS;
51
+ const report = await buildContext({
52
+ sections,
53
+ include: opts.include,
54
+ showClean: opts.showClean,
55
+ repoRoot: context?.repoRoot,
56
+ submodules: context?.submodules,
57
+ });
58
+ if (opts.json) {
59
+ emit.config({ format: "json" });
60
+ emit.data(report);
61
+ return;
62
+ }
63
+ emit.text(`${renderReport(report)}\n`);
64
+ } catch (err) {
65
+ const msg = err instanceof Error ? err.message : String(err);
66
+ emit.error({ code: "context_failed", message: msg });
67
+ process.exit(1);
68
+ }
69
+ },
70
+ );
71
+ }
72
+
73
+ function collectSections(value: string, prev: SectionName[]): SectionName[] {
74
+ const all: SectionName[] = [...DEFAULT_SECTIONS, ...OPT_IN_SECTIONS];
75
+ const out = [...prev];
76
+ for (const tok of value
77
+ .split(",")
78
+ .map((s) => s.trim())
79
+ .filter(Boolean)) {
80
+ if (!all.includes(tok as SectionName)) {
81
+ throw new Error(`unknown section "${tok}". Valid: ${all.join(", ")}`);
82
+ }
83
+ if (!out.includes(tok as SectionName)) out.push(tok as SectionName);
84
+ }
85
+ return out;
86
+ }
87
+
88
+ // ─── TTY rendering ─────────────────────────────────────────────────────────
89
+
90
+ function renderReport(r: ContextReport): string {
91
+ const lines: string[] = [];
92
+ if (r.self) lines.push(...renderSelf(r.self));
93
+ if (r.time) lines.push(...renderTime(r.time));
94
+ if (r.repo) lines.push(...renderRepo(r.repo));
95
+ if (r.commits) lines.push(...renderCommits(r.commits));
96
+ if (r.submodules) lines.push(...renderSubmodules(r.submodules));
97
+ if (r.peers) lines.push(...renderPeers(r.peers));
98
+ if (r.services) lines.push(...renderServices(r.services));
99
+ lines.push("");
100
+ lines.push(`(elapsed: ${r.meta.elapsed_ms}ms)`);
101
+ return lines.join("\n");
102
+ }
103
+
104
+ function section(header: string, body: string[]): string[] {
105
+ return ["", `── ${header} ──`, ...body];
106
+ }
107
+
108
+ function renderSelf(s: NonNullable<ContextReport["self"]>): string[] {
109
+ if ("error" in s) return section("self", [` (unavailable: ${s.error})`]);
110
+ const body: string[] = [];
111
+ body.push(
112
+ ` agent-${s.name ?? "?"} (${formatAge(s.session_age_secs)} old, owner=${s.instance_id.slice(0, 8)}…)`,
113
+ );
114
+ if (s.task) body.push(` task: "${s.task}"`);
115
+ if (s.last_tool) {
116
+ const target = s.last_tool_target ? ` ${truncate(s.last_tool_target, 80)}` : "";
117
+ body.push(` last: ${s.last_tool}${target}`);
118
+ }
119
+ if (s.files_held.length > 0) {
120
+ body.push(` holds ${s.files_held.length} file(s):`);
121
+ for (const f of s.files_held.slice(0, 5)) body.push(` ${f}`);
122
+ if (s.files_held.length > 5) body.push(` +${s.files_held.length - 5} more`);
123
+ } else {
124
+ body.push(" files: none held");
125
+ }
126
+ return section("self", body);
127
+ }
128
+
129
+ function renderTime(t: NonNullable<ContextReport["time"]>): string[] {
130
+ return section("time", [` ${t.chicago} (UTC: ${t.utc})`]);
131
+ }
132
+
133
+ function renderRepo(r: NonNullable<ContextReport["repo"]>): string[] {
134
+ if ("error" in r) return section("repo", [` (unavailable: ${r.error})`]);
135
+ const parts: string[] = [];
136
+ const aheadBehind =
137
+ r.ahead > 0 || r.behind > 0 ? ` (ahead ${r.ahead}, behind ${r.behind} vs origin)` : "";
138
+ parts.push(` cwd: ${r.cwd}`);
139
+ parts.push(` branch: ${r.branch}${aheadBehind}`);
140
+ const dirtyBits: string[] = [];
141
+ if (r.staged) dirtyBits.push(`${r.staged} staged`);
142
+ if (r.modified) dirtyBits.push(`${r.modified} modified`);
143
+ if (r.untracked) dirtyBits.push(`${r.untracked} untracked`);
144
+ parts.push(` status: ${dirtyBits.length ? dirtyBits.join(", ") : "clean"}`);
145
+ return section("repo", parts);
146
+ }
147
+
148
+ function renderCommits(c: NonNullable<ContextReport["commits"]>): string[] {
149
+ if ("error" in c) return section("commits", [` (unavailable: ${c.error})`]);
150
+ if (c.rows.length === 0) return section("commits", [" (none)"]);
151
+ return section(
152
+ "commits (last 3)",
153
+ c.rows.map((row) => ` ${row.sha} ${truncate(row.subject, 80)}`),
154
+ );
155
+ }
156
+
157
+ function renderSubmodules(s: NonNullable<ContextReport["submodules"]>): string[] {
158
+ if ("error" in s) return section("submodules", [` (unavailable: ${s.error})`]);
159
+ if (s.rows.length === 0) {
160
+ const tail = s.clean_omitted > 0 ? ` (${s.clean_omitted} clean omitted)` : "";
161
+ return section("submodules", [` all clean${tail}`]);
162
+ }
163
+ const lines = s.rows.map((sm) => {
164
+ const aheadBehind = sm.ahead > 0 || sm.behind > 0 ? ` ±${sm.ahead}/${sm.behind}` : "";
165
+ const dirty = sm.dirty ? ` (${sm.modifiedFiles}m+${sm.untrackedFiles}u)` : "";
166
+ return ` ${sm.name.padEnd(28)} ${sm.branch}${aheadBehind}${dirty}`;
167
+ });
168
+ const tail = s.clean_omitted > 0 ? [` (+${s.clean_omitted} clean omitted)`] : [];
169
+ return section("submodules", [...lines, ...tail]);
170
+ }
171
+
172
+ function renderPeers(p: NonNullable<ContextReport["peers"]>): string[] {
173
+ if ("error" in p) return section("peers", [` (unavailable: ${p.error})`]);
174
+ if (p.rows.length === 0) return section("peers", [" (none active)"]);
175
+ const lines = p.rows.map((peer) => {
176
+ const taskBit = peer.task ? ` "${truncate(peer.task, 40)}"` : "";
177
+ const filesBit = peer.files > 0 ? `${peer.files}f` : "0f";
178
+ const lastBit = peer.last_tool ? `, last: ${peer.last_tool}` : "";
179
+ return ` agent-${peer.name.padEnd(12)}${taskBit} (${peer.age_min}m old, ${filesBit}${lastBit})`;
180
+ });
181
+ return section("peers", lines);
182
+ }
183
+
184
+ function renderServices(s: NonNullable<ContextReport["services"]>): string[] {
185
+ if ("error" in s) return section("services", [` (unavailable: ${s.error})`]);
186
+ if (s.docker_compose.length === 0) return section("services", [" (no compose project running)"]);
187
+ const lines = s.docker_compose.map((sv) => ` ${sv.service.padEnd(20)} ${sv.status}`);
188
+ return section("services (docker compose)", lines);
189
+ }
190
+
191
+ // ─── Format helpers ────────────────────────────────────────────────────────
192
+
193
+ function formatAge(secs: number): string {
194
+ if (secs < 60) return `${secs}s`;
195
+ if (secs < 3600) return `${Math.floor(secs / 60)}m`;
196
+ if (secs < 86400) {
197
+ const h = Math.floor(secs / 3600);
198
+ const m = Math.floor((secs % 3600) / 60);
199
+ return `${h}h ${m}m`;
200
+ }
201
+ const d = Math.floor(secs / 86400);
202
+ const h = Math.floor((secs % 86400) / 3600);
203
+ return `${d}d ${h}h`;
204
+ }
205
+
206
+ function truncate(s: string, n: number): string {
207
+ if (s.length <= n) return s;
208
+ return `${s.slice(0, n - 1)}…`;
209
+ }
@@ -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 { type Cookie, CookieJar } from "../lib/cookies/index.ts";
6
+
7
+ /**
8
+ * `cookies`: manage the local browser cookie store.
9
+ *
10
+ * Default store path: `~/.cache/harnery/cookies.json`. Override with
11
+ * `--store <path>` if you need a separate jar (e.g., one per environment).
12
+ * Format is CDP-native (compatible with Playwright/agent-browser).
13
+ */
14
+
15
+ const DEFAULT_STORE = resolve(homedir(), ".cache", "harnery", "cookies.json");
16
+
17
+ interface CommonOpts {
18
+ store?: string;
19
+ json?: boolean;
20
+ }
21
+
22
+ function jarFrom(opts: CommonOpts): CookieJar {
23
+ return new CookieJar({
24
+ path: opts.store ?? DEFAULT_STORE,
25
+ source: "bp-cookies",
26
+ });
27
+ }
28
+
29
+ // Module-scoped emit assigned by registerCookiesCommand; the module-level
30
+ // helpers below close over this so the Commander .action callbacks stay
31
+ // concise. Safe because the command tree is registered once at startup.
32
+ let emit: EmitContext;
33
+
34
+ export function registerCookiesCommand(program: Command, emitParam: EmitContext): void {
35
+ emit = emitParam;
36
+ const cmd = program
37
+ .command("cookies")
38
+ .description(
39
+ `Manage the shared browser cookie store (default: ${DEFAULT_STORE}). Format is CDP-native (compatible with Playwright/agent-browser).`,
40
+ )
41
+ .option("--store <path>", "Override store path");
42
+
43
+ cmd.action((opts: CommonOpts) => safe(() => runList(jarFrom(opts), {})));
44
+
45
+ cmd
46
+ .command("list")
47
+ .description("List cookies in the store, grouped by domain")
48
+ .option("--domain <domain>", "Filter by domain")
49
+ .option("--json", "Output as JSON")
50
+ .action((opts: CommonOpts & { domain?: string }) =>
51
+ safe(() => runList(jarFrom({ ...cmd.opts(), ...opts }), opts)),
52
+ );
53
+
54
+ cmd
55
+ .command("set <name> <value>")
56
+ .description("Set a cookie in the store (creates the file if missing)")
57
+ .requiredOption("--domain <domain>", "Cookie domain (e.g., .example.com)")
58
+ .option("--path <path>", "Cookie path", "/")
59
+ .option("--secure", "HTTPS only")
60
+ .option("--httpOnly", "Prevent JavaScript access")
61
+ .option("--sameSite <policy>", "SameSite policy: Strict | Lax | None")
62
+ .option("--expires <unix-seconds>", "Unix timestamp; omit for session cookie")
63
+ .action(
64
+ (
65
+ name: string,
66
+ value: string,
67
+ opts: CommonOpts & {
68
+ domain: string;
69
+ path: string;
70
+ secure?: boolean;
71
+ httpOnly?: boolean;
72
+ sameSite?: string;
73
+ expires?: string;
74
+ },
75
+ ) => safe(() => runSet(jarFrom({ ...cmd.opts(), ...opts }), name, value, opts)),
76
+ );
77
+
78
+ cmd
79
+ .command("clear")
80
+ .description("Remove cookies from the store")
81
+ .option("--domain <domain>", "Drop cookies matching a single domain")
82
+ .option("--all", "Wipe everything (cookies + origins)")
83
+ .action((opts: CommonOpts & { domain?: string; all?: boolean }) =>
84
+ safe(() => runClear(jarFrom({ ...cmd.opts(), ...opts }), opts)),
85
+ );
86
+
87
+ cmd
88
+ .command("header <url>")
89
+ .description("Print a Cookie: header value for the given URL (empty if no match)")
90
+ .action((url: string, opts: CommonOpts) =>
91
+ safe(() => {
92
+ const jar = jarFrom({ ...cmd.opts(), ...opts });
93
+ const out = jar.header(url);
94
+ if (out) emit.text(`${out}\n`);
95
+ }),
96
+ );
97
+
98
+ cmd
99
+ .command("import <file>")
100
+ .description("Merge cookies from a JSON file (CDP/agent-browser shape)")
101
+ .option("--replace", "Replace the entire store instead of merging")
102
+ .action((file: string, opts: CommonOpts & { replace?: boolean }) =>
103
+ safe(() => {
104
+ const jar = jarFrom({ ...cmd.opts(), ...opts });
105
+ const { count } = jar.import(file, opts);
106
+ emit.data({ ok: true, action: "import", count, file });
107
+ }),
108
+ );
109
+
110
+ cmd
111
+ .command("export <file>")
112
+ .description("Write the store to a file (for sharing with another tool)")
113
+ .action((file: string, opts: CommonOpts) =>
114
+ safe(() => {
115
+ const jar = jarFrom({ ...cmd.opts(), ...opts });
116
+ const { count } = jar.export(file);
117
+ emit.file(file, { cookies: count });
118
+ }),
119
+ );
120
+
121
+ cmd
122
+ .command("info")
123
+ .description("Show store path, size, cookie counts, and exporting tool")
124
+ .option("--json", "Output as JSON")
125
+ .action((opts: CommonOpts) => safe(() => runInfo(jarFrom({ ...cmd.opts(), ...opts }), opts)));
126
+ }
127
+
128
+ // ---------------------------------------------------------------------------
129
+ // Subcommand handlers
130
+ // ---------------------------------------------------------------------------
131
+
132
+ function runList(jar: CookieJar, opts: { domain?: string; json?: boolean }): void {
133
+ if (opts.json) emit.config({ format: "json" });
134
+ const cookies = jar.list({ domain: opts.domain });
135
+ emit.rows(cookies as unknown as Record<string, unknown>[]);
136
+ }
137
+
138
+ function runSet(
139
+ jar: CookieJar,
140
+ name: string,
141
+ value: string,
142
+ opts: {
143
+ domain: string;
144
+ path: string;
145
+ secure?: boolean;
146
+ httpOnly?: boolean;
147
+ sameSite?: string;
148
+ expires?: string;
149
+ },
150
+ ): void {
151
+ const cookie: Cookie = {
152
+ name,
153
+ value,
154
+ domain: opts.domain,
155
+ path: opts.path,
156
+ expires: opts.expires ? Number.parseFloat(opts.expires) : -1,
157
+ httpOnly: opts.httpOnly ?? false,
158
+ secure: opts.secure ?? false,
159
+ session: !opts.expires,
160
+ size: name.length + value.length,
161
+ };
162
+ if (opts.sameSite) cookie.sameSite = opts.sameSite;
163
+ jar.set(cookie);
164
+ emit.data({ ok: true, action: "set", name, domain: opts.domain });
165
+ }
166
+
167
+ function runClear(jar: CookieJar, opts: { domain?: string; all?: boolean }): void {
168
+ if (!opts.domain && !opts.all) {
169
+ throw new Error("Specify --domain <domain> or --all");
170
+ }
171
+ const { before, after } = jar.clear(opts);
172
+ const removed = before - after;
173
+ emit.data({
174
+ ok: true,
175
+ action: "clear",
176
+ removed,
177
+ before,
178
+ after,
179
+ domain: opts.domain ?? null,
180
+ all: opts.all ?? false,
181
+ });
182
+ }
183
+
184
+ function runInfo(jar: CookieJar, opts: { json?: boolean }): void {
185
+ if (opts.json) emit.config({ format: "json" });
186
+ const i = jar.info();
187
+ emit.data(i);
188
+ }
189
+
190
+ function safe(fn: () => void): void {
191
+ try {
192
+ fn();
193
+ } catch (err: unknown) {
194
+ const msg = err instanceof Error ? err.message : String(err);
195
+ emit.error({ code: "cookies_error", message: msg });
196
+ process.exit(1);
197
+ }
198
+ }