harnery 0.40.0 → 0.42.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 (595) hide show
  1. package/README.md +1 -1
  2. package/dist/commander.js +4 -0
  3. package/dist/commands/agents.d.ts.map +1 -1
  4. package/dist/commands/agents.js +34 -20
  5. package/dist/commands/artifacts.d.ts.map +1 -1
  6. package/dist/commands/artifacts.js +113 -12
  7. package/dist/commands/browse-ai.d.ts.map +1 -1
  8. package/dist/commands/browse-ai.js +4 -0
  9. package/dist/commands/browse.d.ts +164 -0
  10. package/dist/commands/browse.d.ts.map +1 -1
  11. package/dist/commands/browse.js +388 -45
  12. package/dist/commands/checkpoint.js +8 -12
  13. package/dist/commands/claude-desktop.d.ts.map +1 -1
  14. package/dist/commands/claude-desktop.js +52 -0
  15. package/dist/commands/deinit.d.ts +1 -1
  16. package/dist/commands/deinit.d.ts.map +1 -1
  17. package/dist/commands/deinit.js +8 -4
  18. package/dist/commands/disk.d.ts +6 -0
  19. package/dist/commands/disk.d.ts.map +1 -0
  20. package/dist/commands/disk.js +80 -0
  21. package/dist/commands/docs.d.ts.map +1 -1
  22. package/dist/commands/docs.js +2 -0
  23. package/dist/commands/doctor.d.ts +8 -0
  24. package/dist/commands/doctor.d.ts.map +1 -1
  25. package/dist/commands/doctor.js +58 -3
  26. package/dist/commands/fetch.d.ts.map +1 -1
  27. package/dist/commands/fetch.js +10 -0
  28. package/dist/commands/files.d.ts +16 -0
  29. package/dist/commands/files.d.ts.map +1 -1
  30. package/dist/commands/files.js +54 -2
  31. package/dist/commands/init.d.ts +21 -5
  32. package/dist/commands/init.d.ts.map +1 -1
  33. package/dist/commands/init.js +271 -109
  34. package/dist/commands/instructions.js +5 -4
  35. package/dist/commands/ledger-v3.d.ts.map +1 -1
  36. package/dist/commands/ledger-v3.js +2 -1
  37. package/dist/commands/rm.d.ts +4 -0
  38. package/dist/commands/rm.d.ts.map +1 -0
  39. package/dist/commands/rm.js +87 -0
  40. package/dist/commands/servers.d.ts +7 -0
  41. package/dist/commands/servers.d.ts.map +1 -0
  42. package/dist/commands/servers.js +394 -0
  43. package/dist/commands/tunnel.d.ts.map +1 -1
  44. package/dist/commands/tunnel.js +82 -2
  45. package/dist/commands/webview.d.ts +4 -0
  46. package/dist/commands/webview.d.ts.map +1 -0
  47. package/dist/commands/webview.js +94 -0
  48. package/dist/core/adapter.d.ts +50 -1
  49. package/dist/core/adapter.d.ts.map +1 -1
  50. package/dist/core/adapter.js +59 -1
  51. package/dist/core/adapters/attestation.d.ts.map +1 -1
  52. package/dist/core/adapters/attestation.js +3 -2
  53. package/dist/core/adapters/profiles.d.ts +29 -3
  54. package/dist/core/adapters/profiles.d.ts.map +1 -1
  55. package/dist/core/adapters/profiles.js +53 -1
  56. package/dist/core/adapters/registry.d.ts.map +1 -1
  57. package/dist/core/adapters/registry.js +33 -0
  58. package/dist/core/adapters/types.d.ts +9 -0
  59. package/dist/core/adapters/types.d.ts.map +1 -1
  60. package/dist/core/agents/canonical-emit.d.ts +1 -1
  61. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  62. package/dist/core/agents/canonical-emit.js +2 -7
  63. package/dist/core/agents/cli.js +25 -16
  64. package/dist/core/agents/coord-client.d.ts.map +1 -1
  65. package/dist/core/agents/coord-client.js +7 -2
  66. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  67. package/dist/core/agents/render/session-context.js +2 -0
  68. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  69. package/dist/core/agents/rules/claim-conflict.js +3 -9
  70. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  71. package/dist/core/agents/rules/commit-conflict.js +2 -8
  72. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  73. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  74. package/dist/core/agents/rules/stop-hook.js +1 -1
  75. package/dist/core/agents/session-events.d.ts +6 -2
  76. package/dist/core/agents/session-events.d.ts.map +1 -1
  77. package/dist/core/agents/session-events.js +105 -26
  78. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
  79. package/dist/core/agents/session-finalization-state-v3.js +2 -1
  80. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  81. package/dist/core/agents/session-finalizer-v3.js +5 -4
  82. package/dist/core/agents/session-name-display.d.ts +28 -0
  83. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  84. package/dist/core/agents/session-name-display.js +43 -0
  85. package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
  86. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
  87. package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
  88. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  89. package/dist/core/agents/state/heartbeat-writer.js +21 -2
  90. package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
  91. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  92. package/dist/core/agents/state/live-coordination-view.js +61 -0
  93. package/dist/core/agents/state/live-coordination-writer.js +3 -0
  94. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  95. package/dist/core/agents/state/stale-sweep.js +2 -10
  96. package/dist/core/agents/turn-changes.d.ts +17 -0
  97. package/dist/core/agents/turn-changes.d.ts.map +1 -0
  98. package/dist/core/agents/turn-changes.js +76 -0
  99. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  100. package/dist/core/artifacts/delivery-card.js +11 -3
  101. package/dist/core/artifacts/index.d.ts +140 -4
  102. package/dist/core/artifacts/index.d.ts.map +1 -1
  103. package/dist/core/artifacts/index.js +526 -52
  104. package/dist/core/config.d.ts +73 -11
  105. package/dist/core/config.d.ts.map +1 -1
  106. package/dist/core/config.js +142 -3
  107. package/dist/core/context/index.d.ts.map +1 -1
  108. package/dist/core/context/index.js +2 -1
  109. package/dist/core/conversations/archive.d.ts.map +1 -1
  110. package/dist/core/conversations/archive.js +4 -3
  111. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  112. package/dist/core/diagnostics/bundle.js +5 -4
  113. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
  114. package/dist/core/events/legacy-storage/canary.js +5 -4
  115. package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
  116. package/dist/core/events/legacy-storage/compression.js +2 -1
  117. package/dist/core/events/v3/adapter-id.d.ts +10 -2
  118. package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
  119. package/dist/core/events/v3/adapter-id.js +16 -0
  120. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  121. package/dist/core/events/v3/authority-outbox.js +2 -1
  122. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  123. package/dist/core/events/v3/bootstrap.js +5 -4
  124. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  125. package/dist/core/events/v3/capabilities.js +17 -0
  126. package/dist/core/events/v3/contract.d.ts +5 -0
  127. package/dist/core/events/v3/contract.d.ts.map +1 -1
  128. package/dist/core/events/v3/contract.js +7 -1
  129. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  130. package/dist/core/events/v3/control-witness.js +3 -2
  131. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
  132. package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
  133. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
  134. package/dist/core/events/v3/fingerprint-keys.js +7 -6
  135. package/dist/core/events/v3/generated.d.ts +1 -1
  136. package/dist/core/events/v3/generated.js +1 -1
  137. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  138. package/dist/core/events/v3/live-feed.js +5 -4
  139. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  140. package/dist/core/events/v3/producers/command-recorder.js +8 -7
  141. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  142. package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
  143. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
  144. package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
  145. package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
  146. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  147. package/dist/core/events/v3/producers/hook-base.js +10 -4
  148. package/dist/core/events/v3/producers/hook.d.ts +2 -0
  149. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  150. package/dist/core/events/v3/producers/hook.js +16 -1
  151. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  152. package/dist/core/events/v3/producers/intake.js +16 -6
  153. package/dist/core/events/v3/producers/recorder.d.ts +2 -4
  154. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  155. package/dist/core/events/v3/producers/recorder.js +125 -101
  156. package/dist/core/events/v3/projection.js +9 -1
  157. package/dist/core/events/v3/recovery.d.ts.map +1 -1
  158. package/dist/core/events/v3/recovery.js +4 -3
  159. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
  160. package/dist/core/events/v3/support-storage/inventory.js +2 -1
  161. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
  162. package/dist/core/events/v3/support-storage/maintenance.js +4 -3
  163. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
  164. package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
  165. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
  166. package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
  167. package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
  168. package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
  169. package/dist/core/events/v3/tool-line-changes.js +135 -0
  170. package/dist/core/events/v3/writer.d.ts.map +1 -1
  171. package/dist/core/events/v3/writer.js +8 -7
  172. package/dist/core/governor/planning.d.ts.map +1 -1
  173. package/dist/core/governor/planning.js +6 -5
  174. package/dist/core/governor/service.d.ts.map +1 -1
  175. package/dist/core/governor/service.js +12 -11
  176. package/dist/core/governor/state.d.ts.map +1 -1
  177. package/dist/core/governor/state.js +7 -6
  178. package/dist/core/guard/evaluator.js +1 -0
  179. package/dist/core/guard/storage.d.ts.map +1 -1
  180. package/dist/core/guard/storage.js +3 -2
  181. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
  182. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
  183. package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
  184. package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
  185. package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
  186. package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
  187. package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
  188. package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
  189. package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
  190. package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
  191. package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
  192. package/dist/core/hooks/adapter/behaviors/index.js +20 -0
  193. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
  194. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
  195. package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
  196. package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
  197. package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
  198. package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
  199. package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
  200. package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
  201. package/dist/core/hooks/adapter/behaviors/types.js +1 -0
  202. package/dist/core/hooks/adapter/detect.d.ts +1 -1
  203. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  204. package/dist/core/hooks/adapter/detect.js +2 -3
  205. package/dist/core/hooks/adapter/events.d.ts +46 -1
  206. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  207. package/dist/core/hooks/adapter/events.js +36 -0
  208. package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
  209. package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
  210. package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
  211. package/dist/core/hooks/adapter/output.d.ts +7 -0
  212. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  213. package/dist/core/hooks/adapter/output.js +8 -1
  214. package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
  215. package/dist/core/hooks/adapter/wiring.d.ts +52 -8
  216. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  217. package/dist/core/hooks/adapter/wiring.js +133 -12
  218. package/dist/core/hooks/cli.js +676 -531
  219. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  220. package/dist/core/hooks/effects/image-capture.js +2 -1
  221. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
  222. package/dist/core/hooks/prompt-context/contract.js +1 -0
  223. package/dist/core/hooks/resolve/transcript.d.ts +1 -1
  224. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  225. package/dist/core/hooks/resolve/transcript.js +35 -4
  226. package/dist/core/hooks/run-markers.d.ts +37 -0
  227. package/dist/core/hooks/run-markers.d.ts.map +1 -0
  228. package/dist/core/hooks/run-markers.js +109 -0
  229. package/dist/core/hooks/session-name-presence.d.ts +3 -1
  230. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  231. package/dist/core/hooks/session-name-presence.js +7 -2
  232. package/dist/core/hooks/shell-waiter.d.ts +2 -0
  233. package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
  234. package/dist/core/hooks/shell-waiter.js +173 -0
  235. package/dist/core/resources/service.d.ts.map +1 -1
  236. package/dist/core/resources/service.js +5 -4
  237. package/dist/core/semantic/review.d.ts.map +1 -1
  238. package/dist/core/semantic/review.js +5 -4
  239. package/dist/core/semantic/service.d.ts.map +1 -1
  240. package/dist/core/semantic/service.js +15 -14
  241. package/dist/core/semantic/storage.d.ts.map +1 -1
  242. package/dist/core/semantic/storage.js +5 -4
  243. package/dist/core/servers/index.d.ts +211 -0
  244. package/dist/core/servers/index.d.ts.map +1 -0
  245. package/dist/core/servers/index.js +560 -0
  246. package/dist/core/servers/net.d.ts +58 -0
  247. package/dist/core/servers/net.d.ts.map +1 -0
  248. package/dist/core/servers/net.js +270 -0
  249. package/dist/core/servers/tunnels.d.ts +14 -0
  250. package/dist/core/servers/tunnels.d.ts.map +1 -0
  251. package/dist/core/servers/tunnels.js +33 -0
  252. package/dist/core/storage/atomic-json.d.ts.map +1 -1
  253. package/dist/core/storage/atomic-json.js +7 -3
  254. package/dist/core/storage/builtins.js +1 -0
  255. package/dist/core/storage/durable-history.d.ts.map +1 -1
  256. package/dist/core/storage/durable-history.js +6 -5
  257. package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
  258. package/dist/core/storage/maintenance-providers.js +2 -1
  259. package/dist/core/storage/maintenance.d.ts.map +1 -1
  260. package/dist/core/storage/maintenance.js +7 -6
  261. package/dist/core/storage/metrics.d.ts.map +1 -1
  262. package/dist/core/storage/metrics.js +5 -1
  263. package/dist/core/storage/modes.d.ts +17 -0
  264. package/dist/core/storage/modes.d.ts.map +1 -0
  265. package/dist/core/storage/modes.js +47 -0
  266. package/dist/core/storage/process-log.d.ts.map +1 -1
  267. package/dist/core/storage/process-log.js +3 -2
  268. package/dist/core/storage/receipts.d.ts.map +1 -1
  269. package/dist/core/storage/receipts.js +4 -3
  270. package/dist/core/storage/segments.d.ts.map +1 -1
  271. package/dist/core/storage/segments.js +7 -6
  272. package/dist/core/supervisor/hook-health.d.ts +2 -1
  273. package/dist/core/supervisor/hook-health.d.ts.map +1 -1
  274. package/dist/core/supervisor/hook-health.js +4 -3
  275. package/dist/core/supervisor/service.d.ts.map +1 -1
  276. package/dist/core/supervisor/service.js +7 -6
  277. package/dist/core/work/state.d.ts.map +1 -1
  278. package/dist/core/work/state.js +8 -7
  279. package/dist/core/workflow/adapters.d.ts +7 -0
  280. package/dist/core/workflow/adapters.d.ts.map +1 -1
  281. package/dist/core/workflow/adapters.js +9 -0
  282. package/dist/core/workflow/approvals.d.ts.map +1 -1
  283. package/dist/core/workflow/approvals.js +6 -5
  284. package/dist/core/workflow/billing.d.ts.map +1 -1
  285. package/dist/core/workflow/billing.js +33 -4
  286. package/dist/core/workflow/durable-record.d.ts.map +1 -1
  287. package/dist/core/workflow/durable-record.js +4 -3
  288. package/dist/core/workflow/engine.d.ts.map +1 -1
  289. package/dist/core/workflow/engine.js +30 -1
  290. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  291. package/dist/core/workflow/live-session-v3.js +2 -3
  292. package/dist/core/workflow/run-state.d.ts.map +1 -1
  293. package/dist/core/workflow/run-state.js +3 -2
  294. package/dist/core/workflow/sandbox-projection.d.ts +13 -2
  295. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  296. package/dist/core/workflow/sandbox-projection.js +23 -0
  297. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  298. package/dist/core/workflow/spawn-claude.js +6 -1
  299. package/dist/core/workflow/spawn-codex.d.ts +2 -0
  300. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  301. package/dist/core/workflow/spawn-codex.js +20 -1
  302. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  303. package/dist/core/workflow/spawn-cursor.js +6 -1
  304. package/dist/core/workflow/spawn-opencode.d.ts +36 -0
  305. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
  306. package/dist/core/workflow/spawn-opencode.js +135 -0
  307. package/dist/core/workflow/transcript.d.ts.map +1 -1
  308. package/dist/core/workflow/transcript.js +3 -2
  309. package/dist/core/workflow/types.d.ts +47 -2
  310. package/dist/core/workflow/types.d.ts.map +1 -1
  311. package/dist/core/workflow/worker-access.d.ts +92 -0
  312. package/dist/core/workflow/worker-access.d.ts.map +1 -0
  313. package/dist/core/workflow/worker-access.js +450 -0
  314. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  315. package/dist/core/workflow/workspaces/leases.js +5 -4
  316. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  317. package/dist/core/workflow/workspaces/local-git.js +3 -2
  318. package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
  319. package/dist/core/workflow/workspaces/paths.js +2 -1
  320. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  321. package/dist/core/workflow/workspaces/state.js +10 -9
  322. package/dist/lazy-commands.js +8 -1
  323. package/dist/lib/agent-browser/client.d.ts +9 -0
  324. package/dist/lib/agent-browser/client.d.ts.map +1 -1
  325. package/dist/lib/agent-browser/client.js +13 -0
  326. package/dist/lib/browser/batch-steps.d.ts +18 -0
  327. package/dist/lib/browser/batch-steps.d.ts.map +1 -0
  328. package/dist/lib/browser/batch-steps.js +82 -0
  329. package/dist/lib/browser/client.d.ts +35 -1
  330. package/dist/lib/browser/client.d.ts.map +1 -1
  331. package/dist/lib/browser/client.js +117 -8
  332. package/dist/lib/browser/collect/collector.d.ts +99 -0
  333. package/dist/lib/browser/collect/collector.d.ts.map +1 -0
  334. package/dist/lib/browser/collect/collector.js +202 -0
  335. package/dist/lib/browser/collect/fields.d.ts +31 -0
  336. package/dist/lib/browser/collect/fields.d.ts.map +1 -0
  337. package/dist/lib/browser/collect/fields.js +75 -0
  338. package/dist/lib/browser/collect/index.d.ts +6 -0
  339. package/dist/lib/browser/collect/index.d.ts.map +1 -0
  340. package/dist/lib/browser/collect/index.js +5 -0
  341. package/dist/lib/browser/collect/page-driver.d.ts +14 -0
  342. package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
  343. package/dist/lib/browser/collect/page-driver.js +306 -0
  344. package/dist/lib/browser/collect/presets.d.ts +52 -0
  345. package/dist/lib/browser/collect/presets.d.ts.map +1 -0
  346. package/dist/lib/browser/collect/presets.js +176 -0
  347. package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
  348. package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
  349. package/dist/lib/browser/collect/scroll-plan.js +118 -0
  350. package/dist/lib/browser/identity.d.ts +25 -0
  351. package/dist/lib/browser/identity.d.ts.map +1 -0
  352. package/dist/lib/browser/identity.js +66 -0
  353. package/dist/lib/browser/index.d.ts +3 -2
  354. package/dist/lib/browser/index.d.ts.map +1 -1
  355. package/dist/lib/browser/index.js +2 -1
  356. package/dist/lib/browser/launch-args.d.ts +26 -0
  357. package/dist/lib/browser/launch-args.d.ts.map +1 -1
  358. package/dist/lib/browser/launch-args.js +41 -1
  359. package/dist/lib/browser/page-review-judge.d.ts +2 -0
  360. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  361. package/dist/lib/browser/page-review-judge.js +13 -0
  362. package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
  363. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  364. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  365. package/dist/lib/browser/qa-run.js +1 -0
  366. package/dist/lib/browser/user-agent.d.ts +53 -0
  367. package/dist/lib/browser/user-agent.d.ts.map +1 -0
  368. package/dist/lib/browser/user-agent.js +79 -0
  369. package/dist/lib/browser/windows-chrome.d.ts +59 -0
  370. package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
  371. package/dist/lib/browser/windows-chrome.js +179 -0
  372. package/dist/lib/claude-desktop-share.d.ts +136 -0
  373. package/dist/lib/claude-desktop-share.d.ts.map +1 -0
  374. package/dist/lib/claude-desktop-share.js +394 -0
  375. package/dist/lib/disk-usage.d.ts +50 -0
  376. package/dist/lib/disk-usage.d.ts.map +1 -0
  377. package/dist/lib/disk-usage.js +303 -0
  378. package/dist/lib/docs-lint.d.ts +6 -0
  379. package/dist/lib/docs-lint.d.ts.map +1 -1
  380. package/dist/lib/docs-lint.js +8 -3
  381. package/dist/lib/docs-metadata-managed.d.ts +1 -0
  382. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  383. package/dist/lib/docs-metadata-managed.js +17 -1
  384. package/dist/lib/guarded-remove.d.ts +34 -0
  385. package/dist/lib/guarded-remove.d.ts.map +1 -0
  386. package/dist/lib/guarded-remove.js +310 -0
  387. package/dist/lib/identities/assume.d.ts.map +1 -1
  388. package/dist/lib/identities/assume.js +4 -9
  389. package/dist/lib/instructions/apply.d.ts.map +1 -1
  390. package/dist/lib/instructions/apply.js +2 -0
  391. package/dist/lib/instructions/templates.js +8 -8
  392. package/dist/lib/pace/index.d.ts +2 -0
  393. package/dist/lib/pace/index.d.ts.map +1 -0
  394. package/dist/lib/pace/index.js +1 -0
  395. package/dist/lib/pace/pace.d.ts +95 -0
  396. package/dist/lib/pace/pace.d.ts.map +1 -0
  397. package/dist/lib/pace/pace.js +313 -0
  398. package/dist/lib/tunnel/error-page.d.ts +1 -1
  399. package/dist/lib/tunnel/error-page.d.ts.map +1 -1
  400. package/dist/lib/tunnel/error-page.js +19 -8
  401. package/dist/lib/tunnel/forward-headers.d.ts +11 -0
  402. package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
  403. package/dist/lib/tunnel/forward-headers.js +17 -0
  404. package/dist/lib/tunnel/gate.js +34 -10
  405. package/dist/lib/tunnel/path-scope.d.ts +22 -0
  406. package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
  407. package/dist/lib/tunnel/path-scope.js +62 -0
  408. package/dist/lib/tunnel/state.d.ts +5 -0
  409. package/dist/lib/tunnel/state.d.ts.map +1 -1
  410. package/dist/lib/tunnel/state.js +17 -3
  411. package/dist/lib/webview/index.d.ts +2 -0
  412. package/dist/lib/webview/index.d.ts.map +1 -0
  413. package/dist/lib/webview/index.js +1 -0
  414. package/dist/lib/webview/webview.d.ts +116 -0
  415. package/dist/lib/webview/webview.d.ts.map +1 -0
  416. package/dist/lib/webview/webview.js +289 -0
  417. package/opencode-plugin/package.json +19 -0
  418. package/opencode-plugin/src/index.ts +791 -0
  419. package/package.json +16 -4
  420. package/schemas/config.schema.json +104 -0
  421. package/schemas/event-v3.schema.json +164 -0
  422. package/src/commander.ts +26 -0
  423. package/src/commands/agents.ts +47 -18
  424. package/src/commands/artifacts.ts +171 -19
  425. package/src/commands/browse-ai.ts +8 -0
  426. package/src/commands/browse.ts +570 -48
  427. package/src/commands/checkpoint.ts +7 -9
  428. package/src/commands/claude-desktop.ts +61 -0
  429. package/src/commands/deinit.ts +9 -4
  430. package/src/commands/disk.ts +114 -0
  431. package/src/commands/docs.ts +2 -0
  432. package/src/commands/doctor.ts +63 -3
  433. package/src/commands/fetch.ts +14 -0
  434. package/src/commands/files.ts +93 -2
  435. package/src/commands/init.ts +334 -122
  436. package/src/commands/instructions.ts +8 -4
  437. package/src/commands/ledger-v3.ts +2 -1
  438. package/src/commands/rm.ts +115 -0
  439. package/src/commands/servers.ts +506 -0
  440. package/src/commands/tunnel.ts +102 -2
  441. package/src/commands/webview.ts +159 -0
  442. package/src/core/adapter.ts +102 -1
  443. package/src/core/adapters/attestation.ts +3 -2
  444. package/src/core/adapters/profiles.ts +63 -1
  445. package/src/core/adapters/registry.ts +37 -0
  446. package/src/core/adapters/types.ts +10 -0
  447. package/src/core/agents/canonical-emit.ts +2 -5
  448. package/src/core/agents/cli.ts +26 -17
  449. package/src/core/agents/coord-client.ts +9 -3
  450. package/src/core/agents/render/session-context.ts +1 -0
  451. package/src/core/agents/rules/claim-conflict.ts +3 -8
  452. package/src/core/agents/rules/commit-conflict.ts +2 -7
  453. package/src/core/agents/rules/stop-hook.ts +3 -1
  454. package/src/core/agents/session-events.ts +120 -26
  455. package/src/core/agents/session-finalization-state-v3.ts +2 -1
  456. package/src/core/agents/session-finalizer-v3.ts +5 -4
  457. package/src/core/agents/session-name-display.ts +48 -0
  458. package/src/core/agents/state/heartbeat-reader.ts +7 -0
  459. package/src/core/agents/state/heartbeat-writer.ts +24 -2
  460. package/src/core/agents/state/live-coordination-view.ts +74 -0
  461. package/src/core/agents/state/live-coordination-writer.ts +3 -0
  462. package/src/core/agents/state/stale-sweep.ts +2 -9
  463. package/src/core/agents/turn-changes.ts +97 -0
  464. package/src/core/artifacts/delivery-card.ts +12 -3
  465. package/src/core/artifacts/index.ts +701 -47
  466. package/src/core/config.ts +206 -4
  467. package/src/core/context/index.ts +2 -1
  468. package/src/core/conversations/archive.ts +4 -3
  469. package/src/core/diagnostics/bundle.ts +5 -3
  470. package/src/core/events/legacy-storage/canary.ts +5 -4
  471. package/src/core/events/legacy-storage/compression.ts +2 -1
  472. package/src/core/events/v3/adapter-id.ts +29 -1
  473. package/src/core/events/v3/authority-outbox.ts +2 -1
  474. package/src/core/events/v3/bootstrap.ts +5 -4
  475. package/src/core/events/v3/capabilities.ts +17 -0
  476. package/src/core/events/v3/contract.ts +9 -1
  477. package/src/core/events/v3/control-witness.ts +3 -2
  478. package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
  479. package/src/core/events/v3/fingerprint-keys.ts +7 -6
  480. package/src/core/events/v3/generated.ts +1 -1
  481. package/src/core/events/v3/live-feed.ts +5 -4
  482. package/src/core/events/v3/producers/command-recorder.ts +8 -6
  483. package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
  484. package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
  485. package/src/core/events/v3/producers/hook-base.ts +11 -4
  486. package/src/core/events/v3/producers/hook.ts +19 -1
  487. package/src/core/events/v3/producers/intake.ts +18 -6
  488. package/src/core/events/v3/producers/recorder.ts +139 -114
  489. package/src/core/events/v3/projection.ts +11 -1
  490. package/src/core/events/v3/recovery.ts +4 -3
  491. package/src/core/events/v3/support-storage/inventory.ts +2 -1
  492. package/src/core/events/v3/support-storage/maintenance.ts +8 -3
  493. package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
  494. package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
  495. package/src/core/events/v3/tool-line-changes.ts +139 -0
  496. package/src/core/events/v3/writer.ts +8 -7
  497. package/src/core/governor/planning.ts +6 -5
  498. package/src/core/governor/service.ts +12 -11
  499. package/src/core/governor/state.ts +7 -6
  500. package/src/core/guard/evaluator.ts +1 -0
  501. package/src/core/guard/storage.ts +3 -2
  502. package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
  503. package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
  504. package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
  505. package/src/core/hooks/adapter/behaviors/index.ts +31 -0
  506. package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
  507. package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
  508. package/src/core/hooks/adapter/behaviors/types.ts +110 -0
  509. package/src/core/hooks/adapter/detect.ts +2 -3
  510. package/src/core/hooks/adapter/events.ts +72 -1
  511. package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
  512. package/src/core/hooks/adapter/output.ts +8 -1
  513. package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
  514. package/src/core/hooks/adapter/wiring.ts +198 -16
  515. package/src/core/hooks/cli.ts +776 -539
  516. package/src/core/hooks/effects/image-capture.ts +2 -1
  517. package/src/core/hooks/prompt-context/contract.ts +1 -0
  518. package/src/core/hooks/resolve/transcript.ts +42 -5
  519. package/src/core/hooks/run-markers.ts +132 -0
  520. package/src/core/hooks/session-name-presence.ts +10 -3
  521. package/src/core/hooks/shell-waiter.ts +166 -0
  522. package/src/core/resources/service.ts +5 -4
  523. package/src/core/semantic/review.ts +5 -4
  524. package/src/core/semantic/service.ts +15 -14
  525. package/src/core/semantic/storage.ts +5 -4
  526. package/src/core/servers/index.ts +712 -0
  527. package/src/core/servers/net.ts +283 -0
  528. package/src/core/servers/tunnels.ts +39 -0
  529. package/src/core/storage/atomic-json.ts +7 -3
  530. package/src/core/storage/builtins.ts +1 -0
  531. package/src/core/storage/durable-history.ts +6 -5
  532. package/src/core/storage/maintenance-providers.ts +2 -1
  533. package/src/core/storage/maintenance.ts +7 -6
  534. package/src/core/storage/metrics.ts +5 -1
  535. package/src/core/storage/modes.ts +53 -0
  536. package/src/core/storage/process-log.ts +3 -2
  537. package/src/core/storage/receipts.ts +4 -3
  538. package/src/core/storage/segments.ts +7 -6
  539. package/src/core/supervisor/hook-health.ts +4 -4
  540. package/src/core/supervisor/service.ts +7 -6
  541. package/src/core/work/state.ts +8 -7
  542. package/src/core/workflow/adapters.ts +15 -0
  543. package/src/core/workflow/approvals.ts +6 -5
  544. package/src/core/workflow/billing.ts +34 -4
  545. package/src/core/workflow/durable-record.ts +4 -3
  546. package/src/core/workflow/engine.ts +38 -1
  547. package/src/core/workflow/live-session-v3.ts +2 -3
  548. package/src/core/workflow/run-state.ts +3 -2
  549. package/src/core/workflow/sandbox-projection.ts +38 -2
  550. package/src/core/workflow/spawn-claude.ts +5 -1
  551. package/src/core/workflow/spawn-codex.ts +18 -1
  552. package/src/core/workflow/spawn-cursor.ts +5 -1
  553. package/src/core/workflow/spawn-opencode.ts +153 -0
  554. package/src/core/workflow/transcript.ts +3 -2
  555. package/src/core/workflow/types.ts +62 -2
  556. package/src/core/workflow/worker-access.ts +525 -0
  557. package/src/core/workflow/workspaces/leases.ts +5 -4
  558. package/src/core/workflow/workspaces/local-git.ts +3 -2
  559. package/src/core/workflow/workspaces/paths.ts +2 -1
  560. package/src/core/workflow/workspaces/state.ts +10 -9
  561. package/src/lazy-commands.ts +11 -1
  562. package/src/lib/agent-browser/client.ts +18 -0
  563. package/src/lib/browser/batch-steps.ts +79 -0
  564. package/src/lib/browser/client.ts +147 -9
  565. package/src/lib/browser/collect/collector.ts +306 -0
  566. package/src/lib/browser/collect/fields.ts +87 -0
  567. package/src/lib/browser/collect/index.ts +47 -0
  568. package/src/lib/browser/collect/page-driver.ts +327 -0
  569. package/src/lib/browser/collect/presets.ts +237 -0
  570. package/src/lib/browser/collect/scroll-plan.ts +179 -0
  571. package/src/lib/browser/identity.ts +64 -0
  572. package/src/lib/browser/index.ts +16 -1
  573. package/src/lib/browser/launch-args.ts +53 -1
  574. package/src/lib/browser/page-review-judge.ts +16 -0
  575. package/src/lib/browser/qa-run-contracts.ts +11 -0
  576. package/src/lib/browser/qa-run.ts +1 -0
  577. package/src/lib/browser/user-agent.ts +130 -0
  578. package/src/lib/browser/windows-chrome.ts +227 -0
  579. package/src/lib/claude-desktop-share.ts +511 -0
  580. package/src/lib/disk-usage.ts +347 -0
  581. package/src/lib/docs-lint.ts +8 -3
  582. package/src/lib/docs-metadata-managed.ts +21 -0
  583. package/src/lib/guarded-remove.ts +376 -0
  584. package/src/lib/identities/assume.ts +7 -7
  585. package/src/lib/instructions/apply.ts +2 -0
  586. package/src/lib/instructions/templates.ts +8 -8
  587. package/src/lib/pace/index.ts +14 -0
  588. package/src/lib/pace/pace.ts +370 -0
  589. package/src/lib/tunnel/error-page.ts +25 -9
  590. package/src/lib/tunnel/forward-headers.ts +16 -0
  591. package/src/lib/tunnel/gate.ts +39 -10
  592. package/src/lib/tunnel/path-scope.ts +73 -0
  593. package/src/lib/tunnel/state.ts +20 -3
  594. package/src/lib/webview/index.ts +13 -0
  595. package/src/lib/webview/webview.ts +457 -0
@@ -0,0 +1,87 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { isAbsolute, relative, resolve, sep } from "node:path";
4
+ import { resolveCoordRoot } from "../core/agents/coord-client.js";
5
+ import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../core/events/v3/coordination-view.js";
6
+ import { liveInstanceIdV3 } from "../core/events/v3/live-route-observer.js";
7
+ import { resolveOwner } from "../core/hooks/resolve/owner.js";
8
+ import { guardedRemove } from "../lib/guarded-remove.js";
9
+ export function registerRmCommand(program, emit, context) {
10
+ program
11
+ .command("rm <paths...>")
12
+ .description("Preview guarded removal of untracked files; --yes applies permanent deletion")
13
+ .requiredOption("--root <directory>", "Allowed directory; each target must be strictly inside it")
14
+ .option("-r, --recursive", "Permit directory removal after inspecting its complete contents")
15
+ .option("--allow-protected <path>", "Remove this one protected path (Git metadata, credentials, Harnery state, keys) inside a target; repeat per path", (value, previous = []) => [...previous, value])
16
+ .option("--yes", "Permanently remove validated targets")
17
+ .option("--dry-run", "Preview only, even with --yes")
18
+ .option("--json", "Emit the versioned removal report")
19
+ .action((paths, options) => {
20
+ try {
21
+ const coordRoot = context?.resolveCoordRoot?.() ?? context?.repoRoot ?? resolveCoordRoot();
22
+ const checkClaims = (targets) => {
23
+ if (!coordRoot || !existsSync(resolve(coordRoot, ".harnery")))
24
+ return;
25
+ const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
26
+ const owner = resolveOwner({ payload: null, coordRoot });
27
+ const ownId = owner ? liveInstanceIdV3(owner.instance_id) : undefined;
28
+ const ownSession = ownId ? view.instances[ownId]?.session_id : undefined;
29
+ for (const peer of Object.values(view.instances)) {
30
+ if (!peer.authority_eligible ||
31
+ peer.instance_id === ownId ||
32
+ (ownSession && peer.session_id === ownSession))
33
+ continue;
34
+ for (const claim of peer.files_touched) {
35
+ const claimed = resolve(coordRoot, claim);
36
+ for (const target of targets) {
37
+ if (overlaps(target, claimed))
38
+ throw new Error(`Target overlaps another agent's claim: ${claim} (${peer.instance_id})`);
39
+ }
40
+ }
41
+ }
42
+ };
43
+ // The workspace this command coordinates, and the checkout it runs in:
44
+ // their own .git and .harnery can never be allowed.
45
+ const liveRoots = [coordRoot, gitTopLevel(process.cwd())].filter((dir) => Boolean(dir));
46
+ const report = guardedRemove(paths, { ...options, liveRoots }, checkClaims);
47
+ if (options.json) {
48
+ emit.config({ format: "json" });
49
+ emit.data(report);
50
+ }
51
+ else {
52
+ const lines = [
53
+ `${report.applied ? "Removed" : "Would remove"} ${report.targets.length} target(s), ${report.entries} entries, ${report.bytes} bytes:`,
54
+ ...report.targets,
55
+ ];
56
+ if (report.protected.length)
57
+ lines.push("Protected paths named with --allow-protected:", ...report.protected.map((path) => ` ${path}`));
58
+ if (report.links.length)
59
+ lines.push("Links removed as links (their targets are untouched):", ...report.links.map((link) => ` ${link.path} -> ${link.target}`));
60
+ if (!report.applied)
61
+ lines.push("Preview only. Add --yes to permanently delete these targets.");
62
+ emit.text(lines.join("\n"));
63
+ }
64
+ }
65
+ catch (error) {
66
+ emit.error({
67
+ code: "removal_refused",
68
+ message: error instanceof Error ? error.message : String(error),
69
+ });
70
+ emit.setExitCode(1);
71
+ }
72
+ });
73
+ }
74
+ function gitTopLevel(dir) {
75
+ const result = spawnSync("git", ["-C", dir, "rev-parse", "--show-toplevel"], {
76
+ encoding: "utf8",
77
+ timeout: 10_000,
78
+ });
79
+ return result.status === 0 ? result.stdout.trim() || undefined : undefined;
80
+ }
81
+ function overlaps(a, b) {
82
+ const inside = (parent, child) => {
83
+ const rel = relative(parent, child);
84
+ return rel === "" || (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
85
+ };
86
+ return inside(a, b) || inside(b, a);
87
+ }
@@ -0,0 +1,7 @@
1
+ import type { Command } from "commander";
2
+ import type { EmitContext, HarneryProgramContext } from "../commander.js";
3
+ import { type ServersReport } from "../core/servers/index.js";
4
+ export declare function registerServersCommand(program: Command, emit: EmitContext, context?: HarneryProgramContext): void;
5
+ /** Plain-text table grouped by kind; exported for tests. */
6
+ export declare function renderReport(report: ServersReport, bin: string): string;
7
+ //# sourceMappingURL=servers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../src/commands/servers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG1E,OAAO,EAWL,KAAK,aAAa,EAMnB,MAAM,0BAA0B,CAAC;AAElC,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA0YN;AA8BD,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAmDvE"}
@@ -0,0 +1,394 @@
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { hostname } from "node:os";
3
+ import { resolveCoordRoot } from "../core/agents/coord-client.js";
4
+ import { resolveBinName, serverGcConfig } from "../core/config.js";
5
+ import { adoptServer, allocateServerPort, isValidServerId, listServers, planServerGc, readServer, registerServer, SERVER_DEFAULT_IDLE_HOURS, SERVER_DEFAULT_OWNER_STALE_HOURS, stopServer, touchServer, unregisterServer, } from "../core/servers/index.js";
6
+ export function registerServersCommand(program, emit, context) {
7
+ const root = () => {
8
+ const resolved = context?.resolveCoordRoot?.() ?? context?.repoRoot ?? resolveCoordRoot();
9
+ if (!resolved)
10
+ throw new Error("not inside a Harnery project");
11
+ return resolved;
12
+ };
13
+ const fail = (error, code = "servers_error") => {
14
+ emit.error({ code, message: error instanceof Error ? error.message : String(error) });
15
+ emit.setExitCode(1);
16
+ };
17
+ const cmd = program
18
+ .command("servers")
19
+ .description("Every local server started in this project: list, stop, clean up idle session servers, read logs");
20
+ cmd
21
+ .command("list", { isDefault: true })
22
+ .alias("status")
23
+ .description("List registered servers and any unregistered listener running inside the project")
24
+ .option("--no-scan", "Skip the scan for unregistered listeners")
25
+ .option("--json", "Emit the versioned report")
26
+ .action((options) => {
27
+ try {
28
+ const report = listServers({ coordRoot: root(), scan: options.scan !== false });
29
+ if (options.json) {
30
+ emit.config({ format: "json" });
31
+ emit.data(report);
32
+ }
33
+ else
34
+ emit.text(renderReport(report, resolveBinName(report.coord_root)));
35
+ }
36
+ catch (error) {
37
+ fail(error);
38
+ }
39
+ });
40
+ cmd
41
+ .command("stop [ids...]")
42
+ .description("Stop named servers now; --type selects several and previews unless --yes")
43
+ .option("--type <type>", "Select every running server of this type")
44
+ .option("--pid <pid>", "Stop an unregistered listener found by the list scan (repeatable)", (value, previous = []) => [...previous, value])
45
+ .option("--kind <kind>", "With --type, limit to session or service")
46
+ .option("--yes", "Apply a --type selection")
47
+ .option("--json", "Emit JSON")
48
+ .action(async (ids, options) => {
49
+ try {
50
+ const coordRoot = root();
51
+ const pids = (options.pid ?? []).map((value) => integer(value, "--pid"));
52
+ if (!ids.length && !options.type && !pids.length)
53
+ throw new Error("name server ids, or pass --type or --pid");
54
+ const report = listServers({ coordRoot, scan: pids.length > 0 });
55
+ const strays = pids.map((pid) => {
56
+ const found = report.unregistered.find((item) => item.pid === pid);
57
+ if (!found)
58
+ throw new Error(`pid ${pid} is not an unregistered listener inside this project; only pids shown by "servers list" can be stopped this way`);
59
+ return found;
60
+ });
61
+ const byId = new Map(report.servers.map((view) => [view.record.id, view]));
62
+ const missing = ids.filter((id) => !byId.has(id));
63
+ if (missing.length)
64
+ throw new Error(`no running server named: ${missing.join(", ")}`);
65
+ const selected = [
66
+ ...ids.map((id) => byId.get(id)),
67
+ ...(options.type
68
+ ? report.servers.filter((view) => view.record.type === options.type &&
69
+ view.state === "running" &&
70
+ (!options.kind || view.record.kind === options.kind) &&
71
+ !ids.includes(view.record.id))
72
+ : []),
73
+ ];
74
+ const preview = Boolean(options.type) && !options.yes;
75
+ const results = [];
76
+ for (const stray of strays) {
77
+ results.push(await stopServer({
78
+ schema_version: 1,
79
+ id: `pid-${stray.pid}`,
80
+ kind: "session",
81
+ type: "unregistered",
82
+ label: stray.command,
83
+ pid: stray.pid,
84
+ host: hostname(),
85
+ started_at: new Date().toISOString(),
86
+ registered_at: new Date().toISOString(),
87
+ }, { coordRoot }));
88
+ }
89
+ for (const view of selected) {
90
+ if (preview && !ids.includes(view.record.id))
91
+ results.push({ id: view.record.id, would_stop: true });
92
+ else
93
+ results.push(await stopServer(view.record, { coordRoot }));
94
+ }
95
+ if (options.json) {
96
+ emit.config({ format: "json" });
97
+ emit.data({ applied: !preview, results });
98
+ }
99
+ else {
100
+ emit.text(results.length
101
+ ? results
102
+ .map((r) => "would_stop" in r
103
+ ? `would stop ${r.id}`
104
+ : `${r.stopped ? "stopped" : r.method === "not-running" ? "already stopped" : "could not stop"} ${r.id}${r.detail ? ` (${r.detail})` : ""}`)
105
+ .join("\n") +
106
+ (preview ? `\nPreview only. Re-run with --yes to stop these.` : "")
107
+ : "No matching running servers.");
108
+ }
109
+ if (results.some((r) => "stopped" in r && !r.stopped && r.method === "refused"))
110
+ emit.setExitCode(1);
111
+ }
112
+ catch (error) {
113
+ fail(error);
114
+ }
115
+ });
116
+ cmd
117
+ .command("gc")
118
+ .description(`Stop idle session servers whose starting agent ended (preview unless --yes); services are never touched`)
119
+ .option("--idle-hours <hours>", `Idle window before a server may stop (default ${SERVER_DEFAULT_IDLE_HOURS})`)
120
+ .option("--owner-stale-hours <hours>", `Treat a starting agent unobserved this long as gone (default ${SERVER_DEFAULT_OWNER_STALE_HOURS})`)
121
+ .option("--yes", "Stop the selected servers")
122
+ .option("--json", "Emit JSON")
123
+ .action(async (options) => {
124
+ try {
125
+ const coordRoot = root();
126
+ const configured = serverGcConfig(coordRoot);
127
+ const idleHours = positive(options.idleHours, configured.idle_hours ?? SERVER_DEFAULT_IDLE_HOURS, "--idle-hours");
128
+ const ownerStaleHours = positive(options.ownerStaleHours, configured.owner_stale_hours ?? SERVER_DEFAULT_OWNER_STALE_HOURS, "--owner-stale-hours");
129
+ const report = listServers({ coordRoot, scan: false, ownerStaleHours });
130
+ const decisions = planServerGc(report.servers, { idleHours, ownerStaleHours });
131
+ const stops = decisions.filter((d) => d.action === "stop");
132
+ const results = [];
133
+ if (options.yes) {
134
+ for (const decision of stops) {
135
+ const view = report.servers.find((v) => v.record.id === decision.id);
136
+ results.push(await stopServer(view.record, { coordRoot }));
137
+ }
138
+ }
139
+ if (options.json) {
140
+ emit.config({ format: "json" });
141
+ emit.data({ applied: Boolean(options.yes), pruned: report.pruned, decisions, results });
142
+ }
143
+ else {
144
+ const lines = decisions.map((d) => `${d.action === "stop" ? (options.yes ? "stopped" : "would stop") : "keep"} ${d.id} ${d.reason}`);
145
+ if (report.pruned.length)
146
+ lines.push(`Removed records of exited servers: ${report.pruned.join(", ")}`);
147
+ if (!decisions.length)
148
+ lines.push("No registered servers.");
149
+ if (stops.length && !options.yes)
150
+ lines.push("Preview only. Re-run with --yes to stop.");
151
+ emit.text(lines.join("\n"));
152
+ }
153
+ }
154
+ catch (error) {
155
+ fail(error);
156
+ }
157
+ });
158
+ cmd
159
+ .command("adopt")
160
+ .description("Register running servers that never registered (only pids the list reports as unregistered)")
161
+ .option("--pid <pid>", "Adopt this unregistered listener (repeatable)", (value, previous = []) => [...previous, value])
162
+ .option("--all", "Adopt every unregistered listener the scan reports")
163
+ .option("--type <type>", "Server family to record", "adopted")
164
+ .option("--kind <kind>", "session (cleaned up when idle) or service", "session")
165
+ .option("--label <label>", "Human-readable name (single --pid only)")
166
+ .option("--scope <path>", "What the server serves (default: its working directory)")
167
+ .option("--no-owner", "Record no owner, so gc never stops it")
168
+ .option("--json", "Emit JSON")
169
+ .action((options) => {
170
+ try {
171
+ const coordRoot = root();
172
+ if (options.kind !== "session" && options.kind !== "service")
173
+ throw new Error("--kind must be session or service");
174
+ const pids = options.all
175
+ ? [...new Set(listServers({ coordRoot, sample: false }).unregistered.map((u) => u.pid))]
176
+ : (options.pid ?? []).map((value) => integer(value, "--pid"));
177
+ if (!pids.length)
178
+ throw new Error(options.all ? "no unregistered listeners" : "pass --pid or --all");
179
+ if (options.label && pids.length > 1)
180
+ throw new Error("--label needs a single --pid");
181
+ const records = pids.map((pid) => adoptServer(pid, {
182
+ coordRoot,
183
+ type: options.type,
184
+ kind: options.kind,
185
+ ...(options.label ? { label: options.label } : {}),
186
+ ...(options.scope ? { scope: options.scope } : {}),
187
+ owner: options.owner === false ? "none" : "self",
188
+ }));
189
+ if (options.json) {
190
+ emit.config({ format: "json" });
191
+ emit.data({ adopted: records });
192
+ }
193
+ else
194
+ emit.text(records.map((r) => `adopted ${r.id} ${r.url ?? ""}`).join("\n"));
195
+ }
196
+ catch (error) {
197
+ fail(error);
198
+ }
199
+ });
200
+ cmd
201
+ .command("port <type>")
202
+ .description("Print a free port from the type's configured range (.harnery/config.jsonc servers.port_ranges)")
203
+ .action((type) => {
204
+ try {
205
+ const port = allocateServerPort(type, { coordRoot: root() });
206
+ if (port === null)
207
+ throw new Error(`no port range configured for ${type}`);
208
+ emit.text(String(port));
209
+ }
210
+ catch (error) {
211
+ fail(error);
212
+ }
213
+ });
214
+ cmd
215
+ .command("logs <id>")
216
+ .description("Print the end of a server's log file")
217
+ .option("-n, --lines <n>", "Lines to print", "60")
218
+ .action((id, options) => {
219
+ try {
220
+ const record = readServer(id, { coordRoot: root() });
221
+ if (!record)
222
+ throw new Error(`no server named ${id}`);
223
+ if (!record.log || !existsSync(record.log))
224
+ throw new Error(`${id} did not record a log file`);
225
+ const lines = positive(options.lines, 60, "--lines");
226
+ const size = statSync(record.log).size;
227
+ const content = readFileSync(record.log, "utf8").slice(Math.max(0, size - 512 * 1024));
228
+ emit.text(content
229
+ .split("\n")
230
+ .slice(-Math.floor(lines) - 1)
231
+ .join("\n"));
232
+ }
233
+ catch (error) {
234
+ fail(error);
235
+ }
236
+ });
237
+ cmd
238
+ .command("open <id>")
239
+ .description("Print a server's URL")
240
+ .action((id) => {
241
+ try {
242
+ const record = readServer(id, { coordRoot: root() });
243
+ if (!record)
244
+ throw new Error(`no server named ${id}`);
245
+ if (!record.url)
246
+ throw new Error(`${id} did not record a URL`);
247
+ emit.text(record.url);
248
+ }
249
+ catch (error) {
250
+ fail(error);
251
+ }
252
+ });
253
+ cmd
254
+ .command("register")
255
+ .description("Record a server started by a script or another language (prints the record; the calling agent is recorded as owner)")
256
+ .requiredOption("--type <type>", "Server family, for example preview or review")
257
+ .option("--kind <kind>", "session (per piece of work) or service (long-running)", "session")
258
+ .option("--pid <pid>", "Process that owns the server's lifetime (default: this command's parent)")
259
+ .option("--port <port>", "Listening port")
260
+ .option("--id <id>", "Stable id (default derived from type and scope)")
261
+ .option("--url <url>", "Local URL")
262
+ .option("--scope <path>", "What the server serves, usually a directory")
263
+ .option("--label <label>", "Human-readable name")
264
+ .option("--log <path>", "Log file")
265
+ .option("--cwd <path>", "Working directory")
266
+ .action((options) => {
267
+ try {
268
+ if (options.kind !== "session" && options.kind !== "service")
269
+ throw new Error("--kind must be session or service");
270
+ if (options.id && !isValidServerId(options.id))
271
+ throw new Error(`invalid id: ${options.id}`);
272
+ const record = registerServer({
273
+ kind: options.kind,
274
+ type: options.type,
275
+ pid: options.pid ? integer(options.pid, "--pid") : process.ppid,
276
+ ...(options.port ? { port: integer(options.port, "--port") } : {}),
277
+ ...(options.id ? { id: options.id } : {}),
278
+ ...(options.url ? { url: options.url } : {}),
279
+ ...(options.scope ? { scope: options.scope } : {}),
280
+ ...(options.label ? { label: options.label } : {}),
281
+ ...(options.log ? { log: options.log } : {}),
282
+ ...(options.cwd ? { cwd: options.cwd } : {}),
283
+ }, { coordRoot: root() });
284
+ emit.config({ format: "json" });
285
+ emit.data(record);
286
+ }
287
+ catch (error) {
288
+ fail(error);
289
+ }
290
+ });
291
+ cmd
292
+ .command("unregister <id>")
293
+ .description("Remove a server's record (with --pid, only if the record still names that pid)")
294
+ .option("--pid <pid>", "Only remove when the record names this pid")
295
+ .action((id, options) => {
296
+ try {
297
+ const removed = unregisterServer(id, {
298
+ coordRoot: root(),
299
+ ...(options.pid ? { pid: integer(options.pid, "--pid") } : {}),
300
+ });
301
+ emit.config({ format: "json" });
302
+ emit.data({ id, removed });
303
+ }
304
+ catch (error) {
305
+ fail(error);
306
+ }
307
+ });
308
+ cmd
309
+ .command("touch <id>")
310
+ .description("Mark a server as used now, postponing idle cleanup")
311
+ .action((id) => {
312
+ try {
313
+ touchServer(id, { coordRoot: root() });
314
+ }
315
+ catch (error) {
316
+ fail(error);
317
+ }
318
+ });
319
+ }
320
+ function integer(value, flag) {
321
+ const parsed = Number(value);
322
+ if (!Number.isSafeInteger(parsed) || parsed < 1)
323
+ throw new Error(`${flag} must be a positive integer`);
324
+ return parsed;
325
+ }
326
+ function positive(value, fallback, flag) {
327
+ if (value === undefined)
328
+ return fallback;
329
+ const parsed = Number(value);
330
+ if (!Number.isFinite(parsed) || parsed <= 0)
331
+ throw new Error(`${flag} must be a positive number`);
332
+ return parsed;
333
+ }
334
+ function duration(ms) {
335
+ const minutes = Math.round(ms / 60_000);
336
+ if (minutes < 60)
337
+ return `${minutes}m`;
338
+ const hours = Math.floor(minutes / 60);
339
+ if (hours < 48)
340
+ return `${hours}h${String(minutes % 60).padStart(2, "0")}m`;
341
+ return `${Math.floor(hours / 24)}d`;
342
+ }
343
+ function ownerText(view) {
344
+ if (!view.record.owner)
345
+ return "no agent";
346
+ const name = view.record.owner.name ?? view.record.owner.instance_id.slice(0, 8);
347
+ return view.owner_state === "live" ? name : `${name} (${view.owner_state})`;
348
+ }
349
+ /** Plain-text table grouped by kind; exported for tests. */
350
+ export function renderReport(report, bin) {
351
+ const lines = [];
352
+ for (const kind of ["service", "session"]) {
353
+ const views = report.servers.filter((view) => view.record.kind === kind);
354
+ lines.push(kind === "service"
355
+ ? "Services (stopped only by hand)"
356
+ : "Session servers (cleaned up when idle and their agent is gone)");
357
+ if (!views.length) {
358
+ lines.push(" none");
359
+ continue;
360
+ }
361
+ for (const view of views) {
362
+ const { record } = view;
363
+ const state = view.state === "running" ? "" : ` [${view.state}]`;
364
+ const started = Date.parse(record.started_at);
365
+ const use = kind === "service"
366
+ ? `up ${Number.isFinite(started) ? duration(Date.now() - started) : "?"}`
367
+ : view.connections === null
368
+ ? `idle ${duration(view.idle_ms)}`
369
+ : view.connections > 0
370
+ ? `${view.connections} open connection(s)`
371
+ : `idle ${duration(view.idle_ms)}`;
372
+ lines.push(` ${record.id}${state} ${record.url ?? (record.port ? `port ${record.port}` : "")}`, ` ${record.label} · ${ownerText(view)} · ${use}`);
373
+ }
374
+ }
375
+ if (report.scan === "unsupported") {
376
+ lines.push("Unregistered listeners: not checked on this platform");
377
+ }
378
+ else if (report.unregistered.length) {
379
+ const byPid = new Map();
380
+ for (const item of report.unregistered) {
381
+ const entry = byPid.get(item.pid) ?? { ports: [], command: item.command };
382
+ entry.ports.push(item.port);
383
+ byPid.set(item.pid, entry);
384
+ }
385
+ lines.push(`Unregistered servers inside this project (${byPid.size} processes):`);
386
+ for (const [pid, entry] of byPid)
387
+ lines.push(` pid ${pid} port ${entry.ports.join(", ")} ${entry.command.slice(0, 100)}`);
388
+ lines.push(` These started without registering. Stop one with: ${bin} servers stop --pid <pid>`);
389
+ }
390
+ if (report.pruned.length)
391
+ lines.push(`Removed records of exited servers: ${report.pruned.join(", ")}`);
392
+ lines.push(`Control: ${bin} servers stop <id> · ${bin} servers gc · ${bin} servers logs <id>`);
393
+ return lines.join("\n");
394
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/commands/tunnel.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAQ1E,OAAO,EAYL,KAAK,cAAc,EACnB,KAAK,WAAW,EAGjB,MAAM,wBAAwB,CAAC;AAoDhC,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,SAAgB,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAcpC;AAuoBD;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAsE7F;AA+MD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,YAAY,CAAC,EAAE,qBAAqB,GACnC,IAAI,CA2EN"}
1
+ {"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/commands/tunnel.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAgB1E,OAAO,EAYL,KAAK,cAAc,EACnB,KAAK,WAAW,EAGjB,MAAM,wBAAwB,CAAC;AAuDhC,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,SAAgB,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAcpC;AA2sBD;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAiF7F;AAkND,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,YAAY,CAAC,EAAE,qBAAqB,GACnC,IAAI,CAkFN"}