@phnx-labs/agents-cli 1.22.39 → 1.22.41

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 (569) hide show
  1. package/CHANGELOG.md +316 -0
  2. package/README.md +116 -70
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +45 -27
  5. package/dist/browser.js +2 -2
  6. package/dist/cli/command-registry.d.ts +135 -0
  7. package/dist/cli/command-registry.js +259 -0
  8. package/dist/commands/accounts.d.ts +20 -0
  9. package/dist/commands/accounts.js +186 -25
  10. package/dist/commands/apply.d.ts +3 -3
  11. package/dist/commands/apply.js +20 -63
  12. package/dist/commands/browser.d.ts +15 -0
  13. package/dist/commands/browser.js +318 -131
  14. package/dist/commands/budget.d.ts +7 -6
  15. package/dist/commands/budget.js +8 -7
  16. package/dist/commands/cloud.js +17 -20
  17. package/dist/commands/commands.js +1 -1
  18. package/dist/commands/computer-actions.d.ts +1 -35
  19. package/dist/commands/computer-actions.js +13 -181
  20. package/dist/commands/computer.d.ts +28 -3
  21. package/dist/commands/computer.js +93 -65
  22. package/dist/commands/config.js +16 -3
  23. package/dist/commands/cost.d.ts +2 -1
  24. package/dist/commands/cost.js +7 -6
  25. package/dist/commands/daemon.js +151 -4
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +19 -11
  28. package/dist/commands/events.js +1 -1
  29. package/dist/commands/exec.d.ts +2 -50
  30. package/dist/commands/exec.js +160 -215
  31. package/dist/commands/factory.js +1 -1
  32. package/dist/commands/feed.d.ts +2 -2
  33. package/dist/commands/feed.js +12 -23
  34. package/dist/commands/fleet-capture.js +25 -27
  35. package/dist/commands/focus.d.ts +2 -3
  36. package/dist/commands/focus.js +34 -9
  37. package/dist/commands/go.js +15 -5
  38. package/dist/commands/harness.d.ts +3 -3
  39. package/dist/commands/harness.js +53 -5
  40. package/dist/commands/hooks.js +1 -1
  41. package/dist/commands/import.js +2 -2
  42. package/dist/commands/insights.d.ts +5 -5
  43. package/dist/commands/insights.js +15 -9
  44. package/dist/commands/inspect.d.ts +2 -3
  45. package/dist/commands/inspect.js +4 -16
  46. package/dist/commands/logs.d.ts +2 -2
  47. package/dist/commands/logs.js +9 -9
  48. package/dist/commands/mcp.js +2 -2
  49. package/dist/commands/memory.js +1 -1
  50. package/dist/commands/message.d.ts +1 -1
  51. package/dist/commands/message.js +7 -7
  52. package/dist/commands/mine.d.ts +11 -8
  53. package/dist/commands/mine.js +11 -10
  54. package/dist/commands/models.js +1 -1
  55. package/dist/commands/modes.js +1 -1
  56. package/dist/commands/monitors.js +23 -6
  57. package/dist/commands/output.d.ts +7 -6
  58. package/dist/commands/output.js +11 -10
  59. package/dist/commands/packages.js +4 -4
  60. package/dist/commands/perf.js +1 -1
  61. package/dist/commands/permissions.js +49 -32
  62. package/dist/commands/plugins.d.ts +1 -1
  63. package/dist/commands/plugins.js +3 -3
  64. package/dist/commands/profiles.d.ts +6 -9
  65. package/dist/commands/profiles.js +8 -321
  66. package/dist/commands/projects.d.ts +9 -0
  67. package/dist/commands/projects.js +140 -8
  68. package/dist/commands/prune.js +5 -13
  69. package/dist/commands/refresh-rules.js +1 -1
  70. package/dist/commands/repo.d.ts +5 -7
  71. package/dist/commands/repo.js +34 -18
  72. package/dist/commands/resource-view.js +4 -0
  73. package/dist/commands/resume.d.ts +11 -7
  74. package/dist/commands/resume.js +82 -98
  75. package/dist/commands/route.d.ts +12 -0
  76. package/dist/commands/route.js +261 -0
  77. package/dist/commands/routines.d.ts +2 -3
  78. package/dist/commands/routines.js +120 -145
  79. package/dist/commands/rules.js +1 -1
  80. package/dist/commands/run-account-picker.d.ts +1 -1
  81. package/dist/commands/run-account-picker.js +2 -2
  82. package/dist/commands/run-broadcast.d.ts +21 -0
  83. package/dist/commands/run-broadcast.js +89 -0
  84. package/dist/commands/run-cloud.js +1 -1
  85. package/dist/commands/secrets-vault.d.ts +10 -0
  86. package/dist/commands/{login.js → secrets-vault.js} +34 -14
  87. package/dist/commands/secrets.d.ts +4 -4
  88. package/dist/commands/secrets.js +158 -159
  89. package/dist/commands/sessions-backfill.js +1 -1
  90. package/dist/commands/sessions-browser.d.ts +1 -1
  91. package/dist/commands/sessions-browser.js +9 -5
  92. package/dist/commands/sessions-export.js +2 -2
  93. package/dist/commands/sessions-inject.js +4 -5
  94. package/dist/commands/sessions-migrate.js +16 -27
  95. package/dist/commands/sessions-picker.d.ts +14 -0
  96. package/dist/commands/sessions-picker.js +209 -13
  97. package/dist/commands/sessions-resume.d.ts +7 -3
  98. package/dist/commands/sessions-resume.js +81 -33
  99. package/dist/commands/sessions-share.d.ts +25 -0
  100. package/dist/commands/sessions-share.js +166 -0
  101. package/dist/commands/sessions-stats.js +2 -2
  102. package/dist/commands/sessions.d.ts +75 -68
  103. package/dist/commands/sessions.js +144 -180
  104. package/dist/commands/setup-browser.js +1 -1
  105. package/dist/commands/setup-computer.js +1 -1
  106. package/dist/commands/setup-fleet.js +3 -0
  107. package/dist/commands/setup-mine.d.ts +7 -3
  108. package/dist/commands/setup-mine.js +13 -8
  109. package/dist/commands/setup-preferences.js +2 -2
  110. package/dist/commands/setup-secrets.js +2 -2
  111. package/dist/commands/setup-watchdog.js +2 -2
  112. package/dist/commands/setup.js +7 -2
  113. package/dist/commands/share.d.ts +65 -0
  114. package/dist/commands/share.js +253 -20
  115. package/dist/commands/skills.js +3 -3
  116. package/dist/commands/snapshot.d.ts +2 -2
  117. package/dist/commands/snapshot.js +9 -9
  118. package/dist/commands/ssh.d.ts +1 -1
  119. package/dist/commands/ssh.js +186 -64
  120. package/dist/commands/subagents.js +1 -1
  121. package/dist/commands/sync.js +24 -9
  122. package/dist/commands/teams.d.ts +2 -2
  123. package/dist/commands/teams.js +9 -18
  124. package/dist/commands/tmux.js +5 -1
  125. package/dist/commands/trash.js +1 -1
  126. package/dist/commands/usage.d.ts +1 -1
  127. package/dist/commands/usage.js +2 -2
  128. package/dist/commands/utils.d.ts +4 -14
  129. package/dist/commands/utils.js +6 -27
  130. package/dist/commands/versions.js +2 -2
  131. package/dist/commands/view.d.ts +9 -77
  132. package/dist/commands/view.js +23 -8
  133. package/dist/commands/watchdog.js +1 -1
  134. package/dist/commands/webhook.js +25 -34
  135. package/dist/commands/workflows.js +1 -1
  136. package/dist/index.js +1 -1
  137. package/dist/lib/account-capabilities.d.ts +39 -0
  138. package/dist/lib/account-capabilities.js +59 -0
  139. package/dist/lib/account-catalog.js +1 -1
  140. package/dist/lib/account-registry.d.ts +66 -0
  141. package/dist/lib/account-registry.js +151 -5
  142. package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
  143. package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
  144. package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
  145. package/dist/lib/{usage.js → accounting/usage.js} +11 -11
  146. package/dist/lib/agent-spec/provider.js +1 -1
  147. package/dist/lib/agents.d.ts +72 -4
  148. package/dist/lib/agents.js +231 -199
  149. package/dist/lib/answer-router.d.ts +2 -2
  150. package/dist/lib/ask-classifier.d.ts +1 -1
  151. package/dist/lib/ask-classifier.js +1 -1
  152. package/dist/lib/audit/log.js +1 -1
  153. package/dist/lib/auth-health.d.ts +1 -1
  154. package/dist/lib/auth-health.js +2 -2
  155. package/dist/lib/brand.js +1 -1
  156. package/dist/lib/browser/caller-identity.d.ts +28 -0
  157. package/dist/lib/browser/caller-identity.js +156 -0
  158. package/dist/lib/browser/cdp.js +5 -1
  159. package/dist/lib/browser/chrome.js +12 -1
  160. package/dist/lib/browser/drivers/ssh.d.ts +1 -1
  161. package/dist/lib/browser/drivers/ssh.js +3 -2
  162. package/dist/lib/browser/hygiene.d.ts +10 -2
  163. package/dist/lib/browser/hygiene.js +7 -4
  164. package/dist/lib/browser/ipc.d.ts +22 -2
  165. package/dist/lib/browser/ipc.js +185 -21
  166. package/dist/lib/browser/profiles.d.ts +69 -5
  167. package/dist/lib/browser/profiles.js +135 -13
  168. package/dist/lib/browser/remote-control.d.ts +2 -2
  169. package/dist/lib/browser/remote-control.js +3 -3
  170. package/dist/lib/browser/runtime-state.d.ts +79 -0
  171. package/dist/lib/browser/runtime-state.js +119 -1
  172. package/dist/lib/browser/service.d.ts +137 -2
  173. package/dist/lib/browser/service.js +492 -54
  174. package/dist/lib/browser/sessions-list.d.ts +2 -1
  175. package/dist/lib/browser/sessions-list.js +4 -13
  176. package/dist/lib/browser/types.d.ts +19 -1
  177. package/dist/lib/budget/config.js +1 -1
  178. package/dist/lib/budget/ledger.js +1 -1
  179. package/dist/lib/byok-usage.js +1 -1
  180. package/dist/lib/capabilities.js +3 -15
  181. package/dist/lib/catchup.d.ts +1 -1
  182. package/dist/lib/catchup.js +1 -1
  183. package/dist/lib/cloud/dispatch.js +1 -1
  184. package/dist/lib/cloud/host.d.ts +3 -3
  185. package/dist/lib/cloud/host.js +5 -5
  186. package/dist/lib/cloud/rush.d.ts +9 -21
  187. package/dist/lib/cloud/rush.js +33 -120
  188. package/dist/lib/cloud/types.d.ts +2 -2
  189. package/dist/lib/commands.js +3 -13
  190. package/dist/lib/computer/actions.d.ts +36 -0
  191. package/dist/lib/computer/actions.js +162 -0
  192. package/dist/lib/computer/dispatch.d.ts +2 -2
  193. package/dist/lib/computer/dispatch.js +2 -2
  194. package/dist/lib/computer/sessions-list.d.ts +3 -3
  195. package/dist/lib/computer/sessions-list.js +2 -2
  196. package/dist/lib/config-keys.d.ts +2 -1
  197. package/dist/lib/config-keys.js +8 -4
  198. package/dist/lib/config-machine-keys.d.ts +4 -2
  199. package/dist/lib/config-machine-keys.js +5 -2
  200. package/dist/lib/crabbox/lease.js +9 -1
  201. package/dist/lib/crabbox/runtimes.d.ts +32 -7
  202. package/dist/lib/crabbox/runtimes.js +72 -30
  203. package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
  204. package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
  205. package/dist/lib/daemon-services.d.ts +1 -1
  206. package/dist/lib/daemon-services.js +5 -0
  207. package/dist/lib/daemon-ticks.d.ts +25 -0
  208. package/dist/lib/daemon-ticks.js +31 -1
  209. package/dist/lib/daemon-webhooks.d.ts +104 -0
  210. package/dist/lib/daemon-webhooks.js +215 -0
  211. package/dist/lib/device-config.d.ts +85 -75
  212. package/dist/lib/device-config.js +280 -142
  213. package/dist/lib/devices/config-migration.d.ts +29 -34
  214. package/dist/lib/devices/config-migration.js +209 -130
  215. package/dist/lib/devices/connect.d.ts +2 -2
  216. package/dist/lib/devices/connect.js +2 -2
  217. package/dist/lib/devices/discovery-policy.d.ts +30 -0
  218. package/dist/lib/devices/discovery-policy.js +101 -0
  219. package/dist/lib/devices/fleet-inventory.js +8 -3
  220. package/dist/lib/devices/harness-inventory.d.ts +1 -1
  221. package/dist/lib/devices/harness-inventory.js +12 -3
  222. package/dist/lib/devices/known-hosts.js +1 -1
  223. package/dist/lib/devices/pool.d.ts +10 -5
  224. package/dist/lib/devices/pool.js +5 -7
  225. package/dist/lib/devices/registry.d.ts +1 -1
  226. package/dist/lib/devices/registry.js +1 -1
  227. package/dist/lib/devices/resolve-profile.d.ts +2 -2
  228. package/dist/lib/devices/resolve-profile.js +2 -2
  229. package/dist/lib/devices/resolve-target.d.ts +1 -1
  230. package/dist/lib/devices/resolve-target.js +4 -4
  231. package/dist/lib/devices/self-host.d.ts +1 -1
  232. package/dist/lib/devices/self-host.js +3 -3
  233. package/dist/lib/devices/ssh-config.d.ts +1 -1
  234. package/dist/lib/devices/stats-cache.js +1 -1
  235. package/dist/lib/devices/sync.d.ts +3 -1
  236. package/dist/lib/devices/sync.js +3 -3
  237. package/dist/lib/doctor-diff.js +4 -4
  238. package/dist/lib/drift-sync.js +2 -2
  239. package/dist/lib/drift.js +2 -2
  240. package/dist/lib/event-families.d.ts +1 -1
  241. package/dist/lib/event-stream.d.ts +1 -1
  242. package/dist/lib/event-stream.js +2 -2
  243. package/dist/lib/events-ingest.js +2 -2
  244. package/dist/lib/exec.d.ts +4 -4
  245. package/dist/lib/exec.js +11 -11
  246. package/dist/lib/factory/snapshot.d.ts +1 -1
  247. package/dist/lib/factory/snapshot.js +1 -1
  248. package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
  249. package/dist/lib/{activity.js → feed/activity.js} +7 -7
  250. package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
  251. package/dist/lib/{events.js → feed/events.js} +5 -5
  252. package/dist/lib/{feed.js → feed/feed.js} +4 -4
  253. package/dist/lib/feed-outcome.d.ts +1 -1
  254. package/dist/lib/feed-policy.d.ts +1 -1
  255. package/dist/lib/feed-policy.js +1 -1
  256. package/dist/lib/feed-post.d.ts +1 -1
  257. package/dist/lib/feed-post.js +1 -1
  258. package/dist/lib/feed-ranking.d.ts +1 -1
  259. package/dist/lib/fleet/apply.d.ts +0 -6
  260. package/dist/lib/fleet/apply.js +18 -45
  261. package/dist/lib/fleet/auth-sync.d.ts +16 -35
  262. package/dist/lib/fleet/auth-sync.js +16 -75
  263. package/dist/lib/fleet/capture.js +8 -6
  264. package/dist/lib/fleet/manifest.js +23 -11
  265. package/dist/lib/fleet/types.d.ts +19 -7
  266. package/dist/lib/fleet-cache.d.ts +1 -1
  267. package/dist/lib/fleet-cache.js +1 -1
  268. package/dist/lib/format.d.ts +19 -0
  269. package/dist/lib/format.js +44 -1
  270. package/dist/lib/friction-heuristics.d.ts +1 -1
  271. package/dist/lib/git.d.ts +24 -1
  272. package/dist/lib/git.js +82 -38
  273. package/dist/lib/heal.js +3 -3
  274. package/dist/lib/hooks.d.ts +18 -0
  275. package/dist/lib/hooks.js +113 -1
  276. package/dist/lib/hosts/credentials.d.ts +30 -10
  277. package/dist/lib/hosts/credentials.js +38 -26
  278. package/dist/lib/hosts/dispatch.d.ts +3 -3
  279. package/dist/lib/hosts/dispatch.js +3 -3
  280. package/dist/lib/hosts/option.d.ts +3 -3
  281. package/dist/lib/hosts/option.js +7 -8
  282. package/dist/lib/hosts/passthrough.d.ts +17 -17
  283. package/dist/lib/hosts/passthrough.js +67 -50
  284. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  285. package/dist/lib/hosts/providers/devices.js +1 -1
  286. package/dist/lib/hosts/reconcile.d.ts +1 -1
  287. package/dist/lib/hosts/reconcile.js +1 -1
  288. package/dist/lib/hosts/reconnect.d.ts +1 -1
  289. package/dist/lib/hosts/reconnect.js +2 -2
  290. package/dist/lib/hosts/registry.d.ts +5 -5
  291. package/dist/lib/hosts/registry.js +5 -5
  292. package/dist/lib/hosts/remote-cmd.d.ts +10 -10
  293. package/dist/lib/hosts/remote-cmd.js +25 -18
  294. package/dist/lib/hosts/remote-os.d.ts +4 -4
  295. package/dist/lib/hosts/remote-os.js +4 -4
  296. package/dist/lib/hosts/remote-session-id.d.ts +2 -2
  297. package/dist/lib/hosts/remote-session-id.js +2 -2
  298. package/dist/lib/hosts/routing-flag.d.ts +3 -3
  299. package/dist/lib/hosts/routing-flag.js +4 -5
  300. package/dist/lib/hosts/run-target.d.ts +4 -4
  301. package/dist/lib/hosts/run-target.js +4 -4
  302. package/dist/lib/hosts/session-index.d.ts +2 -2
  303. package/dist/lib/hosts/session-index.js +1 -1
  304. package/dist/lib/hosts/session-marker.d.ts +1 -1
  305. package/dist/lib/hosts/session-marker.js +1 -1
  306. package/dist/lib/hosts/types.d.ts +2 -2
  307. package/dist/lib/hosts/types.js +2 -2
  308. package/dist/lib/import.js +1 -1
  309. package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
  310. package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
  311. package/dist/lib/installations/resolve.js +1 -1
  312. package/dist/lib/installations/strategies.js +1 -1
  313. package/dist/lib/installations/update.js +2 -2
  314. package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
  315. package/dist/lib/{versions.js → installations/versions.js} +51 -31
  316. package/dist/lib/isolation-boundary-report.js +1 -1
  317. package/dist/lib/linear-projects.d.ts +28 -0
  318. package/dist/lib/linear-projects.js +30 -0
  319. package/dist/lib/loop.js +1 -1
  320. package/dist/lib/mailbox-gc.js +1 -1
  321. package/dist/lib/mailbox.js +1 -1
  322. package/dist/lib/mcp-registry.d.ts +62 -0
  323. package/dist/lib/mcp-registry.js +177 -0
  324. package/dist/lib/mcp.d.ts +5 -0
  325. package/dist/lib/mcp.js +124 -307
  326. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  327. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  328. package/dist/lib/menubar/install-menubar.d.ts +7 -0
  329. package/dist/lib/menubar/install-menubar.js +24 -6
  330. package/dist/lib/menubar/snapshot.d.ts +7 -0
  331. package/dist/lib/menubar/snapshot.js +8 -6
  332. package/dist/lib/models.js +1 -1
  333. package/dist/lib/monitors/config.d.ts +12 -0
  334. package/dist/lib/monitors/config.js +3 -0
  335. package/dist/lib/monitors/dispatch.js +26 -5
  336. package/dist/lib/monitors/engine.js +10 -0
  337. package/dist/lib/monitors/sources/webhook.d.ts +1 -1
  338. package/dist/lib/monitors/state.d.ts +42 -0
  339. package/dist/lib/monitors/state.js +30 -0
  340. package/dist/lib/notify.d.ts +1 -1
  341. package/dist/lib/observe-aliases.d.ts +3 -3
  342. package/dist/lib/observe-aliases.js +3 -21
  343. package/dist/lib/output/git-output.js +2 -2
  344. package/dist/lib/overdue.d.ts +1 -1
  345. package/dist/lib/overdue.js +1 -1
  346. package/dist/lib/permissions-registry.d.ts +65 -0
  347. package/dist/lib/permissions-registry.js +599 -0
  348. package/dist/lib/permissions.d.ts +24 -13
  349. package/dist/lib/permissions.js +52 -271
  350. package/dist/lib/picker.d.ts +16 -0
  351. package/dist/lib/picker.js +33 -3
  352. package/dist/lib/placement.d.ts +1 -1
  353. package/dist/lib/placement.js +4 -4
  354. package/dist/lib/platform/paths.d.ts +8 -0
  355. package/dist/lib/platform/paths.js +11 -0
  356. package/dist/lib/platform/posixpath.js +3 -3
  357. package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
  358. package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
  359. package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
  360. package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
  361. package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
  362. package/dist/lib/{skills.js → plugins/skills.js} +7 -7
  363. package/dist/lib/pricing/cost.d.ts +1 -1
  364. package/dist/lib/pricing/cost.js +1 -1
  365. package/dist/lib/profiles-presets.d.ts +1 -1
  366. package/dist/lib/profiles-presets.js +1 -1
  367. package/dist/lib/profiles.js +2 -2
  368. package/dist/lib/project-import.js +4 -1
  369. package/dist/lib/project-key.js +7 -0
  370. package/dist/lib/project-launch.d.ts +1 -1
  371. package/dist/lib/project-launch.js +3 -3
  372. package/dist/lib/project-pull.d.ts +128 -0
  373. package/dist/lib/project-pull.js +384 -0
  374. package/dist/lib/project-root.d.ts +2 -2
  375. package/dist/lib/project-root.js +2 -2
  376. package/dist/lib/project-status.js +1 -1
  377. package/dist/lib/projects.d.ts +23 -0
  378. package/dist/lib/projects.js +29 -6
  379. package/dist/lib/refresh.d.ts +12 -1
  380. package/dist/lib/refresh.js +16 -9
  381. package/dist/lib/registry.d.ts +9 -2
  382. package/dist/lib/registry.js +11 -4
  383. package/dist/lib/resources.d.ts +2 -2
  384. package/dist/lib/resources.js +2 -2
  385. package/dist/lib/routers.d.ts +81 -0
  386. package/dist/lib/routers.js +153 -0
  387. package/dist/lib/routine-context.d.ts +1 -0
  388. package/dist/lib/routine-context.js +7 -2
  389. package/dist/lib/routine-notify-owner.d.ts +1 -1
  390. package/dist/lib/routine-notify.d.ts +1 -1
  391. package/dist/lib/routine-notify.js +1 -1
  392. package/dist/lib/routine-process-cleanup.d.ts +1 -1
  393. package/dist/lib/routine-readiness.d.ts +1 -1
  394. package/dist/lib/routine-readiness.js +11 -4
  395. package/dist/lib/routines-placement.d.ts +12 -2
  396. package/dist/lib/routines-placement.js +20 -3
  397. package/dist/lib/routines-project.d.ts +1 -1
  398. package/dist/lib/routines-project.js +1 -1
  399. package/dist/lib/rules/compile.d.ts +1 -0
  400. package/dist/lib/rules/compile.js +10 -2
  401. package/dist/lib/rules/rules.js +1 -1
  402. package/dist/lib/run-notify.js +1 -1
  403. package/dist/lib/runner.d.ts +80 -2
  404. package/dist/lib/runner.js +261 -67
  405. package/dist/lib/sandbox.d.ts +1 -1
  406. package/dist/lib/scheduler.d.ts +1 -1
  407. package/dist/lib/scheduler.js +1 -1
  408. package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
  409. package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
  410. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  411. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  412. package/dist/lib/secrets/agent.js +2 -2
  413. package/dist/lib/secrets/audit.js +1 -1
  414. package/dist/lib/secrets/bundles.d.ts +4 -4
  415. package/dist/lib/secrets/bundles.js +8 -8
  416. package/dist/lib/secrets/headless.d.ts +16 -0
  417. package/dist/lib/secrets/headless.js +21 -0
  418. package/dist/lib/secrets/index.js +1 -1
  419. package/dist/lib/secrets/list-filter.d.ts +1 -1
  420. package/dist/lib/secrets/list-filter.js +2 -2
  421. package/dist/lib/secrets/push.d.ts +1 -1
  422. package/dist/lib/secrets/push.js +10 -12
  423. package/dist/lib/secrets/remote.d.ts +21 -17
  424. package/dist/lib/secrets/remote.js +39 -23
  425. package/dist/lib/secrets/vault.js +2 -2
  426. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  427. package/dist/lib/self-heal/checks/shims.js +1 -1
  428. package/dist/lib/self-update.d.ts +39 -4
  429. package/dist/lib/self-update.js +78 -25
  430. package/dist/lib/serve/control.d.ts +1 -1
  431. package/dist/lib/serve/control.js +4 -4
  432. package/dist/lib/serve/data.d.ts +1 -1
  433. package/dist/lib/serve/data.js +1 -1
  434. package/dist/lib/serve/stream.js +1 -1
  435. package/dist/lib/service-manifest.d.ts +29 -0
  436. package/dist/lib/service-manifest.js +80 -0
  437. package/dist/lib/session/active.d.ts +59 -7
  438. package/dist/lib/session/active.js +158 -17
  439. package/dist/lib/session/bash-command.js +1 -1
  440. package/dist/lib/session/claude-accounts.d.ts +1 -1
  441. package/dist/lib/session/claude-accounts.js +1 -1
  442. package/dist/lib/session/db.d.ts +10 -2
  443. package/dist/lib/session/db.js +25 -6
  444. package/dist/lib/session/discover.d.ts +77 -0
  445. package/dist/lib/session/discover.js +130 -25
  446. package/dist/lib/session/fork.js +1 -1
  447. package/dist/lib/session/inject.d.ts +1 -1
  448. package/dist/lib/session/insights.d.ts +1 -1
  449. package/dist/lib/session/insights.js +1 -1
  450. package/dist/lib/session/live-metadata.d.ts +15 -0
  451. package/dist/lib/session/live-metadata.js +76 -0
  452. package/dist/lib/session/migrate-targets.d.ts +1 -1
  453. package/dist/lib/session/recovery.d.ts +1 -1
  454. package/dist/lib/session/recovery.js +2 -2
  455. package/dist/lib/session/remote-active.d.ts +10 -1
  456. package/dist/lib/session/remote-active.js +8 -3
  457. package/dist/lib/session/remote-bundle.d.ts +1 -1
  458. package/dist/lib/session/remote-bundle.js +2 -2
  459. package/dist/lib/session/remote-list.d.ts +15 -4
  460. package/dist/lib/session/remote-list.js +40 -3
  461. package/dist/lib/session/remote.d.ts +5 -5
  462. package/dist/lib/session/remote.js +13 -17
  463. package/dist/lib/session/resume-command.d.ts +3 -2
  464. package/dist/lib/session/resume-command.js +4 -3
  465. package/dist/lib/session/resume-owner.d.ts +3 -3
  466. package/dist/lib/session/resume-owner.js +3 -3
  467. package/dist/lib/session/session-cache.d.ts +12 -0
  468. package/dist/lib/session/session-cache.js +2 -0
  469. package/dist/lib/session/share-html.d.ts +55 -0
  470. package/dist/lib/session/share-html.js +319 -0
  471. package/dist/lib/session/shell-programs.js +1 -1
  472. package/dist/lib/session/state.js +5 -5
  473. package/dist/lib/session/team-filter.d.ts +1 -1
  474. package/dist/lib/session/team-filter.js +1 -1
  475. package/dist/lib/session/types.d.ts +3 -3
  476. package/dist/lib/session/width.d.ts +2 -2
  477. package/dist/lib/session/width.js +2 -2
  478. package/dist/lib/settings-manifest.d.ts +2 -0
  479. package/dist/lib/settings-manifest.js +81 -3
  480. package/dist/lib/share/delete.d.ts +21 -0
  481. package/dist/lib/share/delete.js +42 -0
  482. package/dist/lib/share/publish.d.ts +120 -0
  483. package/dist/lib/share/publish.js +243 -18
  484. package/dist/lib/share/worker-template.js +172 -9
  485. package/dist/lib/shims.js +35 -7
  486. package/dist/lib/smart-launch.d.ts +4 -4
  487. package/dist/lib/smart-launch.js +6 -4
  488. package/dist/lib/snapshot.d.ts +4 -4
  489. package/dist/lib/snapshot.js +2 -2
  490. package/dist/lib/ssh-exec.d.ts +1 -1
  491. package/dist/lib/ssh-exec.js +2 -2
  492. package/dist/lib/ssh-tunnel.d.ts +10 -10
  493. package/dist/lib/ssh-tunnel.js +12 -12
  494. package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
  495. package/dist/lib/staleness/checkers/hooks.js +1 -1
  496. package/dist/lib/staleness/detectors/permissions.js +0 -23
  497. package/dist/lib/staleness/detectors/plugins.js +1 -1
  498. package/dist/lib/staleness/fingerprint.js +1 -1
  499. package/dist/lib/staleness/layers.d.ts +1 -1
  500. package/dist/lib/staleness/layers.js +1 -1
  501. package/dist/lib/staleness/writers/mcp.js +3 -1
  502. package/dist/lib/staleness/writers/plugins.js +1 -1
  503. package/dist/lib/staleness/writers/types.d.ts +8 -0
  504. package/dist/lib/startup/command-registry.d.ts +6 -147
  505. package/dist/lib/startup/command-registry.js +40 -303
  506. package/dist/lib/startup/dev-build.d.ts +0 -21
  507. package/dist/lib/startup/dev-build.js +29 -8
  508. package/dist/lib/state.d.ts +19 -1
  509. package/dist/lib/state.js +120 -51
  510. package/dist/lib/subagents.js +1 -1
  511. package/dist/lib/sync-status.js +1 -1
  512. package/dist/lib/sync-umbrella.d.ts +6 -1
  513. package/dist/lib/sync-umbrella.js +9 -4
  514. package/dist/lib/teams/agents.js +2 -2
  515. package/dist/lib/teams/registry.js +1 -1
  516. package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
  517. package/dist/lib/terminal/engine.js +1 -1
  518. package/dist/lib/terminal/index.d.ts +4 -0
  519. package/dist/lib/terminal/index.js +3 -0
  520. package/dist/lib/terminal/inject.d.ts +2 -2
  521. package/dist/lib/terminal/inject.js +2 -2
  522. package/dist/lib/terminal/transport.js +1 -1
  523. package/dist/lib/tmux/index.d.ts +1 -1
  524. package/dist/lib/tmux/index.js +1 -1
  525. package/dist/lib/tmux/session.d.ts +21 -5
  526. package/dist/lib/tmux/session.js +76 -22
  527. package/dist/lib/triggers/handlers.d.ts +38 -3
  528. package/dist/lib/triggers/handlers.js +58 -7
  529. package/dist/lib/triggers/webhook.d.ts +113 -5
  530. package/dist/lib/triggers/webhook.js +223 -44
  531. package/dist/lib/types.d.ts +19 -7
  532. package/dist/lib/usage-fleet.d.ts +1 -1
  533. package/dist/lib/usage-fleet.js +1 -1
  534. package/dist/lib/usage-refresh.d.ts +1 -1
  535. package/dist/lib/usage-refresh.js +3 -3
  536. package/dist/lib/version-duplicates.js +2 -2
  537. package/dist/lib/view-types.d.ts +56 -0
  538. package/dist/lib/view-types.js +1 -0
  539. package/dist/lib/watchdog/rotate.d.ts +2 -2
  540. package/dist/lib/watchdog/rotate.js +3 -3
  541. package/dist/lib/watchdog/runner.d.ts +2 -3
  542. package/dist/lib/watchdog/runner.js +3 -4
  543. package/dist/lib/workflows.js +1 -1
  544. package/dist/lib/wrap.d.ts +33 -0
  545. package/dist/lib/wrap.js +70 -0
  546. package/package.json +2 -1
  547. package/scripts/postinstall.js +2 -2
  548. package/dist/commands/bench.d.ts +0 -2
  549. package/dist/commands/bench.js +0 -101
  550. package/dist/commands/cp.d.ts +0 -84
  551. package/dist/commands/cp.js +0 -231
  552. package/dist/commands/login.d.ts +0 -2
  553. package/dist/lib/resources/commands.d.ts +0 -46
  554. package/dist/lib/resources/commands.js +0 -211
  555. package/dist/lib/resources/hooks.d.ts +0 -16
  556. package/dist/lib/resources/hooks.js +0 -153
  557. package/dist/lib/resources/mcp.d.ts +0 -34
  558. package/dist/lib/resources/mcp.js +0 -250
  559. package/dist/lib/resources/memory.d.ts +0 -15
  560. package/dist/lib/resources/memory.js +0 -46
  561. package/dist/lib/resources/permissions.d.ts +0 -13
  562. package/dist/lib/resources/permissions.js +0 -202
  563. package/dist/lib/resources/rules.d.ts +0 -46
  564. package/dist/lib/resources/rules.js +0 -179
  565. package/dist/lib/resources/skills.d.ts +0 -37
  566. package/dist/lib/resources/skills.js +0 -247
  567. package/dist/lib/resources/subagents.d.ts +0 -46
  568. package/dist/lib/resources/subagents.js +0 -202
  569. /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
@@ -10,11 +10,13 @@ import ora from 'ora';
10
10
  import * as fs from 'fs';
11
11
  import * as path from 'path';
12
12
  import * as yaml from 'yaml';
13
- import { isDaemonRunning, signalDaemonReload, startDaemon, stopDaemon, readDaemonLog, getDaemonStatus, getDaemonLogPath, } from '../lib/daemon.js';
13
+ import { isDaemonRunning, signalDaemonReload, startDaemon, stopDaemon, readDaemonLog, getDaemonStatus, getDaemonLogPath, } from '../lib/daemon/daemon.js';
14
14
  import { assertSchedulerEnabled, assertDaemonEnabled, isDaemonEnabled } from '../lib/device-config.js';
15
- import { resolveAgentName, isAgentHardDeprecated, hardDeprecationError, ROUTINE_AGENT_IDS } from '../lib/agents.js';
16
- import { humanizeCron, humanizeNextRun, formatRepoLink, REPO_DISPLAY_MAX } from '../lib/routines-format.js';
17
- import { listJobs as listAllJobs, deleteJob, readJob, validateJob, writeJob, setJobEnabled, listRuns, routineStats, getLatestRun, getRunDir, getJobPath, isCanonicalRoutineSource, parseAtTime, hasCompletedOneShotRun, isOneShotLikeSchedule, isOneShotRoutine, isPastOneShotRoutine, jobRunsOnThisDevice, checkJobDeviceEligibility, normalizeTriggerEvent, parseHostStrategy, resolveHostStrategy, HOST_STRATEGIES, computeProjectGroup, computeProjectGroupKind, projectGroupKey, projectGroupTitle, projectGroupOrder, normalizeProjects, } from '../lib/routines.js';
15
+ import { parseAgentVersionSpec, isAgentHardDeprecated, hardDeprecationError, ROUTINE_AGENT_IDS } from '../lib/agents.js';
16
+ import { RUN_STRATEGIES, normalizeRunStrategy } from '../lib/accounting/rotate.js';
17
+ import { formatRepoLink, REPO_DISPLAY_MAX } from '../lib/routines-format.js';
18
+ import { listJobs as listAllJobs, deleteJob, readJob, validateJob, writeJob, setJobEnabled, listRuns, routineStats, getLatestRun, getRunDir, getJobPath, isCanonicalRoutineSource, parseAtTime, hasCompletedOneShotRun, isOneShotLikeSchedule, isOneShotRoutine, jobRunsOnThisDevice, checkJobDeviceEligibility, normalizeTriggerEvent, parseHostStrategy, resolveHostStrategy, HOST_STRATEGIES, computeProjectGroupKind, projectGroupKey, projectGroupTitle, projectGroupOrder, normalizeProjects, buildRoutineListJson, fireConditionLabel, nextRunForDisplay, nextRunLabel, localLatestRun, listJobsForDisplay, } from '../lib/scheduling/routines.js';
19
+ export { buildRoutineListJson } from '../lib/scheduling/routines.js';
18
20
  import { listProjectDefs, isSafeProjectName } from '../lib/projects.js';
19
21
  import { evaluateActivationReadinessLive } from '../lib/routine-readiness.js';
20
22
  import { discoverProjectRoutines, findProjectRoutine, materialiseProjectRoutine, syncProjectRoutines, syncAllProjectRoutines, displayProjectPath, } from '../lib/routines-project.js';
@@ -61,31 +63,6 @@ export function formatRunDuration(startedAt, completedAt) {
61
63
  * Human label for what fires a job: its cron schedule, or its event trigger
62
64
  * for schedule-less (trigger-only) routines.
63
65
  */
64
- function fireConditionLabel(job) {
65
- if (job.schedule)
66
- return humanizeCron(job.schedule, job.timezone);
67
- if (job.trigger) {
68
- if (job.trigger.type === 'github_event') {
69
- const scope = job.trigger.repo
70
- ? ` (${job.trigger.repo}${job.trigger.branch ? `@${job.trigger.branch}` : ''})`
71
- : '';
72
- const filters = [
73
- job.trigger.action ? `action=${job.trigger.action}` : null,
74
- job.trigger.label ? `label=${job.trigger.label}` : null,
75
- ].filter(Boolean).join(', ');
76
- return `on github:${job.trigger.event}${scope}${filters ? ` (${filters})` : ''}`;
77
- }
78
- const filters = [
79
- job.trigger.action ? `action=${job.trigger.action}` : null,
80
- job.trigger.teamKey ? `team=${job.trigger.teamKey}` : null,
81
- job.trigger.label ? `label=${job.trigger.label}` : null,
82
- job.trigger.stateTo ? `stateTo=${job.trigger.stateTo}` : null,
83
- job.trigger.stateFrom ? `stateFrom=${job.trigger.stateFrom}` : null,
84
- ].filter(Boolean).join(', ');
85
- return `on linear:${job.trigger.event}${filters ? ` (${filters})` : ''}`;
86
- }
87
- return '-';
88
- }
89
66
  function scheduleLabel(job) {
90
67
  let label = fireConditionLabel(job);
91
68
  if (isOneShotRoutine(job))
@@ -99,16 +76,6 @@ function scheduleLabel(job) {
99
76
  }
100
77
  return label;
101
78
  }
102
- function nextRunForDisplay(job, scheduler) {
103
- if (isPastOneShotRoutine(job))
104
- return null;
105
- return scheduler.getNextRun(job.name);
106
- }
107
- function nextRunLabel(job, scheduler, now) {
108
- if (isPastOneShotRoutine(job))
109
- return 'expired';
110
- return humanizeNextRun(scheduler.getNextRun(job.name) ?? null, now, job.timezone);
111
- }
112
79
  function deviceStateLabel(name, registry) {
113
80
  const profile = registry[normalizeHost(name)] ?? registry[name];
114
81
  if (!profile)
@@ -147,21 +114,6 @@ function deviceLabel(job, width) {
147
114
  : raw;
148
115
  return { raw, display, dim: full.length === 0 || !jobRunsOnThisDevice(job) };
149
116
  }
150
- /**
151
- * The last run THIS device can speak for.
152
- *
153
- * A run record is written by whichever daemon fired the routine, into that
154
- * machine's own runs dir — records carry no device attribution, so a record
155
- * found here only ever describes this device's history. When a routine is
156
- * pinned away from this machine (`devices:` excludes it) any local record is a
157
- * leftover from before the pin, and reporting it as the routine's status paints
158
- * another device's healthy routine red. Report nothing instead; the local
159
- * history stays readable via `agents routines runs <name>`, and the owning
160
- * device's status via `agents routines list --device <name>`.
161
- */
162
- export function localLatestRun(job) {
163
- return jobRunsOnThisDevice(job) ? getLatestRun(job.name) : null;
164
- }
165
117
  export function groupRoutineJobsByDevice(jobs, registry, self = machineId()) {
166
118
  const groups = new Map();
167
119
  const add = (key, title, job) => {
@@ -418,81 +370,6 @@ export function buildRunsJson(runs) {
418
370
  * enabled/disabled picture. Execution paths (`run`/`catchup`/`webhook`) keep
419
371
  * using `listAllJobs` so an un-materialised project routine can never fire.
420
372
  */
421
- function listJobsForDisplay(cwd) {
422
- const jobs = listAllJobs(cwd);
423
- const seen = new Set(jobs.map((j) => j.name));
424
- for (const discovered of discoverProjectRoutines()) {
425
- if (seen.has(discovered.name))
426
- continue;
427
- seen.add(discovered.name);
428
- jobs.push(discovered.config);
429
- }
430
- return jobs;
431
- }
432
- export function buildRoutineListJson() {
433
- try {
434
- monitorRunningJobs();
435
- }
436
- catch { /* best-effort orphan reap */ }
437
- const jobs = listJobsForDisplay(process.cwd());
438
- if (jobs.length === 0)
439
- return [];
440
- const scheduler = new JobScheduler(async () => { });
441
- scheduler.loadAll();
442
- try {
443
- const overdueSet = new Set();
444
- try {
445
- for (const job of detectOverdueJobs())
446
- overdueSet.add(job.name);
447
- }
448
- catch {
449
- // Best-effort indicator; never block the list on detection errors.
450
- }
451
- const now = new Date();
452
- const knownProjectNames = new Set(listProjectDefs().map((project) => project.name));
453
- return jobs.map((job) => {
454
- const latestRun = localLatestRun(job);
455
- const enabledDevices = devicesWithRoutineEnabled(job.name);
456
- return {
457
- name: job.name,
458
- agent: job.agent ?? null,
459
- workflow: job.workflow ?? null,
460
- command: job.command ?? null,
461
- repo: job.repo ?? null,
462
- schedule: job.schedule ?? null,
463
- scheduleHuman: fireConditionLabel(job),
464
- trigger: job.trigger ?? null,
465
- timezone: job.timezone ?? null,
466
- devices: enabledDevices,
467
- enabledDevices,
468
- host: job.host ?? null,
469
- hostStrategy: resolveHostStrategy(job),
470
- source: job.source ?? null,
471
- sourceRepo: job.source?.repo ?? job.repo ?? null,
472
- sourceBranch: job.source?.branch ?? null,
473
- runOnce: Boolean(job.runOnce),
474
- catchup: job.catchup !== false,
475
- oneShot: isOneShotRoutine(job),
476
- expired: isPastOneShotRoutine(job, now),
477
- runsHere: jobRunsOnThisDevice(job),
478
- enabled: job.enabled,
479
- overdue: overdueSet.has(job.name),
480
- nextRun: nextRunForDisplay(job, scheduler)?.toISOString() ?? null,
481
- nextRunHuman: nextRunLabel(job, scheduler, now),
482
- lastStatus: latestRun?.status ?? null,
483
- exitCode: latestRun?.exitCode ?? null,
484
- failureReason: latestRun?.errorMessage ?? null,
485
- lastRunStartedAt: latestRun?.startedAt ?? null,
486
- lastRunCompletedAt: latestRun?.completedAt ?? null,
487
- projects: job.projects ?? [],
488
- projectGroup: computeProjectGroup(job.projects, knownProjectNames),
489
- };
490
- });
491
- }
492
- finally {
493
- scheduler.stopAll();
494
- }
495
- }
496
373
  /** Detect Ctrl+C or premature stream close during an interactive prompt. */
497
374
  function isPromptCancelled(err) {
498
375
  return (err instanceof Error &&
@@ -926,6 +803,12 @@ export function registerRoutinesCommands(program) {
926
803
  agents routines add drain --schedule "0 3 * * *" --agent claude --placement fleet --prompt "Drain queue"
927
804
  agents routines add review --schedule "0 9 * * 1" --agent claude --placement cloud --prompt "Review open PRs"
928
805
 
806
+ # Pin an exact installed version (same agent@version syntax as agents run)
807
+ agents routines add version-pin --schedule "*/5 * * * *" --agent claude@2.1.207 --cwd /path/to/repo --prompt "Reply OK"
808
+
809
+ # Per-routine selection strategy + health-aware fleet placement at each fire
810
+ agents routines add release-shepherd --schedule "*/5 * * * *" --agent claude --strategy balanced --run-on auto --cwd /path/to/repo --prompt "Own the release through verification"
811
+
929
812
  # Enable a routine (materialises a project routine on first enable)
930
813
  agents routines enable security-sweep
931
814
  agents routines disable security-sweep
@@ -934,7 +817,7 @@ export function registerRoutinesCommands(program) {
934
817
  agents routines list
935
818
 
936
819
  # List routines on a specific device
937
- agents routines list --host yosemite-s0
820
+ agents routines list --device yosemite-s0
938
821
 
939
822
  # Create a routine restricted to specific devices
940
823
  agents routines add nightly --schedule "0 2 * * *" --agent claude --prompt "Summarize today's commits" --devices yosemite-s0,mac-mini
@@ -962,7 +845,15 @@ export function registerRoutinesCommands(program) {
962
845
  Version / credit failover (same semantics as 'agents run'):
963
846
  - Omit 'version:' to let the configured run strategy (default: balanced)
964
847
  pick a healthy install and skip accounts that are out of credits or
965
- rate-limited. Pin with 'version: 2.1.x' when you want one install only.
848
+ rate-limited. Pin with '--agent claude@2.1.x' (or 'version:' in YAML)
849
+ when you want one install only; '--strategy pinned|available|balanced'
850
+ persists a per-routine selection policy that beats the firing box's
851
+ run.<agent>.strategy config.
852
+ - Three distinct device flags: '--devices a,b' is the scheduler FIRING
853
+ allowlist (which daemons may fire this routine); '--run-on <name|auto>'
854
+ is BODY placement (where the fired job executes — 'auto' re-picks a
855
+ healthy device at each fire); the parent '--device' manages the
856
+ routine DEFINITION on another machine.
966
857
  - Foreground 'agents routines run' re-dispatches to the next healthy
967
858
  same-agent account when a mid-run rate/usage limit is detected.
968
859
  - Detached/daemon fires use the pre-flight pick only (next tick re-selects).
@@ -1006,7 +897,9 @@ export function registerRoutinesCommands(program) {
1006
897
  .command('add [nameOrPath]')
1007
898
  .description('Create a new routine from a YAML file or inline flags. Starts the scheduler automatically if it is not already running.')
1008
899
  .option('-s, --schedule <cron>', 'Cron schedule in standard format (5 fields: minute hour day month weekday)')
1009
- .option('-a, --agent <agent>', `Which agent runs this routine: ${ROUTINE_AGENT_IDS.join(', ')}`)
900
+ .option('-a, --agent <agent[@version]>', `Which agent runs this routine: ${ROUTINE_AGENT_IDS.join(', ')}. An @version pins that exact installed version (same syntax as agents run), persisted as separate agent + version fields.`)
901
+ .option('--strategy <strategy>', `Version/account selection strategy for this routine: ${RUN_STRATEGIES.join(' | ')}. Overrides run.<agent>.strategy from the firing device's config. Conflicts with an @version pin.`)
902
+ .option('--balanced', 'Shortcut for --strategy balanced.')
1010
903
  .option('--workflow <name>', 'Run an installed workflow (~/.agents/workflows/<name>) via `agents run`. Mutually exclusive with --agent.')
1011
904
  .option('--command <sh>', 'Run a plain shell command directly (no agent, no auth, no sandbox) — for deterministic housekeeping routines. Mutually exclusive with --agent and --workflow; --prompt is not used.')
1012
905
  .option('-p, --prompt <prompt>', 'Task instruction for the agent')
@@ -1015,8 +908,8 @@ export function registerRoutinesCommands(program) {
1015
908
  .option('-t, --timeout <timeout>', 'Kill the agent if it runs longer than this (e.g., 10m, 2h, 3d, 1w; max 1w)', '10m')
1016
909
  .option('--timezone <tz>', 'Interpret schedule in this timezone (e.g., America/Los_Angeles)')
1017
910
  .option('--devices <names>', 'Fleet allowlist (comma-separated): only listed devices schedule and fire this routine. Omit for unrestricted.')
1018
- .option('--run-on <name>', 'BODY placement: execute the job body on this machine over SSH (registered host, device, capability tag, or user@host). Sets hostStrategy=host. Same model as agents run --where device:<name> (docs/concepts.md#placement).')
1019
- .option('--placement <strategy>', `BODY placement strategy: ${HOST_STRATEGIES.join('|')} (default: local, or host when --run-on is set). Maps to the shared Placement model (local|device|fleet|cloud). Not the same as --host (which manages routines on a remote machine).`)
911
+ .option('--run-on <name|auto>', "BODY placement: execute the job body on this machine over SSH (registered host, device, capability tag, or user@host), or 'auto' to pick a healthy, signed-in, unloaded fleet device AT EACH FIRE — the same picker as agents run --device auto. Sets hostStrategy=host ('auto' sets fleet). Distinct from the parent --device (which manages this DEFINITION on another machine) and from --devices (the scheduler firing allowlist).")
912
+ .option('--placement <strategy>', `BODY placement strategy: ${HOST_STRATEGIES.join('|')} (default: local, or host when --run-on is set). Maps to the shared Placement model (local|device|fleet|cloud). Not the same as --device (which manages routines on a remote machine).`)
1020
913
  .option('--run-cwd <dir>', 'Working directory on the --run-on host (--remote-cwd is taken by the remote-management passthrough)')
1021
914
  .option('--at <time>', 'One-shot mode: run once at this time (e.g., "14:30" or "2026-02-24 09:00"), then disable')
1022
915
  .option('--on <source:event>', 'Webhook trigger instead of/in addition to a schedule: github:pull_request or linear:Issue')
@@ -1084,12 +977,53 @@ export function registerRoutinesCommands(program) {
1084
977
  console.error(chalk.red('An agent, workflow, or command is required (use --agent, --workflow, or --command)'));
1085
978
  process.exit(1);
1086
979
  }
1087
- // Hard-deprecated harnesses cannot be scheduled refuse at create time so
1088
- // no new recurring job silently fails against a retired backend.
980
+ // Normalize `--agent <agent[@version]>` into separate bare agent +
981
+ // version fields, the same split `agents run` performs. Storing the raw
982
+ // compound string is the RUSH-2719 bug: validateJob compared
983
+ // 'claude@2.1.207' against bare AgentIds, and the deprecation gate below
984
+ // silently missed a hard-deprecated harness pinned with @version.
985
+ let parsedAgent;
1089
986
  if (options.agent) {
1090
- const routineAgentId = resolveAgentName(options.agent);
1091
- if (routineAgentId && isAgentHardDeprecated(routineAgentId)) {
1092
- console.error(chalk.red(hardDeprecationError(routineAgentId)));
987
+ const parsed = parseAgentVersionSpec(options.agent);
988
+ if ('error' in parsed) {
989
+ console.error(chalk.red(parsed.error));
990
+ process.exit(1);
991
+ }
992
+ parsedAgent = parsed;
993
+ // Hard-deprecated harnesses cannot be scheduled — refuse at create time
994
+ // so no new recurring job silently fails against a retired backend.
995
+ if (isAgentHardDeprecated(parsed.agent)) {
996
+ console.error(chalk.red(hardDeprecationError(parsed.agent)));
997
+ process.exit(1);
998
+ }
999
+ }
1000
+ // --strategy / --balanced: per-routine selection policy, same vocabulary
1001
+ // as agents run. Rejected (not warned) against an @version pin: a warning
1002
+ // printed once at add time is easy to miss and the routine then silently
1003
+ // runs pinned forever.
1004
+ let strategy;
1005
+ if (options.strategy !== undefined || options.balanced) {
1006
+ if (options.strategy !== undefined && options.balanced) {
1007
+ console.error(chalk.red('--balanced conflicts with --strategy. Use one strategy override.'));
1008
+ process.exit(1);
1009
+ }
1010
+ if (!options.agent) {
1011
+ console.error(chalk.red('--strategy only applies to agent routines (set --agent)'));
1012
+ process.exit(1);
1013
+ }
1014
+ if (options.strategy !== undefined) {
1015
+ const normalized = normalizeRunStrategy(options.strategy);
1016
+ if (!normalized) {
1017
+ console.error(chalk.red(`Invalid strategy: ${options.strategy}. Use ${RUN_STRATEGIES.join(', ')}.`));
1018
+ process.exit(1);
1019
+ }
1020
+ strategy = normalized;
1021
+ }
1022
+ else {
1023
+ strategy = 'balanced';
1024
+ }
1025
+ if (parsedAgent?.version) {
1026
+ console.error(chalk.red(`--strategy ${strategy} conflicts with the @${parsedAgent.version} pin — an exact pin leaves nothing to select; drop --strategy or the @version pin`));
1093
1027
  process.exit(1);
1094
1028
  }
1095
1029
  }
@@ -1139,18 +1073,31 @@ export function registerRoutinesCommands(program) {
1139
1073
  console.error(chalk.red(err.message));
1140
1074
  process.exit(1);
1141
1075
  }
1142
- // --run-on implies host strategy when the user didn't pick one.
1076
+ // --run-on implies host strategy when the user didn't pick one;
1077
+ // 'auto' means fleet placement re-picked at each fire, never a literal
1078
+ // SSH target named "auto".
1143
1079
  if (options.runOn && !hostStrategy)
1144
- hostStrategy = 'host';
1080
+ hostStrategy = options.runOn === 'auto' ? 'fleet' : 'host';
1081
+ if (options.runOn === 'auto' && hostStrategy !== 'fleet') {
1082
+ console.error(chalk.red("--run-on auto is fleet placement — drop --placement, or use --placement fleet with it"));
1083
+ process.exit(1);
1084
+ }
1145
1085
  if (hostStrategy === 'host' && !options.runOn) {
1146
1086
  console.error(chalk.red('--placement host requires --run-on <name>'));
1147
1087
  process.exit(1);
1148
1088
  }
1089
+ // No devices auto-pin is needed for off-box placement: under the
1090
+ // per-device activation model (§8), a new routine is activated only on
1091
+ // the creating machine's device manifest (setJobEnabled below), so
1092
+ // exactly one daemon fires it unless it is deliberately enabled
1093
+ // elsewhere — the double-fire guard is structural now.
1149
1094
  const config = {
1150
1095
  name: nameOrPath,
1151
1096
  ...(schedule ? { schedule } : {}),
1152
1097
  ...(trigger ? { trigger } : {}),
1153
- ...(options.agent ? { agent: options.agent } : {}),
1098
+ ...(parsedAgent ? { agent: parsedAgent.agent } : {}),
1099
+ ...(parsedAgent?.version ? { version: parsedAgent.version } : {}),
1100
+ ...(strategy ? { strategy } : {}),
1154
1101
  ...(options.workflow ? { workflow: options.workflow } : {}),
1155
1102
  ...(options.command ? { command: options.command } : {}),
1156
1103
  mode: options.mode,
@@ -1405,6 +1352,8 @@ export function registerRoutinesCommands(program) {
1405
1352
  .option('--state-from <name>', 'Update the Linear previous-state filter before opening the editor')
1406
1353
  .option('--cwd <path>', 'Set the execution directory and save, without opening an editor')
1407
1354
  .option('--project-anchor <name>', 'Set the execution project anchor and save, without opening an editor')
1355
+ .option('--agent <agent[@version]>', 'Set the agent (and optional exact version pin) and save, without opening an editor — same syntax as agents run')
1356
+ .option('--strategy <strategy>', `Set the per-routine version/account selection strategy (${RUN_STRATEGIES.join(' | ')}) and save. Conflicts with an @version pin.`)
1408
1357
  .action(async (name, options) => {
1409
1358
  if (!name) {
1410
1359
  name = await pickJob('Select job to edit', undefined, ['agents routines edit <name>']) ?? undefined;
@@ -1418,7 +1367,7 @@ export function registerRoutinesCommands(program) {
1418
1367
  // and the only edit surface opened $EDITOR — so an agent could never
1419
1368
  // follow its own repair hint (RUSH-2517). Applying and saving directly is
1420
1369
  // what makes that hint true.
1421
- if (options.cwd !== undefined || options.projectAnchor !== undefined) {
1370
+ if (options.cwd !== undefined || options.projectAnchor !== undefined || options.agent !== undefined || options.strategy !== undefined) {
1422
1371
  if (!existing) {
1423
1372
  console.error(chalk.red(`Routine '${name}' not found. Create it first: agents routines add ${name} --schedule "..." --agent claude --prompt "..."`));
1424
1373
  process.exit(1);
@@ -1427,6 +1376,32 @@ export function registerRoutinesCommands(program) {
1427
1376
  existing.cwd = options.cwd;
1428
1377
  if (options.projectAnchor !== undefined)
1429
1378
  existing.project = options.projectAnchor;
1379
+ if (options.agent !== undefined) {
1380
+ const parsed = parseAgentVersionSpec(options.agent);
1381
+ if ('error' in parsed) {
1382
+ console.error(chalk.red(parsed.error));
1383
+ process.exit(1);
1384
+ }
1385
+ if (isAgentHardDeprecated(parsed.agent)) {
1386
+ console.error(chalk.red(hardDeprecationError(parsed.agent)));
1387
+ process.exit(1);
1388
+ }
1389
+ existing.agent = parsed.agent;
1390
+ // An @version pin replaces any previous pin; a bare agent clears it so
1391
+ // the routine returns to strategy/balanced selection.
1392
+ if (parsed.version)
1393
+ existing.version = parsed.version;
1394
+ else
1395
+ delete existing.version;
1396
+ }
1397
+ if (options.strategy !== undefined) {
1398
+ const normalized = normalizeRunStrategy(options.strategy);
1399
+ if (!normalized) {
1400
+ console.error(chalk.red(`Invalid strategy: ${options.strategy}. Use ${RUN_STRATEGIES.join(', ')}.`));
1401
+ process.exit(1);
1402
+ }
1403
+ existing.strategy = normalized;
1404
+ }
1430
1405
  const errors = validateJob(existing);
1431
1406
  if (errors.length > 0) {
1432
1407
  console.error(chalk.red('Validation errors:'));
@@ -2042,7 +2017,7 @@ export function registerRoutinesCommands(program) {
2042
2017
  signalDaemonReload();
2043
2018
  continue;
2044
2019
  }
2045
- const launch = getCliLaunch(['routines', action, name, '--host', device]);
2020
+ const launch = getCliLaunch(['routines', action, name, '--device', device]);
2046
2021
  const result = spawnSync(launch.command, launch.args, { stdio: 'inherit', env: process.env });
2047
2022
  if ((result.status ?? 1) !== 0) {
2048
2023
  if (isTarget) {
@@ -2261,7 +2236,7 @@ export function registerRoutinesCommands(program) {
2261
2236
  console.log(chalk.gray('No scheduler logs'));
2262
2237
  }
2263
2238
  });
2264
- // Every direct routines subcommand accepts the shared --host family so remote
2239
+ // Every direct routines subcommand accepts the shared --device family so remote
2265
2240
  // fall-through works and each subcommand's --help documents the flags.
2266
2241
  for (const sub of routinesCmd.commands) {
2267
2242
  addHostOption(sub);
@@ -8,7 +8,7 @@ import { AGENTS, agentConfigDirName, MANAGED_AGENT_IDS, resolveAgentName, format
8
8
  import { capableAgents } from '../lib/capabilities.js';
9
9
  import { cloneRepo } from '../lib/git.js';
10
10
  import { discoverInstructionsFromRepo, discoverRuleFilesFromRepo, installInstructionsCentrally, uninstallInstructions, listInstalledInstructionsWithScope, instructionsExists, getInstructionsContent, listCentralRules, } from '../lib/rules/rules.js';
11
- import { listInstalledVersions, getGlobalDefault, resolveVersionAlias, syncResourcesToVersion, promptAgentVersionSelection, getVersionHomePath, } from '../lib/versions.js';
11
+ import { listInstalledVersions, getGlobalDefault, resolveVersionAlias, syncResourcesToVersion, promptAgentVersionSelection, getVersionHomePath, } from '../lib/installations/versions.js';
12
12
  import { recordVersionResources, getActiveRulesPreset, setActiveRulesPreset } from '../lib/state.js';
13
13
  import { discoverRulesLayers } from '../lib/rules/compose.js';
14
14
  import * as yaml from 'yaml';
@@ -1,5 +1,5 @@
1
1
  import type { AgentId } from '../lib/types.js';
2
- import { type RotateCandidate } from '../lib/rotate.js';
2
+ import { type RotateCandidate } from '../lib/accounting/rotate.js';
3
3
  export interface RunAccountChoice {
4
4
  name: string;
5
5
  value: string;
@@ -2,8 +2,8 @@ import { select } from '@inquirer/prompts';
2
2
  import chalk from 'chalk';
3
3
  import { agentLabel } from '../lib/agents.js';
4
4
  import { loginHint } from '../lib/signin-badge.js';
5
- import { collectRunCandidates, readinessFromCandidate, isSignInRecoverable, } from '../lib/rotate.js';
6
- import { compareVersions, getGlobalDefault } from '../lib/versions.js';
5
+ import { collectRunCandidates, readinessFromCandidate, isSignInRecoverable, } from '../lib/accounting/rotate.js';
6
+ import { compareVersions, getGlobalDefault } from '../lib/installations/versions.js';
7
7
  import { isInteractiveTerminal, isPromptCancelled, requireInteractiveSelection } from './utils.js';
8
8
  const CANCEL_SELECTION = '__agents_cancel_account_selection__';
9
9
  const WINDOW_ORDER = ['session', 'week', 'sonnet_week', 'month'];
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `agents run --broadcast` — run the same task/prompt across an agent × model
3
+ * matrix (formerly `agents bench`).
4
+ *
5
+ * Task definitions live under apps/cli/bench/tasks/<id>/task.json.
6
+ */
7
+ export interface BroadcastOpts {
8
+ listTasks?: boolean;
9
+ results?: string | true;
10
+ task?: string;
11
+ model?: string;
12
+ concurrency?: string;
13
+ json?: boolean;
14
+ /** Comma-separated agents from the run [agent] positional when broadcasting. */
15
+ agentsCsv?: string;
16
+ prompt?: string;
17
+ /** When true, run the matrix (not just list/results). */
18
+ requireRun?: boolean;
19
+ }
20
+ /** Handle --broadcast / --list-tasks / --results on `agents run`. Always completes the path. */
21
+ export declare function handleBroadcast(opts: BroadcastOpts): Promise<void>;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * `agents run --broadcast` — run the same task/prompt across an agent × model
3
+ * matrix (formerly `agents bench`).
4
+ *
5
+ * Task definitions live under apps/cli/bench/tasks/<id>/task.json.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { detectSignedInRuntimes } from '../lib/crabbox/runtimes.js';
11
+ import { listRuns, loadRun, loadTask, runCells, saveRun, } from '../lib/bench/index.js';
12
+ const TASKS_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../bench/tasks');
13
+ function csv(value) {
14
+ return (value
15
+ ?.split(',')
16
+ .map((item) => item.trim())
17
+ .filter(Boolean) ?? []);
18
+ }
19
+ function taskIds(root = TASKS_ROOT) {
20
+ if (!fs.existsSync(root))
21
+ return [];
22
+ return fs
23
+ .readdirSync(root, { withFileTypes: true })
24
+ .filter((entry) => entry.isDirectory() &&
25
+ fs.existsSync(path.join(root, entry.name, 'task.json')))
26
+ .map((entry) => entry.name)
27
+ .sort();
28
+ }
29
+ function renderResult(result) {
30
+ console.log(`Run ${result.run_id}${result.task_id ? ` · ${result.task_id}` : ''}`);
31
+ for (const cell of result.cells)
32
+ console.log(`${cell.status === 'passed' ? 'PASS' : 'FAIL'} ${cell.agent}${cell.model ? `/${cell.model}` : ''} ${cell.wall_ms} ms exit ${cell.exit ?? 'spawn-error'}`);
33
+ }
34
+ /** Handle --broadcast / --list-tasks / --results on `agents run`. Always completes the path. */
35
+ export async function handleBroadcast(opts) {
36
+ if (opts.listTasks) {
37
+ const tasks = taskIds();
38
+ if (opts.json)
39
+ console.log(JSON.stringify(tasks, null, 2));
40
+ else if (tasks.length === 0)
41
+ console.log('No broadcast tasks installed.');
42
+ else
43
+ tasks.forEach((id) => console.log(id));
44
+ return;
45
+ }
46
+ if (opts.results !== undefined) {
47
+ const runId = opts.results === true ? undefined : opts.results;
48
+ const value = runId ? loadRun(runId) : listRuns();
49
+ if (opts.json)
50
+ console.log(JSON.stringify(value, null, 2));
51
+ else if (Array.isArray(value)) {
52
+ if (value.length === 0)
53
+ console.log('No broadcast results yet.');
54
+ else
55
+ value.forEach(renderResult);
56
+ }
57
+ else
58
+ renderResult(value);
59
+ return;
60
+ }
61
+ if (!opts.requireRun) {
62
+ throw new Error('Pass --broadcast with a prompt or --task <id>, or use --list-tasks / --results.');
63
+ }
64
+ if (!!opts.task === !!opts.prompt) {
65
+ throw new Error('Pass exactly one of --task <id> or a prompt with --broadcast.');
66
+ }
67
+ const task = opts.task ? loadTask(opts.task, TASKS_ROOT) : undefined;
68
+ const prompt = opts.prompt ?? task.prompt;
69
+ let agents = csv(opts.agentsCsv);
70
+ if (agents.length === 0) {
71
+ agents = (await detectSignedInRuntimes())
72
+ .filter((runtime) => runtime.signedIn)
73
+ .map((runtime) => runtime.id);
74
+ }
75
+ if (agents.length === 0) {
76
+ throw new Error('No signed-in native agents found. Pass comma-separated agents: agents run --broadcast claude,codex "…"');
77
+ }
78
+ const models = csv(opts.model);
79
+ const cells = agents.flatMap((agent) => models.length > 0 ? models.map((model) => ({ agent, model })) : [{ agent }]);
80
+ const concurrency = Number(opts.concurrency ?? '3');
81
+ const result = await runCells({ task, prompt, cells, concurrency });
82
+ saveRun(result);
83
+ if (opts.json)
84
+ console.log(JSON.stringify(result, null, 2));
85
+ else
86
+ renderResult(result);
87
+ if (result.cells.some((cell) => cell.status === 'failed'))
88
+ process.exitCode = 1;
89
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `agents run <agent> [prompt] --cloud` — the vendor-cloud placement for a run.
3
3
  *
4
- * One of three run placements: local (default), machine (--host/--device,
4
+ * One of three run placements: local (default), machine (--device,
5
5
  * --lease), cloud (--cloud). Routing goes through the cloud provider registry
6
6
  * exactly like `agents cloud run --agent <agent>`: the agent's native
7
7
  * `cloudProvider` wins, `--provider` overrides. The dispatch itself is the
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `agents secrets vault` — unlock/lock the age-encrypted synced-secrets file
3
+ * at ~/.agents/vault.age (distinct from `agents secrets unlock|lock`, which
4
+ * holds keychain bundles in the secrets-agent).
5
+ *
6
+ * Formerly top-level `agents login` / `agents logout`.
7
+ */
8
+ import type { Command } from 'commander';
9
+ /** Register `agents secrets vault unlock|lock` under the secrets parent. */
10
+ export declare function registerSecretsVaultCommands(secretsCmd: Command): void;