@phnx-labs/agents-cli 1.22.34 → 1.22.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (493) hide show
  1. package/CHANGELOG.md +672 -2
  2. package/README.md +82 -35
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1211 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/attach.js +17 -4
  9. package/dist/commands/audit.d.ts +8 -8
  10. package/dist/commands/audit.js +57 -47
  11. package/dist/commands/browser.js +15 -11
  12. package/dist/commands/cloud.js +1 -1
  13. package/dist/commands/commands.js +0 -11
  14. package/dist/commands/computer-actions.js +33 -0
  15. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  16. package/dist/commands/computer-sessions-picker.js +141 -0
  17. package/dist/commands/computer.d.ts +16 -0
  18. package/dist/commands/computer.js +37 -0
  19. package/dist/commands/config.d.ts +17 -0
  20. package/dist/commands/config.js +401 -0
  21. package/dist/commands/cp.d.ts +84 -0
  22. package/dist/commands/cp.js +231 -0
  23. package/dist/commands/daemon.js +243 -14
  24. package/dist/commands/detach-core.d.ts +1 -1
  25. package/dist/commands/detach-core.js +12 -2
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +64 -5
  28. package/dist/commands/events.d.ts +24 -12
  29. package/dist/commands/events.js +144 -28
  30. package/dist/commands/exec.js +85 -41
  31. package/dist/commands/feed.d.ts +1 -1
  32. package/dist/commands/feed.js +16 -8
  33. package/dist/commands/focus.d.ts +33 -1
  34. package/dist/commands/focus.js +177 -17
  35. package/dist/commands/funnel.d.ts +1 -1
  36. package/dist/commands/go.js +9 -8
  37. package/dist/commands/harness-wizard.d.ts +1 -0
  38. package/dist/commands/harness-wizard.js +18 -20
  39. package/dist/commands/harness.d.ts +2 -0
  40. package/dist/commands/harness.js +59 -26
  41. package/dist/commands/hooks.js +0 -11
  42. package/dist/commands/inspect.d.ts +94 -1
  43. package/dist/commands/inspect.js +866 -40
  44. package/dist/commands/lease.d.ts +4 -4
  45. package/dist/commands/lease.js +6 -6
  46. package/dist/commands/login.js +0 -13
  47. package/dist/commands/logs.d.ts +2 -2
  48. package/dist/commands/logs.js +2 -2
  49. package/dist/commands/mcp.js +7 -2
  50. package/dist/commands/memory.js +7 -2
  51. package/dist/commands/message.d.ts +1 -1
  52. package/dist/commands/message.js +37 -6
  53. package/dist/commands/models.js +4 -0
  54. package/dist/commands/monitors.d.ts +0 -1
  55. package/dist/commands/monitors.js +199 -16
  56. package/dist/commands/open.d.ts +18 -0
  57. package/dist/commands/open.js +57 -0
  58. package/dist/commands/packages.js +2 -107
  59. package/dist/commands/plugins.js +6 -3
  60. package/dist/commands/profiles.d.ts +1 -0
  61. package/dist/commands/profiles.js +16 -160
  62. package/dist/commands/projects.d.ts +28 -0
  63. package/dist/commands/projects.js +125 -5
  64. package/dist/commands/reconnect.js +9 -3
  65. package/dist/commands/repo.js +42 -1
  66. package/dist/commands/resource-view.d.ts +17 -0
  67. package/dist/commands/resource-view.js +36 -14
  68. package/dist/commands/resume.js +9 -2
  69. package/dist/commands/routines.d.ts +0 -2
  70. package/dist/commands/routines.js +473 -289
  71. package/dist/commands/secrets.js +52 -9
  72. package/dist/commands/sessions-export.d.ts +47 -0
  73. package/dist/commands/sessions-export.js +116 -6
  74. package/dist/commands/sessions-import.d.ts +17 -0
  75. package/dist/commands/sessions-import.js +114 -6
  76. package/dist/commands/sessions-migrate.d.ts +27 -0
  77. package/dist/commands/sessions-migrate.js +50 -9
  78. package/dist/commands/sessions-picker.js +23 -4
  79. package/dist/commands/sessions-resume.d.ts +5 -3
  80. package/dist/commands/sessions-resume.js +30 -8
  81. package/dist/commands/sessions-watch.d.ts +2 -0
  82. package/dist/commands/sessions-watch.js +53 -0
  83. package/dist/commands/sessions.d.ts +66 -3
  84. package/dist/commands/sessions.js +298 -47
  85. package/dist/commands/set.d.ts +1 -1
  86. package/dist/commands/set.js +2 -2
  87. package/dist/commands/setup-browser.js +2 -2
  88. package/dist/commands/setup-mine.js +0 -1
  89. package/dist/commands/setup-preferences.js +1 -1
  90. package/dist/commands/setup-share.js +34 -4
  91. package/dist/commands/setup.d.ts +5 -0
  92. package/dist/commands/setup.js +26 -0
  93. package/dist/commands/share.d.ts +85 -0
  94. package/dist/commands/share.js +379 -8
  95. package/dist/commands/skills.js +0 -11
  96. package/dist/commands/snapshot.js +1 -1
  97. package/dist/commands/ssh.d.ts +18 -0
  98. package/dist/commands/ssh.js +549 -210
  99. package/dist/commands/sync.d.ts +5 -0
  100. package/dist/commands/sync.js +212 -32
  101. package/dist/commands/teams.d.ts +13 -0
  102. package/dist/commands/teams.js +187 -30
  103. package/dist/commands/tickets.d.ts +2 -0
  104. package/dist/commands/tickets.js +43 -0
  105. package/dist/commands/update.js +2 -4
  106. package/dist/commands/usage.js +5 -3
  107. package/dist/commands/versions.js +11 -5
  108. package/dist/commands/view.js +15 -7
  109. package/dist/commands/webhook.d.ts +2 -2
  110. package/dist/commands/webhook.js +7 -7
  111. package/dist/index.d.ts +18 -2
  112. package/dist/index.js +53 -1264
  113. package/dist/lib/account-catalog.d.ts +18 -0
  114. package/dist/lib/account-catalog.js +38 -0
  115. package/dist/lib/account-provider-registry.d.ts +18 -0
  116. package/dist/lib/account-provider-registry.js +59 -0
  117. package/dist/lib/account-registry.d.ts +40 -0
  118. package/dist/lib/account-registry.js +239 -0
  119. package/dist/lib/account-schema.d.ts +44 -0
  120. package/dist/lib/account-schema.js +91 -0
  121. package/dist/lib/account-state-service.d.ts +21 -0
  122. package/dist/lib/account-state-service.js +60 -0
  123. package/dist/lib/activity.d.ts +1 -1
  124. package/dist/lib/activity.js +8 -1
  125. package/dist/lib/add-dir.d.ts +80 -0
  126. package/dist/lib/add-dir.js +241 -0
  127. package/dist/lib/agent-cli-commands.d.ts +11 -0
  128. package/dist/lib/agent-cli-commands.js +30 -0
  129. package/dist/lib/agents.js +44 -36
  130. package/dist/lib/answer-router.js +1 -1
  131. package/dist/lib/audit/log.d.ts +10 -27
  132. package/dist/lib/audit/log.js +20 -33
  133. package/dist/lib/auth-health.d.ts +9 -2
  134. package/dist/lib/auth-health.js +42 -9
  135. package/dist/lib/auto-pull-worker.js +7 -3
  136. package/dist/lib/auto-pull.d.ts +44 -3
  137. package/dist/lib/auto-pull.js +88 -5
  138. package/dist/lib/binary-shadow.d.ts +28 -0
  139. package/dist/lib/binary-shadow.js +121 -0
  140. package/dist/lib/brand.js +9 -3
  141. package/dist/lib/browser/ipc.d.ts +30 -0
  142. package/dist/lib/browser/ipc.js +81 -4
  143. package/dist/lib/browser/profiles.d.ts +3 -2
  144. package/dist/lib/browser/profiles.js +65 -22
  145. package/dist/lib/browser/service.d.ts +4 -0
  146. package/dist/lib/browser/service.js +30 -3
  147. package/dist/lib/browser/sessions-list.d.ts +22 -2
  148. package/dist/lib/browser/sessions-list.js +54 -6
  149. package/dist/lib/browser/stream.d.ts +2 -0
  150. package/dist/lib/browser/stream.js +1 -0
  151. package/dist/lib/browser/types.d.ts +19 -0
  152. package/dist/lib/byok-usage.d.ts +9 -2
  153. package/dist/lib/byok-usage.js +133 -31
  154. package/dist/lib/cli-entry.d.ts +11 -0
  155. package/dist/lib/cli-entry.js +46 -0
  156. package/dist/lib/cloud/host.d.ts +1 -1
  157. package/dist/lib/cloud/host.js +2 -2
  158. package/dist/lib/cloud/registry.js +1 -1
  159. package/dist/lib/cloud/types.d.ts +1 -1
  160. package/dist/lib/codex-policy.d.ts +9 -1
  161. package/dist/lib/codex-policy.js +17 -2
  162. package/dist/lib/commands.d.ts +2 -0
  163. package/dist/lib/commands.js +2 -0
  164. package/dist/lib/computer/sessions-list.d.ts +150 -0
  165. package/dist/lib/computer/sessions-list.js +363 -0
  166. package/dist/lib/config-keys.d.ts +86 -0
  167. package/dist/lib/config-keys.js +193 -0
  168. package/dist/lib/config-machine-keys.d.ts +12 -0
  169. package/dist/lib/config-machine-keys.js +17 -0
  170. package/dist/lib/config-transfer.js +3 -4
  171. package/dist/lib/crabbox/cli.d.ts +2 -2
  172. package/dist/lib/crabbox/cli.js +3 -3
  173. package/dist/lib/daemon-health.d.ts +22 -0
  174. package/dist/lib/daemon-health.js +33 -3
  175. package/dist/lib/daemon-services.d.ts +50 -0
  176. package/dist/lib/daemon-services.js +147 -0
  177. package/dist/lib/daemon-ticks.d.ts +35 -66
  178. package/dist/lib/daemon-ticks.js +77 -159
  179. package/dist/lib/daemon.d.ts +72 -4
  180. package/dist/lib/daemon.js +792 -202
  181. package/dist/lib/deeplink/register.d.ts +49 -0
  182. package/dist/lib/deeplink/register.js +253 -0
  183. package/dist/lib/deeplink/url.d.ts +34 -0
  184. package/dist/lib/deeplink/url.js +78 -0
  185. package/dist/lib/device-config.d.ts +124 -29
  186. package/dist/lib/device-config.js +346 -141
  187. package/dist/lib/devices/config-migration.d.ts +42 -0
  188. package/dist/lib/devices/config-migration.js +203 -0
  189. package/dist/lib/devices/connect.js +14 -7
  190. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  191. package/dist/lib/devices/doctor-findings.js +20 -1
  192. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  193. package/dist/lib/devices/harness-inventory.js +0 -0
  194. package/dist/lib/devices/health.d.ts +1 -1
  195. package/dist/lib/devices/health.js +1 -1
  196. package/dist/lib/devices/pending.d.ts +22 -1
  197. package/dist/lib/devices/pending.js +67 -2
  198. package/dist/lib/devices/registry.d.ts +0 -25
  199. package/dist/lib/devices/registry.js +2 -83
  200. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  201. package/dist/lib/devices/resolve-profile.js +44 -0
  202. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  203. package/dist/lib/devices/rollout-verify.js +193 -0
  204. package/dist/lib/devices/ssh-config.js +10 -6
  205. package/dist/lib/event-families.d.ts +28 -0
  206. package/dist/lib/event-families.js +159 -0
  207. package/dist/lib/event-stream.d.ts +9 -1
  208. package/dist/lib/event-stream.js +26 -9
  209. package/dist/lib/events.d.ts +9 -1
  210. package/dist/lib/events.js +21 -6
  211. package/dist/lib/exec.d.ts +30 -0
  212. package/dist/lib/exec.js +220 -122
  213. package/dist/lib/feed-broadcast.d.ts +25 -0
  214. package/dist/lib/feed-broadcast.js +33 -0
  215. package/dist/lib/feed.d.ts +1 -1
  216. package/dist/lib/feed.js +12 -2
  217. package/dist/lib/fleet/capture.js +15 -0
  218. package/dist/lib/fleet/manifest.js +9 -0
  219. package/dist/lib/fleet/types.d.ts +9 -0
  220. package/dist/lib/fleet-status.js +10 -8
  221. package/dist/lib/git.d.ts +20 -6
  222. package/dist/lib/git.js +121 -17
  223. package/dist/lib/hosts/dispatch.d.ts +8 -3
  224. package/dist/lib/hosts/dispatch.js +29 -3
  225. package/dist/lib/hosts/logs.d.ts +2 -2
  226. package/dist/lib/hosts/logs.js +2 -2
  227. package/dist/lib/hosts/option.js +1 -1
  228. package/dist/lib/hosts/passthrough.d.ts +2 -3
  229. package/dist/lib/hosts/passthrough.js +10 -24
  230. package/dist/lib/hosts/progress.js +2 -2
  231. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  232. package/dist/lib/hosts/providers/devices.js +18 -12
  233. package/dist/lib/hosts/ready.d.ts +5 -1
  234. package/dist/lib/hosts/ready.js +9 -3
  235. package/dist/lib/hosts/reconcile.d.ts +2 -2
  236. package/dist/lib/hosts/reconcile.js +2 -2
  237. package/dist/lib/hosts/registry.js +14 -9
  238. package/dist/lib/hosts/remote-cmd.js +1 -1
  239. package/dist/lib/hosts/remote-os.d.ts +9 -6
  240. package/dist/lib/hosts/remote-os.js +13 -6
  241. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  242. package/dist/lib/hosts/routing-flag.js +41 -0
  243. package/dist/lib/hosts/run-target.js +1 -1
  244. package/dist/lib/hosts/session-index.js +1 -1
  245. package/dist/lib/hosts/tasks.d.ts +6 -6
  246. package/dist/lib/hosts/tasks.js +4 -4
  247. package/dist/lib/hosts/types.js +1 -2
  248. package/dist/lib/installations/resolve.js +2 -8
  249. package/dist/lib/isolation-boundary-report.js +0 -1
  250. package/dist/lib/linear-cache.d.ts +7 -0
  251. package/dist/lib/linear-cache.js +31 -4
  252. package/dist/lib/linear-project-counts.d.ts +1 -1
  253. package/dist/lib/linear-project-counts.js +2 -3
  254. package/dist/lib/linear-projects.js +1 -1
  255. package/dist/lib/loop.d.ts +2 -2
  256. package/dist/lib/loop.js +1 -1
  257. package/dist/lib/mailbox-target.d.ts +1 -1
  258. package/dist/lib/mailbox-target.js +1 -1
  259. package/dist/lib/manifest.js +7 -4
  260. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  262. package/dist/lib/menubar/snapshot.d.ts +3 -2
  263. package/dist/lib/menubar/snapshot.js +6 -2
  264. package/dist/lib/migrate-fold.d.ts +33 -0
  265. package/dist/lib/migrate-fold.js +130 -0
  266. package/dist/lib/migrate.d.ts +34 -34
  267. package/dist/lib/migrate.js +106 -128
  268. package/dist/lib/model-tier-overrides.d.ts +1 -1
  269. package/dist/lib/model-tier-overrides.js +15 -2
  270. package/dist/lib/monitors/config.d.ts +17 -3
  271. package/dist/lib/monitors/config.js +52 -18
  272. package/dist/lib/monitors/engine.d.ts +32 -1
  273. package/dist/lib/monitors/engine.js +94 -11
  274. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  275. package/dist/lib/monitors/fingerprint.js +100 -0
  276. package/dist/lib/monitors/remote.d.ts +47 -0
  277. package/dist/lib/monitors/remote.js +81 -0
  278. package/dist/lib/monitors/state.d.ts +39 -0
  279. package/dist/lib/monitors/state.js +56 -0
  280. package/dist/lib/onepassword.d.ts +17 -0
  281. package/dist/lib/onepassword.js +52 -22
  282. package/dist/lib/open-url.js +1 -1
  283. package/dist/lib/picker.d.ts +14 -2
  284. package/dist/lib/picker.js +35 -13
  285. package/dist/lib/placement.d.ts +1 -1
  286. package/dist/lib/placement.js +1 -1
  287. package/dist/lib/pr-land-detach.d.ts +32 -0
  288. package/dist/lib/pr-land-detach.js +79 -0
  289. package/dist/lib/profiles-presets.js +13 -0
  290. package/dist/lib/profiles.d.ts +2 -0
  291. package/dist/lib/profiles.js +44 -1
  292. package/dist/lib/project-focus.d.ts +1 -1
  293. package/dist/lib/project-focus.js +1 -1
  294. package/dist/lib/project-key.d.ts +17 -0
  295. package/dist/lib/project-key.js +26 -0
  296. package/dist/lib/project-probe.d.ts +4 -1
  297. package/dist/lib/project-probe.js +5 -4
  298. package/dist/lib/project-resources.js +2 -18
  299. package/dist/lib/project-root.d.ts +16 -0
  300. package/dist/lib/project-root.js +20 -2
  301. package/dist/lib/projects.d.ts +20 -1
  302. package/dist/lib/projects.js +78 -1
  303. package/dist/lib/refresh-coordinator.d.ts +24 -0
  304. package/dist/lib/refresh-coordinator.js +52 -0
  305. package/dist/lib/registry.d.ts +2 -2
  306. package/dist/lib/registry.js +1 -1
  307. package/dist/lib/resource-aliases.d.ts +13 -0
  308. package/dist/lib/resource-aliases.js +26 -0
  309. package/dist/lib/resources/types.d.ts +1 -1
  310. package/dist/lib/resources.d.ts +16 -0
  311. package/dist/lib/resources.js +66 -10
  312. package/dist/lib/rotate.d.ts +3 -4
  313. package/dist/lib/rotate.js +4 -5
  314. package/dist/lib/routine-activation.d.ts +22 -2
  315. package/dist/lib/routine-activation.js +63 -16
  316. package/dist/lib/routine-context.d.ts +9 -2
  317. package/dist/lib/routine-context.js +21 -6
  318. package/dist/lib/routines-project.d.ts +58 -48
  319. package/dist/lib/routines-project.js +190 -159
  320. package/dist/lib/routines.d.ts +41 -6
  321. package/dist/lib/routines.js +92 -34
  322. package/dist/lib/run-defaults.d.ts +5 -0
  323. package/dist/lib/run-defaults.js +11 -1
  324. package/dist/lib/runner.d.ts +10 -8
  325. package/dist/lib/runner.js +122 -39
  326. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  327. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  328. package/dist/lib/secrets/agent.d.ts +10 -3
  329. package/dist/lib/secrets/agent.js +43 -8
  330. package/dist/lib/secrets/bundles.d.ts +1 -0
  331. package/dist/lib/secrets/bundles.js +92 -80
  332. package/dist/lib/secrets/index.js +32 -9
  333. package/dist/lib/secrets/install-helper.d.ts +4 -4
  334. package/dist/lib/secrets/install-helper.js +4 -4
  335. package/dist/lib/secrets/push.d.ts +40 -6
  336. package/dist/lib/secrets/push.js +58 -11
  337. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  338. package/dist/lib/secrets/read-backoff.js +1 -1
  339. package/dist/lib/secrets/remote.d.ts +24 -0
  340. package/dist/lib/secrets/remote.js +54 -4
  341. package/dist/lib/self-update.d.ts +108 -0
  342. package/dist/lib/self-update.js +276 -1
  343. package/dist/lib/session/active.d.ts +89 -5
  344. package/dist/lib/session/active.js +165 -10
  345. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  346. package/dist/lib/session/actor-sidecar.js +2 -1
  347. package/dist/lib/session/db.d.ts +176 -2
  348. package/dist/lib/session/db.js +484 -17
  349. package/dist/lib/session/discover.js +27 -4
  350. package/dist/lib/session/hook-sessions.js +2 -2
  351. package/dist/lib/session/host-link.d.ts +2 -2
  352. package/dist/lib/session/host-link.js +2 -2
  353. package/dist/lib/session/pid-registry.d.ts +21 -0
  354. package/dist/lib/session/pid-registry.js +57 -0
  355. package/dist/lib/session/remote-active.js +15 -1
  356. package/dist/lib/session/remote.js +2 -2
  357. package/dist/lib/session/session-cache.d.ts +14 -7
  358. package/dist/lib/session/session-cache.js +51 -9
  359. package/dist/lib/session/state.d.ts +2 -2
  360. package/dist/lib/session/state.js +1 -1
  361. package/dist/lib/session/sync/config.d.ts +10 -10
  362. package/dist/lib/session/sync/config.js +10 -10
  363. package/dist/lib/session/sync/r2.d.ts +34 -0
  364. package/dist/lib/session/sync/r2.js +123 -0
  365. package/dist/lib/session/throughput.d.ts +1 -1
  366. package/dist/lib/session/throughput.js +1 -1
  367. package/dist/lib/session/types.d.ts +23 -1
  368. package/dist/lib/session/types.js +15 -0
  369. package/dist/lib/session/viewing-in.d.ts +1 -1
  370. package/dist/lib/session/viewing-in.js +1 -1
  371. package/dist/lib/session/watch.d.ts +101 -0
  372. package/dist/lib/session/watch.js +242 -0
  373. package/dist/lib/share/config.d.ts +4 -0
  374. package/dist/lib/share/config.js +1 -0
  375. package/dist/lib/share/delete.d.ts +93 -0
  376. package/dist/lib/share/delete.js +127 -0
  377. package/dist/lib/share/provision.d.ts +38 -0
  378. package/dist/lib/share/provision.js +50 -0
  379. package/dist/lib/share/publish.d.ts +40 -1
  380. package/dist/lib/share/publish.js +116 -3
  381. package/dist/lib/share/worker-template.js +71 -6
  382. package/dist/lib/shims.d.ts +17 -3
  383. package/dist/lib/shims.js +136 -27
  384. package/dist/lib/signin-badge.js +3 -2
  385. package/dist/lib/skills.js +2 -0
  386. package/dist/lib/smart-launch.d.ts +8 -8
  387. package/dist/lib/smart-launch.js +80 -59
  388. package/dist/lib/ssh-exec.d.ts +1 -1
  389. package/dist/lib/ssh-exec.js +1 -1
  390. package/dist/lib/staleness/prune.d.ts +88 -0
  391. package/dist/lib/staleness/prune.js +69 -0
  392. package/dist/lib/staleness/registry.d.ts +1 -1
  393. package/dist/lib/staleness/writers/commands.js +34 -2
  394. package/dist/lib/staleness/writers/hooks.js +16 -0
  395. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  396. package/dist/lib/staleness/writers/skills.js +19 -0
  397. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  398. package/dist/lib/staleness/writers/subagents.js +0 -4
  399. package/dist/lib/staleness/writers/types.d.ts +32 -0
  400. package/dist/lib/startup/command-registry.d.ts +6 -12
  401. package/dist/lib/startup/command-registry.js +14 -31
  402. package/dist/lib/startup/dev-build.d.ts +10 -0
  403. package/dist/lib/startup/dev-build.js +13 -1
  404. package/dist/lib/startup/spellcheck.d.ts +18 -0
  405. package/dist/lib/startup/spellcheck.js +45 -0
  406. package/dist/lib/state.d.ts +36 -9
  407. package/dist/lib/state.js +96 -46
  408. package/dist/lib/subagents-registry.d.ts +0 -7
  409. package/dist/lib/subagents-registry.js +38 -65
  410. package/dist/lib/subagents.d.ts +0 -33
  411. package/dist/lib/subagents.js +0 -75
  412. package/dist/lib/sync-umbrella.js +1 -1
  413. package/dist/lib/teams/agents.d.ts +41 -1
  414. package/dist/lib/teams/agents.js +187 -9
  415. package/dist/lib/teams/api.d.ts +11 -1
  416. package/dist/lib/teams/api.js +11 -2
  417. package/dist/lib/teams/delivery.d.ts +41 -0
  418. package/dist/lib/teams/delivery.js +60 -0
  419. package/dist/lib/teams/registry.d.ts +14 -0
  420. package/dist/lib/teams/registry.js +51 -1
  421. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  422. package/dist/lib/teams/remoteWorktree.js +29 -0
  423. package/dist/lib/teams/scheduler.d.ts +1 -1
  424. package/dist/lib/teams/scheduler.js +1 -1
  425. package/dist/lib/teams/worktree.d.ts +24 -0
  426. package/dist/lib/teams/worktree.js +42 -0
  427. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  428. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  429. package/dist/lib/terminal/engine.d.ts +4 -0
  430. package/dist/lib/terminal/engine.js +8 -2
  431. package/dist/lib/terminal/types.d.ts +21 -2
  432. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  433. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  434. package/dist/lib/tickets/list.d.ts +53 -0
  435. package/dist/lib/tickets/list.js +153 -0
  436. package/dist/lib/tmux/orphan-reap.d.ts +320 -0
  437. package/dist/lib/tmux/orphan-reap.js +644 -0
  438. package/dist/lib/tmux/session.d.ts +68 -3
  439. package/dist/lib/tmux/session.js +95 -5
  440. package/dist/lib/triggers/handlers.d.ts +20 -0
  441. package/dist/lib/triggers/handlers.js +6 -1
  442. package/dist/lib/types.d.ts +46 -34
  443. package/dist/lib/usage-fleet.d.ts +32 -0
  444. package/dist/lib/usage-fleet.js +125 -0
  445. package/dist/lib/usage-refresh.d.ts +3 -3
  446. package/dist/lib/usage-refresh.js +19 -16
  447. package/dist/lib/usage.d.ts +51 -47
  448. package/dist/lib/usage.js +145 -153
  449. package/dist/lib/version-duplicates.js +2 -2
  450. package/dist/lib/versions.d.ts +56 -13
  451. package/dist/lib/versions.js +195 -45
  452. package/dist/lib/watchdog/log.d.ts +1 -1
  453. package/dist/lib/watchdog/log.js +3 -3
  454. package/dist/lib/watchdog/rotate.d.ts +6 -6
  455. package/dist/lib/watchdog/rotate.js +6 -6
  456. package/dist/lib/workflows.d.ts +1 -1
  457. package/dist/lib/yaml-io.d.ts +47 -0
  458. package/dist/lib/yaml-io.js +55 -0
  459. package/package.json +2 -1
  460. package/scripts/install-helper.js +2 -2
  461. package/scripts/postinstall.js +23 -20
  462. package/dist/commands/defaults.d.ts +0 -7
  463. package/dist/commands/defaults.js +0 -107
  464. package/dist/commands/export.d.ts +0 -11
  465. package/dist/commands/export.js +0 -215
  466. package/dist/commands/helper.d.ts +0 -12
  467. package/dist/commands/helper.js +0 -87
  468. package/dist/commands/hosts.d.ts +0 -11
  469. package/dist/commands/hosts.js +0 -330
  470. package/dist/commands/lock.d.ts +0 -12
  471. package/dist/commands/lock.js +0 -70
  472. package/dist/commands/pull.d.ts +0 -17
  473. package/dist/commands/pull.js +0 -39
  474. package/dist/commands/push.d.ts +0 -14
  475. package/dist/commands/push.js +0 -30
  476. package/dist/commands/wallet.d.ts +0 -20
  477. package/dist/commands/wallet.js +0 -216
  478. package/dist/commands/worktree.d.ts +0 -19
  479. package/dist/commands/worktree.js +0 -272
  480. package/dist/lib/account-labels.d.ts +0 -24
  481. package/dist/lib/account-labels.js +0 -72
  482. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  483. package/dist/lib/auto-dispatch-linear.js +0 -107
  484. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  485. package/dist/lib/auto-dispatch-provider.js +0 -30
  486. package/dist/lib/auto-dispatch.d.ts +0 -93
  487. package/dist/lib/auto-dispatch.js +0 -128
  488. package/dist/lib/export.d.ts +0 -72
  489. package/dist/lib/export.js +0 -269
  490. package/dist/lib/lock.d.ts +0 -93
  491. package/dist/lib/lock.js +0 -207
  492. package/dist/lib/wallet/index.d.ts +0 -78
  493. package/dist/lib/wallet/index.js +0 -253
package/dist/lib/shims.js CHANGED
@@ -223,12 +223,79 @@ async function promptConflictStrategy(conflictInfos) {
223
223
  // The old dispatcher checked only the global dir, so a pinned grok that
224
224
  // installed into the versioned home fell through to the "not installed"
225
225
  // error.
226
- export const SHIM_SCHEMA_VERSION = 29;
226
+ // v30 RUSH-2459: two compounding grok binary-resolution bugs fixed. (1) The
227
+ // "exact version match" grep ran against `ls`'s FULL PATH output, and
228
+ // the versioned home's own path always contains the version string
229
+ // (.../versions/grok/<version>/...), so it matched every candidate
230
+ // unconditionally and silently degraded to "whatever ls sorts first" —
231
+ // now matched against each candidate's basename instead. (2) When no
232
+ // filename genuinely carries the version, the fallback no longer
233
+ // trusts whatever sorts first: it rejects any grok-* candidate under
234
+ // 1MB (real grok binaries are ~100MB+; a stray wrapper/alias script is
235
+ // a few hundred bytes) and prefers the most recently modified
236
+ // survivor. On yosemite-s0 both bugs fired together: a stale, unrelated
237
+ // grok-0.2.118-* file — a 99-byte wrapper that exec'd cursor-agent —
238
+ // sorted alphabetically before the real self-updated grok binary and
239
+ // was silently launched instead.
240
+ export const SHIM_SCHEMA_VERSION = 30;
227
241
  /** Internal marker string used to embed the schema version in shim scripts. */
228
242
  const SHIM_VERSION_MARKER = 'agents-shim-version:';
229
243
  function shellQuote(value) {
230
244
  return `'${value.replace(/'/g, `'\\''`)}'`;
231
245
  }
246
+ /**
247
+ * Bash function embedded in every generated grok binary-resolution block
248
+ * (the dispatcher shim's `generateShimScript` and the direct alias's
249
+ * `generateVersionedAliasScript`). Prints the path to use, or nothing.
250
+ *
251
+ * Prefers a `grok-*` FILENAME that carries the pinned version string —
252
+ * checked against `basename`, never the full path: `dir` is always
253
+ * `.../versions/grok/<version>/home/.grok/downloads`, so the version string
254
+ * is already a substring of every path in that directory regardless of the
255
+ * actual filename. The original `ls "$dir"/grok-* | grep -i "$version"`
256
+ * matched on the full line and so matched every candidate unconditionally,
257
+ * silently degrading to "whatever sorts first" — the versioned-home half of
258
+ * RUSH-2459, distinct from (and compounding) the missing-match fallback bug
259
+ * below.
260
+ *
261
+ * Grok self-updates its binary in place while running under the shim, so a
262
+ * version-home's downloads dir can accumulate several `grok-*` files whose
263
+ * names have drifted away from the version-home's pinned version — when no
264
+ * filename carries it, never trust whatever the directory listing returns
265
+ * first (RUSH-2459: a stale, unrelated 99-byte wrapper script matching the
266
+ * `grok-*` naming pattern sorted before the real ~127MB self-updated binary
267
+ * and was silently exec'd). Instead, reject anything under
268
+ * MIN_GROK_BINARY_BYTES — comfortably above any wrapper/alias artifact,
269
+ * comfortably below a real compiled binary — and among the survivors, pick
270
+ * the most recently modified: the file grok's self-updater actually wrote
271
+ * last. Mirrors the TS implementation, `resolveGrokFallbackBinary` in
272
+ * versions.ts (which reads bare filenames via `fs.readdirSync` and so never
273
+ * had the full-path-match bug).
274
+ */
275
+ const GROK_RESOLVE_BINARY_FN = `_resolve_grok_binary() {
276
+ local dir="$1" version_hint="$2"
277
+ local candidate base size mtime
278
+ for candidate in "$dir"/grok-*; do
279
+ [ -f "$candidate" ] || continue
280
+ base=$(basename "$candidate")
281
+ case "$base" in
282
+ *"$version_hint"*) printf '%s\\n' "$candidate"; return ;;
283
+ esac
284
+ done
285
+ local min_bytes=1000000
286
+ local best="" best_mtime=-1
287
+ for candidate in "$dir"/grok-*; do
288
+ [ -f "$candidate" ] || continue
289
+ size=$(wc -c < "$candidate" 2>/dev/null || echo 0)
290
+ [ "$size" -ge "$min_bytes" ] || continue
291
+ mtime=$(stat -c %Y "$candidate" 2>/dev/null || stat -f %m "$candidate" 2>/dev/null || echo -1)
292
+ if [ "$mtime" -gt "$best_mtime" ]; then
293
+ best_mtime="$mtime"
294
+ best="$candidate"
295
+ fi
296
+ done
297
+ printf '%s\\n' "$best"
298
+ }`;
232
299
  function codexShimLaunchArgs() {
233
300
  return [
234
301
  '-c',
@@ -236,6 +303,43 @@ function codexShimLaunchArgs() {
236
303
  ...codexPolicyArgs('edit'),
237
304
  ].map(shellQuote).join(' ');
238
305
  }
306
+ /**
307
+ * The `exec` tail for a generated shim. For most agents this is a plain
308
+ * `exec "$BINARY"<launchArgs> "$@"`.
309
+ *
310
+ * Codex is special: its `workspace-write` sandbox hardcodes any `.agents/` (and
311
+ * `.codex/`) directory read-only, but agents-cli keeps every worktree at
312
+ * `<repo>/.agents/worktrees/<slug>`, so an in-repo build under a static
313
+ * shim would hit `EROFS`. The `agents run codex` path fixes this by adding
314
+ * `<repo>/.agents` to the profile's `workspace_roots` (see codexEditWritableRoots
315
+ * / repoAgentsDirForCwd), but a static shim has no cwd at generation time. So the
316
+ * shim resolves the repo's `.agents` from `$PWD` at RUN time — worktree-aware,
317
+ * mirroring repoAgentsDirForCwd — and passes it via Codex's own `--add-dir`
318
+ * (verified to compose with the `agents-edit` profile). The resolution is inline
319
+ * bash because the shim is the launch hot path and must not spawn Node to compute
320
+ * one directory. `--add-dir` is added only when the resolved `.agents` exists.
321
+ */
322
+ function shimExecTail(agent, launchArgs) {
323
+ if (agent !== 'codex')
324
+ return `exec "$BINARY"${launchArgs} "$@"`;
325
+ return `_repo_agents=""
326
+ case "$PWD" in
327
+ */.agents/worktrees/*) _repo_agents="\${PWD%%/.agents/worktrees/*}/.agents" ;;
328
+ *)
329
+ _d="$PWD"
330
+ # Stop before $HOME so a dotfiles repo at $HOME is not treated as the project
331
+ # root (mirrors repoRootForCwd's home exclusion in project-key.ts).
332
+ while [ -n "$_d" ] && [ "$_d" != "/" ] && [ "$_d" != "$HOME" ]; do
333
+ if [ -e "$_d/.git" ]; then _repo_agents="$_d/.agents"; break; fi
334
+ _d=$(dirname "$_d")
335
+ done
336
+ ;;
337
+ esac
338
+ if [ -n "$_repo_agents" ] && [ -d "$_repo_agents" ]; then
339
+ exec "$BINARY"${launchArgs} --add-dir "$_repo_agents" "$@"
340
+ fi
341
+ exec "$BINARY"${launchArgs} "$@"`;
342
+ }
239
343
  function getAgentsBinForGeneratedShim() {
240
344
  return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'index.js');
241
345
  }
@@ -501,27 +605,20 @@ VERSION_DIR="$AGENTS_USER_DIR/.history/versions/$AGENT/$VERSION"
501
605
  # for pre-fix installs, the global ~/.grok/downloads), not node_modules. We
502
606
  # still use the agents-cli version dir purely for GROK_HOME isolation.
503
607
  if [ "$AGENT" = "grok" ]; then
608
+ ${GROK_RESOLVE_BINARY_FN}
504
609
  # Check the versioned home first — this is where the binary lands when the
505
610
  # installer runs with GROK_HOME set (i.e. via the shim or a correct
506
611
  # \`agents add grok\`), or when grok self-updates from within the shim.
507
612
  GROK_DOWNLOADS="$VERSION_DIR/home/.grok/downloads"
508
613
  if [ -d "$GROK_DOWNLOADS" ]; then
509
- # Prefer a binary whose filename contains the exact version
510
- BINARY=$(ls "$GROK_DOWNLOADS"/grok-* 2>/dev/null | grep -i "$VERSION" | head -1)
511
- if [ -z "$BINARY" ]; then
512
- # Fallback to the "current" grok binary (symlink or latest)
513
- BINARY=$(ls "$GROK_DOWNLOADS"/grok-* 2>/dev/null | head -1)
514
- fi
614
+ BINARY=$(_resolve_grok_binary "$GROK_DOWNLOADS" "$VERSION")
515
615
  fi
516
616
  # Fall back to the global grok home (binary installed without GROK_HOME set,
517
617
  # e.g. an earlier \`agents add grok@latest\` before this resolution fix).
518
618
  if [ -z "$BINARY" ] || [ ! -x "$BINARY" ]; then
519
619
  GROK_DOWNLOADS="$HOME/.grok/downloads"
520
620
  if [ -d "$GROK_DOWNLOADS" ]; then
521
- BINARY=$(ls "$GROK_DOWNLOADS"/grok-* 2>/dev/null | grep -i "$VERSION" | head -1)
522
- if [ -z "$BINARY" ]; then
523
- BINARY=$(ls "$GROK_DOWNLOADS"/grok-* 2>/dev/null | head -1)
524
- fi
621
+ BINARY=$(_resolve_grok_binary "$GROK_DOWNLOADS" "$VERSION")
525
622
  fi
526
623
  fi
527
624
  if [ -z "$BINARY" ] || [ ! -x "$BINARY" ]; then
@@ -585,13 +682,12 @@ elif [ "$AGENT" = "muse" ]; then
585
682
  fi
586
683
  fi
587
684
  elif [ "$AGENT" = "warp" ]; then
588
- # Warp Agent CLI installs a global, self-updating oz binary (brew cask on
589
- # macOS, the oz-stable apt|yum|pacman package on Linux) -- a platform/package
590
- # specific location, not ~/.local/bin -- so resolve it from PATH with the same
591
- # shims-dir re-exec guard as droid/muse.
685
+ # Warp Agent CLI installs a global, self-updating warp binary at
686
+ # ~/.local/bin/warp (curl installer) -- like droid/muse -- so resolve it from
687
+ # PATH with the same shims-dir re-exec guard as droid/muse.
592
688
  BINARY=$(adopted_original_bin || echo "")
593
689
  if [ -z "$BINARY" ]; then
594
- BINARY=$(command -v oz 2>/dev/null || echo "")
690
+ BINARY=$(command -v warp 2>/dev/null || echo "")
595
691
  case "$(readlink -f "$BINARY" 2>/dev/null)" in
596
692
  "$AGENTS_USER_DIR/.cache/shims/"*) BINARY="" ;;
597
693
  esac
@@ -707,7 +803,7 @@ if [ "\$LAUNCH_SKIP" = "0" ]; then
707
803
  "\$AGENTS_BIN" sync --agent "\$AGENT" --agent-version "\$VERSION" --launch --cwd "\$PWD" --quiet 2>/dev/null || true
708
804
  fi
709
805
 
710
- exec "$BINARY"${launchArgs} "$@"
806
+ ${shimExecTail(agent, launchArgs)}
711
807
  `;
712
808
  }
713
809
  /**
@@ -905,8 +1001,22 @@ export function removeShim(agent) {
905
1001
  * alias failed with "not installed" whenever the binary was staged into
906
1002
  * the versioned home (installer run with GROK_HOME set, or grok
907
1003
  * self-update under the shim).
1004
+ * v16 — RUSH-2459: two compounding grok binary-resolution bugs fixed. (1) The
1005
+ * "exact version match" grep ran against `ls`'s FULL PATH output, and
1006
+ * the versioned home's own path always contains the version string
1007
+ * (.../versions/grok/<version>/...), so it matched every candidate
1008
+ * unconditionally and silently degraded to "whatever ls sorts first" —
1009
+ * now matched against each candidate's basename instead. (2) When no
1010
+ * filename genuinely carries the version, the fallback no longer
1011
+ * trusts whatever sorts first: it rejects any grok-* candidate under
1012
+ * 1MB (real grok binaries are ~100MB+; a stray wrapper/alias script is
1013
+ * a few hundred bytes) and prefers the most recently modified
1014
+ * survivor. On yosemite-s0 both bugs fired together: a stale, unrelated
1015
+ * grok-0.2.118-* file — a 99-byte wrapper that exec'd cursor-agent —
1016
+ * sorted alphabetically before the real self-updated grok binary and
1017
+ * was silently launched instead.
908
1018
  */
909
- export const VERSIONED_ALIAS_SCHEMA_VERSION = 15;
1019
+ export const VERSIONED_ALIAS_SCHEMA_VERSION = 16;
910
1020
  /** Internal marker string used to embed the schema version in versioned alias scripts. */
911
1021
  const VERSIONED_ALIAS_VERSION_MARKER = 'agents-versioned-alias-version:';
912
1022
  // The version string is interpolated into a generated bash script and into
@@ -1025,18 +1135,17 @@ export XDG_CONFIG_HOME="$HOME/.agents/.history/versions/${agent}/${version}/home
1025
1135
  const binaryResolution = agent === 'grok'
1026
1136
  ? `# Grok ships its native binary in the versioned home's .grok/downloads (or,
1027
1137
  # for pre-fix installs, the global ~/.grok/downloads), not node_modules.
1138
+ ${GROK_RESOLVE_BINARY_FN}
1028
1139
  GROK_DOWNLOADS="${versionDir}/home/.grok/downloads"
1029
1140
  BINARY=""
1030
1141
  if [ -d "$GROK_DOWNLOADS" ]; then
1031
- BINARY=$(ls "$GROK_DOWNLOADS"/grok-* 2>/dev/null | grep -i "${version}" | head -1)
1032
- [ -n "$BINARY" ] || BINARY=$(ls "$GROK_DOWNLOADS"/grok-* 2>/dev/null | head -1)
1142
+ BINARY=$(_resolve_grok_binary "$GROK_DOWNLOADS" "${version}")
1033
1143
  fi
1034
1144
  # Fall back to the global grok home (binary installed without GROK_HOME set).
1035
1145
  if [ -z "$BINARY" ] || [ ! -x "$BINARY" ]; then
1036
1146
  GROK_GLOBAL_DOWNLOADS="$HOME/.grok/downloads"
1037
1147
  if [ -d "$GROK_GLOBAL_DOWNLOADS" ]; then
1038
- BINARY=$(ls "$GROK_GLOBAL_DOWNLOADS"/grok-* 2>/dev/null | grep -i "${version}" | head -1)
1039
- [ -n "$BINARY" ] || BINARY=$(ls "$GROK_GLOBAL_DOWNLOADS"/grok-* 2>/dev/null | head -1)
1148
+ BINARY=$(_resolve_grok_binary "$GROK_GLOBAL_DOWNLOADS" "${version}")
1040
1149
  fi
1041
1150
  fi
1042
1151
  # Refuse a PATH match under our own shims dir — it resolves to this alias's
@@ -1073,10 +1182,10 @@ else
1073
1182
  esac
1074
1183
  fi`
1075
1184
  : agent === 'warp'
1076
- ? `# Warp Agent CLI installs a global self-updating \`oz\` binary (brew cask on
1077
- # macOS, oz-stable apt|yum|pacman on Linux)a platform-specific location, not
1078
- # ~/.local/bin — so resolve it from PATH, refusing anything under our shims dir.
1079
- BINARY=$(command -v oz 2>/dev/null || echo "")
1185
+ ? `# Warp Agent CLI installs a global self-updating \`warp\` binary at
1186
+ # ~/.local/bin/warp (curl installer) like droid/muse so resolve it from
1187
+ # PATH, refusing anything under our shims dir.
1188
+ BINARY=$(command -v warp 2>/dev/null || echo "")
1080
1189
  case "$BINARY" in
1081
1190
  "$HOME/.agents/.cache/shims/"*) BINARY="" ;;
1082
1191
  esac`
@@ -1094,7 +1203,7 @@ if [ -z "$BINARY" ] || [ ! -x "$BINARY" ]; then
1094
1203
  fi
1095
1204
  ${managedEnv}
1096
1205
 
1097
- exec "$BINARY"${launchArgs} "$@"
1206
+ ${shimExecTail(agent, launchArgs)}
1098
1207
  `;
1099
1208
  }
1100
1209
  /**
@@ -24,11 +24,12 @@ export function loginHint(agentId) {
24
24
  return `${cli}, then /login`;
25
25
  case 'codex':
26
26
  case 'grok':
27
- // Warp Agent CLI: `oz login` opens a browser sign-in (or set WARP_API_KEY).
28
- case 'warp':
29
27
  return `${cli} login`;
30
28
  case 'opencode':
31
29
  return `${cli} auth login`;
30
+ // Warp Agent CLI has no `login` subcommand: running `warp` opens a browser
31
+ // sign-in on launch (or set WARP_API_KEY / pass --api-key), so the default
32
+ // bare-`warp` hint is correct.
32
33
  default:
33
34
  return cli;
34
35
  }
@@ -10,6 +10,7 @@ import * as fs from 'fs';
10
10
  import * as path from 'path';
11
11
  import * as os from 'os';
12
12
  import * as yaml from 'yaml';
13
+ import { normalizeAliases } from './resource-aliases.js';
13
14
  import { AGENTS, ensureSkillsDir, agentConfigDirName } from './agents.js';
14
15
  import { capableAgents, isCapable } from './capabilities.js';
15
16
  import { getUserSkillsDir, getSkillsDir as getSystemSkillsDir, getProjectAgentsDir, getEnabledExtraRepos, getTrashSkillsDir } from './state.js';
@@ -98,6 +99,7 @@ export function tryParseSkillMetadata(skillDir) {
98
99
  version: parsed.version,
99
100
  license: parsed.license,
100
101
  keywords: parsed.keywords,
102
+ aliases: normalizeAliases(parsed.aliases),
101
103
  },
102
104
  };
103
105
  }
@@ -59,11 +59,13 @@ export interface DeviceAutoPlan {
59
59
  }>;
60
60
  pickedDeviceKey: string;
61
61
  }
62
+ export declare function formatNoHealthyDeviceError(pool: string[], signals: Map<string, DevicePlacementSignal>, agent?: string): string;
62
63
  /**
63
64
  * Pick the least-loaded healthy device that can run `agent` when the harness is
64
- * known. `run auto` omits the agent and ranks the same live health/load signals
65
- * without an installed-harness filter. The local machine participates in the
66
- * same probe; a fully unusable fleet degrades to local instead of stranding a run.
65
+ * known. `run auto` omits the agent and treats any ready account on the device
66
+ * as eligible. The local machine participates in the
67
+ * same probe and must pass the same eligibility checks. An empty eligible pool
68
+ * fails loud; automatic placement never silently becomes a local launch.
67
69
  */
68
70
  export declare function resolveDeviceAuto(agent?: string, opts?: {
69
71
  eligibleHosts?: string[];
@@ -87,12 +89,10 @@ export type DeviceAutoHostOptions = {
87
89
  strategy?: string;
88
90
  };
89
91
  export type DeviceAutoApplyResult = {
90
- /** True when affinity ran (success or degrade-to-local). */
92
+ /** True when automatic placement ran successfully. */
91
93
  attempted: boolean;
92
94
  /** True when deprecated `--smart` was seen. */
93
95
  deprecationSmart: boolean;
94
- /** Affinity threw: host slots cleared → local; message for stderr. */
95
- skipped?: string;
96
96
  /** Present when affinity resolved without error. */
97
97
  banner?: {
98
98
  hostLabel: string;
@@ -102,8 +102,8 @@ export type DeviceAutoApplyResult = {
102
102
  };
103
103
  /**
104
104
  * Apply `--device auto` / `--host auto` (and deprecated `--smart`) onto run options.
105
- * Mutates `options` in place. On affinity failure, clears auto slots (local) and
106
- * returns `skipped` never throws; callers must not hard-exit.
105
+ * Mutates `options` in place. Placement failures propagate without rewriting
106
+ * `auto`, so callers fail loud instead of silently launching locally.
107
107
  */
108
108
  export declare function applyDeviceAutoToOptions(options: DeviceAutoHostOptions, deps?: {
109
109
  resolve?: () => DeviceAutoPlan | Promise<DeviceAutoPlan>;
@@ -11,6 +11,7 @@ import { loadDevicesSync } from './devices/registry.js';
11
11
  import { normalizeHost } from './machine-id.js';
12
12
  import { probePoolSignals } from './teams/placement-probe.js';
13
13
  import { pickBestDevice } from './teams/scheduler.js';
14
+ import { getAccountInfo } from './agents.js';
14
15
  /** Peakiness of usage weights; >1 amplifies the most-used option. */
15
16
  export const DEFAULT_AFFINITY_ALPHA = 1.3;
16
17
  /**
@@ -64,38 +65,73 @@ export function listOnlineDeviceNames(localName = localMachineId()) {
64
65
  }
65
66
  return [...names];
66
67
  }
68
+ export function formatNoHealthyDeviceError(pool, signals, agent) {
69
+ const excluded = pool.map((key) => {
70
+ const signal = signals.get(key);
71
+ const reason = signal?.reachable !== true
72
+ ? 'unreachable'
73
+ : signal.headroom === 'loaded'
74
+ ? 'overloaded'
75
+ : signal.installed !== true || signal.signedIn !== true
76
+ ? 'no ready harness account'
77
+ : 'ineligible';
78
+ return `${key} (${reason})`;
79
+ }).join(', ');
80
+ const target = agent ? `can run ${agent}` : "for 'run auto'";
81
+ return `agents: no healthy device ${target} — excluded: ${excluded}; earliest window resets unknown`;
82
+ }
67
83
  /**
68
84
  * Pick the least-loaded healthy device that can run `agent` when the harness is
69
- * known. `run auto` omits the agent and ranks the same live health/load signals
70
- * without an installed-harness filter. The local machine participates in the
71
- * same probe; a fully unusable fleet degrades to local instead of stranding a run.
85
+ * known. `run auto` omits the agent and treats any ready account on the device
86
+ * as eligible. The local machine participates in the
87
+ * same probe and must pass the same eligibility checks. An empty eligible pool
88
+ * fails loud; automatic placement never silently becomes a local launch.
72
89
  */
73
90
  export async function resolveDeviceAuto(agent, opts = {}) {
74
91
  const local = normalizeHost(opts.localMachine ?? localMachineId());
75
92
  const pool = [...new Set((opts.eligibleHosts ?? listOnlineDeviceNames(local)).map(normalizeHost))];
76
93
  if (!pool.includes(local))
77
94
  pool.push(local);
78
- try {
79
- const signals = await (opts.probe ?? probePoolSignals)(pool, agent);
80
- const picked = pickBestDevice(pool, [], { signals, agentLabel: agent });
81
- return {
82
- host: picked === local ? null : picked,
83
- pickedDeviceKey: picked,
84
- candidates: pool.map((key) => ({
85
- key,
86
- loadPercent: signals.get(key)?.loadPercent,
87
- installed: signals.get(key)?.installed,
88
- signedIn: signals.get(key)?.signedIn,
89
- })),
90
- };
95
+ const signals = await (opts.probe ?? probePoolSignals)(pool, agent);
96
+ if (!agent && !opts.probe) {
97
+ const { collectFleetHarnesses } = await import('../commands/ssh.js');
98
+ const inventory = await collectFleetHarnesses({ devices: pool });
99
+ const byHost = new Map(inventory.map((result) => [normalizeHost(result.host), result]));
100
+ for (const key of pool) {
101
+ const result = byHost.get(key);
102
+ const accountEligible = !!result && !result.error && !result.skipped && result.rows.some((row) => row.ready);
103
+ const current = signals.get(key);
104
+ if (current)
105
+ signals.set(key, { ...current, installed: accountEligible, signedIn: accountEligible });
106
+ }
91
107
  }
92
- catch {
93
- return {
94
- host: null,
95
- pickedDeviceKey: local,
96
- candidates: [{ key: local }],
97
- };
108
+ if (agent && !opts.probe && signals.has(local)) {
109
+ const info = await getAccountInfo(agent).catch(() => null);
110
+ const eligible = !!info?.signedIn && info.usageStatus !== 'rate_limited' && info.usageStatus !== 'out_of_credits';
111
+ signals.set(local, { ...signals.get(local), signedIn: eligible });
98
112
  }
113
+ const eligiblePool = pool.filter((key) => {
114
+ const signal = signals.get(key);
115
+ if (signal?.reachable !== true || signal.headroom === 'loaded')
116
+ return false;
117
+ if (!agent)
118
+ return opts.probe ? true : signal.installed === true && signal.signedIn === true;
119
+ return signal.installed === true && signal.signedIn === true;
120
+ });
121
+ if (eligiblePool.length === 0) {
122
+ throw new Error(formatNoHealthyDeviceError(pool, signals, agent));
123
+ }
124
+ const picked = pickBestDevice(eligiblePool, [], { signals, agentLabel: agent });
125
+ return {
126
+ host: picked === local ? null : picked,
127
+ pickedDeviceKey: picked,
128
+ candidates: pool.map((key) => ({
129
+ key,
130
+ loadPercent: signals.get(key)?.loadPercent,
131
+ installed: signals.get(key)?.installed,
132
+ signedIn: signals.get(key)?.signedIn,
133
+ })),
134
+ };
99
135
  }
100
136
  /**
101
137
  * Resolve host for `--device auto`. Does NOT pick harness or accounts.
@@ -152,8 +188,8 @@ export function isDeviceAuto(value) {
152
188
  const HOST_SLOTS = ['host', 'device', 'on', 'computer'];
153
189
  /**
154
190
  * Apply `--device auto` / `--host auto` (and deprecated `--smart`) onto run options.
155
- * Mutates `options` in place. On affinity failure, clears auto slots (local) and
156
- * returns `skipped` never throws; callers must not hard-exit.
191
+ * Mutates `options` in place. Placement failures propagate without rewriting
192
+ * `auto`, so callers fail loud instead of silently launching locally.
157
193
  */
158
194
  export async function applyDeviceAutoToOptions(options, deps = {}) {
159
195
  let deprecationSmart = false;
@@ -167,42 +203,27 @@ export async function applyDeviceAutoToOptions(options, deps = {}) {
167
203
  if (!hasAuto) {
168
204
  return { attempted: false, deprecationSmart };
169
205
  }
170
- try {
171
- const resolve = deps.resolve ?? (() => resolveDeviceAuto(deps.agent));
172
- const plan = await resolve();
173
- const concrete = plan.host; // null = local
174
- for (const k of HOST_SLOTS) {
175
- if (isDeviceAuto(options[k])) {
176
- options[k] = concrete ?? undefined;
177
- }
206
+ const resolve = deps.resolve ?? (() => resolveDeviceAuto(deps.agent));
207
+ const plan = await resolve();
208
+ const concrete = plan.host; // null = local
209
+ for (const k of HOST_SLOTS) {
210
+ if (isDeviceAuto(options[k])) {
211
+ options[k] = concrete ?? undefined;
178
212
  }
179
- const accountPickerRequested = deps.accountPickerRequested ?? false;
180
- if (!accountPickerRequested && !options.strategy && !options.balanced) {
181
- options.balanced = true;
182
- }
183
- const hostLabel = concrete ?? 'local';
184
- const deviceHint = plan.candidates
185
- .slice(0, 4)
186
- .map((c) => `${c.key}:${c.loadPercent === undefined ? '?' : `${Math.round(c.loadPercent)}%`}`)
187
- .join(', ');
188
- const acctNote = accountPickerRequested ? 'accounts=picker' : 'accounts=balanced';
189
- return {
190
- attempted: true,
191
- deprecationSmart,
192
- banner: { hostLabel, deviceHint, acctNote },
193
- };
194
213
  }
195
- catch (err) {
196
- // Graceful degrade: clear auto slots so the run continues locally.
197
- for (const k of HOST_SLOTS) {
198
- if (isDeviceAuto(options[k])) {
199
- options[k] = undefined;
200
- }
201
- }
202
- return {
203
- attempted: true,
204
- deprecationSmart,
205
- skipped: err.message,
206
- };
214
+ const accountPickerRequested = deps.accountPickerRequested ?? false;
215
+ if (!accountPickerRequested && !options.strategy && !options.balanced) {
216
+ options.balanced = true;
207
217
  }
218
+ const hostLabel = concrete ?? 'local';
219
+ const deviceHint = plan.candidates
220
+ .slice(0, 4)
221
+ .map((c) => `${c.key}:${c.loadPercent === undefined ? '?' : `${Math.round(c.loadPercent)}%`}`)
222
+ .join(', ');
223
+ const acctNote = accountPickerRequested ? 'accounts=picker' : 'accounts=balanced';
224
+ return {
225
+ attempted: true,
226
+ deprecationSmart,
227
+ banner: { hostLabel, deviceHint, acctNote },
228
+ };
208
229
  }
@@ -2,7 +2,7 @@
2
2
  * Shared SSH exec primitive — the single hardened choke point for running a
3
3
  * command on a remote host over the system `ssh`.
4
4
  *
5
- * `agents hosts` dispatch and the browser driver both go through here so the
5
+ * `agents run --host` dispatch and the browser driver both go through here so the
6
6
  * connection hardening (`BatchMode`, `accept-new`, `ConnectTimeout`) and the
7
7
  * target-injection guard live in exactly one place. Target validation is the
8
8
  * canonical definition; `commands/secrets.ts` re-exports it.
@@ -2,7 +2,7 @@
2
2
  * Shared SSH exec primitive — the single hardened choke point for running a
3
3
  * command on a remote host over the system `ssh`.
4
4
  *
5
- * `agents hosts` dispatch and the browser driver both go through here so the
5
+ * `agents run --host` dispatch and the browser driver both go through here so the
6
6
  * connection hardening (`BatchMode`, `accept-new`, `ConnectTimeout`) and the
7
7
  * target-injection guard live in exactly one place. Target validation is the
8
8
  * canonical definition; `commands/secrets.ts` re-exports it.
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Manifest-bounded prune (RUSH-2438).
3
+ *
4
+ * `agents sync` was additive-only: it installed/updated resources present in
5
+ * source but never removed a resource that had been DELETED from source, so a
6
+ * removed command/skill/hook lingered in every installed version home forever
7
+ * (and stayed live in the `/` menu). Bare `agents sync <agent>` full syncs did
8
+ * sweep orphans, but the repo-scoped forms the reconcile path actually uses —
9
+ * `agents sync <agent>@all system`, `agents sync <agent> system --force` — pass
10
+ * a selection, which turned the orphan sweeps off. This closes that gap.
11
+ *
12
+ * The prune set is computed by name, bounded by the sync manifest:
13
+ *
14
+ * prune = (names the last sync recorded as installed)
15
+ * − (names still present in source across ALL layers)
16
+ * ∩ (names currently materialized in the version home)
17
+ *
18
+ * Each clause is a safety guarantee:
19
+ * - The manifest bound means only agents-installed resources are ever
20
+ * candidates — a file the user hand-authored into the version home was
21
+ * never recorded, so it is never touched.
22
+ * - Diffing against ALL layers (not just the scoped one) means a resource
23
+ * still provided by any other layer — e.g. a same-named user command that
24
+ * shadows a removed system command — stays: it is still "in source".
25
+ * - Requiring the name to be materialized skips work for anything already
26
+ * gone and never errors on a missing path.
27
+ *
28
+ * When there is NO manifest we cannot know what a prior sync installed, so we
29
+ * FAIL LOUD by pruning nothing and reporting it — never a "delete everything
30
+ * not in source" guess. The manifest is written by the next full sync, so the
31
+ * baseline heals itself.
32
+ *
33
+ * Deletion itself is delegated to each writer's `remove()` (the inverse of
34
+ * `write()`), so per-harness layout knowledge — native file vs command-skill
35
+ * dir vs goose recipe — lives in one place and can't drift.
36
+ */
37
+ import type { AgentId } from '../types.js';
38
+ import type { SyncManifest } from './types.js';
39
+ /**
40
+ * Kinds prune reconciles. Restricted to the name-keyed file/dir resources whose
41
+ * writer implements `remove()`. Deliberately excluded, each with a reason:
42
+ * - hooks — a version-home hook script is coupled to a settings.json /
43
+ * hooks.json REGISTRATION. Pruning the last hook to zero would delete the
44
+ * script but must also GC its registration in the same pass, and that lands
45
+ * in `src/lib/hooks.ts` — a Windows-portable-path surface the CI windows leg
46
+ * gates on. Split to RUSH-2456 so this PR stays Linux-only-green; hook FILES
47
+ * are still reconciled by the in-write orphan sweep (versions.ts, gated on
48
+ * `hooksToSync > 0`).
49
+ * - rules / permissions — synced as a wholesale rewrite (one composed file /
50
+ * the full allowlist), so a removed rule or group already drops out.
51
+ * - plugins — carry their own reconciliation via `cleanOrphanedPluginSkills`.
52
+ * - mcp — registered through each agent's CLI/config, a separate removal path.
53
+ * - subagents / workflows — no clean per-name inverse yet (multi-agent index
54
+ * finalize; native workflow trees); tracked for a follow-up.
55
+ */
56
+ export declare const PRUNABLE_KINDS: readonly ["commands", "skills"];
57
+ export type PrunableKind = typeof PRUNABLE_KINDS[number];
58
+ export interface PruneInput {
59
+ agent: AgentId;
60
+ version: string;
61
+ versionHome: string;
62
+ cwd: string;
63
+ /**
64
+ * The sync manifest loaded BEFORE this sync ran — the record of what the last
65
+ * sync installed. `null` means no prior full sync established a baseline.
66
+ */
67
+ previousManifest: SyncManifest | null;
68
+ /**
69
+ * Current source resource names across ALL layers (project/user/system/extras),
70
+ * per prunable kind. A name present here is still "in source" and never pruned.
71
+ */
72
+ sourceNames: Record<PrunableKind, ReadonlyArray<string>>;
73
+ }
74
+ export interface PruneOutcome {
75
+ /** Names actually removed from the version home, per kind. */
76
+ pruned: Record<PrunableKind, string[]>;
77
+ /**
78
+ * True when prune ran with no manifest and therefore deleted nothing — the
79
+ * fail-loud baseline case. Callers surface this so a skipped reconcile is
80
+ * never mistaken for "nothing to prune".
81
+ */
82
+ skippedNoManifest: boolean;
83
+ }
84
+ /**
85
+ * Remove resources that a prior sync installed and that are now gone from
86
+ * source, from one agent@version home. Deletes nothing when no manifest exists.
87
+ */
88
+ export declare function pruneRemovedResources(input: PruneInput): PruneOutcome;