@phnx-labs/agents-cli 1.22.35 → 1.22.38

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 (500) hide show
  1. package/CHANGELOG.md +708 -2
  2. package/README.md +83 -43
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1212 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/artifacts-setup.d.ts +53 -0
  9. package/dist/commands/artifacts-setup.js +161 -0
  10. package/dist/commands/artifacts.d.ts +18 -0
  11. package/dist/commands/artifacts.js +58 -0
  12. package/dist/commands/attach.js +17 -4
  13. package/dist/commands/audit.d.ts +8 -8
  14. package/dist/commands/audit.js +57 -47
  15. package/dist/commands/browser.js +17 -11
  16. package/dist/commands/cloud.js +1 -1
  17. package/dist/commands/commands.js +0 -11
  18. package/dist/commands/computer-actions.js +33 -0
  19. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  20. package/dist/commands/computer-sessions-picker.js +141 -0
  21. package/dist/commands/computer.d.ts +16 -0
  22. package/dist/commands/computer.js +37 -0
  23. package/dist/commands/config.d.ts +17 -0
  24. package/dist/commands/config.js +401 -0
  25. package/dist/commands/cp.d.ts +84 -0
  26. package/dist/commands/cp.js +231 -0
  27. package/dist/commands/daemon.js +243 -14
  28. package/dist/commands/detach-core.d.ts +1 -1
  29. package/dist/commands/detach-core.js +12 -2
  30. package/dist/commands/detach.js +1 -1
  31. package/dist/commands/doctor.js +64 -5
  32. package/dist/commands/events.d.ts +24 -12
  33. package/dist/commands/events.js +144 -28
  34. package/dist/commands/exec.js +86 -42
  35. package/dist/commands/feed.d.ts +1 -1
  36. package/dist/commands/feed.js +16 -8
  37. package/dist/commands/focus.d.ts +33 -1
  38. package/dist/commands/focus.js +177 -17
  39. package/dist/commands/funnel.d.ts +1 -1
  40. package/dist/commands/go.js +9 -8
  41. package/dist/commands/harness-wizard.d.ts +1 -0
  42. package/dist/commands/harness-wizard.js +18 -20
  43. package/dist/commands/harness.d.ts +2 -0
  44. package/dist/commands/harness.js +59 -26
  45. package/dist/commands/hooks.js +0 -11
  46. package/dist/commands/inspect.d.ts +94 -1
  47. package/dist/commands/inspect.js +866 -40
  48. package/dist/commands/lease.d.ts +4 -4
  49. package/dist/commands/lease.js +6 -6
  50. package/dist/commands/login.js +0 -13
  51. package/dist/commands/logs.d.ts +2 -2
  52. package/dist/commands/logs.js +2 -2
  53. package/dist/commands/mcp.js +7 -2
  54. package/dist/commands/memory.js +7 -2
  55. package/dist/commands/message.d.ts +1 -1
  56. package/dist/commands/message.js +37 -6
  57. package/dist/commands/models.js +71 -0
  58. package/dist/commands/monitors.d.ts +0 -1
  59. package/dist/commands/monitors.js +199 -16
  60. package/dist/commands/open.d.ts +18 -0
  61. package/dist/commands/open.js +57 -0
  62. package/dist/commands/packages.js +2 -107
  63. package/dist/commands/plugins.js +6 -3
  64. package/dist/commands/profiles.d.ts +1 -0
  65. package/dist/commands/profiles.js +16 -160
  66. package/dist/commands/projects.d.ts +28 -0
  67. package/dist/commands/projects.js +125 -5
  68. package/dist/commands/reconnect.js +9 -3
  69. package/dist/commands/repo.js +42 -1
  70. package/dist/commands/resource-view.d.ts +17 -0
  71. package/dist/commands/resource-view.js +36 -14
  72. package/dist/commands/resume.js +9 -2
  73. package/dist/commands/routines.d.ts +0 -2
  74. package/dist/commands/routines.js +473 -289
  75. package/dist/commands/secrets.js +52 -9
  76. package/dist/commands/sessions-export.d.ts +47 -0
  77. package/dist/commands/sessions-export.js +116 -6
  78. package/dist/commands/sessions-import.d.ts +17 -0
  79. package/dist/commands/sessions-import.js +114 -6
  80. package/dist/commands/sessions-migrate.d.ts +27 -0
  81. package/dist/commands/sessions-migrate.js +50 -9
  82. package/dist/commands/sessions-picker.js +23 -4
  83. package/dist/commands/sessions-resume.d.ts +5 -3
  84. package/dist/commands/sessions-resume.js +30 -8
  85. package/dist/commands/sessions-watch.d.ts +2 -0
  86. package/dist/commands/sessions-watch.js +53 -0
  87. package/dist/commands/sessions.d.ts +66 -3
  88. package/dist/commands/sessions.js +298 -47
  89. package/dist/commands/setup-browser.js +2 -2
  90. package/dist/commands/setup-mine.js +0 -1
  91. package/dist/commands/setup-preferences.js +1 -1
  92. package/dist/commands/setup.d.ts +5 -0
  93. package/dist/commands/setup.js +31 -5
  94. package/dist/commands/share.d.ts +87 -7
  95. package/dist/commands/share.js +320 -58
  96. package/dist/commands/skills.js +0 -11
  97. package/dist/commands/snapshot.js +1 -1
  98. package/dist/commands/ssh.d.ts +18 -0
  99. package/dist/commands/ssh.js +549 -210
  100. package/dist/commands/sync.d.ts +5 -0
  101. package/dist/commands/sync.js +212 -32
  102. package/dist/commands/teams.d.ts +13 -0
  103. package/dist/commands/teams.js +187 -30
  104. package/dist/commands/tickets.d.ts +2 -0
  105. package/dist/commands/tickets.js +43 -0
  106. package/dist/commands/update.js +2 -4
  107. package/dist/commands/usage.js +5 -3
  108. package/dist/commands/versions.js +11 -5
  109. package/dist/commands/view.js +15 -7
  110. package/dist/commands/webhook.d.ts +2 -2
  111. package/dist/commands/webhook.js +7 -7
  112. package/dist/index.d.ts +18 -2
  113. package/dist/index.js +53 -1264
  114. package/dist/lib/account-catalog.d.ts +18 -0
  115. package/dist/lib/account-catalog.js +38 -0
  116. package/dist/lib/account-provider-registry.d.ts +18 -0
  117. package/dist/lib/account-provider-registry.js +59 -0
  118. package/dist/lib/account-registry.d.ts +40 -0
  119. package/dist/lib/account-registry.js +239 -0
  120. package/dist/lib/account-schema.d.ts +44 -0
  121. package/dist/lib/account-schema.js +91 -0
  122. package/dist/lib/account-state-service.d.ts +21 -0
  123. package/dist/lib/account-state-service.js +60 -0
  124. package/dist/lib/activity.d.ts +1 -1
  125. package/dist/lib/activity.js +8 -1
  126. package/dist/lib/add-dir.d.ts +80 -0
  127. package/dist/lib/add-dir.js +241 -0
  128. package/dist/lib/agent-cli-commands.d.ts +11 -0
  129. package/dist/lib/agent-cli-commands.js +30 -0
  130. package/dist/lib/agents.js +44 -36
  131. package/dist/lib/answer-router.js +1 -1
  132. package/dist/lib/audit/log.d.ts +10 -27
  133. package/dist/lib/audit/log.js +20 -33
  134. package/dist/lib/auth-health.d.ts +9 -2
  135. package/dist/lib/auth-health.js +42 -9
  136. package/dist/lib/auto-pull-worker.js +7 -3
  137. package/dist/lib/auto-pull.d.ts +44 -3
  138. package/dist/lib/auto-pull.js +88 -5
  139. package/dist/lib/binary-shadow.d.ts +28 -0
  140. package/dist/lib/binary-shadow.js +121 -0
  141. package/dist/lib/brand.js +9 -3
  142. package/dist/lib/browser/hygiene.d.ts +90 -0
  143. package/dist/lib/browser/hygiene.js +146 -0
  144. package/dist/lib/browser/ipc.d.ts +30 -0
  145. package/dist/lib/browser/ipc.js +93 -4
  146. package/dist/lib/browser/profiles.d.ts +3 -2
  147. package/dist/lib/browser/profiles.js +65 -22
  148. package/dist/lib/browser/service.d.ts +79 -1
  149. package/dist/lib/browser/service.js +231 -14
  150. package/dist/lib/browser/sessions-list.d.ts +22 -2
  151. package/dist/lib/browser/sessions-list.js +54 -6
  152. package/dist/lib/browser/stream.d.ts +2 -0
  153. package/dist/lib/browser/stream.js +1 -0
  154. package/dist/lib/browser/types.d.ts +63 -1
  155. package/dist/lib/byok-usage.d.ts +9 -2
  156. package/dist/lib/byok-usage.js +133 -31
  157. package/dist/lib/cli-entry.d.ts +11 -0
  158. package/dist/lib/cli-entry.js +46 -0
  159. package/dist/lib/cloud/host.d.ts +1 -1
  160. package/dist/lib/cloud/host.js +2 -2
  161. package/dist/lib/cloud/registry.js +1 -1
  162. package/dist/lib/cloud/types.d.ts +1 -1
  163. package/dist/lib/commands.d.ts +2 -0
  164. package/dist/lib/commands.js +2 -0
  165. package/dist/lib/computer/sessions-list.d.ts +150 -0
  166. package/dist/lib/computer/sessions-list.js +363 -0
  167. package/dist/lib/config-keys.d.ts +86 -0
  168. package/dist/lib/config-keys.js +193 -0
  169. package/dist/lib/config-machine-keys.d.ts +12 -0
  170. package/dist/lib/config-machine-keys.js +17 -0
  171. package/dist/lib/config-transfer.js +3 -4
  172. package/dist/lib/crabbox/cli.d.ts +2 -2
  173. package/dist/lib/crabbox/cli.js +3 -3
  174. package/dist/lib/daemon-health.d.ts +22 -0
  175. package/dist/lib/daemon-health.js +33 -3
  176. package/dist/lib/daemon-services.d.ts +50 -0
  177. package/dist/lib/daemon-services.js +147 -0
  178. package/dist/lib/daemon-ticks.d.ts +35 -66
  179. package/dist/lib/daemon-ticks.js +77 -159
  180. package/dist/lib/daemon.d.ts +72 -4
  181. package/dist/lib/daemon.js +792 -202
  182. package/dist/lib/deeplink/register.d.ts +49 -0
  183. package/dist/lib/deeplink/register.js +253 -0
  184. package/dist/lib/deeplink/url.d.ts +34 -0
  185. package/dist/lib/deeplink/url.js +78 -0
  186. package/dist/lib/device-config.d.ts +124 -29
  187. package/dist/lib/device-config.js +346 -141
  188. package/dist/lib/devices/config-migration.d.ts +42 -0
  189. package/dist/lib/devices/config-migration.js +203 -0
  190. package/dist/lib/devices/connect.js +14 -7
  191. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  192. package/dist/lib/devices/doctor-findings.js +20 -1
  193. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  194. package/dist/lib/devices/harness-inventory.js +0 -0
  195. package/dist/lib/devices/health.d.ts +1 -1
  196. package/dist/lib/devices/health.js +1 -1
  197. package/dist/lib/devices/pending.d.ts +22 -1
  198. package/dist/lib/devices/pending.js +67 -2
  199. package/dist/lib/devices/registry.d.ts +0 -25
  200. package/dist/lib/devices/registry.js +2 -83
  201. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  202. package/dist/lib/devices/resolve-profile.js +44 -0
  203. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  204. package/dist/lib/devices/rollout-verify.js +193 -0
  205. package/dist/lib/devices/ssh-config.js +10 -6
  206. package/dist/lib/event-families.d.ts +28 -0
  207. package/dist/lib/event-families.js +159 -0
  208. package/dist/lib/event-stream.d.ts +9 -1
  209. package/dist/lib/event-stream.js +26 -9
  210. package/dist/lib/events.d.ts +9 -1
  211. package/dist/lib/events.js +21 -6
  212. package/dist/lib/exec.d.ts +30 -0
  213. package/dist/lib/exec.js +219 -121
  214. package/dist/lib/feed-broadcast.d.ts +25 -0
  215. package/dist/lib/feed-broadcast.js +33 -0
  216. package/dist/lib/feed.d.ts +1 -1
  217. package/dist/lib/feed.js +12 -2
  218. package/dist/lib/fleet/capture.js +15 -0
  219. package/dist/lib/fleet/manifest.js +9 -0
  220. package/dist/lib/fleet/types.d.ts +9 -0
  221. package/dist/lib/fleet-status.js +10 -8
  222. package/dist/lib/git.d.ts +21 -7
  223. package/dist/lib/git.js +122 -18
  224. package/dist/lib/hosts/dispatch.d.ts +8 -3
  225. package/dist/lib/hosts/dispatch.js +29 -3
  226. package/dist/lib/hosts/logs.d.ts +2 -2
  227. package/dist/lib/hosts/logs.js +2 -2
  228. package/dist/lib/hosts/option.js +1 -1
  229. package/dist/lib/hosts/passthrough.d.ts +2 -3
  230. package/dist/lib/hosts/passthrough.js +10 -24
  231. package/dist/lib/hosts/progress.js +2 -2
  232. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  233. package/dist/lib/hosts/providers/devices.js +18 -12
  234. package/dist/lib/hosts/ready.d.ts +5 -1
  235. package/dist/lib/hosts/ready.js +9 -3
  236. package/dist/lib/hosts/reconcile.d.ts +2 -2
  237. package/dist/lib/hosts/reconcile.js +2 -2
  238. package/dist/lib/hosts/registry.js +14 -9
  239. package/dist/lib/hosts/remote-cmd.js +1 -1
  240. package/dist/lib/hosts/remote-os.d.ts +9 -6
  241. package/dist/lib/hosts/remote-os.js +13 -6
  242. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  243. package/dist/lib/hosts/routing-flag.js +41 -0
  244. package/dist/lib/hosts/run-target.js +1 -1
  245. package/dist/lib/hosts/session-index.js +1 -1
  246. package/dist/lib/hosts/tasks.d.ts +6 -6
  247. package/dist/lib/hosts/tasks.js +4 -4
  248. package/dist/lib/hosts/types.js +1 -2
  249. package/dist/lib/installations/resolve.js +2 -8
  250. package/dist/lib/isolation-boundary-report.js +0 -1
  251. package/dist/lib/linear-cache.d.ts +7 -0
  252. package/dist/lib/linear-cache.js +31 -4
  253. package/dist/lib/linear-project-counts.d.ts +1 -1
  254. package/dist/lib/linear-project-counts.js +2 -3
  255. package/dist/lib/linear-projects.js +1 -1
  256. package/dist/lib/loop.d.ts +2 -2
  257. package/dist/lib/loop.js +1 -1
  258. package/dist/lib/mailbox-target.d.ts +1 -1
  259. package/dist/lib/mailbox-target.js +1 -1
  260. package/dist/lib/manifest.js +7 -4
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  262. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  263. package/dist/lib/menubar/snapshot.d.ts +3 -2
  264. package/dist/lib/menubar/snapshot.js +6 -2
  265. package/dist/lib/migrate-fold.d.ts +33 -0
  266. package/dist/lib/migrate-fold.js +130 -0
  267. package/dist/lib/migrate.d.ts +34 -34
  268. package/dist/lib/migrate.js +106 -128
  269. package/dist/lib/model-tier-overrides.d.ts +1 -1
  270. package/dist/lib/model-tier-overrides.js +15 -2
  271. package/dist/lib/monitors/config.d.ts +17 -3
  272. package/dist/lib/monitors/config.js +52 -18
  273. package/dist/lib/monitors/engine.d.ts +32 -1
  274. package/dist/lib/monitors/engine.js +94 -11
  275. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  276. package/dist/lib/monitors/fingerprint.js +100 -0
  277. package/dist/lib/monitors/remote.d.ts +47 -0
  278. package/dist/lib/monitors/remote.js +81 -0
  279. package/dist/lib/monitors/state.d.ts +39 -0
  280. package/dist/lib/monitors/state.js +56 -0
  281. package/dist/lib/onepassword.d.ts +17 -0
  282. package/dist/lib/onepassword.js +52 -22
  283. package/dist/lib/open-url.js +1 -1
  284. package/dist/lib/picker.d.ts +14 -2
  285. package/dist/lib/picker.js +35 -13
  286. package/dist/lib/placement.d.ts +1 -1
  287. package/dist/lib/placement.js +1 -1
  288. package/dist/lib/pr-land-detach.d.ts +32 -0
  289. package/dist/lib/pr-land-detach.js +79 -0
  290. package/dist/lib/profiles-presets.js +13 -0
  291. package/dist/lib/profiles.d.ts +2 -0
  292. package/dist/lib/profiles.js +44 -1
  293. package/dist/lib/project-focus.d.ts +1 -1
  294. package/dist/lib/project-focus.js +1 -1
  295. package/dist/lib/project-probe.d.ts +4 -1
  296. package/dist/lib/project-probe.js +5 -4
  297. package/dist/lib/project-resources.js +2 -18
  298. package/dist/lib/project-root.d.ts +16 -0
  299. package/dist/lib/project-root.js +20 -2
  300. package/dist/lib/projects.d.ts +20 -1
  301. package/dist/lib/projects.js +78 -1
  302. package/dist/lib/refresh-coordinator.d.ts +24 -0
  303. package/dist/lib/refresh-coordinator.js +52 -0
  304. package/dist/lib/registry.d.ts +2 -2
  305. package/dist/lib/registry.js +1 -1
  306. package/dist/lib/resource-aliases.d.ts +13 -0
  307. package/dist/lib/resource-aliases.js +26 -0
  308. package/dist/lib/resources/types.d.ts +1 -1
  309. package/dist/lib/resources.d.ts +16 -0
  310. package/dist/lib/resources.js +66 -10
  311. package/dist/lib/rotate.d.ts +3 -4
  312. package/dist/lib/rotate.js +4 -5
  313. package/dist/lib/routine-activation.d.ts +22 -2
  314. package/dist/lib/routine-activation.js +63 -16
  315. package/dist/lib/routine-context.d.ts +9 -2
  316. package/dist/lib/routine-context.js +21 -6
  317. package/dist/lib/routines-project.d.ts +58 -48
  318. package/dist/lib/routines-project.js +190 -159
  319. package/dist/lib/routines.d.ts +44 -7
  320. package/dist/lib/routines.js +92 -34
  321. package/dist/lib/run-defaults.d.ts +5 -0
  322. package/dist/lib/run-defaults.js +11 -1
  323. package/dist/lib/runner.d.ts +10 -8
  324. package/dist/lib/runner.js +122 -39
  325. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  326. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  327. package/dist/lib/secrets/agent.d.ts +10 -3
  328. package/dist/lib/secrets/agent.js +43 -8
  329. package/dist/lib/secrets/bundles.d.ts +1 -0
  330. package/dist/lib/secrets/bundles.js +92 -80
  331. package/dist/lib/secrets/index.js +32 -9
  332. package/dist/lib/secrets/install-helper.d.ts +4 -4
  333. package/dist/lib/secrets/install-helper.js +4 -4
  334. package/dist/lib/secrets/push.d.ts +40 -6
  335. package/dist/lib/secrets/push.js +58 -11
  336. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  337. package/dist/lib/secrets/read-backoff.js +1 -1
  338. package/dist/lib/secrets/remote.d.ts +24 -0
  339. package/dist/lib/secrets/remote.js +54 -4
  340. package/dist/lib/self-update.d.ts +108 -0
  341. package/dist/lib/self-update.js +276 -1
  342. package/dist/lib/session/active.d.ts +89 -5
  343. package/dist/lib/session/active.js +165 -10
  344. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  345. package/dist/lib/session/actor-sidecar.js +2 -1
  346. package/dist/lib/session/db.d.ts +176 -2
  347. package/dist/lib/session/db.js +484 -17
  348. package/dist/lib/session/discover.js +27 -4
  349. package/dist/lib/session/hook-sessions.js +2 -2
  350. package/dist/lib/session/host-link.d.ts +2 -2
  351. package/dist/lib/session/host-link.js +2 -2
  352. package/dist/lib/session/pid-registry.d.ts +21 -0
  353. package/dist/lib/session/pid-registry.js +57 -0
  354. package/dist/lib/session/remote-active.js +15 -1
  355. package/dist/lib/session/remote.js +2 -2
  356. package/dist/lib/session/session-cache.d.ts +14 -7
  357. package/dist/lib/session/session-cache.js +51 -9
  358. package/dist/lib/session/state.d.ts +2 -2
  359. package/dist/lib/session/state.js +1 -1
  360. package/dist/lib/session/sync/config.d.ts +10 -10
  361. package/dist/lib/session/sync/config.js +10 -10
  362. package/dist/lib/session/sync/r2.d.ts +34 -0
  363. package/dist/lib/session/sync/r2.js +123 -0
  364. package/dist/lib/session/throughput.d.ts +1 -1
  365. package/dist/lib/session/throughput.js +1 -1
  366. package/dist/lib/session/types.d.ts +23 -1
  367. package/dist/lib/session/types.js +15 -0
  368. package/dist/lib/session/viewing-in.d.ts +1 -1
  369. package/dist/lib/session/viewing-in.js +1 -1
  370. package/dist/lib/session/watch.d.ts +101 -0
  371. package/dist/lib/session/watch.js +242 -0
  372. package/dist/lib/share/analytics.js +1 -1
  373. package/dist/lib/share/capture.d.ts +1 -1
  374. package/dist/lib/share/capture.js +3 -3
  375. package/dist/lib/share/config.d.ts +6 -2
  376. package/dist/lib/share/config.js +6 -5
  377. package/dist/lib/share/delete.js +3 -3
  378. package/dist/lib/share/provision.d.ts +38 -0
  379. package/dist/lib/share/provision.js +51 -1
  380. package/dist/lib/share/publish.d.ts +40 -1
  381. package/dist/lib/share/publish.js +119 -6
  382. package/dist/lib/share/worker-template.d.ts +12 -1
  383. package/dist/lib/share/worker-template.js +83 -7
  384. package/dist/lib/shims.d.ts +17 -3
  385. package/dist/lib/shims.js +98 -26
  386. package/dist/lib/signin-badge.js +3 -2
  387. package/dist/lib/skills.js +2 -0
  388. package/dist/lib/smart-launch.d.ts +8 -8
  389. package/dist/lib/smart-launch.js +80 -59
  390. package/dist/lib/ssh-exec.d.ts +1 -1
  391. package/dist/lib/ssh-exec.js +1 -1
  392. package/dist/lib/staleness/prune.d.ts +88 -0
  393. package/dist/lib/staleness/prune.js +69 -0
  394. package/dist/lib/staleness/registry.d.ts +1 -1
  395. package/dist/lib/staleness/writers/commands.js +34 -2
  396. package/dist/lib/staleness/writers/hooks.js +16 -0
  397. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  398. package/dist/lib/staleness/writers/skills.js +19 -0
  399. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  400. package/dist/lib/staleness/writers/subagents.js +0 -4
  401. package/dist/lib/staleness/writers/types.d.ts +32 -0
  402. package/dist/lib/startup/command-registry.d.ts +16 -14
  403. package/dist/lib/startup/command-registry.js +26 -37
  404. package/dist/lib/startup/dev-build.d.ts +10 -0
  405. package/dist/lib/startup/dev-build.js +13 -1
  406. package/dist/lib/startup/spellcheck.d.ts +18 -0
  407. package/dist/lib/startup/spellcheck.js +45 -0
  408. package/dist/lib/state.d.ts +36 -9
  409. package/dist/lib/state.js +96 -46
  410. package/dist/lib/subagents-registry.d.ts +0 -7
  411. package/dist/lib/subagents-registry.js +38 -65
  412. package/dist/lib/subagents.d.ts +0 -33
  413. package/dist/lib/subagents.js +0 -75
  414. package/dist/lib/sync-umbrella.js +1 -1
  415. package/dist/lib/teams/agents.d.ts +41 -1
  416. package/dist/lib/teams/agents.js +187 -9
  417. package/dist/lib/teams/api.d.ts +11 -1
  418. package/dist/lib/teams/api.js +11 -2
  419. package/dist/lib/teams/delivery.d.ts +41 -0
  420. package/dist/lib/teams/delivery.js +60 -0
  421. package/dist/lib/teams/registry.d.ts +14 -0
  422. package/dist/lib/teams/registry.js +51 -1
  423. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  424. package/dist/lib/teams/remoteWorktree.js +29 -0
  425. package/dist/lib/teams/scheduler.d.ts +1 -1
  426. package/dist/lib/teams/scheduler.js +1 -1
  427. package/dist/lib/teams/worktree.d.ts +24 -0
  428. package/dist/lib/teams/worktree.js +42 -0
  429. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  430. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  431. package/dist/lib/terminal/engine.d.ts +4 -0
  432. package/dist/lib/terminal/engine.js +8 -2
  433. package/dist/lib/terminal/types.d.ts +21 -2
  434. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  435. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  436. package/dist/lib/tickets/list.d.ts +53 -0
  437. package/dist/lib/tickets/list.js +153 -0
  438. package/dist/lib/tmux/orphan-reap.d.ts +316 -0
  439. package/dist/lib/tmux/orphan-reap.js +638 -0
  440. package/dist/lib/tmux/session.d.ts +68 -3
  441. package/dist/lib/tmux/session.js +96 -5
  442. package/dist/lib/triggers/handlers.d.ts +20 -0
  443. package/dist/lib/triggers/handlers.js +16 -1
  444. package/dist/lib/triggers/webhook.js +10 -0
  445. package/dist/lib/types.d.ts +47 -35
  446. package/dist/lib/usage-fleet.d.ts +32 -0
  447. package/dist/lib/usage-fleet.js +125 -0
  448. package/dist/lib/usage-refresh.d.ts +3 -3
  449. package/dist/lib/usage-refresh.js +19 -16
  450. package/dist/lib/usage.d.ts +51 -47
  451. package/dist/lib/usage.js +145 -153
  452. package/dist/lib/version-duplicates.js +2 -2
  453. package/dist/lib/versions.d.ts +56 -13
  454. package/dist/lib/versions.js +195 -45
  455. package/dist/lib/watchdog/log.d.ts +1 -1
  456. package/dist/lib/watchdog/log.js +3 -3
  457. package/dist/lib/watchdog/rotate.d.ts +6 -6
  458. package/dist/lib/watchdog/rotate.js +6 -6
  459. package/dist/lib/workflows.d.ts +1 -1
  460. package/dist/lib/yaml-io.d.ts +47 -0
  461. package/dist/lib/yaml-io.js +55 -0
  462. package/package.json +2 -1
  463. package/scripts/install-helper.js +2 -2
  464. package/scripts/postinstall.js +23 -20
  465. package/dist/commands/defaults.d.ts +0 -7
  466. package/dist/commands/defaults.js +0 -107
  467. package/dist/commands/export.d.ts +0 -11
  468. package/dist/commands/export.js +0 -215
  469. package/dist/commands/helper.d.ts +0 -12
  470. package/dist/commands/helper.js +0 -87
  471. package/dist/commands/hosts.d.ts +0 -11
  472. package/dist/commands/hosts.js +0 -330
  473. package/dist/commands/lock.d.ts +0 -12
  474. package/dist/commands/lock.js +0 -70
  475. package/dist/commands/pull.d.ts +0 -17
  476. package/dist/commands/pull.js +0 -39
  477. package/dist/commands/push.d.ts +0 -14
  478. package/dist/commands/push.js +0 -30
  479. package/dist/commands/set.d.ts +0 -15
  480. package/dist/commands/set.js +0 -79
  481. package/dist/commands/setup-share.d.ts +0 -17
  482. package/dist/commands/setup-share.js +0 -85
  483. package/dist/commands/wallet.d.ts +0 -20
  484. package/dist/commands/wallet.js +0 -216
  485. package/dist/commands/worktree.d.ts +0 -19
  486. package/dist/commands/worktree.js +0 -272
  487. package/dist/lib/account-labels.d.ts +0 -24
  488. package/dist/lib/account-labels.js +0 -72
  489. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  490. package/dist/lib/auto-dispatch-linear.js +0 -107
  491. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  492. package/dist/lib/auto-dispatch-provider.js +0 -30
  493. package/dist/lib/auto-dispatch.d.ts +0 -93
  494. package/dist/lib/auto-dispatch.js +0 -128
  495. package/dist/lib/export.d.ts +0 -72
  496. package/dist/lib/export.js +0 -269
  497. package/dist/lib/lock.d.ts +0 -93
  498. package/dist/lib/lock.js +0 -207
  499. package/dist/lib/wallet/index.d.ts +0 -78
  500. package/dist/lib/wallet/index.js +0 -253
@@ -12,9 +12,12 @@ import * as fs from 'fs';
12
12
  import * as path from 'path';
13
13
  import * as yaml from 'yaml';
14
14
  import { isDaemonRunning, signalDaemonReload, startDaemon, } from '../lib/daemon.js';
15
- import { listMonitors, readMonitor, writeMonitor, deleteMonitor, setMonitorEnabled, getMonitorPath, validateMonitor, monitorRunsOnThisDevice, } from '../lib/monitors/config.js';
16
- import { evaluateMonitorOnce } from '../lib/monitors/engine.js';
17
- import { listFires, readState } from '../lib/monitors/state.js';
15
+ import { findDuplicateMonitor, monitorFingerprint } from '../lib/monitors/fingerprint.js';
16
+ import { gatherFleetMonitors, NO_MONITOR_FANOUT_ENV } from '../lib/monitors/remote.js';
17
+ import { listMonitors, readMonitor, writeMonitor, deleteMonitor, setMonitorEnabled, getMonitorPath, validateMonitor, monitorRunsOnThisDevice, parseInterval, } from '../lib/monitors/config.js';
18
+ import { formatRelativeTime } from '../lib/session/relative-time.js';
19
+ import { evaluateMonitorOnce, POLL_SOURCE_TYPES } from '../lib/monitors/engine.js';
20
+ import { listFires, readState, readLiveness } from '../lib/monitors/state.js';
18
21
  import { listRuns, getLatestRun, getRunDir } from '../lib/routines.js';
19
22
  import { getMonitorsDir } from '../lib/state.js';
20
23
  import { IS_WINDOWS } from '../lib/platform/index.js';
@@ -72,6 +75,54 @@ function ownerLabel(monitor) {
72
75
  return monitor.devices.join(',');
73
76
  return 'all';
74
77
  }
78
+ /** A monitor's evaluation cadence in ms (falls back to the engine default). */
79
+ function monitorIntervalMs(monitor) {
80
+ if (monitor.source.interval)
81
+ return parseInterval(monitor.source.interval) ?? 60_000;
82
+ return 60_000;
83
+ }
84
+ /**
85
+ * True when an enabled, locally-owned monitor's last poll is far enough past its
86
+ * interval that the engine has plainly stopped checking it (dead engine, swallowed
87
+ * start failure, never picked up). Tolerates a few missed ticks before flagging.
88
+ */
89
+ function isStalled(monitor, liveness) {
90
+ if (!monitor.enabled || !monitorRunsOnThisDevice(monitor))
91
+ return false;
92
+ if (!liveness)
93
+ return false; // "never polled" is its own state, handled separately
94
+ const staleAfter = Math.max(monitorIntervalMs(monitor) * 3, 90_000);
95
+ return Date.now() - new Date(liveness.lastCheckedAt).getTime() > staleAfter;
96
+ }
97
+ /**
98
+ * The human liveness line for a monitor. This is the RUSH-2485 fix: it makes
99
+ * "the engine has never touched this" (`never polled`) visibly distinct from
100
+ * "polling steadily, condition just isn't matching" (`checked Nx`), from a real
101
+ * fire, and from a stalled engine.
102
+ */
103
+ function livenessLabel(monitor, state, liveness) {
104
+ const here = monitorRunsOnThisDevice(monitor);
105
+ if (!monitor.enabled)
106
+ return chalk.gray('paused');
107
+ if (!here) {
108
+ // Not owned by this box — this daemon never checks it, so there's no local
109
+ // liveness to report; fall back to fire history if the owner synced it.
110
+ return state?.lastFiredAt ? chalk.gray(`fired ${formatRelativeTime(state.lastFiredAt)}`) : chalk.gray('owned elsewhere');
111
+ }
112
+ if (!liveness)
113
+ return chalk.yellow('never polled');
114
+ if (isStalled(monitor, liveness)) {
115
+ return chalk.red(`STALLED — last poll ${formatRelativeTime(liveness.lastCheckedAt)}`);
116
+ }
117
+ const checkedAgo = formatRelativeTime(liveness.lastCheckedAt);
118
+ if (liveness.lastError) {
119
+ return chalk.red(`checked ${liveness.checkCount}x · error: ${liveness.lastError.replace(/\s+/g, ' ').slice(0, 60)}`);
120
+ }
121
+ if (state?.lastFiredAt) {
122
+ return chalk.green(`fired ${formatRelativeTime(state.lastFiredAt)}`) + chalk.gray(` · checked ${liveness.checkCount}x`);
123
+ }
124
+ return chalk.gray(`checked ${liveness.checkCount}x · last ${checkedAgo} · no match yet`);
125
+ }
75
126
  /** Start or reload the background daemon so a newly-added monitor is watched. */
76
127
  function ensureDaemonRunning() {
77
128
  if (isDaemonRunning()) {
@@ -88,6 +139,37 @@ function ensureDaemonRunning() {
88
139
  stderrLine(chalk.yellow('Could not start the daemon. Start it manually with: agents routines start'));
89
140
  }
90
141
  }
142
+ /**
143
+ * Assert the postcondition of `add`: the engine actually picked the monitor up.
144
+ * Config acceptance is not enough — RUSH-2485 was a monitor that added cleanly,
145
+ * listed as `on`, and never polled. A poll-model monitor owned by and enabled on
146
+ * this box should show a liveness heartbeat within a couple of engine ticks; wait
147
+ * for it and report the real outcome instead of reporting success on write. A
148
+ * miss is a warning, not a hard failure — a freshly-started daemon may still be
149
+ * booting — but it is surfaced so a dead engine can never masquerade as healthy.
150
+ */
151
+ async function assertEnginePickup(monitor) {
152
+ const pollSource = POLL_SOURCE_TYPES.has(monitor.source.type);
153
+ if (!monitor.enabled || !monitorRunsOnThisDevice(monitor) || !pollSource)
154
+ return; // nothing to assert here
155
+ const before = readLiveness(monitor.name);
156
+ const baseline = before?.checkCount ?? 0;
157
+ const deadline = Date.now() + 12_000; // a couple of 5s ticks, plus daemon-boot slack
158
+ stderrLine(chalk.gray(' waiting for the engine to poll it…'));
159
+ while (Date.now() < deadline) {
160
+ await new Promise((r) => setTimeout(r, 500));
161
+ const now = readLiveness(monitor.name);
162
+ if (now && now.checkCount > baseline) {
163
+ console.log(chalk.green(` engine picked it up — first poll ${formatRelativeTime(now.lastCheckedAt)}`));
164
+ if (now.lastError) {
165
+ stderrLine(chalk.yellow(` note: that poll errored — ${now.lastError.replace(/\s+/g, ' ').slice(0, 80)}`));
166
+ }
167
+ return;
168
+ }
169
+ }
170
+ stderrLine(chalk.yellow(` the engine has not polled '${monitor.name}' yet.`));
171
+ stderrLine(chalk.yellow(` confirm the daemon is running (agents routines status) and re-check with: agents monitors view ${monitor.name}`));
172
+ }
91
173
  /** Validate a single device name against the registered fleet; exit on miss. */
92
174
  async function validateDevice(name) {
93
175
  const normalized = normalizeHost(name.trim());
@@ -242,6 +324,58 @@ async function pickMonitor(message, alternatives = []) {
242
324
  }
243
325
  }
244
326
  /** Register the `agents monitors` command tree. */
327
+ /**
328
+ * Refuse a monitor that duplicates one already in play — same NAME (which
329
+ * `writeMonitor` would silently overwrite) or same BEHAVIOR under any name, on
330
+ * this box or any other. Exits the process on a refusal.
331
+ *
332
+ * Shared by BOTH `add` paths. The file path (`add ./watcher.yml`) returns early
333
+ * and used to skip the guard entirely, so a duplicate could be walked straight
334
+ * in through a YAML file — the one input an agent is most likely to generate.
335
+ */
336
+ async function guardAgainstDuplicateMonitor(config, force) {
337
+ if (force)
338
+ return;
339
+ const existing = listMonitors();
340
+ const sameName = existing.find((m) => m.name === config.name);
341
+ if (sameName) {
342
+ stderrLine(chalk.red(`Monitor '${config.name}' already exists — adding would overwrite it.`));
343
+ stderrLine(chalk.gray(` Inspect it: agents monitors view ${config.name}`));
344
+ stderrLine(chalk.gray(` Replace it: agents monitors add ${config.name} ... --force`));
345
+ process.exit(1);
346
+ }
347
+ const duplicate = findDuplicateMonitor(config, existing);
348
+ if (duplicate) {
349
+ stderrLine(chalk.red(`Monitor '${duplicate}' already watches this exact source and fires the same action.`));
350
+ stderrLine(chalk.gray(' Adding it again would fire the same trigger twice.'));
351
+ stderrLine(chalk.gray(` Inspect it: agents monitors view ${duplicate}`));
352
+ stderrLine(chalk.gray(` Add anyway: agents monitors add ${config.name} ... --force`));
353
+ process.exit(1);
354
+ }
355
+ // The case a local check cannot see: another agent, on another box, already
356
+ // watching this same work item with these same arguments. One work item, two
357
+ // triggers. Identity is the arguments, so the claim has to be fleet-wide —
358
+ // different arguments (another PR) are not a clash and still pass.
359
+ if (process.env[NO_MONITOR_FANOUT_ENV])
360
+ return;
361
+ const fleet = await gatherFleetMonitors();
362
+ const mine = monitorFingerprint(config);
363
+ const clash = fleet.monitors.find((r) => monitorFingerprint(r.monitor) === mine);
364
+ if (clash) {
365
+ stderrLine(chalk.red(`Monitor '${clash.monitor.name}' on ${chalk.bold(clash.machine)} already watches this exact source and fires the same action.`));
366
+ stderrLine(chalk.gray(' Two boxes watching one work item is a double trigger.'));
367
+ stderrLine(chalk.gray(` Inspect it: agents ssh ${clash.machine} 'agents monitors view ${clash.monitor.name}'`));
368
+ stderrLine(chalk.gray(` Add anyway: agents monitors add ${config.name} ... --force`));
369
+ process.exit(1);
370
+ }
371
+ // Never treat "could not ask" as "no duplicate".
372
+ if (fleet.discoveryFailed) {
373
+ stderrLine(chalk.yellow(' Note: could not reach the device registry — the fleet was not checked for duplicates.'));
374
+ }
375
+ else if (fleet.skipped.length > 0) {
376
+ stderrLine(chalk.yellow(` Note: could not check ${fleet.skipped.join(', ')} — a duplicate there would not have been caught.`));
377
+ }
378
+ }
245
379
  export function registerMonitorsCommands(program) {
246
380
  const monitorsCmd = program
247
381
  .command('monitors')
@@ -315,11 +449,12 @@ export function registerMonitorsCommands(program) {
315
449
  .option('--notify [channel]', 'Notify the owner (notify.owner); [channel] overrides the owner channel')
316
450
  .option('--webhook-out <url>', 'POST the event to this URL')
317
451
  // PLACEMENT / hygiene
318
- .option('--device <name>', 'OWNER (not body placement) — the single machine that evaluates + fires (exactly-once). See docs/00-concepts.md#placement.')
452
+ .option('--device <name>', 'OWNER (not body placement) — the single machine that evaluates + fires (exactly-once). See docs/concepts.md#placement.')
319
453
  .option('--devices <list>', 'Allowlist (comma-separated): each device fires independently')
320
454
  .option('--run-on <host>', 'BODY placement — execute the ACTION on this machine over SSH (same idea as run --where device:<host>)')
321
455
  .option('--rate-limit <spec>', 'Auto-pause if it fires more than N/<interval> (e.g. 5/1m)')
322
456
  .option('--disabled', 'Create the monitor paused (enable later with resume)')
457
+ .option('--force', 'Overwrite a same-named monitor, or add one that duplicates an existing watcher')
323
458
  .action(async (nameOrPath, options) => {
324
459
  // File mode: a single arg pointing at an existing .yml with no source flags.
325
460
  const hasSourceFlag = Boolean(options.watch || options.poll || options.pollHttp || options.on || options.ws || options.watchFile || options.watchDevice);
@@ -342,9 +477,11 @@ export function registerMonitorsCommands(program) {
342
477
  stderrLine(chalk.red(` - ${err}`));
343
478
  process.exit(1);
344
479
  }
480
+ await guardAgainstDuplicateMonitor(config, options.force === true);
345
481
  writeMonitor(config);
346
482
  console.log(chalk.green(`Monitor '${name}' added`));
347
483
  ensureDaemonRunning();
484
+ await assertEnginePickup(config);
348
485
  return;
349
486
  }
350
487
  if (!nameOrPath) {
@@ -413,10 +550,12 @@ export function registerMonitorsCommands(program) {
413
550
  if (condition.mode === 'match' && condition.match && /^(issued|success|ok|pass(ed)?|done|ready)$/i.test(condition.match)) {
414
551
  stderrLine(chalk.yellow(` Note: --match '${condition.match}' only fires on success — it stays silent if the source breaks or never matches.`));
415
552
  }
553
+ await guardAgainstDuplicateMonitor(config, options.force === true);
416
554
  writeMonitor(config);
417
555
  console.log(chalk.green(`Monitor '${nameOrPath}' added`));
418
556
  console.log(chalk.gray(` ${sourceLabel(source)} → [${condition.mode}] → ${actionLabel(action)} · owner: ${ownerLabel(config)}`));
419
557
  ensureDaemonRunning();
558
+ await assertEnginePickup(config);
420
559
  });
421
560
  // ─── list ────────────────────────────────────────────────────────────────────
422
561
  monitorsCmd
@@ -428,16 +567,28 @@ export function registerMonitorsCommands(program) {
428
567
  if (options.json) {
429
568
  const payload = monitors.map((m) => {
430
569
  const state = readState(m.name);
570
+ const liveness = readLiveness(m.name);
431
571
  return {
432
572
  name: m.name,
433
573
  enabled: m.enabled,
434
574
  source: m.source,
435
575
  condition: m.condition,
436
- action: { type: m.action.type },
576
+ // Full action, not just `type`: the cross-machine duplicate guard
577
+ // fingerprints source+condition+action, so a type-only action made
578
+ // every `--run` monitor unmatchable and the fleet check inert for
579
+ // exactly the case it exists for. `source` already ships whole.
580
+ action: m.action,
437
581
  owner: ownerLabel(m),
438
582
  runsHere: monitorRunsOnThisDevice(m),
439
583
  lastSeenAt: state?.lastSeenAt ?? null,
440
584
  lastFiredAt: state?.lastFiredAt ?? null,
585
+ // Liveness heartbeat (RUSH-2485): distinguishes never-polled from
586
+ // polling-not-matching from a stalled engine.
587
+ lastCheckedAt: liveness?.lastCheckedAt ?? null,
588
+ checkCount: liveness?.checkCount ?? 0,
589
+ lastError: liveness?.lastError ?? null,
590
+ consecutiveErrors: liveness?.consecutiveErrors ?? 0,
591
+ stalled: isStalled(m, liveness),
441
592
  };
442
593
  });
443
594
  stdoutJson(payload);
@@ -451,12 +602,12 @@ export function registerMonitorsCommands(program) {
451
602
  console.log(chalk.bold('Monitors\n'));
452
603
  for (const m of monitors) {
453
604
  const state = readState(m.name);
605
+ const liveness = readLiveness(m.name);
454
606
  const enabled = m.enabled ? chalk.green('on') : chalk.gray('off');
455
607
  const here = monitorRunsOnThisDevice(m);
456
608
  const owner = here ? ownerLabel(m) : chalk.gray(ownerLabel(m));
457
- const lastFired = state?.lastFiredAt ? `fired ${state.lastFiredAt}` : chalk.gray('never fired');
458
609
  console.log(` ${chalk.cyan(m.name.padEnd(22))} ${enabled.padEnd(3)} ${sourceLabel(m.source)}`);
459
- console.log(` ${' '.repeat(22)} ${chalk.gray(`[${m.condition.mode}]`)} → ${actionLabel(m.action)} ${chalk.gray(`owner: ${owner}`)} ${chalk.gray(lastFired)}`);
610
+ console.log(` ${' '.repeat(22)} ${chalk.gray(`[${m.condition.mode}]`)} → ${actionLabel(m.action)} ${chalk.gray(`owner: ${owner}`)} ${livenessLabel(m, state, liveness)}`);
460
611
  }
461
612
  console.log();
462
613
  });
@@ -477,6 +628,7 @@ export function registerMonitorsCommands(program) {
477
628
  process.exit(1);
478
629
  }
479
630
  const state = readState(name);
631
+ const liveness = readLiveness(name);
480
632
  const recentFires = listFires(name).slice(-5);
481
633
  if (options.json) {
482
634
  stdoutJson({
@@ -485,14 +637,30 @@ export function registerMonitorsCommands(program) {
485
637
  owner: ownerLabel(monitor),
486
638
  runsHere: monitorRunsOnThisDevice(monitor),
487
639
  state,
640
+ liveness,
641
+ stalled: isStalled(monitor, liveness),
488
642
  recentFires,
489
643
  });
490
644
  return;
491
645
  }
492
646
  console.log(chalk.bold(`Monitor: ${name}\n`));
493
647
  console.log(yaml.stringify(monitor));
648
+ // Liveness first (RUSH-2485): the heartbeat is the answer to "is this thing
649
+ // actually running?" — it renders even when the monitor has never fired.
650
+ console.log(chalk.bold('Liveness'));
651
+ console.log(` ${livenessLabel(monitor, state, liveness)}`);
652
+ if (liveness) {
653
+ console.log(chalk.gray(` last checked: ${liveness.lastCheckedAt} (${formatRelativeTime(liveness.lastCheckedAt)})`));
654
+ console.log(chalk.gray(` checks: ${liveness.checkCount}`));
655
+ if (liveness.lastError) {
656
+ console.log(chalk.red(` last error: ${liveness.lastError.replace(/\s+/g, ' ').slice(0, 200)} (${liveness.consecutiveErrors} in a row)`));
657
+ }
658
+ }
659
+ else if (monitor.enabled && monitorRunsOnThisDevice(monitor)) {
660
+ console.log(chalk.yellow(' The engine has not polled this monitor yet. If this persists, the daemon may not have picked it up — check: agents routines status'));
661
+ }
494
662
  if (state) {
495
- console.log(chalk.bold('Watched state'));
663
+ console.log(chalk.bold('\nWatched state'));
496
664
  console.log(chalk.gray(` last seen: ${state.lastSeenAt}`));
497
665
  if (state.lastFiredAt)
498
666
  console.log(chalk.gray(` last fired: ${state.lastFiredAt}`));
@@ -566,19 +734,29 @@ export function registerMonitorsCommands(program) {
566
734
  if (!name)
567
735
  return;
568
736
  }
737
+ // getMonitorPath is user-layer only: edits always land in the user dir,
738
+ // never the pull-only system mirror. Editing a system built-in (no user
739
+ // copy yet) materializes one, prefilled with the built-in's own config.
569
740
  let monitorPath = getMonitorPath(name);
570
741
  if (!monitorPath) {
571
742
  const dir = getMonitorsDir();
572
743
  fs.mkdirSync(dir, { recursive: true });
573
744
  monitorPath = safeJoin(dir, `${name}.yml`);
574
- const template = yaml.stringify({
575
- name,
576
- source: { type: 'poll', command: 'echo hello', interval: '1m' },
577
- condition: { mode: 'on-change' },
578
- action: { type: 'notify' },
579
- });
580
- fs.writeFileSync(monitorPath, template, 'utf-8');
581
- console.log(chalk.gray(`Created new monitor file: ${monitorPath}`));
745
+ const builtIn = readMonitor(name);
746
+ if (builtIn) {
747
+ fs.writeFileSync(monitorPath, yaml.stringify(builtIn), 'utf-8');
748
+ console.log(chalk.gray(`Editing a copy of built-in monitor '${name}' in your user dir: ${monitorPath}`));
749
+ }
750
+ else {
751
+ const template = yaml.stringify({
752
+ name,
753
+ source: { type: 'poll', command: 'echo hello', interval: '1m' },
754
+ condition: { mode: 'on-change' },
755
+ action: { type: 'notify' },
756
+ });
757
+ fs.writeFileSync(monitorPath, template, 'utf-8');
758
+ console.log(chalk.gray(`Created new monitor file: ${monitorPath}`));
759
+ }
582
760
  }
583
761
  const editor = process.env.EDITOR || process.env.VISUAL || (IS_WINDOWS ? 'notepad' : 'vi');
584
762
  const parts = editor.split(/\s+/).filter(Boolean);
@@ -772,6 +950,11 @@ export function registerMonitorsCommands(program) {
772
950
  stderrLine(chalk.gray('Daemon reloaded'));
773
951
  }
774
952
  }
953
+ else if (readMonitor(name)) {
954
+ // Resolvable but not in the user dir: a pull-only system built-in.
955
+ stderrLine(chalk.red(`Monitor '${name}' is a built-in and can't be removed; pause it with: agents monitors pause ${name}`));
956
+ process.exit(1);
957
+ }
775
958
  else {
776
959
  stderrLine(chalk.red(`Monitor '${name}' not found`));
777
960
  process.exit(1);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `agents open` — resolve an `agents://` deep link, and manage the OS handler
3
+ * that routes such links here.
4
+ *
5
+ * agents open agents://session/<id> resume that session in a terminal
6
+ * agents open register register the agents:// scheme with the OS
7
+ * agents open unregister remove the handler
8
+ * agents open status report whether the handler is registered
9
+ *
10
+ * A rendered artifact (plan/report) embeds `agents://session/<id>` in its
11
+ * provenance line; clicking it hands the URL to the OS, which invokes
12
+ * `agents open <url>`. This command parses it (lib/deeplink/url.ts) and hands the
13
+ * session id to the existing resume dispatcher, which resolves the owning host
14
+ * and opens the terminal with the cursor in the input bar. The id is passed as
15
+ * argv, never interpolated into a shell.
16
+ */
17
+ import type { Command } from 'commander';
18
+ export declare function registerOpenCommand(program: Command): void;
@@ -0,0 +1,57 @@
1
+ import chalk from 'chalk';
2
+ import { parseAgentsUrl } from '../lib/deeplink/url.js';
3
+ import { registerAgentsUrlScheme, unregisterAgentsUrlScheme, agentsUrlSchemeStatus, } from '../lib/deeplink/register.js';
4
+ export function registerOpenCommand(program) {
5
+ const open = program
6
+ .command('open [url]')
7
+ .description('Resume a session from an agents:// deep link, or register/unregister/status the OS URL-scheme handler.')
8
+ .action(async (url) => {
9
+ if (!url) {
10
+ open.help();
11
+ return;
12
+ }
13
+ await handleUrl(url);
14
+ });
15
+ open
16
+ .command('register')
17
+ .description('Register the agents:// URL scheme with the OS so artifact links resume sessions (idempotent).')
18
+ .action(() => {
19
+ const status = registerAgentsUrlScheme();
20
+ if (status.registered) {
21
+ console.log(chalk.green('agents:// scheme registered.') + chalk.gray(` ${status.detail}`));
22
+ }
23
+ else {
24
+ console.log(chalk.yellow('Could not register the agents:// scheme.') + chalk.gray(` ${status.detail}`));
25
+ process.exitCode = 1;
26
+ }
27
+ });
28
+ open
29
+ .command('unregister')
30
+ .description('Remove the agents:// URL scheme handler.')
31
+ .action(() => {
32
+ const status = unregisterAgentsUrlScheme();
33
+ console.log(chalk.gray(status.detail));
34
+ });
35
+ open
36
+ .command('status')
37
+ .description('Report whether the agents:// URL scheme handler is registered.')
38
+ .action(() => {
39
+ const status = agentsUrlSchemeStatus();
40
+ const label = status.registered ? chalk.green('registered') : chalk.yellow('not registered');
41
+ console.log(`agents:// handler: ${label} ${chalk.gray(`(${status.platform})`)}`);
42
+ console.log(chalk.gray(` ${status.detail}`));
43
+ if (!status.registered)
44
+ process.exitCode = 1;
45
+ });
46
+ }
47
+ async function handleUrl(url) {
48
+ const parsed = parseAgentsUrl(url);
49
+ if ('error' in parsed) {
50
+ console.error(chalk.red(`Not a valid agents:// link: ${parsed.error}`));
51
+ process.exitCode = 2;
52
+ return;
53
+ }
54
+ // Lazy-import the resume dispatcher so `register`/`status` stay cold-start cheap.
55
+ const { dispatchSessionLifecycleInPlace } = await import('./sessions-resume.js');
56
+ await dispatchSessionLifecycleInPlace(parsed.id, parsed.host ? [parsed.host] : []);
57
+ }
@@ -6,15 +6,13 @@
6
6
  * hooks from configured registries or GitHub sources.
7
7
  */
8
8
  import * as fs from 'fs';
9
- import * as path from 'path';
10
9
  import chalk from 'chalk';
11
10
  import ora from 'ora';
12
- import { getAgentsDir, getEnabledExtraRepos } from '../lib/state.js';
13
11
  import { AGENTS, getAllCliStates, agentLabel, } from '../lib/agents.js';
14
12
  import { capableAgents } from '../lib/capabilities.js';
15
13
  import { DEFAULT_REGISTRIES } from '../lib/types.js';
16
- import { getRegistries, setRegistry, removeRegistry, search as searchRegistries, resolvePackage, validatedNpmSpec, validatedPyPISpec, buildSkillIndex, verifySkillIntegrity, parseOwnerRepoFromRemote, } from '../lib/registry.js';
17
- import { cloneRepo, commitAndPush, getCurrentBranch, getRemoteUrl, isGitRepo } from '../lib/git.js';
14
+ import { getRegistries, setRegistry, removeRegistry, search as searchRegistries, resolvePackage, validatedNpmSpec, validatedPyPISpec, verifySkillIntegrity, } from '../lib/registry.js';
15
+ import { cloneRepo } from '../lib/git.js';
18
16
  import { discoverCommands, resolveCommandSource, installCommand, installCommandCentrally, } from '../lib/commands.js';
19
17
  import { discoverSkillsFromRepo, installSkill, installSkillCentrally, } from '../lib/skills.js';
20
18
  import { discoverHooksFromRepo, installHooks, installHooksCentrally, } from '../lib/hooks.js';
@@ -328,109 +326,6 @@ When to use:
328
326
  }
329
327
  });
330
328
  // ==========================================================================
331
- // PUBLISH COMMAND (self-hosted, git-index skill registry)
332
- // ==========================================================================
333
- program
334
- .command('publish')
335
- .description('Generate a skills-index.json for a git repo and push it, making its skills discoverable via agents search/install')
336
- .option('--repo <alias>', 'Publish an extra repo added via `agents repo add` (default: your ~/.agents repo)')
337
- .option('--name <name>', 'Registry name to suggest in the output (default: the repo name)')
338
- .option('--branch <branch>', 'Branch to push the index to and reference in the raw URL (default: the repo\'s current branch)')
339
- .option('--dry-run', 'Write the index and print the URL without committing or pushing')
340
- .addHelpText('after', `
341
- Publish walks a repo's skills/ directory, records a sha256 of every SKILL.md,
342
- and writes skills-index.json at the repo root — a flat index that 'agents search'
343
- and 'agents install' can consume directly from raw.githubusercontent.com. No
344
- hosted infrastructure: the index is just a file committed to your GitHub repo.
345
-
346
- Examples:
347
- # Publish your ~/.agents repo's skills
348
- agents publish
349
-
350
- # Publish an extra repo added via 'agents repo add'
351
- agents publish --repo team-skills
352
-
353
- # Preview the index without pushing
354
- agents publish --dry-run
355
-
356
- After publishing, share the printed 'agents registry add skill ...' command so
357
- others can search and install your skills. Installs verify each SKILL.md against
358
- the sha256 in the index and abort on mismatch.
359
- `)
360
- .action(async (options) => {
361
- // Resolve the target repo: an extra repo by alias, else the primary ~/.agents repo.
362
- let repoDir;
363
- if (options.repo) {
364
- const extra = getEnabledExtraRepos().find((r) => r.alias === options.repo);
365
- if (!extra) {
366
- console.log(chalk.red(`No enabled extra repo aliased '${options.repo}'.`));
367
- console.log(chalk.gray('Add one with: agents repo add <source> --as <alias>'));
368
- process.exit(1);
369
- }
370
- repoDir = extra.dir;
371
- }
372
- else {
373
- repoDir = getAgentsDir();
374
- }
375
- if (!isGitRepo(repoDir)) {
376
- console.log(chalk.red(`${repoDir} is not a git repository.`));
377
- console.log(chalk.gray('publish commits + pushes the index, so the repo needs a GitHub remote.'));
378
- process.exit(1);
379
- }
380
- const remoteUrl = await getRemoteUrl(repoDir);
381
- const repoSlug = remoteUrl ? parseOwnerRepoFromRemote(remoteUrl) : null;
382
- if (!repoSlug) {
383
- console.log(chalk.red(`Could not resolve an 'owner/repo' from the git remote of ${repoDir}.`));
384
- console.log(chalk.gray(` Remote: ${remoteUrl || '(none)'} — publish needs a GitHub origin.`));
385
- process.exit(1);
386
- }
387
- const spinner = ora('Building skills index...').start();
388
- const index = buildSkillIndex(repoDir, repoSlug, { generatedAt: new Date().toISOString() });
389
- spinner.stop();
390
- if (index.skills.length === 0) {
391
- console.log(chalk.yellow(`No skills found under ${repoDir}/skills.`));
392
- console.log(chalk.gray('Add a skill (a directory with a SKILL.md) and re-run publish.'));
393
- process.exit(1);
394
- }
395
- const indexPath = path.join(repoDir, 'skills-index.json');
396
- fs.writeFileSync(indexPath, JSON.stringify(index, null, 2) + '\n', 'utf-8');
397
- console.log(chalk.bold(`\nIndexed ${index.skills.length} skill(s) into skills-index.json:`));
398
- for (const s of index.skills) {
399
- console.log(` ${chalk.cyan(s.name)} ${chalk.gray(`sha256:${s.sha256?.slice(0, 12)}…`)}`);
400
- }
401
- // The branch the URL references must be the branch the index actually
402
- // lands on. In a real push that's whatever commitAndPush reports back
403
- // (the requested --branch, else the checked-out branch); in a dry run we
404
- // resolve it the same way without pushing.
405
- let urlBranch;
406
- if (options.dryRun) {
407
- urlBranch = options.branch || (await getCurrentBranch(repoDir));
408
- console.log(chalk.gray(`\nDry run — wrote ${indexPath} but did not commit or push.`));
409
- }
410
- else {
411
- const pushSpinner = ora('Committing and pushing skills-index.json...').start();
412
- const result = await commitAndPush(repoDir, 'chore: update skills-index.json (agents publish)', options.branch);
413
- if (!result.success) {
414
- pushSpinner.fail(`Push failed: ${result.error}`);
415
- console.log(chalk.gray('The index was written locally — commit and push it manually to publish.'));
416
- process.exit(1);
417
- }
418
- // commitAndPush always reports the pushed branch on success; the `??`
419
- // only satisfies the optional return type, it is not a behavior path.
420
- urlBranch = result.branch ?? (await getCurrentBranch(repoDir));
421
- pushSpinner.succeed(`Pushed skills-index.json to ${urlBranch}`);
422
- }
423
- const rawUrl = `https://raw.githubusercontent.com/${repoSlug}/${urlBranch}/skills-index.json`;
424
- const registryName = options.name || repoSlug.split('/')[1] || 'my-skills';
425
- console.log(chalk.bold('\nPublished. Share these with anyone who wants your skills:\n'));
426
- console.log(chalk.gray(' Index URL:'));
427
- console.log(` ${rawUrl}`);
428
- console.log(chalk.gray('\n Register + search + install:'));
429
- console.log(` ${chalk.green(`agents registry add skill ${registryName} ${rawUrl}`)}`);
430
- console.log(` ${chalk.green(`agents search ${index.skills[0].name} --type skill`)}`);
431
- console.log(` ${chalk.green(`agents install skill:${index.skills[0].name} --agents claude,codex,cursor`)}`);
432
- });
433
- // ==========================================================================
434
329
  // INSTALL COMMAND (unified package installation)
435
330
  // ==========================================================================
436
331
  program
@@ -282,10 +282,11 @@ Examples:
282
282
  }
283
283
  console.log();
284
284
  });
285
- // agents plugins sync <name> [agent]
285
+ // Deprecated: superseded by `agents sync --plugin <name>`. Kept as a warned,
286
+ // functional alias so old muscle-memory and scripts don't break.
286
287
  pluginsCmd
287
- .command('sync <name> [agent]')
288
- .description('Apply a plugin to an agent. Syncs every installed version (pass agent@version to target one).')
288
+ .command('sync <name> [agent]', { hidden: true })
289
+ .description('Deprecated use `agents sync --plugin <name>` instead.')
289
290
  .option('--allow-exec-surfaces', 'Enable the plugin even when it ships hooks/, .mcp.json, bin/, scripts/, settings.json, or permissions/')
290
291
  .addHelpText('after', `
291
292
  Examples:
@@ -302,6 +303,8 @@ Examples:
302
303
  agents plugins sync hivemind claude --allow-exec-surfaces
303
304
  `)
304
305
  .action(async (name, agentArg, options) => {
306
+ console.warn(chalk.yellow('`agents plugins sync` is deprecated — use `agents sync --plugin` instead:'));
307
+ console.warn(chalk.gray(` agents sync --plugin ${name}`));
305
308
  const plugin = getPlugin(name);
306
309
  if (!plugin) {
307
310
  console.log(chalk.red(`Plugin '${name}' not found`));
@@ -25,6 +25,7 @@ export interface AddProfileOptions {
25
25
  model?: string;
26
26
  baseUrl?: string;
27
27
  authProvider?: string;
28
+ account?: string;
28
29
  version?: string;
29
30
  keyStdin?: boolean;
30
31
  force?: boolean;