@phnx-labs/agents-cli 1.22.38 → 1.22.40

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 (554) hide show
  1. package/CHANGELOG.md +302 -0
  2. package/README.md +111 -70
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +46 -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 +260 -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.js +206 -94
  13. package/dist/commands/budget.d.ts +7 -6
  14. package/dist/commands/budget.js +8 -7
  15. package/dist/commands/cloud.js +17 -20
  16. package/dist/commands/commands.js +1 -1
  17. package/dist/commands/computer-actions.d.ts +1 -35
  18. package/dist/commands/computer-actions.js +13 -181
  19. package/dist/commands/computer.d.ts +28 -3
  20. package/dist/commands/computer.js +93 -65
  21. package/dist/commands/config.js +47 -4
  22. package/dist/commands/cost.d.ts +2 -1
  23. package/dist/commands/cost.js +7 -6
  24. package/dist/commands/daemon.js +151 -4
  25. package/dist/commands/detach.js +1 -1
  26. package/dist/commands/doctor.js +19 -11
  27. package/dist/commands/events.js +1 -1
  28. package/dist/commands/exec.d.ts +2 -50
  29. package/dist/commands/exec.js +161 -216
  30. package/dist/commands/factory.js +1 -1
  31. package/dist/commands/feed.d.ts +2 -2
  32. package/dist/commands/feed.js +9 -12
  33. package/dist/commands/fleet-capture.js +25 -27
  34. package/dist/commands/focus.d.ts +2 -3
  35. package/dist/commands/focus.js +34 -9
  36. package/dist/commands/go.js +15 -5
  37. package/dist/commands/harness.d.ts +3 -3
  38. package/dist/commands/harness.js +53 -5
  39. package/dist/commands/hooks.js +1 -1
  40. package/dist/commands/import.js +2 -2
  41. package/dist/commands/insights.d.ts +5 -5
  42. package/dist/commands/insights.js +15 -9
  43. package/dist/commands/inspect.d.ts +2 -3
  44. package/dist/commands/inspect.js +4 -16
  45. package/dist/commands/logs.d.ts +2 -2
  46. package/dist/commands/logs.js +9 -9
  47. package/dist/commands/mcp.js +2 -2
  48. package/dist/commands/memory.js +1 -1
  49. package/dist/commands/message.d.ts +1 -1
  50. package/dist/commands/message.js +7 -7
  51. package/dist/commands/mine.d.ts +11 -8
  52. package/dist/commands/mine.js +11 -10
  53. package/dist/commands/models.js +1 -1
  54. package/dist/commands/modes.js +1 -1
  55. package/dist/commands/monitors.js +23 -6
  56. package/dist/commands/output.d.ts +7 -6
  57. package/dist/commands/output.js +11 -10
  58. package/dist/commands/packages.js +4 -4
  59. package/dist/commands/perf.js +1 -1
  60. package/dist/commands/permissions.js +49 -32
  61. package/dist/commands/plugins.d.ts +1 -1
  62. package/dist/commands/plugins.js +3 -3
  63. package/dist/commands/profiles.d.ts +6 -9
  64. package/dist/commands/profiles.js +8 -321
  65. package/dist/commands/projects.d.ts +9 -0
  66. package/dist/commands/projects.js +140 -8
  67. package/dist/commands/prune.js +5 -13
  68. package/dist/commands/refresh-rules.js +1 -1
  69. package/dist/commands/repo.d.ts +5 -7
  70. package/dist/commands/repo.js +34 -18
  71. package/dist/commands/resource-view.js +4 -0
  72. package/dist/commands/resume.d.ts +11 -7
  73. package/dist/commands/resume.js +82 -98
  74. package/dist/commands/route.d.ts +12 -0
  75. package/dist/commands/route.js +261 -0
  76. package/dist/commands/routines.d.ts +2 -3
  77. package/dist/commands/routines.js +120 -145
  78. package/dist/commands/rules.js +1 -1
  79. package/dist/commands/run-account-picker.d.ts +1 -1
  80. package/dist/commands/run-account-picker.js +2 -2
  81. package/dist/commands/run-broadcast.d.ts +21 -0
  82. package/dist/commands/run-broadcast.js +89 -0
  83. package/dist/commands/run-cloud.js +1 -1
  84. package/dist/commands/secrets-vault.d.ts +10 -0
  85. package/dist/commands/{login.js → secrets-vault.js} +34 -14
  86. package/dist/commands/secrets.d.ts +4 -4
  87. package/dist/commands/secrets.js +72 -63
  88. package/dist/commands/sessions-backfill.js +1 -1
  89. package/dist/commands/sessions-browser.d.ts +1 -1
  90. package/dist/commands/sessions-browser.js +9 -5
  91. package/dist/commands/sessions-export.js +2 -2
  92. package/dist/commands/sessions-inject.js +4 -5
  93. package/dist/commands/sessions-migrate.js +16 -27
  94. package/dist/commands/sessions-picker.d.ts +13 -0
  95. package/dist/commands/sessions-picker.js +182 -8
  96. package/dist/commands/sessions-resume.d.ts +7 -3
  97. package/dist/commands/sessions-resume.js +81 -33
  98. package/dist/commands/sessions-stats.js +2 -2
  99. package/dist/commands/sessions.d.ts +75 -68
  100. package/dist/commands/sessions.js +142 -180
  101. package/dist/commands/setup-computer.js +1 -1
  102. package/dist/commands/setup-fleet.js +3 -0
  103. package/dist/commands/setup-mine.d.ts +7 -3
  104. package/dist/commands/setup-mine.js +13 -8
  105. package/dist/commands/setup-secrets.js +2 -2
  106. package/dist/commands/setup-watchdog.js +2 -2
  107. package/dist/commands/setup.js +7 -2
  108. package/dist/commands/share.d.ts +65 -0
  109. package/dist/commands/share.js +253 -20
  110. package/dist/commands/skills.js +3 -3
  111. package/dist/commands/snapshot.d.ts +2 -2
  112. package/dist/commands/snapshot.js +9 -9
  113. package/dist/commands/ssh.d.ts +1 -1
  114. package/dist/commands/ssh.js +318 -48
  115. package/dist/commands/subagents.js +1 -1
  116. package/dist/commands/sync.js +24 -9
  117. package/dist/commands/teams.d.ts +2 -2
  118. package/dist/commands/teams.js +9 -18
  119. package/dist/commands/tmux.js +5 -1
  120. package/dist/commands/trash.js +1 -1
  121. package/dist/commands/usage.d.ts +1 -1
  122. package/dist/commands/usage.js +2 -2
  123. package/dist/commands/utils.d.ts +4 -14
  124. package/dist/commands/utils.js +6 -27
  125. package/dist/commands/versions.js +2 -2
  126. package/dist/commands/view.d.ts +9 -77
  127. package/dist/commands/view.js +23 -8
  128. package/dist/commands/watchdog.js +1 -1
  129. package/dist/commands/webhook.js +11 -25
  130. package/dist/commands/workflows.js +1 -1
  131. package/dist/index.js +1 -1
  132. package/dist/lib/account-capabilities.d.ts +39 -0
  133. package/dist/lib/account-capabilities.js +59 -0
  134. package/dist/lib/account-catalog.js +1 -1
  135. package/dist/lib/account-registry.d.ts +66 -0
  136. package/dist/lib/account-registry.js +151 -5
  137. package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
  138. package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
  139. package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
  140. package/dist/lib/{usage.js → accounting/usage.js} +11 -11
  141. package/dist/lib/agent-spec/provider.js +1 -1
  142. package/dist/lib/agents.d.ts +72 -4
  143. package/dist/lib/agents.js +231 -199
  144. package/dist/lib/answer-router.d.ts +2 -2
  145. package/dist/lib/ask-classifier.d.ts +1 -1
  146. package/dist/lib/ask-classifier.js +1 -1
  147. package/dist/lib/audit/log.js +1 -1
  148. package/dist/lib/auth-health.d.ts +1 -1
  149. package/dist/lib/auth-health.js +2 -2
  150. package/dist/lib/brand.js +1 -1
  151. package/dist/lib/browser/caller-identity.d.ts +28 -0
  152. package/dist/lib/browser/caller-identity.js +156 -0
  153. package/dist/lib/browser/cdp.js +1 -1
  154. package/dist/lib/browser/drivers/ssh.d.ts +1 -1
  155. package/dist/lib/browser/drivers/ssh.js +2 -2
  156. package/dist/lib/browser/hygiene.d.ts +10 -2
  157. package/dist/lib/browser/hygiene.js +7 -4
  158. package/dist/lib/browser/ipc.d.ts +22 -2
  159. package/dist/lib/browser/ipc.js +185 -21
  160. package/dist/lib/browser/profiles.d.ts +67 -3
  161. package/dist/lib/browser/profiles.js +129 -7
  162. package/dist/lib/browser/remote-control.d.ts +2 -2
  163. package/dist/lib/browser/remote-control.js +3 -3
  164. package/dist/lib/browser/runtime-state.d.ts +79 -0
  165. package/dist/lib/browser/runtime-state.js +119 -1
  166. package/dist/lib/browser/service.d.ts +113 -1
  167. package/dist/lib/browser/service.js +454 -40
  168. package/dist/lib/browser/sessions-list.d.ts +2 -1
  169. package/dist/lib/browser/sessions-list.js +4 -13
  170. package/dist/lib/browser/types.d.ts +18 -0
  171. package/dist/lib/budget/config.js +1 -1
  172. package/dist/lib/budget/ledger.js +1 -1
  173. package/dist/lib/byok-usage.js +1 -1
  174. package/dist/lib/capabilities.js +3 -15
  175. package/dist/lib/catchup.d.ts +1 -1
  176. package/dist/lib/catchup.js +1 -1
  177. package/dist/lib/cloud/dispatch.js +1 -1
  178. package/dist/lib/cloud/host.d.ts +3 -3
  179. package/dist/lib/cloud/host.js +5 -5
  180. package/dist/lib/cloud/rush.d.ts +9 -21
  181. package/dist/lib/cloud/rush.js +33 -120
  182. package/dist/lib/cloud/types.d.ts +2 -2
  183. package/dist/lib/commands.js +3 -13
  184. package/dist/lib/computer/actions.d.ts +36 -0
  185. package/dist/lib/computer/actions.js +162 -0
  186. package/dist/lib/computer/dispatch.d.ts +2 -2
  187. package/dist/lib/computer/dispatch.js +2 -2
  188. package/dist/lib/computer/sessions-list.d.ts +3 -3
  189. package/dist/lib/computer/sessions-list.js +2 -2
  190. package/dist/lib/config-keys.d.ts +12 -3
  191. package/dist/lib/config-keys.js +29 -6
  192. package/dist/lib/config-machine-keys.d.ts +4 -2
  193. package/dist/lib/config-machine-keys.js +6 -2
  194. package/dist/lib/crabbox/lease.js +9 -1
  195. package/dist/lib/crabbox/runtimes.d.ts +32 -7
  196. package/dist/lib/crabbox/runtimes.js +72 -30
  197. package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
  198. package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
  199. package/dist/lib/daemon-services.d.ts +1 -1
  200. package/dist/lib/daemon-services.js +5 -0
  201. package/dist/lib/daemon-ticks.d.ts +25 -0
  202. package/dist/lib/daemon-ticks.js +31 -1
  203. package/dist/lib/daemon-webhooks.d.ts +102 -0
  204. package/dist/lib/daemon-webhooks.js +210 -0
  205. package/dist/lib/device-config.d.ts +116 -72
  206. package/dist/lib/device-config.js +366 -132
  207. package/dist/lib/devices/config-migration.d.ts +29 -34
  208. package/dist/lib/devices/config-migration.js +209 -130
  209. package/dist/lib/devices/connect.d.ts +2 -2
  210. package/dist/lib/devices/connect.js +2 -2
  211. package/dist/lib/devices/discovery-policy.d.ts +30 -0
  212. package/dist/lib/devices/discovery-policy.js +101 -0
  213. package/dist/lib/devices/fleet-inventory.js +8 -3
  214. package/dist/lib/devices/harness-inventory.d.ts +1 -1
  215. package/dist/lib/devices/harness-inventory.js +12 -3
  216. package/dist/lib/devices/known-hosts.js +1 -1
  217. package/dist/lib/devices/pool.d.ts +61 -0
  218. package/dist/lib/devices/pool.js +83 -0
  219. package/dist/lib/devices/registry.d.ts +1 -1
  220. package/dist/lib/devices/registry.js +1 -1
  221. package/dist/lib/devices/resolve-profile.d.ts +2 -2
  222. package/dist/lib/devices/resolve-profile.js +2 -2
  223. package/dist/lib/devices/resolve-target.d.ts +1 -1
  224. package/dist/lib/devices/resolve-target.js +4 -4
  225. package/dist/lib/devices/self-host.d.ts +1 -1
  226. package/dist/lib/devices/self-host.js +3 -3
  227. package/dist/lib/devices/ssh-config.d.ts +1 -1
  228. package/dist/lib/devices/stats-cache.js +1 -1
  229. package/dist/lib/devices/sync.d.ts +3 -1
  230. package/dist/lib/devices/sync.js +3 -3
  231. package/dist/lib/doctor-diff.js +4 -4
  232. package/dist/lib/drift-sync.js +2 -2
  233. package/dist/lib/drift.js +2 -2
  234. package/dist/lib/event-families.d.ts +1 -1
  235. package/dist/lib/event-stream.d.ts +1 -1
  236. package/dist/lib/event-stream.js +2 -2
  237. package/dist/lib/events-ingest.js +2 -2
  238. package/dist/lib/exec.d.ts +8 -5
  239. package/dist/lib/exec.js +19 -13
  240. package/dist/lib/factory/snapshot.d.ts +1 -1
  241. package/dist/lib/factory/snapshot.js +1 -1
  242. package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
  243. package/dist/lib/{activity.js → feed/activity.js} +7 -7
  244. package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
  245. package/dist/lib/{events.js → feed/events.js} +5 -5
  246. package/dist/lib/{feed.js → feed/feed.js} +4 -4
  247. package/dist/lib/feed-outcome.d.ts +1 -1
  248. package/dist/lib/feed-policy.d.ts +1 -1
  249. package/dist/lib/feed-policy.js +1 -1
  250. package/dist/lib/feed-post.d.ts +1 -1
  251. package/dist/lib/feed-post.js +1 -1
  252. package/dist/lib/feed-ranking.d.ts +1 -1
  253. package/dist/lib/fleet/apply.d.ts +0 -6
  254. package/dist/lib/fleet/apply.js +18 -45
  255. package/dist/lib/fleet/auth-sync.d.ts +16 -35
  256. package/dist/lib/fleet/auth-sync.js +16 -75
  257. package/dist/lib/fleet/capture.js +8 -6
  258. package/dist/lib/fleet/manifest.js +23 -11
  259. package/dist/lib/fleet/types.d.ts +19 -7
  260. package/dist/lib/fleet-cache.d.ts +1 -1
  261. package/dist/lib/fleet-cache.js +1 -1
  262. package/dist/lib/format.d.ts +19 -0
  263. package/dist/lib/format.js +44 -1
  264. package/dist/lib/friction-heuristics.d.ts +1 -1
  265. package/dist/lib/git.d.ts +24 -1
  266. package/dist/lib/git.js +82 -38
  267. package/dist/lib/heal.js +3 -3
  268. package/dist/lib/hooks.d.ts +18 -0
  269. package/dist/lib/hooks.js +113 -1
  270. package/dist/lib/hosts/credentials.d.ts +30 -10
  271. package/dist/lib/hosts/credentials.js +38 -26
  272. package/dist/lib/hosts/dispatch.d.ts +3 -3
  273. package/dist/lib/hosts/dispatch.js +3 -3
  274. package/dist/lib/hosts/option.d.ts +3 -3
  275. package/dist/lib/hosts/option.js +7 -8
  276. package/dist/lib/hosts/passthrough.d.ts +17 -17
  277. package/dist/lib/hosts/passthrough.js +67 -50
  278. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  279. package/dist/lib/hosts/providers/devices.js +1 -1
  280. package/dist/lib/hosts/reconcile.d.ts +1 -1
  281. package/dist/lib/hosts/reconcile.js +1 -1
  282. package/dist/lib/hosts/reconnect.d.ts +1 -1
  283. package/dist/lib/hosts/reconnect.js +2 -2
  284. package/dist/lib/hosts/registry.d.ts +5 -5
  285. package/dist/lib/hosts/registry.js +5 -5
  286. package/dist/lib/hosts/remote-cmd.d.ts +10 -10
  287. package/dist/lib/hosts/remote-cmd.js +25 -18
  288. package/dist/lib/hosts/remote-os.d.ts +4 -4
  289. package/dist/lib/hosts/remote-os.js +4 -4
  290. package/dist/lib/hosts/remote-session-id.d.ts +2 -2
  291. package/dist/lib/hosts/remote-session-id.js +2 -2
  292. package/dist/lib/hosts/routing-flag.d.ts +3 -3
  293. package/dist/lib/hosts/routing-flag.js +4 -5
  294. package/dist/lib/hosts/run-target.d.ts +4 -4
  295. package/dist/lib/hosts/run-target.js +4 -4
  296. package/dist/lib/hosts/session-index.d.ts +2 -2
  297. package/dist/lib/hosts/session-index.js +1 -1
  298. package/dist/lib/hosts/session-marker.d.ts +1 -1
  299. package/dist/lib/hosts/session-marker.js +1 -1
  300. package/dist/lib/hosts/types.d.ts +2 -2
  301. package/dist/lib/hosts/types.js +2 -2
  302. package/dist/lib/import.js +1 -1
  303. package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +49 -1
  304. package/dist/lib/{migrate.js → installations/migrate.js} +265 -38
  305. package/dist/lib/installations/resolve.js +1 -1
  306. package/dist/lib/installations/strategies.js +1 -1
  307. package/dist/lib/installations/update.js +2 -2
  308. package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
  309. package/dist/lib/{versions.js → installations/versions.js} +51 -31
  310. package/dist/lib/isolation-boundary-report.js +1 -1
  311. package/dist/lib/linear-projects.d.ts +28 -0
  312. package/dist/lib/linear-projects.js +30 -0
  313. package/dist/lib/loop.js +1 -1
  314. package/dist/lib/mailbox-gc.js +1 -1
  315. package/dist/lib/mailbox.js +1 -1
  316. package/dist/lib/mcp-registry.d.ts +62 -0
  317. package/dist/lib/mcp-registry.js +177 -0
  318. package/dist/lib/mcp.d.ts +5 -0
  319. package/dist/lib/mcp.js +124 -307
  320. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  321. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  322. package/dist/lib/menubar/install-menubar.d.ts +7 -0
  323. package/dist/lib/menubar/install-menubar.js +24 -6
  324. package/dist/lib/menubar/snapshot.d.ts +7 -0
  325. package/dist/lib/menubar/snapshot.js +8 -6
  326. package/dist/lib/models.js +1 -1
  327. package/dist/lib/monitors/config.d.ts +12 -0
  328. package/dist/lib/monitors/config.js +3 -0
  329. package/dist/lib/monitors/dispatch.js +26 -5
  330. package/dist/lib/monitors/engine.js +10 -0
  331. package/dist/lib/monitors/sources/webhook.d.ts +1 -1
  332. package/dist/lib/monitors/state.d.ts +42 -0
  333. package/dist/lib/monitors/state.js +30 -0
  334. package/dist/lib/notify.d.ts +1 -1
  335. package/dist/lib/observe-aliases.d.ts +2 -2
  336. package/dist/lib/observe-aliases.js +2 -11
  337. package/dist/lib/output/git-output.js +2 -2
  338. package/dist/lib/overdue.d.ts +1 -1
  339. package/dist/lib/overdue.js +1 -1
  340. package/dist/lib/permissions-registry.d.ts +65 -0
  341. package/dist/lib/permissions-registry.js +599 -0
  342. package/dist/lib/permissions.d.ts +24 -13
  343. package/dist/lib/permissions.js +52 -271
  344. package/dist/lib/picker.d.ts +16 -0
  345. package/dist/lib/picker.js +33 -3
  346. package/dist/lib/placement.d.ts +1 -1
  347. package/dist/lib/placement.js +4 -4
  348. package/dist/lib/platform/paths.d.ts +8 -0
  349. package/dist/lib/platform/paths.js +11 -0
  350. package/dist/lib/platform/posixpath.js +3 -3
  351. package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
  352. package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
  353. package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
  354. package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
  355. package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
  356. package/dist/lib/{skills.js → plugins/skills.js} +7 -7
  357. package/dist/lib/pricing/cost.d.ts +1 -1
  358. package/dist/lib/pricing/cost.js +1 -1
  359. package/dist/lib/profiles-presets.d.ts +1 -1
  360. package/dist/lib/profiles-presets.js +1 -1
  361. package/dist/lib/profiles.js +2 -2
  362. package/dist/lib/project-import.js +4 -1
  363. package/dist/lib/project-launch.d.ts +1 -1
  364. package/dist/lib/project-launch.js +3 -3
  365. package/dist/lib/project-pull.d.ts +128 -0
  366. package/dist/lib/project-pull.js +384 -0
  367. package/dist/lib/project-root.d.ts +2 -2
  368. package/dist/lib/project-root.js +2 -2
  369. package/dist/lib/project-status.js +1 -1
  370. package/dist/lib/projects.d.ts +23 -0
  371. package/dist/lib/projects.js +29 -6
  372. package/dist/lib/refresh.d.ts +12 -1
  373. package/dist/lib/refresh.js +16 -9
  374. package/dist/lib/registry.d.ts +9 -2
  375. package/dist/lib/registry.js +11 -4
  376. package/dist/lib/resources.d.ts +2 -2
  377. package/dist/lib/resources.js +2 -2
  378. package/dist/lib/routers.d.ts +81 -0
  379. package/dist/lib/routers.js +153 -0
  380. package/dist/lib/routine-context.d.ts +1 -0
  381. package/dist/lib/routine-context.js +7 -2
  382. package/dist/lib/routine-notify-owner.d.ts +1 -1
  383. package/dist/lib/routine-notify.d.ts +1 -1
  384. package/dist/lib/routine-notify.js +1 -1
  385. package/dist/lib/routine-process-cleanup.d.ts +1 -1
  386. package/dist/lib/routine-readiness.d.ts +1 -1
  387. package/dist/lib/routine-readiness.js +11 -4
  388. package/dist/lib/routines-placement.d.ts +12 -2
  389. package/dist/lib/routines-placement.js +20 -3
  390. package/dist/lib/routines-project.d.ts +1 -1
  391. package/dist/lib/routines-project.js +1 -1
  392. package/dist/lib/rules/compile.d.ts +1 -0
  393. package/dist/lib/rules/compile.js +10 -2
  394. package/dist/lib/rules/rules.js +1 -1
  395. package/dist/lib/run-notify.js +1 -1
  396. package/dist/lib/runner.d.ts +80 -2
  397. package/dist/lib/runner.js +241 -62
  398. package/dist/lib/sandbox.d.ts +1 -1
  399. package/dist/lib/scheduler.d.ts +1 -1
  400. package/dist/lib/scheduler.js +1 -1
  401. package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
  402. package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
  403. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  404. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  405. package/dist/lib/secrets/agent.js +2 -2
  406. package/dist/lib/secrets/audit.js +1 -1
  407. package/dist/lib/secrets/bundles.d.ts +3 -3
  408. package/dist/lib/secrets/bundles.js +7 -7
  409. package/dist/lib/secrets/index.js +1 -1
  410. package/dist/lib/secrets/list-filter.d.ts +1 -1
  411. package/dist/lib/secrets/list-filter.js +2 -2
  412. package/dist/lib/secrets/push.d.ts +1 -1
  413. package/dist/lib/secrets/push.js +10 -12
  414. package/dist/lib/secrets/remote.d.ts +12 -10
  415. package/dist/lib/secrets/remote.js +21 -14
  416. package/dist/lib/secrets/vault.js +2 -2
  417. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  418. package/dist/lib/self-heal/checks/shims.js +1 -1
  419. package/dist/lib/self-update.d.ts +39 -4
  420. package/dist/lib/self-update.js +78 -25
  421. package/dist/lib/serve/control.d.ts +1 -1
  422. package/dist/lib/serve/control.js +4 -4
  423. package/dist/lib/serve/data.d.ts +1 -1
  424. package/dist/lib/serve/data.js +1 -1
  425. package/dist/lib/serve/stream.js +1 -1
  426. package/dist/lib/service-manifest.d.ts +29 -0
  427. package/dist/lib/service-manifest.js +80 -0
  428. package/dist/lib/session/active.d.ts +59 -7
  429. package/dist/lib/session/active.js +158 -17
  430. package/dist/lib/session/bash-command.js +1 -1
  431. package/dist/lib/session/claude-accounts.d.ts +1 -1
  432. package/dist/lib/session/claude-accounts.js +1 -1
  433. package/dist/lib/session/db.d.ts +10 -2
  434. package/dist/lib/session/db.js +25 -6
  435. package/dist/lib/session/discover.d.ts +77 -0
  436. package/dist/lib/session/discover.js +130 -25
  437. package/dist/lib/session/fork.js +1 -1
  438. package/dist/lib/session/inject.d.ts +1 -1
  439. package/dist/lib/session/insights.d.ts +1 -1
  440. package/dist/lib/session/insights.js +1 -1
  441. package/dist/lib/session/live-metadata.d.ts +15 -0
  442. package/dist/lib/session/live-metadata.js +76 -0
  443. package/dist/lib/session/migrate-targets.d.ts +1 -1
  444. package/dist/lib/session/recovery.d.ts +1 -1
  445. package/dist/lib/session/recovery.js +2 -2
  446. package/dist/lib/session/remote-active.d.ts +10 -1
  447. package/dist/lib/session/remote-active.js +8 -3
  448. package/dist/lib/session/remote-bundle.d.ts +1 -1
  449. package/dist/lib/session/remote-bundle.js +2 -2
  450. package/dist/lib/session/remote-list.d.ts +15 -4
  451. package/dist/lib/session/remote-list.js +40 -3
  452. package/dist/lib/session/remote.d.ts +5 -5
  453. package/dist/lib/session/remote.js +13 -17
  454. package/dist/lib/session/resume-command.d.ts +3 -2
  455. package/dist/lib/session/resume-command.js +4 -3
  456. package/dist/lib/session/resume-owner.d.ts +3 -3
  457. package/dist/lib/session/resume-owner.js +3 -3
  458. package/dist/lib/session/session-cache.d.ts +12 -0
  459. package/dist/lib/session/session-cache.js +2 -0
  460. package/dist/lib/session/shell-programs.js +1 -1
  461. package/dist/lib/session/state.js +5 -5
  462. package/dist/lib/session/team-filter.d.ts +1 -1
  463. package/dist/lib/session/team-filter.js +1 -1
  464. package/dist/lib/session/types.d.ts +3 -3
  465. package/dist/lib/session/width.d.ts +2 -2
  466. package/dist/lib/session/width.js +2 -2
  467. package/dist/lib/share/delete.d.ts +21 -0
  468. package/dist/lib/share/delete.js +42 -0
  469. package/dist/lib/share/publish.d.ts +82 -0
  470. package/dist/lib/share/publish.js +170 -18
  471. package/dist/lib/share/worker-template.js +172 -9
  472. package/dist/lib/shims.js +35 -7
  473. package/dist/lib/smart-launch.d.ts +36 -6
  474. package/dist/lib/smart-launch.js +65 -8
  475. package/dist/lib/snapshot.d.ts +4 -4
  476. package/dist/lib/snapshot.js +2 -2
  477. package/dist/lib/ssh-exec.d.ts +1 -1
  478. package/dist/lib/ssh-exec.js +2 -2
  479. package/dist/lib/ssh-tunnel.d.ts +10 -10
  480. package/dist/lib/ssh-tunnel.js +12 -12
  481. package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
  482. package/dist/lib/staleness/checkers/hooks.js +1 -1
  483. package/dist/lib/staleness/detectors/permissions.js +0 -23
  484. package/dist/lib/staleness/detectors/plugins.js +1 -1
  485. package/dist/lib/staleness/fingerprint.js +1 -1
  486. package/dist/lib/staleness/layers.d.ts +1 -1
  487. package/dist/lib/staleness/layers.js +1 -1
  488. package/dist/lib/staleness/writers/mcp.js +3 -1
  489. package/dist/lib/staleness/writers/plugins.js +1 -1
  490. package/dist/lib/staleness/writers/types.d.ts +8 -0
  491. package/dist/lib/startup/command-registry.d.ts +5 -147
  492. package/dist/lib/startup/command-registry.js +38 -303
  493. package/dist/lib/startup/dev-build.d.ts +0 -21
  494. package/dist/lib/startup/dev-build.js +29 -8
  495. package/dist/lib/state.d.ts +19 -1
  496. package/dist/lib/state.js +120 -51
  497. package/dist/lib/subagents.js +1 -1
  498. package/dist/lib/sync-status.js +1 -1
  499. package/dist/lib/sync-umbrella.d.ts +6 -1
  500. package/dist/lib/sync-umbrella.js +9 -4
  501. package/dist/lib/teams/agents.js +2 -2
  502. package/dist/lib/teams/registry.js +1 -1
  503. package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
  504. package/dist/lib/terminal/engine.js +1 -1
  505. package/dist/lib/terminal/index.d.ts +4 -0
  506. package/dist/lib/terminal/index.js +3 -0
  507. package/dist/lib/terminal/inject.d.ts +2 -2
  508. package/dist/lib/terminal/inject.js +2 -2
  509. package/dist/lib/terminal/transport.js +1 -1
  510. package/dist/lib/tmux/index.d.ts +1 -1
  511. package/dist/lib/tmux/index.js +1 -1
  512. package/dist/lib/tmux/session.d.ts +21 -5
  513. package/dist/lib/tmux/session.js +76 -22
  514. package/dist/lib/triggers/handlers.d.ts +1 -1
  515. package/dist/lib/triggers/handlers.js +2 -2
  516. package/dist/lib/triggers/webhook.d.ts +36 -2
  517. package/dist/lib/triggers/webhook.js +97 -42
  518. package/dist/lib/types.d.ts +18 -6
  519. package/dist/lib/usage-fleet.d.ts +1 -1
  520. package/dist/lib/usage-fleet.js +1 -1
  521. package/dist/lib/usage-refresh.d.ts +1 -1
  522. package/dist/lib/usage-refresh.js +3 -3
  523. package/dist/lib/version-duplicates.js +2 -2
  524. package/dist/lib/view-types.d.ts +56 -0
  525. package/dist/lib/view-types.js +1 -0
  526. package/dist/lib/watchdog/rotate.d.ts +2 -2
  527. package/dist/lib/watchdog/rotate.js +3 -3
  528. package/dist/lib/watchdog/runner.d.ts +2 -3
  529. package/dist/lib/watchdog/runner.js +3 -4
  530. package/dist/lib/workflows.js +1 -1
  531. package/package.json +2 -1
  532. package/scripts/postinstall.js +2 -2
  533. package/dist/commands/bench.d.ts +0 -2
  534. package/dist/commands/bench.js +0 -101
  535. package/dist/commands/cp.d.ts +0 -84
  536. package/dist/commands/cp.js +0 -231
  537. package/dist/commands/login.d.ts +0 -2
  538. package/dist/lib/resources/commands.d.ts +0 -46
  539. package/dist/lib/resources/commands.js +0 -211
  540. package/dist/lib/resources/hooks.d.ts +0 -16
  541. package/dist/lib/resources/hooks.js +0 -153
  542. package/dist/lib/resources/mcp.d.ts +0 -34
  543. package/dist/lib/resources/mcp.js +0 -250
  544. package/dist/lib/resources/memory.d.ts +0 -15
  545. package/dist/lib/resources/memory.js +0 -46
  546. package/dist/lib/resources/permissions.d.ts +0 -13
  547. package/dist/lib/resources/permissions.js +0 -202
  548. package/dist/lib/resources/rules.d.ts +0 -46
  549. package/dist/lib/resources/rules.js +0 -179
  550. package/dist/lib/resources/skills.d.ts +0 -37
  551. package/dist/lib/resources/skills.js +0 -247
  552. package/dist/lib/resources/subagents.d.ts +0 -46
  553. package/dist/lib/resources/subagents.js +0 -202
  554. /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
@@ -1,7 +1,10 @@
1
- /** Strict session resume convenience command. */
1
+ /**
2
+ * Strict session resume — identity resolution, source-device routing, and
3
+ * delegation to `agents run --resume`. Registered under `agents sessions resume`
4
+ * (see sessions-resume.ts); this module owns the helpers + in-process action.
5
+ */
2
6
  import { spawn } from 'child_process';
3
7
  import chalk from 'chalk';
4
- import { setHelpSections } from '../lib/help.js';
5
8
  import { resolveSessionMetadataValue } from './sessions.js';
6
9
  import { sessionOwnerDevice, consumeResumePinned, RESUME_PINNED_ENV } from '../lib/session/resume-owner.js';
7
10
  /**
@@ -13,7 +16,7 @@ import { sessionOwnerDevice, consumeResumePinned, RESUME_PINNED_ENV } from '../l
13
16
  * released surface.
14
17
  */
15
18
  export function buildResumeRemoteArgs(sessionId, prompt, options) {
16
- const args = ['resume', sessionId, ...(prompt === undefined ? [] : [prompt])];
19
+ const args = ['sessions', 'resume', sessionId, ...(prompt === undefined ? [] : [prompt])];
17
20
  if (options.mode)
18
21
  args.push('--mode', options.mode);
19
22
  if (options.interactive)
@@ -26,7 +29,7 @@ export function buildResumeRemoteArgs(sessionId, prompt, options) {
26
29
  args.push('--quiet');
27
30
  return args;
28
31
  }
29
- /** Translate `agents resume <id>` to the canonical `agents run` surface after
32
+ /** Translate `agents sessions resume <id>` to the canonical `agents run` surface after
30
33
  * resolving the source identity. The run command remains the only executor. */
31
34
  export function buildResumeRunArgs(session, prompt, options) {
32
35
  const spec = session.version ? `${session.agent}@${session.version}` : session.agent;
@@ -43,103 +46,84 @@ export function buildResumeRunArgs(session, prompt, options) {
43
46
  args.push('--quiet');
44
47
  return args;
45
48
  }
46
- export function registerResumeCommand(program) {
47
- const cmd = program
48
- .command('resume <session> [prompt]')
49
- .description('Resume a session by id, tmux alias, or exact label with its original harness, version, device, account, cwd, and mode. Searches the fleet automatically; a local full-id hit resumes with zero SSH.')
50
- .option('-m, --mode <mode>', 'Override the recorded launch mode')
51
- .option('-i, --interactive', 'Resume interactively even when a prompt is provided')
52
- .option('--headless', 'Resume headlessly (a prompt is required)')
53
- .option('--cwd <path>', 'Override the recorded working directory')
54
- .option('-q, --quiet', 'Suppress routing banners')
55
- .option('--here', 'Run on this machine even if the session belongs to another device')
56
- .action(async (sessionId, prompt, options) => {
57
- // Read (and clear) the routing pin before anything else, so it can never
58
- // reach the agent's own children.
59
- const pinnedHere = consumeResumePinned() || !!options.here;
60
- const outcome = await resolveSessionMetadataValue(sessionId.trim());
61
- if (outcome.kind === 'partial') {
62
- // RUSH-2492: an unreachable peer is a warning, not a hard failure. The
63
- // resolver already resolves an id found on the reachable fleet (SES-9a),
64
- // so reaching here means the session was not found on any device we COULD
65
- // reach it may live on an unreachable peer, which we could not check.
66
- const offline = outcome.failedPeers;
67
- console.error(chalk.yellow(`Warning: ${offline.length} device(s) unreachable, not checked: ${offline.join(', ')}`));
68
- console.error(chalk.red(`No session matching "${sessionId}" on any reachable device (${offline.length} unreachable, not checked).`));
69
- console.error(chalk.gray(' If it lives on an offline box, wake it (agents devices) or run there: agents ssh <device>'));
70
- process.exitCode = 1;
71
- return;
72
- }
73
- if (outcome.kind === 'not-found') {
74
- console.error(chalk.red(`No session matching "${sessionId}".`));
75
- process.exitCode = 1;
76
- return;
49
+ /** True when the caller asked for the strict resume path (prompt and/or flags). */
50
+ export function wantsStrictResume(prompt, options) {
51
+ return (prompt !== undefined ||
52
+ !!options.mode ||
53
+ !!options.interactive ||
54
+ !!options.headless ||
55
+ !!options.cwd ||
56
+ !!options.quiet ||
57
+ !!options.here);
58
+ }
59
+ /**
60
+ * Strict single-session resume: resolve id/label across the fleet, hop to the
61
+ * owning device when needed, then delegate to `agents run --resume`.
62
+ */
63
+ export async function runStrictResume(sessionId, prompt, options) {
64
+ // Read (and clear) the routing pin before anything else, so it can never
65
+ // reach the agent's own children.
66
+ const pinnedHere = consumeResumePinned() || !!options.here;
67
+ const outcome = await resolveSessionMetadataValue(sessionId.trim());
68
+ if (outcome.kind === 'partial') {
69
+ // RUSH-2492: an unreachable peer is a warning, not a hard failure. The
70
+ // resolver already resolves an id found on the reachable fleet (SES-9a),
71
+ // so reaching here means the session was not found on any device we COULD
72
+ // reach — it may live on an unreachable peer, which we could not check.
73
+ const offline = outcome.failedPeers;
74
+ console.error(chalk.yellow(`Warning: ${offline.length} device(s) unreachable, not checked: ${offline.join(', ')}`));
75
+ console.error(chalk.red(`No session matching "${sessionId}" on any reachable device (${offline.length} unreachable, not checked).`));
76
+ console.error(chalk.gray(' If it lives on an offline box, wake it (agents devices) or run there: agents ssh <device>'));
77
+ process.exitCode = 1;
78
+ return;
79
+ }
80
+ if (outcome.kind === 'not-found') {
81
+ console.error(chalk.red(`No session matching "${sessionId}".`));
82
+ process.exitCode = 1;
83
+ return;
84
+ }
85
+ if (outcome.kind === 'ambiguous') {
86
+ console.error(chalk.red(`"${sessionId}" matches ${outcome.candidates.length} sessions. Pass the full session id.`));
87
+ process.exitCode = 1;
88
+ return;
89
+ }
90
+ // The harness keeps its conversation state on the machine that produced
91
+ // the session, so a peer-owned session MUST resume there. Running it here
92
+ // starts the agent against state this box does not have — silently, since
93
+ // a synced mirror makes the transcript look local (RUSH-2022).
94
+ const owner = pinnedHere ? undefined : sessionOwnerDevice(outcome.session);
95
+ if (owner) {
96
+ if (!options.quiet) {
97
+ process.stderr.write(chalk.gray(`[agents] session ${outcome.session.shortId} belongs to ${owner} → resuming there\n`));
77
98
  }
78
- if (outcome.kind === 'ambiguous') {
79
- console.error(chalk.red(`"${sessionId}" matches ${outcome.candidates.length} sessions. Pass the full session id.`));
99
+ // `runOnPeer` is the existing transport for "this session's transcript
100
+ // and agent binary are on that box" (lib/session/remote-list.ts) — the
101
+ // same one the picker already uses. Not the `--host` passthrough: that
102
+ // one re-discovers locally and marks the run AGENTS_FLEET_REMOTE, which
103
+ // a long-lived resumed session must not inherit.
104
+ const { runOnPeer } = await import('../lib/session/remote-list.js');
105
+ const rc = await runOnPeer(buildResumeRemoteArgs(outcome.session.id, prompt, options), owner, { tty: !!process.stdout.isTTY, env: { [RESUME_PINNED_ENV]: '1' } });
106
+ if (rc === 'no-target') {
107
+ console.error(chalk.red(`Session ${outcome.session.shortId} lives on ${owner}, which isn't a reachable device right now.`));
108
+ console.error(chalk.gray(`Register/wake it (agents devices), or run there: agents ssh ${owner}`));
80
109
  process.exitCode = 1;
81
- return;
82
- }
83
- // The harness keeps its conversation state on the machine that produced
84
- // the session, so a peer-owned session MUST resume there. Running it here
85
- // starts the agent against state this box does not have — silently, since
86
- // a synced mirror makes the transcript look local (RUSH-2022).
87
- const owner = pinnedHere ? undefined : sessionOwnerDevice(outcome.session);
88
- if (owner) {
89
- if (!options.quiet) {
90
- process.stderr.write(chalk.gray(`[agents] session ${outcome.session.shortId} belongs to ${owner} → resuming there\n`));
91
- }
92
- // `runOnPeer` is the existing transport for "this session's transcript
93
- // and agent binary are on that box" (lib/session/remote-list.ts) — the
94
- // same one the picker already uses. Not the `--host` passthrough: that
95
- // one re-discovers locally and marks the run AGENTS_FLEET_REMOTE, which
96
- // a long-lived resumed session must not inherit.
97
- const { runOnPeer } = await import('../lib/session/remote-list.js');
98
- const rc = await runOnPeer(buildResumeRemoteArgs(outcome.session.id, prompt, options), owner, { tty: !!process.stdout.isTTY, env: { [RESUME_PINNED_ENV]: '1' } });
99
- if (rc === 'no-target') {
100
- console.error(chalk.red(`Session ${outcome.session.shortId} lives on ${owner}, which isn't a reachable device right now.`));
101
- console.error(chalk.gray(`Register/wake it (agents devices), or run there: agents ssh ${owner}`));
102
- process.exitCode = 1;
103
- }
104
- return;
105
110
  }
106
- const args = buildResumeRunArgs(outcome.session, prompt, options);
107
- const child = spawn(process.execPath, [process.argv[1], ...args], {
108
- stdio: 'inherit',
109
- env: {
110
- ...process.env,
111
- // Avoid repeating the fleet lookup in the delegated local `run`
112
- // process. The value is metadata-only and is not forwarded over SSH;
113
- // the owner performs its own local SQLite lookup.
114
- AGENTS_RESUME_SOURCE_JSON: JSON.stringify(outcome.session),
115
- },
116
- });
117
- const exitCode = await new Promise((resolve) => {
118
- child.once('error', () => resolve(127));
119
- child.once('exit', (code, signal) => resolve(code ?? (signal ? 1 : 0)));
120
- });
121
- process.exitCode = exitCode;
111
+ return;
112
+ }
113
+ const args = buildResumeRunArgs(outcome.session, prompt, options);
114
+ const child = spawn(process.execPath, [process.argv[1], ...args], {
115
+ stdio: 'inherit',
116
+ env: {
117
+ ...process.env,
118
+ // Avoid repeating the fleet lookup in the delegated local `run`
119
+ // process. The value is metadata-only and is not forwarded over SSH;
120
+ // the owner performs its own local SQLite lookup.
121
+ AGENTS_RESUME_SOURCE_JSON: JSON.stringify(outcome.session),
122
+ },
122
123
  });
123
- setHelpSections(cmd, {
124
- examples: `
125
- # Resume by full id
126
- agents resume 019fd0c8-b3e9-77a2-a1a4-444698c4d897
127
-
128
- # Resume and continue headlessly
129
- agents resume 019fd0c8-b3e9-77a2-a1a4-444698c4d897 "finish the tests"
130
-
131
- # Resume by exact label (auto-resumes the one match)
132
- agents resume "fix the flaky ssh test"
133
-
134
- # Resume by durable tmux alias or its unique suffix
135
- agents resume ag-codex-c1f3d813
136
- agents resume c1f3d813
137
-
138
- # Deliberately change permissions
139
- agents resume 019fd0c8-b3e9-77a2-a1a4-444698c4d897 --mode edit`,
140
- notes: `
141
- A full ID resolves from the local session database first (zero SSH) and, on a local miss, fans out with the first peer holding it cancelling the rest. An exact label always consults the fleet (labels are not globally unique) and auto-resumes the one match; a cross-machine label collision surfaces as an ambiguity.
142
- A session that ran on another device resumes ON that device over SSH — the harness's conversation state lives there, so running it here would start against state this machine does not have. --here overrides that and runs locally.
143
- Use agents run auto --resume <id> when the original account is unavailable and another harness may continue.`,
124
+ const exitCode = await new Promise((resolve) => {
125
+ child.once('error', () => resolve(127));
126
+ child.once('exit', (code, signal) => resolve(code ?? (signal ? 1 : 0)));
144
127
  });
128
+ process.exitCode = exitCode;
145
129
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Named router management commands.
3
+ *
4
+ * Registers the `agents route` command tree for creating, viewing, and
5
+ * removing named routers -- reusable, task-typed allowlists of harnesses x
6
+ * models/tiers x linked accounts that a future routing decision resolves
7
+ * strictly within (see `.agents/artifacts/2026-08-10/agent-router-spec.md`,
8
+ * requirements E1/E2). This ticket ships persistence + management only;
9
+ * invoking a router to route a task is a separate ticket.
10
+ */
11
+ import type { Command } from 'commander';
12
+ export declare function registerRouteCommands(program: Command): void;
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Named router management commands.
3
+ *
4
+ * Registers the `agents route` command tree for creating, viewing, and
5
+ * removing named routers -- reusable, task-typed allowlists of harnesses x
6
+ * models/tiers x linked accounts that a future routing decision resolves
7
+ * strictly within (see `.agents/artifacts/2026-08-10/agent-router-spec.md`,
8
+ * requirements E1/E2). This ticket ships persistence + management only;
9
+ * invoking a router to route a task is a separate ticket.
10
+ */
11
+ import chalk from 'chalk';
12
+ import { listRouters, readRouter, writeRouter, deleteRouter, routerExists, routerSource, routersDir, validateRouter, } from '../lib/routers.js';
13
+ import { MODEL_TIERS, isTierToken } from '../lib/model-tiers.js';
14
+ import { die } from '../lib/format.js';
15
+ import { setHelpSections } from '../lib/help.js';
16
+ import { findAccount } from '../lib/account-registry.js';
17
+ import * as path from 'path';
18
+ /**
19
+ * Read a router that must be safely editable/removable from here: `writeRouter`
20
+ * and `deleteRouter` only ever touch the user layer, so editing a router that
21
+ * currently resolves from a project/system layer would silently write to a
22
+ * user-layer file that stays permanently shadowed (the edit "succeeds" but is
23
+ * never read back — the router keeps resolving to its project/system copy).
24
+ * Fails loud instead, naming the layer and pointing at the fix.
25
+ */
26
+ function requireEditableRouter(name) {
27
+ const source = routerSource(name);
28
+ if (source === null)
29
+ die(`Router '${name}' not found.`);
30
+ if (source !== 'user') {
31
+ die(`Router '${name}' resolves from the '${source}' layer, not 'user' -- ` +
32
+ `agents route can only edit or remove a user-layer router. Edit its file directly, ` +
33
+ `or create a user-layer router under a different name.`);
34
+ }
35
+ return readRouter(name);
36
+ }
37
+ /** Highest-tier-reached summary for a router's declared model/tier allowlist. */
38
+ function routerTierSummary(router) {
39
+ const seen = new Set();
40
+ for (const allowlist of Object.values(router.harnesses)) {
41
+ for (const token of allowlist.models) {
42
+ if (isTierToken(token))
43
+ seen.add(token);
44
+ }
45
+ }
46
+ if (seen.size === 0)
47
+ return '-';
48
+ const ordered = MODEL_TIERS.filter((t) => seen.has(t));
49
+ return ordered.length === 1 ? `tier=${ordered[0]}` : `tier<=${ordered[ordered.length - 1]}`;
50
+ }
51
+ function accountCount(router) {
52
+ const accounts = new Set();
53
+ for (const allowlist of Object.values(router.harnesses)) {
54
+ for (const account of allowlist.accounts ?? [])
55
+ accounts.add(`${account}`);
56
+ }
57
+ return accounts.size;
58
+ }
59
+ function renderRouterRow(router) {
60
+ const harnessCount = Object.keys(router.harnesses).length;
61
+ return ` ${chalk.cyan(router.name.padEnd(16))} ${harnessCount} harnesses . ${accountCount(router)} accounts . ${routerTierSummary(router)}`;
62
+ }
63
+ function printRouterDetail(router) {
64
+ const header = router.task ? `router: ${router.name} task type: ${router.task}` : `router: ${router.name}`;
65
+ console.log(chalk.bold(header));
66
+ const harnessNames = Object.keys(router.harnesses);
67
+ if (harnessNames.length === 0) {
68
+ console.log(chalk.gray(' (no harnesses allowed yet -- add one with `agents route allow <name> <harness> <model|tier>...`)'));
69
+ }
70
+ for (const name of harnessNames) {
71
+ const allowlist = router.harnesses[name];
72
+ console.log(` ${chalk.cyan(name.padEnd(10))} models: [${allowlist.models.join(', ')}] accounts: [${(allowlist.accounts ?? []).join(', ')}]`);
73
+ }
74
+ if (router.weights) {
75
+ const w = router.weights;
76
+ const parts = [];
77
+ if (w.cost != null)
78
+ parts.push(`cost ${w.cost}`);
79
+ if (w.success != null)
80
+ parts.push(`success ${w.success}`);
81
+ if (w.headroom != null)
82
+ parts.push(`headroom ${w.headroom}`);
83
+ console.log(` ${chalk.gray('weights:')} ${parts.join(' . ')} hijack: ${router.hijack ? 'on' : 'off'}`);
84
+ }
85
+ else {
86
+ console.log(` ${chalk.gray('hijack:')} ${router.hijack ? 'on' : 'off'}`);
87
+ }
88
+ }
89
+ export function registerRouteCommands(program) {
90
+ const routeCmd = program
91
+ .command('route')
92
+ .description('Named routers -- reusable, task-typed allowlists of harnesses x models/tiers x linked accounts.');
93
+ setHelpSections(routeCmd, {
94
+ examples: `
95
+ # Create a router scoped to two harnesses, capped at a tier
96
+ agents route create research --harness gemini,kimi --tier cheap,default
97
+
98
+ # Narrow one harness's model set
99
+ agents route allow research kimi kimi-k2
100
+
101
+ # Link accounts so routing under this router only ever picks them
102
+ agents route link-account research gemini personal
103
+ agents route link-account research kimi work
104
+
105
+ # Inspect it
106
+ agents route show research
107
+ agents route list --json
108
+ `,
109
+ notes: `
110
+ A router is a generalization of a profile -- a profile is a router
111
+ pinned to one harness and one account. It never resolves a target
112
+ outside its declared harness/model/tier allowlist or linked accounts.
113
+
114
+ Routers are a layered resource (project > user > system, like commands,
115
+ skills, and profiles) but 'agents route create'/'allow'/'link-account'
116
+ always write to the user layer (~/.agents/routers/<name>.yml).
117
+ `,
118
+ });
119
+ routeCmd
120
+ .command('create <name>')
121
+ .description('Create a named router with an initial harness + tier allowlist.')
122
+ .option('--harness <list>', 'Comma-separated harness ids to allow, e.g. gemini,kimi')
123
+ .option('--tier <list>', 'Comma-separated tier tokens applied to every listed harness, e.g. cheap,default')
124
+ .option('--task <type>', 'Free-text task type this router serves, e.g. research')
125
+ .action((name, opts) => {
126
+ if (routerExists(name)) {
127
+ die(`Router '${name}' already exists. Use 'agents route allow ${name} <harness> <model|tier>...' to edit it.`);
128
+ }
129
+ if (!opts.harness) {
130
+ die("Missing --harness. Example: agents route create research --harness gemini,kimi --tier cheap,default");
131
+ }
132
+ const harnesses = opts.harness.split(',').map((h) => h.trim()).filter(Boolean);
133
+ const tiers = (opts.tier ?? '').split(',').map((t) => t.trim()).filter(Boolean);
134
+ const router = {
135
+ name,
136
+ task: opts.task,
137
+ harnesses: Object.fromEntries(harnesses.map((h) => [h, { models: [...tiers] }])),
138
+ };
139
+ try {
140
+ validateRouter(router);
141
+ }
142
+ catch (err) {
143
+ die(err.message);
144
+ }
145
+ writeRouter(router);
146
+ console.log(chalk.green(`+ created router "${name}"`) + chalk.gray(` (${path.join(routersDir(), `${name}.yml`)})`));
147
+ });
148
+ routeCmd
149
+ .command('list')
150
+ .description('List every configured router.')
151
+ .option('--json', 'Emit machine-readable JSON')
152
+ .action((opts) => {
153
+ const routers = listRouters();
154
+ if (opts.json) {
155
+ console.log(JSON.stringify(routers.map((r) => ({
156
+ name: r.name,
157
+ task: r.task ?? null,
158
+ harnessCount: Object.keys(r.harnesses).length,
159
+ accountCount: accountCount(r),
160
+ tierSummary: routerTierSummary(r),
161
+ })), null, 2));
162
+ return;
163
+ }
164
+ if (routers.length === 0) {
165
+ console.log(chalk.gray('No routers configured.'));
166
+ console.log(chalk.gray('Try: agents route create research --harness gemini,kimi --tier cheap,default'));
167
+ return;
168
+ }
169
+ for (const router of routers)
170
+ console.log(renderRouterRow(router));
171
+ });
172
+ routeCmd
173
+ .command('show <name>')
174
+ .alias('view')
175
+ .description("Show a router's harness/model/account allowlist, weights, and hijack flag.")
176
+ .option('--json', 'Emit machine-readable JSON')
177
+ .action((name, opts) => {
178
+ let router;
179
+ try {
180
+ router = readRouter(name);
181
+ }
182
+ catch (err) {
183
+ die(err.message);
184
+ }
185
+ if (opts.json) {
186
+ console.log(JSON.stringify(router, null, 2));
187
+ return;
188
+ }
189
+ printRouterDetail(router);
190
+ });
191
+ routeCmd
192
+ .command('allow <name> <harness> <models...>')
193
+ .description("Set (replace) a harness's eligible model/tier allowlist under a router.")
194
+ .action((name, harness, models) => {
195
+ const router = requireEditableRouter(name);
196
+ const existingAccounts = router.harnesses[harness]?.accounts;
197
+ const next = {
198
+ ...router,
199
+ harnesses: {
200
+ ...router.harnesses,
201
+ [harness]: { models, ...(existingAccounts ? { accounts: existingAccounts } : {}) },
202
+ },
203
+ };
204
+ try {
205
+ validateRouter(next);
206
+ }
207
+ catch (err) {
208
+ die(err.message);
209
+ }
210
+ writeRouter(next);
211
+ console.log(chalk.green(`Router '${name}': ${harness} models -> [${models.join(', ')}]`));
212
+ });
213
+ routeCmd
214
+ .command('link-account <name> <harness> <account>')
215
+ .description('Link a durable credential account to a harness under a router.')
216
+ .action((name, harness, account) => {
217
+ if (!findAccount(account))
218
+ die(`Unknown account '${account}'.`);
219
+ const router = requireEditableRouter(name);
220
+ const allowlist = router.harnesses[harness];
221
+ if (!allowlist) {
222
+ die(`Harness '${harness}' is not part of router '${name}'. Add it first: agents route allow ${name} ${harness} <model|tier>...`);
223
+ }
224
+ allowlist.accounts = allowlist.accounts ?? [];
225
+ if (!allowlist.accounts.includes(account))
226
+ allowlist.accounts.push(account);
227
+ writeRouter(router);
228
+ console.log(chalk.green(`Router '${name}': linked ${harness} account '${account}'`));
229
+ });
230
+ routeCmd
231
+ .command('unlink-account <name> <harness> <account>')
232
+ .description('Unlink a durable credential account from a harness under a router.')
233
+ .action((name, harness, account) => {
234
+ if (!findAccount(account))
235
+ die(`Unknown account '${account}'.`);
236
+ const router = requireEditableRouter(name);
237
+ const allowlist = router.harnesses[harness];
238
+ if (!allowlist) {
239
+ die(`Harness '${harness}' is not part of router '${name}'.`);
240
+ }
241
+ allowlist.accounts = (allowlist.accounts ?? []).filter((a) => a !== account);
242
+ writeRouter(router);
243
+ console.log(chalk.green(`Router '${name}': unlinked ${harness} account '${account}'`));
244
+ });
245
+ routeCmd
246
+ .command('rm <name>')
247
+ .alias('remove')
248
+ .description('Delete a router.')
249
+ .action((name) => {
250
+ const source = routerSource(name);
251
+ if (source === null)
252
+ die(`Router '${name}' not found.`);
253
+ if (source !== 'user') {
254
+ die(`Router '${name}' resolves from the '${source}' layer, not 'user' -- agents route rm can only remove a user-layer router.`);
255
+ }
256
+ const existed = deleteRouter(name);
257
+ if (!existed)
258
+ die(`Router '${name}' not found.`);
259
+ console.log(chalk.green(`Router '${name}' removed.`));
260
+ });
261
+ }
@@ -6,7 +6,8 @@
6
6
  * Also exposes scheduler lifecycle controls (start/stop/status/logs).
7
7
  */
8
8
  import type { Command } from 'commander';
9
- import type { JobConfig, RunMeta } from '../lib/routines.js';
9
+ export { buildRoutineListJson } from '../lib/scheduling/routines.js';
10
+ import type { JobConfig, RunMeta } from '../lib/scheduling/routines.js';
10
11
  import type { DeviceRegistry } from '../lib/devices/registry.js';
11
12
  /**
12
13
  * Human-friendly wall-clock a run took (e.g. " · 3 min", " · 45 sec"), or ""
@@ -26,7 +27,6 @@ export declare function formatRunDuration(startedAt: string, completedAt: string
26
27
  * history stays readable via `agents routines runs <name>`, and the owning
27
28
  * device's status via `agents routines list --device <name>`.
28
29
  */
29
- export declare function localLatestRun(job: JobConfig): RunMeta | null;
30
30
  export interface RoutineListGroup {
31
31
  key: string;
32
32
  title: string;
@@ -46,6 +46,5 @@ export declare function groupRoutineJobsByDevice(jobs: JobConfig[], registry: De
46
46
  */
47
47
  export declare function groupRoutineJobsByProject(jobs: JobConfig[], knownProjectNames: Set<string>): RoutineListGroup[];
48
48
  export declare function buildRunsJson(runs: RunMeta[]): Record<string, unknown>[];
49
- export declare function buildRoutineListJson(): Record<string, unknown>[];
50
49
  /** Register the `agents routines` command tree. */
51
50
  export declare function registerRoutinesCommands(program: Command): void;