@phnx-labs/agents-cli 1.22.34 → 1.22.37

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 (493) hide show
  1. package/CHANGELOG.md +672 -2
  2. package/README.md +82 -35
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1211 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/attach.js +17 -4
  9. package/dist/commands/audit.d.ts +8 -8
  10. package/dist/commands/audit.js +57 -47
  11. package/dist/commands/browser.js +15 -11
  12. package/dist/commands/cloud.js +1 -1
  13. package/dist/commands/commands.js +0 -11
  14. package/dist/commands/computer-actions.js +33 -0
  15. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  16. package/dist/commands/computer-sessions-picker.js +141 -0
  17. package/dist/commands/computer.d.ts +16 -0
  18. package/dist/commands/computer.js +37 -0
  19. package/dist/commands/config.d.ts +17 -0
  20. package/dist/commands/config.js +401 -0
  21. package/dist/commands/cp.d.ts +84 -0
  22. package/dist/commands/cp.js +231 -0
  23. package/dist/commands/daemon.js +243 -14
  24. package/dist/commands/detach-core.d.ts +1 -1
  25. package/dist/commands/detach-core.js +12 -2
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +64 -5
  28. package/dist/commands/events.d.ts +24 -12
  29. package/dist/commands/events.js +144 -28
  30. package/dist/commands/exec.js +85 -41
  31. package/dist/commands/feed.d.ts +1 -1
  32. package/dist/commands/feed.js +16 -8
  33. package/dist/commands/focus.d.ts +33 -1
  34. package/dist/commands/focus.js +177 -17
  35. package/dist/commands/funnel.d.ts +1 -1
  36. package/dist/commands/go.js +9 -8
  37. package/dist/commands/harness-wizard.d.ts +1 -0
  38. package/dist/commands/harness-wizard.js +18 -20
  39. package/dist/commands/harness.d.ts +2 -0
  40. package/dist/commands/harness.js +59 -26
  41. package/dist/commands/hooks.js +0 -11
  42. package/dist/commands/inspect.d.ts +94 -1
  43. package/dist/commands/inspect.js +866 -40
  44. package/dist/commands/lease.d.ts +4 -4
  45. package/dist/commands/lease.js +6 -6
  46. package/dist/commands/login.js +0 -13
  47. package/dist/commands/logs.d.ts +2 -2
  48. package/dist/commands/logs.js +2 -2
  49. package/dist/commands/mcp.js +7 -2
  50. package/dist/commands/memory.js +7 -2
  51. package/dist/commands/message.d.ts +1 -1
  52. package/dist/commands/message.js +37 -6
  53. package/dist/commands/models.js +4 -0
  54. package/dist/commands/monitors.d.ts +0 -1
  55. package/dist/commands/monitors.js +199 -16
  56. package/dist/commands/open.d.ts +18 -0
  57. package/dist/commands/open.js +57 -0
  58. package/dist/commands/packages.js +2 -107
  59. package/dist/commands/plugins.js +6 -3
  60. package/dist/commands/profiles.d.ts +1 -0
  61. package/dist/commands/profiles.js +16 -160
  62. package/dist/commands/projects.d.ts +28 -0
  63. package/dist/commands/projects.js +125 -5
  64. package/dist/commands/reconnect.js +9 -3
  65. package/dist/commands/repo.js +42 -1
  66. package/dist/commands/resource-view.d.ts +17 -0
  67. package/dist/commands/resource-view.js +36 -14
  68. package/dist/commands/resume.js +9 -2
  69. package/dist/commands/routines.d.ts +0 -2
  70. package/dist/commands/routines.js +473 -289
  71. package/dist/commands/secrets.js +52 -9
  72. package/dist/commands/sessions-export.d.ts +47 -0
  73. package/dist/commands/sessions-export.js +116 -6
  74. package/dist/commands/sessions-import.d.ts +17 -0
  75. package/dist/commands/sessions-import.js +114 -6
  76. package/dist/commands/sessions-migrate.d.ts +27 -0
  77. package/dist/commands/sessions-migrate.js +50 -9
  78. package/dist/commands/sessions-picker.js +23 -4
  79. package/dist/commands/sessions-resume.d.ts +5 -3
  80. package/dist/commands/sessions-resume.js +30 -8
  81. package/dist/commands/sessions-watch.d.ts +2 -0
  82. package/dist/commands/sessions-watch.js +53 -0
  83. package/dist/commands/sessions.d.ts +66 -3
  84. package/dist/commands/sessions.js +298 -47
  85. package/dist/commands/set.d.ts +1 -1
  86. package/dist/commands/set.js +2 -2
  87. package/dist/commands/setup-browser.js +2 -2
  88. package/dist/commands/setup-mine.js +0 -1
  89. package/dist/commands/setup-preferences.js +1 -1
  90. package/dist/commands/setup-share.js +34 -4
  91. package/dist/commands/setup.d.ts +5 -0
  92. package/dist/commands/setup.js +26 -0
  93. package/dist/commands/share.d.ts +85 -0
  94. package/dist/commands/share.js +379 -8
  95. package/dist/commands/skills.js +0 -11
  96. package/dist/commands/snapshot.js +1 -1
  97. package/dist/commands/ssh.d.ts +18 -0
  98. package/dist/commands/ssh.js +549 -210
  99. package/dist/commands/sync.d.ts +5 -0
  100. package/dist/commands/sync.js +212 -32
  101. package/dist/commands/teams.d.ts +13 -0
  102. package/dist/commands/teams.js +187 -30
  103. package/dist/commands/tickets.d.ts +2 -0
  104. package/dist/commands/tickets.js +43 -0
  105. package/dist/commands/update.js +2 -4
  106. package/dist/commands/usage.js +5 -3
  107. package/dist/commands/versions.js +11 -5
  108. package/dist/commands/view.js +15 -7
  109. package/dist/commands/webhook.d.ts +2 -2
  110. package/dist/commands/webhook.js +7 -7
  111. package/dist/index.d.ts +18 -2
  112. package/dist/index.js +53 -1264
  113. package/dist/lib/account-catalog.d.ts +18 -0
  114. package/dist/lib/account-catalog.js +38 -0
  115. package/dist/lib/account-provider-registry.d.ts +18 -0
  116. package/dist/lib/account-provider-registry.js +59 -0
  117. package/dist/lib/account-registry.d.ts +40 -0
  118. package/dist/lib/account-registry.js +239 -0
  119. package/dist/lib/account-schema.d.ts +44 -0
  120. package/dist/lib/account-schema.js +91 -0
  121. package/dist/lib/account-state-service.d.ts +21 -0
  122. package/dist/lib/account-state-service.js +60 -0
  123. package/dist/lib/activity.d.ts +1 -1
  124. package/dist/lib/activity.js +8 -1
  125. package/dist/lib/add-dir.d.ts +80 -0
  126. package/dist/lib/add-dir.js +241 -0
  127. package/dist/lib/agent-cli-commands.d.ts +11 -0
  128. package/dist/lib/agent-cli-commands.js +30 -0
  129. package/dist/lib/agents.js +44 -36
  130. package/dist/lib/answer-router.js +1 -1
  131. package/dist/lib/audit/log.d.ts +10 -27
  132. package/dist/lib/audit/log.js +20 -33
  133. package/dist/lib/auth-health.d.ts +9 -2
  134. package/dist/lib/auth-health.js +42 -9
  135. package/dist/lib/auto-pull-worker.js +7 -3
  136. package/dist/lib/auto-pull.d.ts +44 -3
  137. package/dist/lib/auto-pull.js +88 -5
  138. package/dist/lib/binary-shadow.d.ts +28 -0
  139. package/dist/lib/binary-shadow.js +121 -0
  140. package/dist/lib/brand.js +9 -3
  141. package/dist/lib/browser/ipc.d.ts +30 -0
  142. package/dist/lib/browser/ipc.js +81 -4
  143. package/dist/lib/browser/profiles.d.ts +3 -2
  144. package/dist/lib/browser/profiles.js +65 -22
  145. package/dist/lib/browser/service.d.ts +4 -0
  146. package/dist/lib/browser/service.js +30 -3
  147. package/dist/lib/browser/sessions-list.d.ts +22 -2
  148. package/dist/lib/browser/sessions-list.js +54 -6
  149. package/dist/lib/browser/stream.d.ts +2 -0
  150. package/dist/lib/browser/stream.js +1 -0
  151. package/dist/lib/browser/types.d.ts +19 -0
  152. package/dist/lib/byok-usage.d.ts +9 -2
  153. package/dist/lib/byok-usage.js +133 -31
  154. package/dist/lib/cli-entry.d.ts +11 -0
  155. package/dist/lib/cli-entry.js +46 -0
  156. package/dist/lib/cloud/host.d.ts +1 -1
  157. package/dist/lib/cloud/host.js +2 -2
  158. package/dist/lib/cloud/registry.js +1 -1
  159. package/dist/lib/cloud/types.d.ts +1 -1
  160. package/dist/lib/codex-policy.d.ts +9 -1
  161. package/dist/lib/codex-policy.js +17 -2
  162. package/dist/lib/commands.d.ts +2 -0
  163. package/dist/lib/commands.js +2 -0
  164. package/dist/lib/computer/sessions-list.d.ts +150 -0
  165. package/dist/lib/computer/sessions-list.js +363 -0
  166. package/dist/lib/config-keys.d.ts +86 -0
  167. package/dist/lib/config-keys.js +193 -0
  168. package/dist/lib/config-machine-keys.d.ts +12 -0
  169. package/dist/lib/config-machine-keys.js +17 -0
  170. package/dist/lib/config-transfer.js +3 -4
  171. package/dist/lib/crabbox/cli.d.ts +2 -2
  172. package/dist/lib/crabbox/cli.js +3 -3
  173. package/dist/lib/daemon-health.d.ts +22 -0
  174. package/dist/lib/daemon-health.js +33 -3
  175. package/dist/lib/daemon-services.d.ts +50 -0
  176. package/dist/lib/daemon-services.js +147 -0
  177. package/dist/lib/daemon-ticks.d.ts +35 -66
  178. package/dist/lib/daemon-ticks.js +77 -159
  179. package/dist/lib/daemon.d.ts +72 -4
  180. package/dist/lib/daemon.js +792 -202
  181. package/dist/lib/deeplink/register.d.ts +49 -0
  182. package/dist/lib/deeplink/register.js +253 -0
  183. package/dist/lib/deeplink/url.d.ts +34 -0
  184. package/dist/lib/deeplink/url.js +78 -0
  185. package/dist/lib/device-config.d.ts +124 -29
  186. package/dist/lib/device-config.js +346 -141
  187. package/dist/lib/devices/config-migration.d.ts +42 -0
  188. package/dist/lib/devices/config-migration.js +203 -0
  189. package/dist/lib/devices/connect.js +14 -7
  190. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  191. package/dist/lib/devices/doctor-findings.js +20 -1
  192. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  193. package/dist/lib/devices/harness-inventory.js +0 -0
  194. package/dist/lib/devices/health.d.ts +1 -1
  195. package/dist/lib/devices/health.js +1 -1
  196. package/dist/lib/devices/pending.d.ts +22 -1
  197. package/dist/lib/devices/pending.js +67 -2
  198. package/dist/lib/devices/registry.d.ts +0 -25
  199. package/dist/lib/devices/registry.js +2 -83
  200. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  201. package/dist/lib/devices/resolve-profile.js +44 -0
  202. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  203. package/dist/lib/devices/rollout-verify.js +193 -0
  204. package/dist/lib/devices/ssh-config.js +10 -6
  205. package/dist/lib/event-families.d.ts +28 -0
  206. package/dist/lib/event-families.js +159 -0
  207. package/dist/lib/event-stream.d.ts +9 -1
  208. package/dist/lib/event-stream.js +26 -9
  209. package/dist/lib/events.d.ts +9 -1
  210. package/dist/lib/events.js +21 -6
  211. package/dist/lib/exec.d.ts +30 -0
  212. package/dist/lib/exec.js +220 -122
  213. package/dist/lib/feed-broadcast.d.ts +25 -0
  214. package/dist/lib/feed-broadcast.js +33 -0
  215. package/dist/lib/feed.d.ts +1 -1
  216. package/dist/lib/feed.js +12 -2
  217. package/dist/lib/fleet/capture.js +15 -0
  218. package/dist/lib/fleet/manifest.js +9 -0
  219. package/dist/lib/fleet/types.d.ts +9 -0
  220. package/dist/lib/fleet-status.js +10 -8
  221. package/dist/lib/git.d.ts +20 -6
  222. package/dist/lib/git.js +121 -17
  223. package/dist/lib/hosts/dispatch.d.ts +8 -3
  224. package/dist/lib/hosts/dispatch.js +29 -3
  225. package/dist/lib/hosts/logs.d.ts +2 -2
  226. package/dist/lib/hosts/logs.js +2 -2
  227. package/dist/lib/hosts/option.js +1 -1
  228. package/dist/lib/hosts/passthrough.d.ts +2 -3
  229. package/dist/lib/hosts/passthrough.js +10 -24
  230. package/dist/lib/hosts/progress.js +2 -2
  231. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  232. package/dist/lib/hosts/providers/devices.js +18 -12
  233. package/dist/lib/hosts/ready.d.ts +5 -1
  234. package/dist/lib/hosts/ready.js +9 -3
  235. package/dist/lib/hosts/reconcile.d.ts +2 -2
  236. package/dist/lib/hosts/reconcile.js +2 -2
  237. package/dist/lib/hosts/registry.js +14 -9
  238. package/dist/lib/hosts/remote-cmd.js +1 -1
  239. package/dist/lib/hosts/remote-os.d.ts +9 -6
  240. package/dist/lib/hosts/remote-os.js +13 -6
  241. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  242. package/dist/lib/hosts/routing-flag.js +41 -0
  243. package/dist/lib/hosts/run-target.js +1 -1
  244. package/dist/lib/hosts/session-index.js +1 -1
  245. package/dist/lib/hosts/tasks.d.ts +6 -6
  246. package/dist/lib/hosts/tasks.js +4 -4
  247. package/dist/lib/hosts/types.js +1 -2
  248. package/dist/lib/installations/resolve.js +2 -8
  249. package/dist/lib/isolation-boundary-report.js +0 -1
  250. package/dist/lib/linear-cache.d.ts +7 -0
  251. package/dist/lib/linear-cache.js +31 -4
  252. package/dist/lib/linear-project-counts.d.ts +1 -1
  253. package/dist/lib/linear-project-counts.js +2 -3
  254. package/dist/lib/linear-projects.js +1 -1
  255. package/dist/lib/loop.d.ts +2 -2
  256. package/dist/lib/loop.js +1 -1
  257. package/dist/lib/mailbox-target.d.ts +1 -1
  258. package/dist/lib/mailbox-target.js +1 -1
  259. package/dist/lib/manifest.js +7 -4
  260. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  262. package/dist/lib/menubar/snapshot.d.ts +3 -2
  263. package/dist/lib/menubar/snapshot.js +6 -2
  264. package/dist/lib/migrate-fold.d.ts +33 -0
  265. package/dist/lib/migrate-fold.js +130 -0
  266. package/dist/lib/migrate.d.ts +34 -34
  267. package/dist/lib/migrate.js +106 -128
  268. package/dist/lib/model-tier-overrides.d.ts +1 -1
  269. package/dist/lib/model-tier-overrides.js +15 -2
  270. package/dist/lib/monitors/config.d.ts +17 -3
  271. package/dist/lib/monitors/config.js +52 -18
  272. package/dist/lib/monitors/engine.d.ts +32 -1
  273. package/dist/lib/monitors/engine.js +94 -11
  274. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  275. package/dist/lib/monitors/fingerprint.js +100 -0
  276. package/dist/lib/monitors/remote.d.ts +47 -0
  277. package/dist/lib/monitors/remote.js +81 -0
  278. package/dist/lib/monitors/state.d.ts +39 -0
  279. package/dist/lib/monitors/state.js +56 -0
  280. package/dist/lib/onepassword.d.ts +17 -0
  281. package/dist/lib/onepassword.js +52 -22
  282. package/dist/lib/open-url.js +1 -1
  283. package/dist/lib/picker.d.ts +14 -2
  284. package/dist/lib/picker.js +35 -13
  285. package/dist/lib/placement.d.ts +1 -1
  286. package/dist/lib/placement.js +1 -1
  287. package/dist/lib/pr-land-detach.d.ts +32 -0
  288. package/dist/lib/pr-land-detach.js +79 -0
  289. package/dist/lib/profiles-presets.js +13 -0
  290. package/dist/lib/profiles.d.ts +2 -0
  291. package/dist/lib/profiles.js +44 -1
  292. package/dist/lib/project-focus.d.ts +1 -1
  293. package/dist/lib/project-focus.js +1 -1
  294. package/dist/lib/project-key.d.ts +17 -0
  295. package/dist/lib/project-key.js +26 -0
  296. package/dist/lib/project-probe.d.ts +4 -1
  297. package/dist/lib/project-probe.js +5 -4
  298. package/dist/lib/project-resources.js +2 -18
  299. package/dist/lib/project-root.d.ts +16 -0
  300. package/dist/lib/project-root.js +20 -2
  301. package/dist/lib/projects.d.ts +20 -1
  302. package/dist/lib/projects.js +78 -1
  303. package/dist/lib/refresh-coordinator.d.ts +24 -0
  304. package/dist/lib/refresh-coordinator.js +52 -0
  305. package/dist/lib/registry.d.ts +2 -2
  306. package/dist/lib/registry.js +1 -1
  307. package/dist/lib/resource-aliases.d.ts +13 -0
  308. package/dist/lib/resource-aliases.js +26 -0
  309. package/dist/lib/resources/types.d.ts +1 -1
  310. package/dist/lib/resources.d.ts +16 -0
  311. package/dist/lib/resources.js +66 -10
  312. package/dist/lib/rotate.d.ts +3 -4
  313. package/dist/lib/rotate.js +4 -5
  314. package/dist/lib/routine-activation.d.ts +22 -2
  315. package/dist/lib/routine-activation.js +63 -16
  316. package/dist/lib/routine-context.d.ts +9 -2
  317. package/dist/lib/routine-context.js +21 -6
  318. package/dist/lib/routines-project.d.ts +58 -48
  319. package/dist/lib/routines-project.js +190 -159
  320. package/dist/lib/routines.d.ts +41 -6
  321. package/dist/lib/routines.js +92 -34
  322. package/dist/lib/run-defaults.d.ts +5 -0
  323. package/dist/lib/run-defaults.js +11 -1
  324. package/dist/lib/runner.d.ts +10 -8
  325. package/dist/lib/runner.js +122 -39
  326. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  327. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  328. package/dist/lib/secrets/agent.d.ts +10 -3
  329. package/dist/lib/secrets/agent.js +43 -8
  330. package/dist/lib/secrets/bundles.d.ts +1 -0
  331. package/dist/lib/secrets/bundles.js +92 -80
  332. package/dist/lib/secrets/index.js +32 -9
  333. package/dist/lib/secrets/install-helper.d.ts +4 -4
  334. package/dist/lib/secrets/install-helper.js +4 -4
  335. package/dist/lib/secrets/push.d.ts +40 -6
  336. package/dist/lib/secrets/push.js +58 -11
  337. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  338. package/dist/lib/secrets/read-backoff.js +1 -1
  339. package/dist/lib/secrets/remote.d.ts +24 -0
  340. package/dist/lib/secrets/remote.js +54 -4
  341. package/dist/lib/self-update.d.ts +108 -0
  342. package/dist/lib/self-update.js +276 -1
  343. package/dist/lib/session/active.d.ts +89 -5
  344. package/dist/lib/session/active.js +165 -10
  345. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  346. package/dist/lib/session/actor-sidecar.js +2 -1
  347. package/dist/lib/session/db.d.ts +176 -2
  348. package/dist/lib/session/db.js +484 -17
  349. package/dist/lib/session/discover.js +27 -4
  350. package/dist/lib/session/hook-sessions.js +2 -2
  351. package/dist/lib/session/host-link.d.ts +2 -2
  352. package/dist/lib/session/host-link.js +2 -2
  353. package/dist/lib/session/pid-registry.d.ts +21 -0
  354. package/dist/lib/session/pid-registry.js +57 -0
  355. package/dist/lib/session/remote-active.js +15 -1
  356. package/dist/lib/session/remote.js +2 -2
  357. package/dist/lib/session/session-cache.d.ts +14 -7
  358. package/dist/lib/session/session-cache.js +51 -9
  359. package/dist/lib/session/state.d.ts +2 -2
  360. package/dist/lib/session/state.js +1 -1
  361. package/dist/lib/session/sync/config.d.ts +10 -10
  362. package/dist/lib/session/sync/config.js +10 -10
  363. package/dist/lib/session/sync/r2.d.ts +34 -0
  364. package/dist/lib/session/sync/r2.js +123 -0
  365. package/dist/lib/session/throughput.d.ts +1 -1
  366. package/dist/lib/session/throughput.js +1 -1
  367. package/dist/lib/session/types.d.ts +23 -1
  368. package/dist/lib/session/types.js +15 -0
  369. package/dist/lib/session/viewing-in.d.ts +1 -1
  370. package/dist/lib/session/viewing-in.js +1 -1
  371. package/dist/lib/session/watch.d.ts +101 -0
  372. package/dist/lib/session/watch.js +242 -0
  373. package/dist/lib/share/config.d.ts +4 -0
  374. package/dist/lib/share/config.js +1 -0
  375. package/dist/lib/share/delete.d.ts +93 -0
  376. package/dist/lib/share/delete.js +127 -0
  377. package/dist/lib/share/provision.d.ts +38 -0
  378. package/dist/lib/share/provision.js +50 -0
  379. package/dist/lib/share/publish.d.ts +40 -1
  380. package/dist/lib/share/publish.js +116 -3
  381. package/dist/lib/share/worker-template.js +71 -6
  382. package/dist/lib/shims.d.ts +17 -3
  383. package/dist/lib/shims.js +136 -27
  384. package/dist/lib/signin-badge.js +3 -2
  385. package/dist/lib/skills.js +2 -0
  386. package/dist/lib/smart-launch.d.ts +8 -8
  387. package/dist/lib/smart-launch.js +80 -59
  388. package/dist/lib/ssh-exec.d.ts +1 -1
  389. package/dist/lib/ssh-exec.js +1 -1
  390. package/dist/lib/staleness/prune.d.ts +88 -0
  391. package/dist/lib/staleness/prune.js +69 -0
  392. package/dist/lib/staleness/registry.d.ts +1 -1
  393. package/dist/lib/staleness/writers/commands.js +34 -2
  394. package/dist/lib/staleness/writers/hooks.js +16 -0
  395. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  396. package/dist/lib/staleness/writers/skills.js +19 -0
  397. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  398. package/dist/lib/staleness/writers/subagents.js +0 -4
  399. package/dist/lib/staleness/writers/types.d.ts +32 -0
  400. package/dist/lib/startup/command-registry.d.ts +6 -12
  401. package/dist/lib/startup/command-registry.js +14 -31
  402. package/dist/lib/startup/dev-build.d.ts +10 -0
  403. package/dist/lib/startup/dev-build.js +13 -1
  404. package/dist/lib/startup/spellcheck.d.ts +18 -0
  405. package/dist/lib/startup/spellcheck.js +45 -0
  406. package/dist/lib/state.d.ts +36 -9
  407. package/dist/lib/state.js +96 -46
  408. package/dist/lib/subagents-registry.d.ts +0 -7
  409. package/dist/lib/subagents-registry.js +38 -65
  410. package/dist/lib/subagents.d.ts +0 -33
  411. package/dist/lib/subagents.js +0 -75
  412. package/dist/lib/sync-umbrella.js +1 -1
  413. package/dist/lib/teams/agents.d.ts +41 -1
  414. package/dist/lib/teams/agents.js +187 -9
  415. package/dist/lib/teams/api.d.ts +11 -1
  416. package/dist/lib/teams/api.js +11 -2
  417. package/dist/lib/teams/delivery.d.ts +41 -0
  418. package/dist/lib/teams/delivery.js +60 -0
  419. package/dist/lib/teams/registry.d.ts +14 -0
  420. package/dist/lib/teams/registry.js +51 -1
  421. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  422. package/dist/lib/teams/remoteWorktree.js +29 -0
  423. package/dist/lib/teams/scheduler.d.ts +1 -1
  424. package/dist/lib/teams/scheduler.js +1 -1
  425. package/dist/lib/teams/worktree.d.ts +24 -0
  426. package/dist/lib/teams/worktree.js +42 -0
  427. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  428. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  429. package/dist/lib/terminal/engine.d.ts +4 -0
  430. package/dist/lib/terminal/engine.js +8 -2
  431. package/dist/lib/terminal/types.d.ts +21 -2
  432. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  433. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  434. package/dist/lib/tickets/list.d.ts +53 -0
  435. package/dist/lib/tickets/list.js +153 -0
  436. package/dist/lib/tmux/orphan-reap.d.ts +320 -0
  437. package/dist/lib/tmux/orphan-reap.js +644 -0
  438. package/dist/lib/tmux/session.d.ts +68 -3
  439. package/dist/lib/tmux/session.js +95 -5
  440. package/dist/lib/triggers/handlers.d.ts +20 -0
  441. package/dist/lib/triggers/handlers.js +6 -1
  442. package/dist/lib/types.d.ts +46 -34
  443. package/dist/lib/usage-fleet.d.ts +32 -0
  444. package/dist/lib/usage-fleet.js +125 -0
  445. package/dist/lib/usage-refresh.d.ts +3 -3
  446. package/dist/lib/usage-refresh.js +19 -16
  447. package/dist/lib/usage.d.ts +51 -47
  448. package/dist/lib/usage.js +145 -153
  449. package/dist/lib/version-duplicates.js +2 -2
  450. package/dist/lib/versions.d.ts +56 -13
  451. package/dist/lib/versions.js +195 -45
  452. package/dist/lib/watchdog/log.d.ts +1 -1
  453. package/dist/lib/watchdog/log.js +3 -3
  454. package/dist/lib/watchdog/rotate.d.ts +6 -6
  455. package/dist/lib/watchdog/rotate.js +6 -6
  456. package/dist/lib/workflows.d.ts +1 -1
  457. package/dist/lib/yaml-io.d.ts +47 -0
  458. package/dist/lib/yaml-io.js +55 -0
  459. package/package.json +2 -1
  460. package/scripts/install-helper.js +2 -2
  461. package/scripts/postinstall.js +23 -20
  462. package/dist/commands/defaults.d.ts +0 -7
  463. package/dist/commands/defaults.js +0 -107
  464. package/dist/commands/export.d.ts +0 -11
  465. package/dist/commands/export.js +0 -215
  466. package/dist/commands/helper.d.ts +0 -12
  467. package/dist/commands/helper.js +0 -87
  468. package/dist/commands/hosts.d.ts +0 -11
  469. package/dist/commands/hosts.js +0 -330
  470. package/dist/commands/lock.d.ts +0 -12
  471. package/dist/commands/lock.js +0 -70
  472. package/dist/commands/pull.d.ts +0 -17
  473. package/dist/commands/pull.js +0 -39
  474. package/dist/commands/push.d.ts +0 -14
  475. package/dist/commands/push.js +0 -30
  476. package/dist/commands/wallet.d.ts +0 -20
  477. package/dist/commands/wallet.js +0 -216
  478. package/dist/commands/worktree.d.ts +0 -19
  479. package/dist/commands/worktree.js +0 -272
  480. package/dist/lib/account-labels.d.ts +0 -24
  481. package/dist/lib/account-labels.js +0 -72
  482. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  483. package/dist/lib/auto-dispatch-linear.js +0 -107
  484. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  485. package/dist/lib/auto-dispatch-provider.js +0 -30
  486. package/dist/lib/auto-dispatch.d.ts +0 -93
  487. package/dist/lib/auto-dispatch.js +0 -128
  488. package/dist/lib/export.d.ts +0 -72
  489. package/dist/lib/export.js +0 -269
  490. package/dist/lib/lock.d.ts +0 -93
  491. package/dist/lib/lock.js +0 -207
  492. package/dist/lib/wallet/index.d.ts +0 -78
  493. package/dist/lib/wallet/index.js +0 -253
@@ -19,14 +19,105 @@ import { execFileSync } from 'child_process';
19
19
  import * as fs from 'fs';
20
20
  import * as path from 'path';
21
21
  import { setHelpSections } from '../lib/help.js';
22
- import { getDaemonStatus, isDaemonRunning, isDaemonWedged, readDaemonLog, startDaemon, stopDaemon, signalDaemonReload, findSurvivingStateDirDaemons, } from '../lib/daemon.js';
22
+ import { getDaemonStatus, isDaemonRunning, isDaemonWedged, readDaemonLog, startDaemon, stopDaemon, signalDaemonReload, findSurvivingStateDirDaemons, getDaemonLogPath, isDaemonAutostartCircuitOpen, } from '../lib/daemon.js';
23
23
  import { getConfigValue, setConfigValue, isDaemonEnabled } from '../lib/device-config.js';
24
- import { readSubsystemHealth, SUBSYSTEM_SECRETS_BROKER, SUBSYSTEM_BROWSER_IPC, } from '../lib/daemon-health.js';
24
+ import { readSubsystemHealth, SUBSYSTEM_SECRETS_BROKER, SUBSYSTEM_BROWSER_IPC, SUBSYSTEM_DAEMON_START, } from '../lib/daemon-health.js';
25
+ import { DAEMON_SERVICE_IDS, listDaemonServiceStates, setDaemonServiceEnabled, getDaemonServicesConfigPath, } from '../lib/daemon-services.js';
25
26
  import { listJobs, getLatestRun } from '../lib/routines.js';
26
27
  import { JobScheduler } from '../lib/scheduler.js';
27
- import { getDaemonDir } from '../lib/state.js';
28
28
  import { followFile } from '../lib/log-follow.js';
29
29
  import { parseDuration } from '../lib/hooks/cache.js';
30
+ import { registerFunnelCommand } from './funnel.js';
31
+ /**
32
+ * Provably absent, or null when unknowable.
33
+ *
34
+ * `fs.existsSync` cannot express the difference: it returns false for ANY failed
35
+ * stat, so `EACCES` on a parent directory is indistinguishable from deletion.
36
+ * The feeding scan is box-wide `ps` with no uid filter, so that gap is reachable
37
+ * on any shared box — `/root` is mode 700, and a stat of a root-owned daemon's
38
+ * entry from an ordinary uid returns false while the file is perfectly present.
39
+ * Reporting that would tell the user to `kill` a healthy daemon they do not own,
40
+ * with a command that would `EPERM` anyway.
41
+ *
42
+ * `statSync(p, { throwIfNoEntry: false })` returns `undefined` only for `ENOENT`
43
+ * and throws for everything else, which is exactly the distinction needed.
44
+ */
45
+ function entryAbsent(p) {
46
+ try {
47
+ return fs.statSync(p, { throwIfNoEntry: false }) === undefined;
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ /**
54
+ * A daemon whose launch entry is provably gone from disk (RUSH-2493).
55
+ *
56
+ * This predicate answers only "is this one's code gone?". WHO may be told about
57
+ * it, and whether that report is actionable, is {@link staleDaemons}'s job — a
58
+ * separation reached the hard way: an early revision reported every box-wide
59
+ * `ps` match as actionable (re-opening RUSH-2368), and the correction then
60
+ * over-swung to registry-only, which silently excluded the very incident below.
61
+ *
62
+ * Observed 2026-08-10 on yosemite-s0: a daemon ran for 4h14m from
63
+ * `.agents/worktrees/rush-2431-binary-shadow/apps/cli/dist/index.js` after that
64
+ * worktree was deleted. `systemctl --user is-active` said `active`,
65
+ * `agents daemon status` reported healthy, and nothing anywhere named it —
66
+ * while it held a second routine scheduler, the double-fire class the
67
+ * one-scheduler-one-executor rule exists to prevent. A restart would also have
68
+ * failed, since the manifest pointed at the same missing path.
69
+ *
70
+ * ABSOLUTE PATHS ONLY. `entryFromTokens` returns the second-to-last argv token,
71
+ * which is the entry for a real daemon (`getDaemonLaunch` always spawns an
72
+ * absolute one) but is arbitrary text for anything else — `node -e '<code>'
73
+ * __daemon-run` yields the code blob, which of course does not exist on disk.
74
+ * Requiring absoluteness keeps a non-path token from being reported as deleted
75
+ * code, the same false-positive class RUSH-2368 had to correct for duplicates.
76
+ *
77
+ * That guard also covers an entry path containing SPACES, which `ps` renders
78
+ * unquoted and the tokenizer therefore splits: `/tmp/ghost space/sub/index.js`
79
+ * yields `space/sub/index.js`, not absolute, so a healthy daemon on such a path
80
+ * is never accused (verified live). The cost is a false NEGATIVE — a genuinely
81
+ * deleted entry containing a space is not reported either. That is the safe
82
+ * direction to fail: missing one detection is a silence we already lived with,
83
+ * whereas telling someone to `kill` a healthy shared daemon is a new harm.
84
+ */
85
+ function entryIsGone(p) {
86
+ return p.entry !== null && path.isAbsolute(p.entry) && p.entryMissing === true;
87
+ }
88
+ /**
89
+ * Stale daemons split into two tiers, because DETECTION and ACCUSATION are
90
+ * different acts with different blast radii.
91
+ *
92
+ * RUSH-2368's harm was the accusation, not the sighting: a leaked fixture "was
93
+ * reported as a stray to `kill`". So the narrow registry scope is what gates
94
+ * anything actionable — a `doctor` problem, a non-zero exit, a `kill` — while a
95
+ * same-uid sighting is merely shown.
96
+ *
97
+ * That split is not academic. The incident this feature exists to catch was
98
+ * neither the tracked pid nor in the registry: it ran under an ephemeral `/tmp`
99
+ * cwd from a deleted worktree, and `lib/daemon.ts` documents that such a process
100
+ * "registers under its own state dir and is invisible here" BY DESIGN. Gating
101
+ * the display on the registry too would have made this command silent on the
102
+ * exact 4h14m ghost that motivated it.
103
+ *
104
+ * `actionable` — this device's daemon, or this install's registry. Drives
105
+ * `doctor` problems and the `kill`/`restart` remediation.
106
+ * `visible` — additionally any daemon running as THIS uid. Shown in
107
+ * `status`, never exits non-zero, never told to kill.
108
+ *
109
+ * A different uid is never named at all: we cannot reliably stat its entry
110
+ * ({@link entryAbsent}), and we could not signal it if we tried.
111
+ */
112
+ function staleDaemons(processes, ownerPid, registered) {
113
+ const isOurs = (p) => p.pid === ownerPid || registered.has(p.pid);
114
+ const myUid = typeof process.getuid === 'function' ? process.getuid() : null;
115
+ const gone = processes.filter(entryIsGone);
116
+ return {
117
+ actionable: gone.filter(isOurs),
118
+ visible: gone.filter((p) => isOurs(p) || (myUid !== null && p.uid === myUid)),
119
+ };
120
+ }
30
121
  /**
31
122
  * Resolve the working directory a live process was started from, or null if
32
123
  * unavailable. Linux only (`/proc/<pid>/cwd`) — there is no equivalent
@@ -118,26 +209,31 @@ function scanDaemonProcesses() {
118
209
  return [];
119
210
  let out;
120
211
  try {
121
- out = execFileSync('ps', ['-eo', 'pid=,args='], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
212
+ out = execFileSync('ps', ['-eo', 'pid=,uid=,args='], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
122
213
  }
123
214
  catch {
124
215
  return [];
125
216
  }
126
217
  const found = [];
127
218
  for (const line of out.split('\n')) {
128
- const m = line.trim().match(/^(\d+)\s+(.*)$/);
219
+ const m = line.trim().match(/^(\d+)\s+(\d+)\s+(.*)$/);
129
220
  if (!m)
130
221
  continue;
131
- const args = m[2].trim();
222
+ const args = m[3].trim();
132
223
  const tokens = args.split(/\s+/);
133
224
  if (tokens.length === 0 || tokens[tokens.length - 1] !== '__daemon-run')
134
225
  continue;
135
226
  const pid = parseInt(m[1], 10);
136
227
  if (isNaN(pid))
137
228
  continue;
229
+ const uidParsed = parseInt(m[2], 10);
230
+ const uid = isNaN(uidParsed) ? null : uidParsed;
138
231
  const entry = entryFromTokens(tokens);
139
232
  const version = entry ? resolveVersionNear(entry, pid) : null;
140
- found.push({ pid, entry, version });
233
+ // Asks whether the code is on disk for the NEXT launch -- what a restart and
234
+ // every other reader will see -- not what this pid currently has mapped.
235
+ const entryMissing = entry ? entryAbsent(entry) : false;
236
+ found.push({ pid, entry, version, entryMissing, uid });
141
237
  }
142
238
  return found;
143
239
  }
@@ -255,6 +351,17 @@ async function runStatus(opts) {
255
351
  const processes = scanDaemonProcesses();
256
352
  const owner = pid ? processes.find((p) => p.pid === pid) : undefined;
257
353
  const duplicates = registryScopedDuplicates(processes, pid ?? null);
354
+ // Every daemon whose code is gone from disk, including this device's own if
355
+ // it is one. Not filtered by the duplicate scope — see entryIsGone.
356
+ // Deliberately its own read, NOT shared with registryScopedDuplicates above.
357
+ // That one passes `exclude` INTO findSurvivingStateDirDaemons to drop the
358
+ // owner, so handing it a shared empty-exclude snapshot would put ownerPid back
359
+ // in the set and report this device's daemon as its own duplicate. The saving
360
+ // would be one `ps` spawn per registered pid, at the 1-3 that actually run.
361
+ const registeredPids = new Set(findSurvivingStateDirDaemons(new Set()));
362
+ const staleTiers = staleDaemons(processes, pid ?? null, registeredPids);
363
+ const stale = staleTiers.visible;
364
+ const ownerEntryGone = owner ? entryIsGone(owner) : false;
258
365
  const [secrets, browserIpc] = await Promise.all([probeSecretsBroker(), probeBrowserIPC()]);
259
366
  const scheduler = schedulerSummary();
260
367
  if (opts.json) {
@@ -266,7 +373,18 @@ async function runStatus(opts) {
266
373
  logPath: status.logPath,
267
374
  binaryPath: owner?.entry ?? status.binaryPath,
268
375
  binaryVersion: owner?.version ?? null,
376
+ binaryMissing: ownerEntryGone,
269
377
  duplicates: duplicates.map((d) => ({ pid: d.pid, entry: d.entry, version: d.version })),
378
+ // `actionable` is part of the contract, not decoration: a routine or
379
+ // monitor reading this must be able to tell a ghost it may act on from one
380
+ // that is merely visible. Without it the machine surface re-opens exactly
381
+ // what the two-tier split closed for the text surface.
382
+ staleBinaries: stale.map((d) => ({
383
+ pid: d.pid,
384
+ entry: d.entry,
385
+ version: d.version,
386
+ actionable: staleTiers.actionable.some((a) => a.pid === d.pid),
387
+ })),
270
388
  daemonEnabled: enabled,
271
389
  services: {
272
390
  secretsBroker: {
@@ -304,11 +422,36 @@ async function runStatus(opts) {
304
422
  console.log(` Uptime: ${humanDuration(uptime)}`);
305
423
  if (heartbeatAgeMs !== null)
306
424
  console.log(` Heartbeat: ${Math.round(heartbeatAgeMs / 1000)}s ago`);
307
- console.log(` Binary: ${chalk.gray(owner?.entry ?? status.binaryPath ?? 'unknown')}`);
425
+ const binaryLabel = owner?.entry ?? status.binaryPath ?? 'unknown';
426
+ console.log(` Binary: ${ownerEntryGone ? chalk.red(`${binaryLabel} (MISSING from disk)`) : chalk.gray(binaryLabel)}`);
308
427
  console.log(` Version: ${chalk.gray(owner?.version ?? 'unknown')}`);
309
428
  console.log(` Log: ${chalk.gray(status.logPath)}`);
310
429
  if (!enabled)
311
430
  console.log(chalk.yellow(` daemon.enabled is false — nothing auto-starts it. Explicit start: agents daemon start`));
431
+ if (stale.length > 0) {
432
+ console.log(chalk.red(`\nStale code (${stale.length})\n`));
433
+ const actionablePids = new Set(staleTiers.actionable.map((d) => d.pid));
434
+ for (const d of stale) {
435
+ const mine = pid !== null && d.pid === pid ? ' — this is the daemon above' : '';
436
+ const note = mine || (actionablePids.has(d.pid) ? '' : ' — not this install; shown for visibility');
437
+ console.log(` PID ${d.pid} ${chalk.gray(d.entry ?? 'unknown entry')}${chalk.red(' (deleted)')}${chalk.gray(note)}`);
438
+ }
439
+ const advice = [
440
+ '\n These run code that no longer exists on disk, so a restart fails and their',
441
+ ' behaviour is whatever was loaded when the file was deleted.',
442
+ ];
443
+ // Only offer a remedy when a row here is one we may act on. Printing
444
+ // `kill <pid>` under a section whose only rows are visibility-tier is
445
+ // RUSH-2368's harm re-entering through the render layer after the data
446
+ // layer stopped producing it.
447
+ if (staleTiers.actionable.length > 0) {
448
+ advice.push(` Yours: ${chalk.white('agents daemon restart')} A stray this install owns: ${chalk.white('kill <pid>')}`);
449
+ }
450
+ else {
451
+ advice.push(' None belong to this install — nothing for you to stop here.');
452
+ }
453
+ console.log(chalk.gray(advice.join('\n')));
454
+ }
312
455
  if (duplicates.length > 0) {
313
456
  console.log(chalk.red(`\nDuplicates (${duplicates.length})\n`));
314
457
  for (const d of duplicates) {
@@ -377,7 +520,7 @@ async function runLogs(opts) {
377
520
  const sinceMs = opts.since ? Date.now() - (parseDuration(opts.since) ?? 0) * 1000 : undefined;
378
521
  const lineCount = opts.lines ? parseInt(opts.lines, 10) : 50;
379
522
  if (opts.follow) {
380
- const logPath = path.join(getDaemonDir(), 'logs.jsonl');
523
+ const logPath = getDaemonLogPath();
381
524
  for (const entry of parseLogLines(readDaemonLog(lineCount)).filter((e) => passesFilters(e, opts.level, sinceMs))) {
382
525
  if (opts.json)
383
526
  console.log(JSON.stringify(entry));
@@ -419,10 +562,37 @@ async function runDoctor(opts) {
419
562
  problems.push('Daemon is not running. Start it: agents daemon start');
420
563
  if (status.running && isDaemonWedged())
421
564
  problems.push('Daemon is wedged (heartbeat stale). Restart: agents daemon restart');
422
- const duplicates = registryScopedDuplicates(scanDaemonProcesses(), status.pid);
565
+ // RUSH-2418: an open auto-start circuit breaker is the FIRST thing to report
566
+ // for a stopped daemon — otherwise the only advice is "agents daemon start",
567
+ // which is the exact action the breaker just refused, with no hint that a
568
+ // breaker exists or what the underlying failure was. This is where the
569
+ // breaker's own message sends the operator, so it has to answer them.
570
+ const startHealth = readSubsystemHealth(SUBSYSTEM_DAEMON_START);
571
+ if (isDaemonAutostartCircuitOpen()) {
572
+ problems.push(`Daemon auto-start is disabled after ${startHealth?.consecutiveFailures ?? 0} consecutive starts that never reported healthy: ` +
573
+ `${startHealth?.lastError ?? 'no reason recorded'}. Fix the cause, then retry with: agents daemon start`);
574
+ }
575
+ else if (!status.running && startHealth && startHealth.consecutiveFailures > 0) {
576
+ // Only while the daemon is DOWN. A start is marked as failed the moment it
577
+ // is issued and cleared once the daemon finishes booting, so a running
578
+ // daemon with a non-zero streak is just the boot window (or a daemon
579
+ // launched outside startDaemon) — reporting it there is a false alarm that
580
+ // clears itself a second later.
581
+ problems.push(`Daemon start has ${startHealth.consecutiveFailures} consecutive failure(s): ${startHealth.lastError}`);
582
+ }
583
+ const healthProcesses = scanDaemonProcesses();
584
+ const duplicates = registryScopedDuplicates(healthProcesses, status.pid);
423
585
  if (duplicates.length > 0) {
424
586
  problems.push(`${duplicates.length} duplicate daemon process(es) running: ${duplicates.map((d) => d.pid).join(', ')}. Stop the stray(s).`);
425
587
  }
588
+ // A daemon whose entry is gone from disk is a problem even when it answers
589
+ // every probe: it cannot restart, and it is running whatever was loaded
590
+ // before the file was deleted (RUSH-2493).
591
+ for (const p of staleDaemons(healthProcesses, status.pid, new Set(findSurvivingStateDirDaemons(new Set()))).actionable) {
592
+ const own = status.pid !== null && p.pid === status.pid;
593
+ problems.push(`Daemon pid ${p.pid} runs code deleted from disk (${p.entry}). ` +
594
+ (own ? 'Restart it: agents daemon restart' : 'Stray from a removed install/worktree. Stop it: kill ' + p.pid));
595
+ }
426
596
  const secrets = await probeSecretsBroker();
427
597
  if (!secrets.reachable)
428
598
  problems.push('Secrets broker is unreachable.');
@@ -468,7 +638,7 @@ export function registerDaemonCommand(program) {
468
638
  # Identity, duplicates, and per-service health in one view
469
639
  agents daemon status
470
640
 
471
- # Machine-readable status (for scripts / Factory)
641
+ # Machine-readable status (for scripts / AGI EXT)
472
642
  agents daemon status --json
473
643
 
474
644
  # Start / stop / restart the daemon process
@@ -486,6 +656,10 @@ export function registerDaemonCommand(program) {
486
656
  # Just the two hosted services (secrets broker, browser IPC)
487
657
  agents daemon services
488
658
 
659
+ # Manage public ingress for daemon-world webhook receivers
660
+ agents daemon funnel status yosemite-s0
661
+ agents daemon funnel up yosemite-s0 --local-port 8787 --port 443
662
+
489
663
  # Tail the daemon's own log, warnings and up, from the last hour
490
664
  agents daemon logs -f --level warn --since 1h
491
665
 
@@ -504,7 +678,7 @@ export function registerDaemonCommand(program) {
504
678
  `,
505
679
  });
506
680
  cmd.command('status')
507
- .description('Identity (state/pid/uptime/binary), duplicate daemon processes, and per-service health.')
681
+ .description('Identity (state/pid/uptime/binary), duplicate daemons, daemons running deleted code, and per-service health.')
508
682
  .option('--json', 'Emit as JSON')
509
683
  .action(async (opts, command) => {
510
684
  await runStatus({ json: command.optsWithGlobals().json === true });
@@ -595,12 +769,67 @@ export function registerDaemonCommand(program) {
595
769
  const ok = signalDaemonReload();
596
770
  console.log(ok ? chalk.green('Daemon reloaded') : chalk.yellow('Reload signal not delivered (unsupported on this platform, or the daemon just exited)'));
597
771
  });
598
- cmd.command('services')
599
- .description('The two hosted services (secrets broker, browser IPC): bound state, socket path, and health.')
772
+ const servicesCmd = cmd
773
+ .command('services')
774
+ .description('The hosted services: health, bound state, socket path, and per-service toggles.')
600
775
  .option('--json', 'Emit as JSON')
601
776
  .action(async (opts, command) => {
602
777
  await runServices({ json: command.optsWithGlobals().json === true });
603
778
  });
779
+ servicesCmd
780
+ .command('list')
781
+ .description('List every daemon service and whether it is enabled.')
782
+ .option('--json', 'Emit as JSON')
783
+ .action(async (opts, command) => {
784
+ const json = command.optsWithGlobals().json === true;
785
+ const states = listDaemonServiceStates();
786
+ if (json) {
787
+ console.log(JSON.stringify(states.map((s) => ({
788
+ id: s.id,
789
+ title: s.title,
790
+ enabled: s.enabled,
791
+ description: s.description,
792
+ })), null, 2));
793
+ return;
794
+ }
795
+ console.log(chalk.bold('Daemon services'));
796
+ for (const s of states) {
797
+ const state = s.enabled ? chalk.green('enabled') : chalk.gray('disabled');
798
+ console.log(` ${s.id.padEnd(18)} ${state}`);
799
+ console.log(` ${chalk.gray(s.description)}`);
800
+ }
801
+ console.log(chalk.gray(`\nConfig: ${getDaemonServicesConfigPath()}`));
802
+ console.log(chalk.gray('Changes take effect on the next daemon reload or restart.'));
803
+ });
804
+ servicesCmd
805
+ .command('enable <service>')
806
+ .description('Enable a daemon service.')
807
+ .action((service) => {
808
+ if (!DAEMON_SERVICE_IDS.includes(service)) {
809
+ console.error(chalk.red(`Unknown service '${service}'. Run 'agents daemon services list' for valid services.`));
810
+ process.exit(1);
811
+ }
812
+ setDaemonServiceEnabled(service, true);
813
+ console.log(chalk.green(`Enabled '${service}'.`));
814
+ if (isDaemonRunning()) {
815
+ console.log(chalk.gray('Run `agents daemon reload` (or restart) to apply.'));
816
+ }
817
+ });
818
+ servicesCmd
819
+ .command('disable <service>')
820
+ .description('Disable a daemon service.')
821
+ .action((service) => {
822
+ if (!DAEMON_SERVICE_IDS.includes(service)) {
823
+ console.error(chalk.red(`Unknown service '${service}'. Run 'agents daemon services list' for valid services.`));
824
+ process.exit(1);
825
+ }
826
+ setDaemonServiceEnabled(service, false);
827
+ console.log(chalk.green(`Disabled '${service}'.`));
828
+ if (isDaemonRunning()) {
829
+ console.log(chalk.gray('Run `agents daemon reload` (or restart) to apply.'));
830
+ }
831
+ });
832
+ registerFunnelCommand(cmd);
604
833
  cmd.command('logs')
605
834
  .description('Read the daemon\'s own log (lifecycle + subsystem errors — not routine run output).')
606
835
  .option('-n, --lines <number>', 'Show this many recent lines', '50')
@@ -3,7 +3,7 @@
3
3
  * resolver. Kept import-light (only a type import) so it is unit-tested without
4
4
  * loading the live-session discovery graph.
5
5
  */
6
- import type { ActiveSession } from '../lib/session/active.js';
6
+ import { type ActiveSession } from '../lib/session/active.js';
7
7
  /**
8
8
  * The prompt the backgrounded run resumes with. Its whole job is to stop a
9
9
  * now-unwatched agent from stalling on a confirmation nobody will answer: it
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Pure core of `agents sessions detach` — the nudge, the resumed-run argv, and the id
3
+ * resolver. Kept import-light (only a type import) so it is unit-tested without
4
+ * loading the live-session discovery graph.
5
+ */
6
+ import { sessionProcessHost } from '../lib/session/active.js';
1
7
  /**
2
8
  * The prompt the backgrounded run resumes with. Its whole job is to stop a
3
9
  * now-unwatched agent from stalling on a confirmation nobody will answer: it
@@ -40,8 +46,12 @@ export function resolveDetachTarget(s, self) {
40
46
  if (!sessionId) {
41
47
  return { kind: 'refuse', reason: 'That session has no id to resume, so it cannot be detached.' };
42
48
  }
43
- if (s.machine && s.machine !== self) {
44
- return { kind: 'remote', machine: s.machine, sessionId };
49
+ // The box to hop to is where the PROCESS is (a shim lives on its dispatcher),
50
+ // which is not always `machine`. `sessionProcessHost` returns undefined when
51
+ // the process is here, so a value means a genuine remote takeover.
52
+ const processHost = sessionProcessHost(s, self);
53
+ if (processHost) {
54
+ return { kind: 'remote', machine: processHost, sessionId };
45
55
  }
46
56
  return { kind: 'local', sessionId };
47
57
  }
@@ -166,6 +166,6 @@ export async function detachAction(id, opts = {}) {
166
166
  detachedAtMs: Date.now(),
167
167
  });
168
168
  console.log(chalk.green(`◒ Backgrounded ${agent} ${short}`) +
169
- chalk.gray(` — running headless (pid ${pid}). Bring it back: agents sessions attach ${short}`));
169
+ chalk.gray(` — running headless (pid ${pid}). Bring it back: agents sessions resume ${short}`));
170
170
  console.log(chalk.gray(` logs: ${logFile}`));
171
171
  }
@@ -38,7 +38,12 @@ import { auditWindowsSshEnrollment, diagnoseWindowsSshFailure } from '../lib/dev
38
38
  import { scanUserRcFiles, masterPassphraseInEnv } from '../lib/secrets/rc-hygiene.js';
39
39
  import { terminalWidth, truncateToWidth, stringWidth, padToWidth } from '../lib/session/width.js';
40
40
  import { readRepoBehindMarkers } from '../lib/auto-pull.js';
41
+ import { detectAgentsBinaryShadows } from '../lib/binary-shadow.js';
42
+ import { remediateStaleAgentsCliInstalls, resolveRunningPackageRoot, } from '../lib/self-update.js';
41
43
  import * as fs from 'fs';
44
+ import * as path from 'path';
45
+ import { fileURLToPath } from 'url';
46
+ const __doctorDirname = path.dirname(fileURLToPath(import.meta.url));
42
47
  const AGENT_NAMES = Object.fromEntries(ALL_AGENT_IDS.map((id) => [id, AGENTS[id].name]));
43
48
  // ─── overview mode (no target) ────────────────────────────────────────────────
44
49
  function collapseWhitespace(s) {
@@ -450,6 +455,7 @@ async function runDevicesDoctor(opts) {
450
455
  // Can the owner-delivery lane escalate a block from THIS box? Local only —
451
456
  // remote boxes self-report it in their own `agents doctor --json`.
452
457
  ownerSink: await probeOwnerSink(readMeta()),
458
+ binaryShadows: detectAgentsBinaryShadows(),
453
459
  }));
454
460
  accounts[localName] = r.inventory?.signIn ?? {};
455
461
  continue;
@@ -1160,6 +1166,40 @@ function renderHookRuntimeRepairText(repair) {
1160
1166
  console.log(` ${chalk.red('hold ')} ${chalk.gray(unresolved)}`);
1161
1167
  }
1162
1168
  }
1169
+ /**
1170
+ * RUSH-2415: delete npx-cache / unsafe-legacy / pre-1.22.30 agents-cli copies
1171
+ * when a fixed peer already exists. Bare `doctor --fix` is the remediation
1172
+ * surface the multi-install warning points at; a targeted
1173
+ * `doctor <agent>@<version> --fix` only heals that version home and must not
1174
+ * touch other CLI installs on the box.
1175
+ */
1176
+ function purgeStaleAgentsCliCopies(_opts) {
1177
+ let runningRoot;
1178
+ try {
1179
+ // dist/commands/doctor.js (or src/commands/doctor.ts under vitest) —
1180
+ // resolveRunningPackageRoot walks up until package.json names this package.
1181
+ runningRoot = resolveRunningPackageRoot(__doctorDirname);
1182
+ }
1183
+ catch {
1184
+ return null;
1185
+ }
1186
+ return remediateStaleAgentsCliInstalls({
1187
+ runningRoot,
1188
+ runningVersion: getCliVersion(),
1189
+ });
1190
+ }
1191
+ function renderStaleInstallPurgeText(purge) {
1192
+ if (purge.removed.length === 0 && purge.failed.length === 0)
1193
+ return;
1194
+ console.log(chalk.bold('\nStale agents-cli installs'));
1195
+ for (const r of purge.removed) {
1196
+ const why = r.reasons.join(', ');
1197
+ console.log(` ${chalk.green('purged')} ${chalk.gray(`${r.packageRoot} ${r.version} (${why})`)}`);
1198
+ }
1199
+ for (const f of purge.failed) {
1200
+ console.log(` ${chalk.red('hold ')} ${chalk.gray(`${f.packageRoot} ${f.version} — ${f.error}`)}`);
1201
+ }
1202
+ }
1163
1203
  async function runFix(parsed, opts) {
1164
1204
  // Heal targets the global install — project layer is irrelevant, so cwd is
1165
1205
  // left to heal's neutral default rather than process.cwd().
@@ -1180,23 +1220,41 @@ async function runFix(parsed, opts) {
1180
1220
  // repair have settled. This routine never calls sync/register and never
1181
1221
  // retries; unresolved wrappers remain an explicit non-zero doctor outcome.
1182
1222
  const hookRuntimeRepair = repairManagedHookRuntimeArtifacts({ filter: runtimeRepairFilter(parsed) });
1223
+ // Bare doctor --fix also purges latent pre-fix / legacy agents-cli copies
1224
+ // that only warn today (RUSH-2415). A scoped agent@version fix leaves them
1225
+ // alone — the multi-install surface is machine-wide, not per-agent.
1226
+ const staleInstallPurge = parsed === null ? purgeStaleAgentsCliCopies(opts) : null;
1183
1227
  const rewireFailed = rewired.some((entry) => entry.failure !== undefined);
1184
1228
  if (healChangedAnything(result) ||
1185
1229
  rewired.some((entry) => entry.rewired > 0 || entry.remaining > 0 || entry.failure !== undefined) ||
1186
- hookRuntimeRepair.attempts.length > 0) {
1230
+ hookRuntimeRepair.attempts.length > 0 ||
1231
+ (staleInstallPurge !== null && (staleInstallPurge.removed.length > 0 || staleInstallPurge.failed.length > 0))) {
1187
1232
  invalidateDoctorOverviewCache();
1188
1233
  }
1189
1234
  if (opts.json) {
1190
- console.log(JSON.stringify({ ...result, hookRewire: rewired, hookRuntimeRepair }, null, 2));
1191
- if (rewireFailed || hookRuntimeRepair.needsAttention.length > 0)
1235
+ console.log(JSON.stringify({
1236
+ ...result,
1237
+ hookRewire: rewired,
1238
+ hookRuntimeRepair,
1239
+ ...(staleInstallPurge ? { staleInstallPurge } : {}),
1240
+ }, null, 2));
1241
+ if (rewireFailed
1242
+ || hookRuntimeRepair.needsAttention.length > 0
1243
+ || (staleInstallPurge !== null && staleInstallPurge.failed.length > 0)) {
1192
1244
  process.exitCode = 1;
1245
+ }
1193
1246
  return;
1194
1247
  }
1195
1248
  renderHealText(result);
1196
1249
  renderHookRewireText(rewired);
1197
1250
  renderHookRuntimeRepairText(hookRuntimeRepair);
1198
- if (rewireFailed || hookRuntimeRepair.needsAttention.length > 0)
1251
+ if (staleInstallPurge)
1252
+ renderStaleInstallPurgeText(staleInstallPurge);
1253
+ if (rewireFailed
1254
+ || hookRuntimeRepair.needsAttention.length > 0
1255
+ || (staleInstallPurge !== null && staleInstallPurge.failed.length > 0)) {
1199
1256
  process.exitCode = 1;
1257
+ }
1200
1258
  }
1201
1259
  function checkLabel(row) {
1202
1260
  return `${AGENT_NAMES[row.agent] || row.agent}@${row.version}`;
@@ -1374,7 +1432,7 @@ export function registerDoctorCommand(program) {
1374
1432
  .description('Diagnose CLI availability, sync status, and resource divergence (optionally for a specific agent[@version]).')
1375
1433
  .option('--json', 'Output machine-readable JSON')
1376
1434
  .option('--diff', 'In target mode, include unified diffs for divergent files')
1377
- .option('--fix', 'Heal gaps: install missing resources, repair invalid plugin manifests, refresh stale plugins, and reconcile drift (all installed versions, or just the target)')
1435
+ .option('--fix', 'Heal gaps: install missing resources, repair invalid plugin manifests, refresh stale plugins, reconcile drift, and purge stale/legacy agents-cli installs (npx-cache, pre-1.22.30, unsafe helper installer) when a fixed peer exists')
1378
1436
  .option('--kind <kinds>', 'Restrict to comma-separated resource kinds (commands,skills,hooks,rules,mcp,permissions,subagents,plugins,promptcuts)')
1379
1437
  .option('--cwd <path>', 'Resolution cwd for project layer detection (default: process.cwd())')
1380
1438
  .option('--adopt <agent>', "Take over the agent's native launcher that shadows the shim (symlink it to the version-managed shim; reversible with --release)")
@@ -1591,6 +1649,7 @@ export function registerDoctorCommand(program) {
1591
1649
  .map((r) => `${r.agent}@${r.version}`);
1592
1650
  const findings = buildLocalFindings({
1593
1651
  device: localName,
1652
+ binaryShadows: detectAgentsBinaryShadows(),
1594
1653
  syncRows,
1595
1654
  orphanRows,
1596
1655
  repoBehind: repoBehindMarkers,
@@ -1,17 +1,16 @@
1
1
  /**
2
- * `agents events` — read the unified event stream.
2
+ * `agents events` — read the unified event stream (the one ops/timeline product).
3
3
  *
4
- * One stream over BOTH operational events (`~/.agents/.history/events/YYYY-MM-DD/`: every
5
- * `agents <module> <cmd>` invocation plus typed events like secrets access,
6
- * version installs) AND agent-semantic events (the per-session activity logs:
7
- * plans, PRs, worktrees, sub-agents, artifacts). Each is stamped with who ran
8
- * it and from where. This is the audit trail for "who accessed a secret /
9
- * created a team" AND the activity trail for "what did the agents just do".
4
+ * One stream over BOTH operational events (`~/.agents/.history/events/YYYY-MM-DD/`:
5
+ * every `agents <module> <cmd>` invocation plus typed events like secrets access,
6
+ * browser/computer, daemon lifecycle, version installs) AND agent-semantic events
7
+ * (per-session activity: plans, PRs, worktrees, sub-agents, artifacts). Run-dispatch
8
+ * outcomes land here as `run.dispatched` (readable via `--include runs`).
10
9
  *
11
- * Filter by `--module` (top-level group, e.g. teams; `activity` for agent
12
- * events), `--command` (path prefix), `--event` (typed event), `--agent`, and
13
- * `--since`. `--audit` restricts to operational events only. `--follow` tails
14
- * today's operational log live.
10
+ * `agents audit` and `agents logs` are thin aliases of this command.
11
+ *
12
+ * Filter with sessions-style `--include` / `--exclude` families (ops, activity,
13
+ * commands, runs, security) plus field filters (`--module`, `--event`, …).
15
14
  */
16
15
  import type { Command } from 'commander';
17
16
  /**
@@ -43,10 +42,23 @@ export interface EventsOptions {
43
42
  limit?: string;
44
43
  json?: boolean;
45
44
  follow?: boolean;
45
+ /** @deprecated Prefer --include ops / --exclude activity */
46
46
  audit?: boolean;
47
+ include?: string;
48
+ exclude?: string;
47
49
  }
48
50
  /** Add the one canonical event-reader option surface to a command or alias. */
49
51
  export declare function addEventsReadOptions(command: Command, includeAuditFlag?: boolean): Command;
50
- /** Canonical reader used by both `agents events` and `agents logs audit`. */
52
+ /** Canonical reader used by `agents events`, `agents audit`, and `agents logs`. */
51
53
  export declare function runEventsCommand(options: EventsOptions, forceAudit?: boolean): Promise<void>;
54
+ /** Shared by `events stats` and the `logs stats` alias. */
55
+ export declare function runEventsStats(opts: {
56
+ since?: string;
57
+ json?: boolean;
58
+ }): Promise<void>;
52
59
  export declare function registerEventsCommand(program: Command): void;
60
+ /** Shared by `events rotate` and the `logs rotate` alias. */
61
+ export declare function runEventsRotate(opts: {
62
+ days?: string;
63
+ maxMb?: string;
64
+ }): void;