@phnx-labs/agents-cli 1.22.35 → 1.22.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/CHANGELOG.md +708 -2
  2. package/README.md +83 -43
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1212 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/artifacts-setup.d.ts +53 -0
  9. package/dist/commands/artifacts-setup.js +161 -0
  10. package/dist/commands/artifacts.d.ts +18 -0
  11. package/dist/commands/artifacts.js +58 -0
  12. package/dist/commands/attach.js +17 -4
  13. package/dist/commands/audit.d.ts +8 -8
  14. package/dist/commands/audit.js +57 -47
  15. package/dist/commands/browser.js +17 -11
  16. package/dist/commands/cloud.js +1 -1
  17. package/dist/commands/commands.js +0 -11
  18. package/dist/commands/computer-actions.js +33 -0
  19. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  20. package/dist/commands/computer-sessions-picker.js +141 -0
  21. package/dist/commands/computer.d.ts +16 -0
  22. package/dist/commands/computer.js +37 -0
  23. package/dist/commands/config.d.ts +17 -0
  24. package/dist/commands/config.js +401 -0
  25. package/dist/commands/cp.d.ts +84 -0
  26. package/dist/commands/cp.js +231 -0
  27. package/dist/commands/daemon.js +243 -14
  28. package/dist/commands/detach-core.d.ts +1 -1
  29. package/dist/commands/detach-core.js +12 -2
  30. package/dist/commands/detach.js +1 -1
  31. package/dist/commands/doctor.js +64 -5
  32. package/dist/commands/events.d.ts +24 -12
  33. package/dist/commands/events.js +144 -28
  34. package/dist/commands/exec.js +86 -42
  35. package/dist/commands/feed.d.ts +1 -1
  36. package/dist/commands/feed.js +16 -8
  37. package/dist/commands/focus.d.ts +33 -1
  38. package/dist/commands/focus.js +177 -17
  39. package/dist/commands/funnel.d.ts +1 -1
  40. package/dist/commands/go.js +9 -8
  41. package/dist/commands/harness-wizard.d.ts +1 -0
  42. package/dist/commands/harness-wizard.js +18 -20
  43. package/dist/commands/harness.d.ts +2 -0
  44. package/dist/commands/harness.js +59 -26
  45. package/dist/commands/hooks.js +0 -11
  46. package/dist/commands/inspect.d.ts +94 -1
  47. package/dist/commands/inspect.js +866 -40
  48. package/dist/commands/lease.d.ts +4 -4
  49. package/dist/commands/lease.js +6 -6
  50. package/dist/commands/login.js +0 -13
  51. package/dist/commands/logs.d.ts +2 -2
  52. package/dist/commands/logs.js +2 -2
  53. package/dist/commands/mcp.js +7 -2
  54. package/dist/commands/memory.js +7 -2
  55. package/dist/commands/message.d.ts +1 -1
  56. package/dist/commands/message.js +37 -6
  57. package/dist/commands/models.js +71 -0
  58. package/dist/commands/monitors.d.ts +0 -1
  59. package/dist/commands/monitors.js +199 -16
  60. package/dist/commands/open.d.ts +18 -0
  61. package/dist/commands/open.js +57 -0
  62. package/dist/commands/packages.js +2 -107
  63. package/dist/commands/plugins.js +6 -3
  64. package/dist/commands/profiles.d.ts +1 -0
  65. package/dist/commands/profiles.js +16 -160
  66. package/dist/commands/projects.d.ts +28 -0
  67. package/dist/commands/projects.js +125 -5
  68. package/dist/commands/reconnect.js +9 -3
  69. package/dist/commands/repo.js +42 -1
  70. package/dist/commands/resource-view.d.ts +17 -0
  71. package/dist/commands/resource-view.js +36 -14
  72. package/dist/commands/resume.js +9 -2
  73. package/dist/commands/routines.d.ts +0 -2
  74. package/dist/commands/routines.js +473 -289
  75. package/dist/commands/secrets.js +52 -9
  76. package/dist/commands/sessions-export.d.ts +47 -0
  77. package/dist/commands/sessions-export.js +116 -6
  78. package/dist/commands/sessions-import.d.ts +17 -0
  79. package/dist/commands/sessions-import.js +114 -6
  80. package/dist/commands/sessions-migrate.d.ts +27 -0
  81. package/dist/commands/sessions-migrate.js +50 -9
  82. package/dist/commands/sessions-picker.js +23 -4
  83. package/dist/commands/sessions-resume.d.ts +5 -3
  84. package/dist/commands/sessions-resume.js +30 -8
  85. package/dist/commands/sessions-watch.d.ts +2 -0
  86. package/dist/commands/sessions-watch.js +53 -0
  87. package/dist/commands/sessions.d.ts +66 -3
  88. package/dist/commands/sessions.js +298 -47
  89. package/dist/commands/setup-browser.js +2 -2
  90. package/dist/commands/setup-mine.js +0 -1
  91. package/dist/commands/setup-preferences.js +1 -1
  92. package/dist/commands/setup.d.ts +5 -0
  93. package/dist/commands/setup.js +31 -5
  94. package/dist/commands/share.d.ts +87 -7
  95. package/dist/commands/share.js +320 -58
  96. package/dist/commands/skills.js +0 -11
  97. package/dist/commands/snapshot.js +1 -1
  98. package/dist/commands/ssh.d.ts +18 -0
  99. package/dist/commands/ssh.js +549 -210
  100. package/dist/commands/sync.d.ts +5 -0
  101. package/dist/commands/sync.js +212 -32
  102. package/dist/commands/teams.d.ts +13 -0
  103. package/dist/commands/teams.js +187 -30
  104. package/dist/commands/tickets.d.ts +2 -0
  105. package/dist/commands/tickets.js +43 -0
  106. package/dist/commands/update.js +2 -4
  107. package/dist/commands/usage.js +5 -3
  108. package/dist/commands/versions.js +11 -5
  109. package/dist/commands/view.js +15 -7
  110. package/dist/commands/webhook.d.ts +2 -2
  111. package/dist/commands/webhook.js +7 -7
  112. package/dist/index.d.ts +18 -2
  113. package/dist/index.js +53 -1264
  114. package/dist/lib/account-catalog.d.ts +18 -0
  115. package/dist/lib/account-catalog.js +38 -0
  116. package/dist/lib/account-provider-registry.d.ts +18 -0
  117. package/dist/lib/account-provider-registry.js +59 -0
  118. package/dist/lib/account-registry.d.ts +40 -0
  119. package/dist/lib/account-registry.js +239 -0
  120. package/dist/lib/account-schema.d.ts +44 -0
  121. package/dist/lib/account-schema.js +91 -0
  122. package/dist/lib/account-state-service.d.ts +21 -0
  123. package/dist/lib/account-state-service.js +60 -0
  124. package/dist/lib/activity.d.ts +1 -1
  125. package/dist/lib/activity.js +8 -1
  126. package/dist/lib/add-dir.d.ts +80 -0
  127. package/dist/lib/add-dir.js +241 -0
  128. package/dist/lib/agent-cli-commands.d.ts +11 -0
  129. package/dist/lib/agent-cli-commands.js +30 -0
  130. package/dist/lib/agents.js +44 -36
  131. package/dist/lib/answer-router.js +1 -1
  132. package/dist/lib/audit/log.d.ts +10 -27
  133. package/dist/lib/audit/log.js +20 -33
  134. package/dist/lib/auth-health.d.ts +9 -2
  135. package/dist/lib/auth-health.js +42 -9
  136. package/dist/lib/auto-pull-worker.js +7 -3
  137. package/dist/lib/auto-pull.d.ts +44 -3
  138. package/dist/lib/auto-pull.js +88 -5
  139. package/dist/lib/binary-shadow.d.ts +28 -0
  140. package/dist/lib/binary-shadow.js +121 -0
  141. package/dist/lib/brand.js +9 -3
  142. package/dist/lib/browser/hygiene.d.ts +90 -0
  143. package/dist/lib/browser/hygiene.js +146 -0
  144. package/dist/lib/browser/ipc.d.ts +30 -0
  145. package/dist/lib/browser/ipc.js +93 -4
  146. package/dist/lib/browser/profiles.d.ts +3 -2
  147. package/dist/lib/browser/profiles.js +65 -22
  148. package/dist/lib/browser/service.d.ts +79 -1
  149. package/dist/lib/browser/service.js +231 -14
  150. package/dist/lib/browser/sessions-list.d.ts +22 -2
  151. package/dist/lib/browser/sessions-list.js +54 -6
  152. package/dist/lib/browser/stream.d.ts +2 -0
  153. package/dist/lib/browser/stream.js +1 -0
  154. package/dist/lib/browser/types.d.ts +63 -1
  155. package/dist/lib/byok-usage.d.ts +9 -2
  156. package/dist/lib/byok-usage.js +133 -31
  157. package/dist/lib/cli-entry.d.ts +11 -0
  158. package/dist/lib/cli-entry.js +46 -0
  159. package/dist/lib/cloud/host.d.ts +1 -1
  160. package/dist/lib/cloud/host.js +2 -2
  161. package/dist/lib/cloud/registry.js +1 -1
  162. package/dist/lib/cloud/types.d.ts +1 -1
  163. package/dist/lib/commands.d.ts +2 -0
  164. package/dist/lib/commands.js +2 -0
  165. package/dist/lib/computer/sessions-list.d.ts +150 -0
  166. package/dist/lib/computer/sessions-list.js +363 -0
  167. package/dist/lib/config-keys.d.ts +86 -0
  168. package/dist/lib/config-keys.js +193 -0
  169. package/dist/lib/config-machine-keys.d.ts +12 -0
  170. package/dist/lib/config-machine-keys.js +17 -0
  171. package/dist/lib/config-transfer.js +3 -4
  172. package/dist/lib/crabbox/cli.d.ts +2 -2
  173. package/dist/lib/crabbox/cli.js +3 -3
  174. package/dist/lib/daemon-health.d.ts +22 -0
  175. package/dist/lib/daemon-health.js +33 -3
  176. package/dist/lib/daemon-services.d.ts +50 -0
  177. package/dist/lib/daemon-services.js +147 -0
  178. package/dist/lib/daemon-ticks.d.ts +35 -66
  179. package/dist/lib/daemon-ticks.js +77 -159
  180. package/dist/lib/daemon.d.ts +72 -4
  181. package/dist/lib/daemon.js +792 -202
  182. package/dist/lib/deeplink/register.d.ts +49 -0
  183. package/dist/lib/deeplink/register.js +253 -0
  184. package/dist/lib/deeplink/url.d.ts +34 -0
  185. package/dist/lib/deeplink/url.js +78 -0
  186. package/dist/lib/device-config.d.ts +124 -29
  187. package/dist/lib/device-config.js +346 -141
  188. package/dist/lib/devices/config-migration.d.ts +42 -0
  189. package/dist/lib/devices/config-migration.js +203 -0
  190. package/dist/lib/devices/connect.js +14 -7
  191. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  192. package/dist/lib/devices/doctor-findings.js +20 -1
  193. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  194. package/dist/lib/devices/harness-inventory.js +0 -0
  195. package/dist/lib/devices/health.d.ts +1 -1
  196. package/dist/lib/devices/health.js +1 -1
  197. package/dist/lib/devices/pending.d.ts +22 -1
  198. package/dist/lib/devices/pending.js +67 -2
  199. package/dist/lib/devices/registry.d.ts +0 -25
  200. package/dist/lib/devices/registry.js +2 -83
  201. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  202. package/dist/lib/devices/resolve-profile.js +44 -0
  203. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  204. package/dist/lib/devices/rollout-verify.js +193 -0
  205. package/dist/lib/devices/ssh-config.js +10 -6
  206. package/dist/lib/event-families.d.ts +28 -0
  207. package/dist/lib/event-families.js +159 -0
  208. package/dist/lib/event-stream.d.ts +9 -1
  209. package/dist/lib/event-stream.js +26 -9
  210. package/dist/lib/events.d.ts +9 -1
  211. package/dist/lib/events.js +21 -6
  212. package/dist/lib/exec.d.ts +30 -0
  213. package/dist/lib/exec.js +219 -121
  214. package/dist/lib/feed-broadcast.d.ts +25 -0
  215. package/dist/lib/feed-broadcast.js +33 -0
  216. package/dist/lib/feed.d.ts +1 -1
  217. package/dist/lib/feed.js +12 -2
  218. package/dist/lib/fleet/capture.js +15 -0
  219. package/dist/lib/fleet/manifest.js +9 -0
  220. package/dist/lib/fleet/types.d.ts +9 -0
  221. package/dist/lib/fleet-status.js +10 -8
  222. package/dist/lib/git.d.ts +21 -7
  223. package/dist/lib/git.js +122 -18
  224. package/dist/lib/hosts/dispatch.d.ts +8 -3
  225. package/dist/lib/hosts/dispatch.js +29 -3
  226. package/dist/lib/hosts/logs.d.ts +2 -2
  227. package/dist/lib/hosts/logs.js +2 -2
  228. package/dist/lib/hosts/option.js +1 -1
  229. package/dist/lib/hosts/passthrough.d.ts +2 -3
  230. package/dist/lib/hosts/passthrough.js +10 -24
  231. package/dist/lib/hosts/progress.js +2 -2
  232. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  233. package/dist/lib/hosts/providers/devices.js +18 -12
  234. package/dist/lib/hosts/ready.d.ts +5 -1
  235. package/dist/lib/hosts/ready.js +9 -3
  236. package/dist/lib/hosts/reconcile.d.ts +2 -2
  237. package/dist/lib/hosts/reconcile.js +2 -2
  238. package/dist/lib/hosts/registry.js +14 -9
  239. package/dist/lib/hosts/remote-cmd.js +1 -1
  240. package/dist/lib/hosts/remote-os.d.ts +9 -6
  241. package/dist/lib/hosts/remote-os.js +13 -6
  242. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  243. package/dist/lib/hosts/routing-flag.js +41 -0
  244. package/dist/lib/hosts/run-target.js +1 -1
  245. package/dist/lib/hosts/session-index.js +1 -1
  246. package/dist/lib/hosts/tasks.d.ts +6 -6
  247. package/dist/lib/hosts/tasks.js +4 -4
  248. package/dist/lib/hosts/types.js +1 -2
  249. package/dist/lib/installations/resolve.js +2 -8
  250. package/dist/lib/isolation-boundary-report.js +0 -1
  251. package/dist/lib/linear-cache.d.ts +7 -0
  252. package/dist/lib/linear-cache.js +31 -4
  253. package/dist/lib/linear-project-counts.d.ts +1 -1
  254. package/dist/lib/linear-project-counts.js +2 -3
  255. package/dist/lib/linear-projects.js +1 -1
  256. package/dist/lib/loop.d.ts +2 -2
  257. package/dist/lib/loop.js +1 -1
  258. package/dist/lib/mailbox-target.d.ts +1 -1
  259. package/dist/lib/mailbox-target.js +1 -1
  260. package/dist/lib/manifest.js +7 -4
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  262. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  263. package/dist/lib/menubar/snapshot.d.ts +3 -2
  264. package/dist/lib/menubar/snapshot.js +6 -2
  265. package/dist/lib/migrate-fold.d.ts +33 -0
  266. package/dist/lib/migrate-fold.js +130 -0
  267. package/dist/lib/migrate.d.ts +34 -34
  268. package/dist/lib/migrate.js +106 -128
  269. package/dist/lib/model-tier-overrides.d.ts +1 -1
  270. package/dist/lib/model-tier-overrides.js +15 -2
  271. package/dist/lib/monitors/config.d.ts +17 -3
  272. package/dist/lib/monitors/config.js +52 -18
  273. package/dist/lib/monitors/engine.d.ts +32 -1
  274. package/dist/lib/monitors/engine.js +94 -11
  275. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  276. package/dist/lib/monitors/fingerprint.js +100 -0
  277. package/dist/lib/monitors/remote.d.ts +47 -0
  278. package/dist/lib/monitors/remote.js +81 -0
  279. package/dist/lib/monitors/state.d.ts +39 -0
  280. package/dist/lib/monitors/state.js +56 -0
  281. package/dist/lib/onepassword.d.ts +17 -0
  282. package/dist/lib/onepassword.js +52 -22
  283. package/dist/lib/open-url.js +1 -1
  284. package/dist/lib/picker.d.ts +14 -2
  285. package/dist/lib/picker.js +35 -13
  286. package/dist/lib/placement.d.ts +1 -1
  287. package/dist/lib/placement.js +1 -1
  288. package/dist/lib/pr-land-detach.d.ts +32 -0
  289. package/dist/lib/pr-land-detach.js +79 -0
  290. package/dist/lib/profiles-presets.js +13 -0
  291. package/dist/lib/profiles.d.ts +2 -0
  292. package/dist/lib/profiles.js +44 -1
  293. package/dist/lib/project-focus.d.ts +1 -1
  294. package/dist/lib/project-focus.js +1 -1
  295. package/dist/lib/project-probe.d.ts +4 -1
  296. package/dist/lib/project-probe.js +5 -4
  297. package/dist/lib/project-resources.js +2 -18
  298. package/dist/lib/project-root.d.ts +16 -0
  299. package/dist/lib/project-root.js +20 -2
  300. package/dist/lib/projects.d.ts +20 -1
  301. package/dist/lib/projects.js +78 -1
  302. package/dist/lib/refresh-coordinator.d.ts +24 -0
  303. package/dist/lib/refresh-coordinator.js +52 -0
  304. package/dist/lib/registry.d.ts +2 -2
  305. package/dist/lib/registry.js +1 -1
  306. package/dist/lib/resource-aliases.d.ts +13 -0
  307. package/dist/lib/resource-aliases.js +26 -0
  308. package/dist/lib/resources/types.d.ts +1 -1
  309. package/dist/lib/resources.d.ts +16 -0
  310. package/dist/lib/resources.js +66 -10
  311. package/dist/lib/rotate.d.ts +3 -4
  312. package/dist/lib/rotate.js +4 -5
  313. package/dist/lib/routine-activation.d.ts +22 -2
  314. package/dist/lib/routine-activation.js +63 -16
  315. package/dist/lib/routine-context.d.ts +9 -2
  316. package/dist/lib/routine-context.js +21 -6
  317. package/dist/lib/routines-project.d.ts +58 -48
  318. package/dist/lib/routines-project.js +190 -159
  319. package/dist/lib/routines.d.ts +44 -7
  320. package/dist/lib/routines.js +92 -34
  321. package/dist/lib/run-defaults.d.ts +5 -0
  322. package/dist/lib/run-defaults.js +11 -1
  323. package/dist/lib/runner.d.ts +10 -8
  324. package/dist/lib/runner.js +122 -39
  325. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  326. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  327. package/dist/lib/secrets/agent.d.ts +10 -3
  328. package/dist/lib/secrets/agent.js +43 -8
  329. package/dist/lib/secrets/bundles.d.ts +1 -0
  330. package/dist/lib/secrets/bundles.js +92 -80
  331. package/dist/lib/secrets/index.js +32 -9
  332. package/dist/lib/secrets/install-helper.d.ts +4 -4
  333. package/dist/lib/secrets/install-helper.js +4 -4
  334. package/dist/lib/secrets/push.d.ts +40 -6
  335. package/dist/lib/secrets/push.js +58 -11
  336. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  337. package/dist/lib/secrets/read-backoff.js +1 -1
  338. package/dist/lib/secrets/remote.d.ts +24 -0
  339. package/dist/lib/secrets/remote.js +54 -4
  340. package/dist/lib/self-update.d.ts +108 -0
  341. package/dist/lib/self-update.js +276 -1
  342. package/dist/lib/session/active.d.ts +89 -5
  343. package/dist/lib/session/active.js +165 -10
  344. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  345. package/dist/lib/session/actor-sidecar.js +2 -1
  346. package/dist/lib/session/db.d.ts +176 -2
  347. package/dist/lib/session/db.js +484 -17
  348. package/dist/lib/session/discover.js +27 -4
  349. package/dist/lib/session/hook-sessions.js +2 -2
  350. package/dist/lib/session/host-link.d.ts +2 -2
  351. package/dist/lib/session/host-link.js +2 -2
  352. package/dist/lib/session/pid-registry.d.ts +21 -0
  353. package/dist/lib/session/pid-registry.js +57 -0
  354. package/dist/lib/session/remote-active.js +15 -1
  355. package/dist/lib/session/remote.js +2 -2
  356. package/dist/lib/session/session-cache.d.ts +14 -7
  357. package/dist/lib/session/session-cache.js +51 -9
  358. package/dist/lib/session/state.d.ts +2 -2
  359. package/dist/lib/session/state.js +1 -1
  360. package/dist/lib/session/sync/config.d.ts +10 -10
  361. package/dist/lib/session/sync/config.js +10 -10
  362. package/dist/lib/session/sync/r2.d.ts +34 -0
  363. package/dist/lib/session/sync/r2.js +123 -0
  364. package/dist/lib/session/throughput.d.ts +1 -1
  365. package/dist/lib/session/throughput.js +1 -1
  366. package/dist/lib/session/types.d.ts +23 -1
  367. package/dist/lib/session/types.js +15 -0
  368. package/dist/lib/session/viewing-in.d.ts +1 -1
  369. package/dist/lib/session/viewing-in.js +1 -1
  370. package/dist/lib/session/watch.d.ts +101 -0
  371. package/dist/lib/session/watch.js +242 -0
  372. package/dist/lib/share/analytics.js +1 -1
  373. package/dist/lib/share/capture.d.ts +1 -1
  374. package/dist/lib/share/capture.js +3 -3
  375. package/dist/lib/share/config.d.ts +6 -2
  376. package/dist/lib/share/config.js +6 -5
  377. package/dist/lib/share/delete.js +3 -3
  378. package/dist/lib/share/provision.d.ts +38 -0
  379. package/dist/lib/share/provision.js +51 -1
  380. package/dist/lib/share/publish.d.ts +40 -1
  381. package/dist/lib/share/publish.js +119 -6
  382. package/dist/lib/share/worker-template.d.ts +12 -1
  383. package/dist/lib/share/worker-template.js +83 -7
  384. package/dist/lib/shims.d.ts +17 -3
  385. package/dist/lib/shims.js +98 -26
  386. package/dist/lib/signin-badge.js +3 -2
  387. package/dist/lib/skills.js +2 -0
  388. package/dist/lib/smart-launch.d.ts +8 -8
  389. package/dist/lib/smart-launch.js +80 -59
  390. package/dist/lib/ssh-exec.d.ts +1 -1
  391. package/dist/lib/ssh-exec.js +1 -1
  392. package/dist/lib/staleness/prune.d.ts +88 -0
  393. package/dist/lib/staleness/prune.js +69 -0
  394. package/dist/lib/staleness/registry.d.ts +1 -1
  395. package/dist/lib/staleness/writers/commands.js +34 -2
  396. package/dist/lib/staleness/writers/hooks.js +16 -0
  397. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  398. package/dist/lib/staleness/writers/skills.js +19 -0
  399. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  400. package/dist/lib/staleness/writers/subagents.js +0 -4
  401. package/dist/lib/staleness/writers/types.d.ts +32 -0
  402. package/dist/lib/startup/command-registry.d.ts +16 -14
  403. package/dist/lib/startup/command-registry.js +26 -37
  404. package/dist/lib/startup/dev-build.d.ts +10 -0
  405. package/dist/lib/startup/dev-build.js +13 -1
  406. package/dist/lib/startup/spellcheck.d.ts +18 -0
  407. package/dist/lib/startup/spellcheck.js +45 -0
  408. package/dist/lib/state.d.ts +36 -9
  409. package/dist/lib/state.js +96 -46
  410. package/dist/lib/subagents-registry.d.ts +0 -7
  411. package/dist/lib/subagents-registry.js +38 -65
  412. package/dist/lib/subagents.d.ts +0 -33
  413. package/dist/lib/subagents.js +0 -75
  414. package/dist/lib/sync-umbrella.js +1 -1
  415. package/dist/lib/teams/agents.d.ts +41 -1
  416. package/dist/lib/teams/agents.js +187 -9
  417. package/dist/lib/teams/api.d.ts +11 -1
  418. package/dist/lib/teams/api.js +11 -2
  419. package/dist/lib/teams/delivery.d.ts +41 -0
  420. package/dist/lib/teams/delivery.js +60 -0
  421. package/dist/lib/teams/registry.d.ts +14 -0
  422. package/dist/lib/teams/registry.js +51 -1
  423. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  424. package/dist/lib/teams/remoteWorktree.js +29 -0
  425. package/dist/lib/teams/scheduler.d.ts +1 -1
  426. package/dist/lib/teams/scheduler.js +1 -1
  427. package/dist/lib/teams/worktree.d.ts +24 -0
  428. package/dist/lib/teams/worktree.js +42 -0
  429. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  430. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  431. package/dist/lib/terminal/engine.d.ts +4 -0
  432. package/dist/lib/terminal/engine.js +8 -2
  433. package/dist/lib/terminal/types.d.ts +21 -2
  434. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  435. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  436. package/dist/lib/tickets/list.d.ts +53 -0
  437. package/dist/lib/tickets/list.js +153 -0
  438. package/dist/lib/tmux/orphan-reap.d.ts +316 -0
  439. package/dist/lib/tmux/orphan-reap.js +638 -0
  440. package/dist/lib/tmux/session.d.ts +68 -3
  441. package/dist/lib/tmux/session.js +96 -5
  442. package/dist/lib/triggers/handlers.d.ts +20 -0
  443. package/dist/lib/triggers/handlers.js +16 -1
  444. package/dist/lib/triggers/webhook.js +10 -0
  445. package/dist/lib/types.d.ts +47 -35
  446. package/dist/lib/usage-fleet.d.ts +32 -0
  447. package/dist/lib/usage-fleet.js +125 -0
  448. package/dist/lib/usage-refresh.d.ts +3 -3
  449. package/dist/lib/usage-refresh.js +19 -16
  450. package/dist/lib/usage.d.ts +51 -47
  451. package/dist/lib/usage.js +145 -153
  452. package/dist/lib/version-duplicates.js +2 -2
  453. package/dist/lib/versions.d.ts +56 -13
  454. package/dist/lib/versions.js +195 -45
  455. package/dist/lib/watchdog/log.d.ts +1 -1
  456. package/dist/lib/watchdog/log.js +3 -3
  457. package/dist/lib/watchdog/rotate.d.ts +6 -6
  458. package/dist/lib/watchdog/rotate.js +6 -6
  459. package/dist/lib/workflows.d.ts +1 -1
  460. package/dist/lib/yaml-io.d.ts +47 -0
  461. package/dist/lib/yaml-io.js +55 -0
  462. package/package.json +2 -1
  463. package/scripts/install-helper.js +2 -2
  464. package/scripts/postinstall.js +23 -20
  465. package/dist/commands/defaults.d.ts +0 -7
  466. package/dist/commands/defaults.js +0 -107
  467. package/dist/commands/export.d.ts +0 -11
  468. package/dist/commands/export.js +0 -215
  469. package/dist/commands/helper.d.ts +0 -12
  470. package/dist/commands/helper.js +0 -87
  471. package/dist/commands/hosts.d.ts +0 -11
  472. package/dist/commands/hosts.js +0 -330
  473. package/dist/commands/lock.d.ts +0 -12
  474. package/dist/commands/lock.js +0 -70
  475. package/dist/commands/pull.d.ts +0 -17
  476. package/dist/commands/pull.js +0 -39
  477. package/dist/commands/push.d.ts +0 -14
  478. package/dist/commands/push.js +0 -30
  479. package/dist/commands/set.d.ts +0 -15
  480. package/dist/commands/set.js +0 -79
  481. package/dist/commands/setup-share.d.ts +0 -17
  482. package/dist/commands/setup-share.js +0 -85
  483. package/dist/commands/wallet.d.ts +0 -20
  484. package/dist/commands/wallet.js +0 -216
  485. package/dist/commands/worktree.d.ts +0 -19
  486. package/dist/commands/worktree.js +0 -272
  487. package/dist/lib/account-labels.d.ts +0 -24
  488. package/dist/lib/account-labels.js +0 -72
  489. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  490. package/dist/lib/auto-dispatch-linear.js +0 -107
  491. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  492. package/dist/lib/auto-dispatch-provider.js +0 -30
  493. package/dist/lib/auto-dispatch.d.ts +0 -93
  494. package/dist/lib/auto-dispatch.js +0 -128
  495. package/dist/lib/export.d.ts +0 -72
  496. package/dist/lib/export.js +0 -269
  497. package/dist/lib/lock.d.ts +0 -93
  498. package/dist/lib/lock.js +0 -207
  499. package/dist/lib/wallet/index.d.ts +0 -78
  500. package/dist/lib/wallet/index.js +0 -253
@@ -22,7 +22,7 @@
22
22
  import { sshExec } from '../ssh-exec.js';
23
23
  import { remoteShellFor, buildWindowsStdinImportCommand } from '../hosts/remote-cmd.js';
24
24
  import { resolveRemoteOsSync } from '../hosts/remote-os.js';
25
- import { remoteSecretsRaw, verifyRemoteKeychainPush, keychainWriteFailureMessage, buildRemoteFileImportCommand, } from './remote.js';
25
+ import { remoteSecretsRaw, verifyRemoteKeychainPush, keychainWriteFailureMessage, buildRemoteFileImportCommand, credentialTransportSshOpts, } from './remote.js';
26
26
  import { readAndResolveBundleEnv } from './bundles.js';
27
27
  /**
28
28
  * Serialize a resolved env map to `.env` lines that round-trip losslessly through
@@ -42,15 +42,35 @@ export function bundleEnvToDotenv(env) {
42
42
  }
43
43
  return lines.join('\n') + '\n';
44
44
  }
45
+ /** Preserve the literal-vs-secret schema that dotenv transport cannot encode. */
46
+ export function planLiteralRestoration(bundle, literalValues = {}) {
47
+ return Object.entries(literalValues).map(([key, value]) => ({
48
+ key,
49
+ removeArgs: ['remove', bundle, key, '--yes'],
50
+ addArgs: ['add', bundle, key, '--value', value],
51
+ }));
52
+ }
45
53
  /**
46
54
  * Read and resolve a bundle once, for pushing to one or more hosts.
47
55
  *
48
- * `agentOnly` + `keyMode: 'storage'` match what `export --host` has always
49
- * passed: storage-shaped values, and the headless guard that fails fast rather
50
- * than popping Touch ID inside an automated run.
56
+ * `keyMode: 'storage'` is fixed a push always sends storage-shaped values.
57
+ *
58
+ * `agentOnly` is the caller's to decide, and it is NOT a security level: it
59
+ * selects the broker-only read (fail fast with the `agents secrets unlock` hint)
60
+ * over the interactive read (macOS may raise a Touch ID sheet). The headless
61
+ * guard exists because an AGENT LAUNCH must never enumerate the keychain — a
62
+ * per-bundle prefix becomes a broad `agents-cli.` scan after service-name
63
+ * hashing, and macOS evaluates unrelated biometry ACLs during it, one sheet per
64
+ * installed version (bundles.ts, RUSH-2440). A human at a TTY is not that case:
65
+ * they can answer one prompt, and the interactive sibling reads (`view --reveal`,
66
+ * `exec`) already let them. NOT `get` — it is unconditionally `agentOnly` on
67
+ * purpose, because prompting would hang a `$(agents secrets get …)` capture
68
+ * mid-pipeline (SEC-13b). It defaults to `true` so an automated caller that says
69
+ * nothing stays broker-only.
51
70
  */
52
- export function resolveBundleForPush(bundle, caller) {
53
- const { env } = readAndResolveBundleEnv(bundle, { caller, keyMode: 'storage', agentOnly: true });
71
+ export function resolveBundleForPush(bundle, caller, opts = {}) {
72
+ const agentOnly = opts.agentOnly ?? true;
73
+ const { env } = readAndResolveBundleEnv(bundle, { caller, keyMode: 'storage', agentOnly });
54
74
  return { env, dotenv: bundleEnvToDotenv(env), keyCount: Object.keys(env).length };
55
75
  }
56
76
  function isPowershellTarget(host) {
@@ -70,7 +90,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
70
90
  passphrase: opts.passphrase ?? '',
71
91
  force: opts.force,
72
92
  });
73
- return { kind: 'ssh', remoteCmd, input };
93
+ return { kind: 'ssh', remoteCmd, input, multiplex: false };
74
94
  }
75
95
  if (powershell) {
76
96
  // Keychain on a Windows target: the `agents.ps1` shim doesn't forward
@@ -82,6 +102,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
82
102
  kind: 'ssh',
83
103
  remoteCmd: buildWindowsStdinImportCommand(bundle, { force: opts.force }),
84
104
  input: resolved.dotenv,
105
+ multiplex: false,
85
106
  };
86
107
  }
87
108
  // Keychain on a POSIX target: OS-aware wrapping + the hardened ssh engine
@@ -91,6 +112,7 @@ export function planPushTransport(resolved, bundle, host, opts) {
91
112
  kind: 'remote-secrets',
92
113
  args: ['import', bundle, '--from', '-', ...(opts.force ? ['--force'] : [])],
93
114
  input: resolved.dotenv,
115
+ multiplex: false,
94
116
  };
95
117
  }
96
118
  /**
@@ -105,9 +127,15 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
105
127
  const plan = planPushTransport(resolved, bundle, host, opts);
106
128
  if (plan.kind === 'refuse')
107
129
  return fail(plan.message);
130
+ // Every ssh below rides the credential-transport posture: the managed host key
131
+ // is pinned (a changed key is refused) and the connection never reuses or
132
+ // leaves a persistent authenticated control master to the destination
133
+ // (RUSH-2527, `credentialTransportSshOpts`). The plan's `multiplex: false` is
134
+ // the raw-`ssh` branch's half of that; the `remote-secrets` branch and the
135
+ // read-back/policy/literal follow-ups pass `secret: true` for the same posture.
108
136
  const res = plan.kind === 'ssh'
109
- ? sshExec(host, plan.remoteCmd, { input: plan.input })
110
- : remoteSecretsRaw(host, plan.args, { input: plan.input, osLookupName: host });
137
+ ? sshExec(host, plan.remoteCmd, { input: plan.input, hostKeyOpts: credentialTransportSshOpts(host).hostKeyOpts, multiplex: plan.multiplex })
138
+ : remoteSecretsRaw(host, plan.args, { input: plan.input, osLookupName: host, secret: true });
111
139
  if (res.code === null) {
112
140
  return fail(res.stderr.trim() || (res.timedOut ? 'ssh timed out' : 'ssh failed'));
113
141
  }
@@ -123,13 +151,32 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
123
151
  // metadata-only bundle that breaks later with "stored item not found". The
124
152
  // file backend is headless-readable by construction, so it is skipped.
125
153
  if (opts.remoteBackend === 'keychain') {
126
- const verdict = verifyRemoteKeychainPush(host, bundle, Object.keys(resolved.env), { osLookupName: host });
154
+ const verdict = verifyRemoteKeychainPush(host, bundle, Object.keys(resolved.env), { osLookupName: host, secret: true });
127
155
  if (!verdict.ok) {
128
156
  return fail(verdict.kind === 'locked-keychain'
129
157
  ? keychainWriteFailureMessage(host, bundle, verdict.reason)
130
158
  : `pushed '${bundle}' but could not verify it on the remote: ${verdict.reason}`);
131
159
  }
132
160
  }
161
+ if (opts.policyNever) {
162
+ const policy = remoteSecretsRaw(host, ['policy', bundle, 'never', '--i-understand'], { osLookupName: host, secret: true });
163
+ if (policy.code !== 0) {
164
+ const msg = (policy.stderr || policy.stdout || '').trim();
165
+ return fail(`pushed '${bundle}' but could not set remote policy never${msg ? `: ${msg}` : ''}`);
166
+ }
167
+ }
168
+ for (const step of planLiteralRestoration(bundle, opts.literalValues)) {
169
+ const removed = remoteSecretsRaw(host, step.removeArgs, { osLookupName: host, secret: true });
170
+ if (removed.code !== 0) {
171
+ const msg = (removed.stderr || removed.stdout || '').trim();
172
+ return fail(`pushed '${bundle}' but could not replace transported ${step.key}${msg ? `: ${msg}` : ''}`);
173
+ }
174
+ const literal = remoteSecretsRaw(host, step.addArgs, { osLookupName: host, secret: true });
175
+ if (literal.code !== 0) {
176
+ const msg = (literal.stderr || literal.stdout || '').trim();
177
+ return fail(`pushed '${bundle}' but could not preserve literal ${step.key}${msg ? `: ${msg}` : ''}`);
178
+ }
179
+ }
133
180
  const remoteMsg = (res.stdout || '').trim().split('\n').map((l) => l.trim()).filter(Boolean).pop();
134
181
  return {
135
182
  ok: true,
@@ -141,5 +188,5 @@ export function pushResolvedBundleToHost(resolved, bundle, host, opts) {
141
188
  }
142
189
  /** Resolve and push in one call — for a single host. */
143
190
  export function pushBundleToHost(bundle, host, opts) {
144
- return pushResolvedBundleToHost(resolveBundleForPush(bundle, opts.operation), bundle, host, opts);
191
+ return pushResolvedBundleToHost(resolveBundleForPush(bundle, opts.operation, { agentOnly: opts.agentOnly }), bundle, host, opts);
145
192
  }
@@ -2,7 +2,7 @@
2
2
  * Negative memo for failed/cancelled macOS keychain reads (the "back-off").
3
3
  *
4
4
  * A cancelled Touch ID sheet is the user saying "not now" — but a polling
5
- * caller (the Factory extension host's `agents view` loop, a watch script)
5
+ * caller (AGI EXT host's `agents view` loop, a watch script)
6
6
  * retries the same read a few seconds later and pops the sheet again, forever.
7
7
  * The headless guard (index.ts `assertRawKeychainReadAllowed`) covers the
8
8
  * no-TTY case; this memo covers a context that CAN prompt but just had its
@@ -2,7 +2,7 @@
2
2
  * Negative memo for failed/cancelled macOS keychain reads (the "back-off").
3
3
  *
4
4
  * A cancelled Touch ID sheet is the user saying "not now" — but a polling
5
- * caller (the Factory extension host's `agents view` loop, a watch script)
5
+ * caller (AGI EXT host's `agents view` loop, a watch script)
6
6
  * retries the same read a few seconds later and pops the sheet again, forever.
7
7
  * The headless guard (index.ts `assertRawKeychainReadAllowed`) covers the
8
8
  * no-TTY case; this memo covers a context that CAN prompt but just had its
@@ -16,6 +16,28 @@
16
16
  * in argv / `ps` / remote shell history. Nothing is persisted locally.
17
17
  */
18
18
  import { type SshExecResult } from '../ssh-exec.js';
19
+ /**
20
+ * SSH options for a SECRET-carrying transport (RUSH-2527). Every `agents secrets
21
+ * --host` operation moves credential bytes — over ssh stdin (push) or ssh stdout
22
+ * (resolve/read-back) — so it MUST NOT ride the shared `accept-new` baseline
23
+ * against the user's own `~/.ssh/known_hosts` with a reusable control socket.
24
+ * Two hardenings over that baseline, matching the posture the `--copy-creds`
25
+ * dispatch already uses (`hosts/dispatch.ts` -> `hostKeyCheckingOpts`):
26
+ *
27
+ * - **Managed pinned host keys.** Verify against the CLI-owned known_hosts
28
+ * store (`known-hosts.ts`), not `~/.ssh/known_hosts`. A CHANGED key on a
29
+ * known host is refused (`StrictHostKeyChecking` `yes` once pinned,
30
+ * `accept-new` — which still refuses a changed key, only learns a genuinely
31
+ * new one — before that). So a machine-in-the-middle swapping a pinned host's
32
+ * key can never receive or return a secret.
33
+ * - **No multiplex reuse.** `multiplex: false` — a credential channel never
34
+ * leaves a persistent `ControlMaster` socket lingering (60s `ControlPersist`)
35
+ * that any other `agents` invocation to that host would silently reuse.
36
+ */
37
+ export declare function credentialTransportSshOpts(target: string): {
38
+ hostKeyOpts: string[];
39
+ multiplex: false;
40
+ };
19
41
  /**
20
42
  * Trust boundary for a remote-resolved env map. A peer's `secrets export` output
21
43
  * is untrusted input: a compromised or misconfigured host could return keys that
@@ -76,6 +98,7 @@ export declare function remoteSecretsRaw(target: string, args: string[], opts?:
76
98
  tty?: boolean;
77
99
  input?: string;
78
100
  osLookupName?: string;
101
+ secret?: boolean;
79
102
  }): SshExecResult;
80
103
  /**
81
104
  * Run a remote `agents secrets <args>` FOREGROUND, with the local stdio wired
@@ -176,6 +199,7 @@ export declare function keychainWriteFailureMessage(host: string, bundle: string
176
199
  */
177
200
  export declare function verifyRemoteKeychainPush(target: string, bundle: string, pushedKeys: string[], opts?: {
178
201
  osLookupName?: string;
202
+ secret?: boolean;
179
203
  }): RemoteKeychainWriteVerification;
180
204
  /**
181
205
  * The `bash -lc` command + stdin payload that drives a **file-backed** remote
@@ -22,7 +22,33 @@ import { sshTargetFor } from '../hosts/types.js';
22
22
  import { buildRemoteAgentsInvocation } from '../hosts/remote-cmd.js';
23
23
  import { resolveRemoteOsSync } from '../hosts/remote-os.js';
24
24
  import { isLoaderOrInterpreterEnv } from './bundles.js';
25
+ import { isHostPinned, hostKeyCheckingOpts } from '../devices/known-hosts.js';
25
26
  const REMOTE_TIMEOUT_MS = 30_000;
27
+ /** The host part of an ssh target (`user@host` -> `host`) for known_hosts matching. */
28
+ function hostKeyLookupName(target) {
29
+ return target.split('@').pop() ?? target;
30
+ }
31
+ /**
32
+ * SSH options for a SECRET-carrying transport (RUSH-2527). Every `agents secrets
33
+ * --host` operation moves credential bytes — over ssh stdin (push) or ssh stdout
34
+ * (resolve/read-back) — so it MUST NOT ride the shared `accept-new` baseline
35
+ * against the user's own `~/.ssh/known_hosts` with a reusable control socket.
36
+ * Two hardenings over that baseline, matching the posture the `--copy-creds`
37
+ * dispatch already uses (`hosts/dispatch.ts` -> `hostKeyCheckingOpts`):
38
+ *
39
+ * - **Managed pinned host keys.** Verify against the CLI-owned known_hosts
40
+ * store (`known-hosts.ts`), not `~/.ssh/known_hosts`. A CHANGED key on a
41
+ * known host is refused (`StrictHostKeyChecking` `yes` once pinned,
42
+ * `accept-new` — which still refuses a changed key, only learns a genuinely
43
+ * new one — before that). So a machine-in-the-middle swapping a pinned host's
44
+ * key can never receive or return a secret.
45
+ * - **No multiplex reuse.** `multiplex: false` — a credential channel never
46
+ * leaves a persistent `ControlMaster` socket lingering (60s `ControlPersist`)
47
+ * that any other `agents` invocation to that host would silently reuse.
48
+ */
49
+ export function credentialTransportSshOpts(target) {
50
+ return { hostKeyOpts: hostKeyCheckingOpts(isHostPinned(hostKeyLookupName(target))), multiplex: false };
51
+ }
26
52
  /**
27
53
  * Trust boundary for a remote-resolved env map. A peer's `secrets export` output
28
54
  * is untrusted input: a compromised or misconfigured host could return keys that
@@ -128,11 +154,21 @@ export function splitBundleRef(ref) {
128
154
  */
129
155
  export function remoteSecretsRaw(target, args, opts = {}) {
130
156
  const remoteCmd = buildRemoteAgentsInvocation(['secrets', ...args], undefined, osForTarget(target, opts.osLookupName));
157
+ // A secret-bearing call (`secret: true`) pins the managed host key and refuses
158
+ // to multiplex — see `credentialTransportSshOpts` (RUSH-2527). A `-tt` session
159
+ // (a remote reveal/passphrase prompt) additionally allocates a PTY and never
160
+ // multiplexes, and it COMPOSES with the secret posture: a `view --reveal` over
161
+ // `--host` both prompts AND streams the plaintext value back over ssh stdout,
162
+ // so it needs the managed host-key pin too — `tty` must not short-circuit past
163
+ // `secret`. A plain browse `list` passes neither and keeps the shared baseline.
164
+ const posture = opts.secret ? credentialTransportSshOpts(target) : {};
165
+ const conn = opts.tty
166
+ ? { ...posture, extraSshArgs: ['-tt'], multiplex: false }
167
+ : posture;
131
168
  return sshExec(target, remoteCmd, {
132
169
  timeoutMs: REMOTE_TIMEOUT_MS,
133
170
  input: opts.input,
134
- extraSshArgs: opts.tty ? ['-tt'] : undefined,
135
- multiplex: opts.tty ? false : undefined,
171
+ ...conn,
136
172
  });
137
173
  }
138
174
  /**
@@ -150,7 +186,10 @@ export function remoteSecretsRaw(target, args, opts = {}) {
150
186
  */
151
187
  export function remoteSecretsStream(target, args, opts = {}) {
152
188
  const remoteCmd = buildRemoteAgentsInvocation(['secrets', ...args], undefined, osForTarget(target, opts.osLookupName));
153
- return sshStream(target, remoteCmd, { tty: true });
189
+ // `unlock --host` carries the remote bundle's passphrase to the destination over
190
+ // this interactive channel, so it is secret-bearing: pin the managed host key
191
+ // (a changed key is refused) and never multiplex (RUSH-2527).
192
+ return sshStream(target, remoteCmd, { tty: true, ...credentialTransportSshOpts(target) });
154
193
  }
155
194
  /**
156
195
  * Resolve a remote bundle to a plaintext env map by driving the remote's
@@ -168,8 +207,12 @@ export function remoteSecretsStream(target, args, opts = {}) {
168
207
  export async function remoteResolveEnv(target, bundle, opts = {}) {
169
208
  assertValidSshTarget(target);
170
209
  const remoteCmd = buildRemoteAgentsInvocation(['secrets', 'export', bundle, '--plaintext', '--format', 'json'], undefined, osForTarget(target, opts.osLookupName));
210
+ // Resolving a remote bundle streams its plaintext values back over ssh stdout,
211
+ // so this read is secret-bearing: pin the managed host key and never leave a
212
+ // reusable control master to the source (RUSH-2527, `credentialTransportSshOpts`).
171
213
  const res = sshExec(target, remoteCmd, {
172
214
  timeoutMs: REMOTE_TIMEOUT_MS,
215
+ ...credentialTransportSshOpts(target),
173
216
  });
174
217
  if (res.code !== 0) {
175
218
  const msg = (res.stderr || res.stdout || '').trim();
@@ -317,7 +360,14 @@ export function keychainWriteFailureMessage(host, bundle, reason) {
317
360
  */
318
361
  export function verifyRemoteKeychainPush(target, bundle, pushedKeys, opts = {}) {
319
362
  const remoteCmd = buildRemoteAgentsInvocation(['secrets', 'export', bundle, '--plaintext', '--format', 'json'], undefined, osForTarget(target, opts.osLookupName));
320
- const res = sshExec(target, remoteCmd, { timeoutMs: REMOTE_TIMEOUT_MS });
363
+ // This read-back streams the just-pushed plaintext over ssh stdout, so it is
364
+ // as secret-bearing as the push itself — the push path passes `secret: true`
365
+ // so it too pins the managed host key and leaves no reusable control master to
366
+ // the destination (RUSH-2527).
367
+ const res = sshExec(target, remoteCmd, {
368
+ timeoutMs: REMOTE_TIMEOUT_MS,
369
+ ...(opts.secret ? credentialTransportSshOpts(target) : {}),
370
+ });
321
371
  if (res.code !== 0) {
322
372
  const why = res.timedOut ? 'timed out' : res.code === null ? 'ssh failed' : `exit ${res.code}`;
323
373
  const stderr = `${why}${(res.stderr || res.stdout || '').trim() ? `: ${(res.stderr || res.stdout).trim()}` : ''}`;
@@ -12,6 +12,14 @@
12
12
  * to PATH resolution.
13
13
  */
14
14
  export declare const NPM_PACKAGE_NAME = "@phnx-labs/agents-cli";
15
+ /**
16
+ * First published release that stopped the usage/auth-health probe from reading
17
+ * Claude Code's interactive login (commit 3f3554c51). Pre-this versions on a
18
+ * macOS box re-introduce the Touch ID storm + fleet-wide revocation class
19
+ * (RUSH-2415 / RUSH-1822). Anything older is a latent regression while a fixed
20
+ * copy sits next to it.
21
+ */
22
+ export declare const TOUCH_ID_STORM_FIXED_SINCE = "1.22.30";
15
23
  export type PackageManager = 'npm' | 'bun';
16
24
  /**
17
25
  * The directory bun installs global packages into:
@@ -55,6 +63,44 @@ export declare function saveUpdateCheck(file: string, latestVersion: string): vo
55
63
  export declare function dismissUpdateVersion(file: string, version: string): void;
56
64
  /** Whether the cached state warrants an upgrade prompt for a copy running `currentVersion`. */
57
65
  export declare function shouldPromptUpgrade(cache: UpdateCheckCache | null, currentVersion: string): boolean;
66
+ /**
67
+ * Short TTL for the multi-install PATH scan cache (RUSH-2324). The full
68
+ * `findAgentsCliInstalls` walk over PATH + known roots costs ~1ms on a warm
69
+ * box and runs on every ordinary CLI invocation via `maybeWarnMultiInstall`.
70
+ * Same 5-minute window as the detached-sync spawn gate so both bootstrap
71
+ * savings share one recency policy.
72
+ */
73
+ export declare const MULTI_INSTALL_SCAN_TTL_MS: number;
74
+ /** On-disk shape for the multi-install scan cache (beside `.update-check`). */
75
+ export interface MultiInstallScanCache {
76
+ scannedAt: number;
77
+ /** Full PATH string at scan time — any change invalidates the cache. */
78
+ pathEnv: string;
79
+ runningRoot: string;
80
+ runningVersion: string;
81
+ inventory: MultiInstallInventoryEntry[];
82
+ }
83
+ /** Read a multi-install scan cache. Returns null if missing or corrupt. */
84
+ export declare function readMultiInstallScanCache(file: string): MultiInstallScanCache | null;
85
+ /** Persist a multi-install scan result. Best-effort. */
86
+ export declare function writeMultiInstallScanCache(file: string, cache: MultiInstallScanCache): void;
87
+ /**
88
+ * Whether a multi-install scan cache is still usable for this invocation.
89
+ * Invalid when missing, past TTL, PATH changed, or the running copy identity
90
+ * (root / version) changed — those are exactly the cases where a re-scan can
91
+ * surface a different inventory and re-fire the warning.
92
+ */
93
+ export declare function isMultiInstallScanFresh(cache: MultiInstallScanCache | null, pathEnv: string, runningRoot: string, runningVersion: string, now?: number, ttlMs?: number): boolean;
94
+ /**
95
+ * Resolve the multi-install inventory, hitting the on-disk scan cache when
96
+ * fresh. Callers that only need the inventory (the bootstrap multi-install
97
+ * warning) avoid the ~1ms PATH walk on the warm path (RUSH-2324).
98
+ */
99
+ export declare function resolveMultiInstallInventory(runningRoot: string, runningVersion: string, pathEnv: string, cacheFile: string, opts?: {
100
+ now?: number;
101
+ ttlMs?: number;
102
+ findOpts?: FindAgentsCliInstallsOptions;
103
+ }): MultiInstallInventoryEntry[];
58
104
  /**
59
105
  * The on-disk package root of the copy that is currently running.
60
106
  *
@@ -156,6 +202,68 @@ export interface MultiInstallInventoryEntry {
156
202
  note: string;
157
203
  }
158
204
  export declare function buildMultiInstallInventory(runningRoot: string, runningVersion: string, installs: AgentsCliInstall[]): MultiInstallInventoryEntry[];
205
+ /** Why a discovered install is safe to delete without an interactive confirm. */
206
+ export type RemovableInstallReason = 'npx-cache' | 'unsafe-legacy-helper' | 'pre-fixed-version';
207
+ export interface RemovableAgentsCliInstall {
208
+ packageRoot: string;
209
+ version: string;
210
+ reasons: RemovableInstallReason[];
211
+ }
212
+ export interface PurgeRemovableInstallsResult {
213
+ removed: RemovableAgentsCliInstall[];
214
+ failed: Array<RemovableAgentsCliInstall & {
215
+ error: string;
216
+ }>;
217
+ skippedRunning: number;
218
+ }
219
+ /** True when the package root lives under npm's `_npx` cache (ephemeral runs). */
220
+ export declare function isNpxCacheInstall(packageRoot: string): boolean;
221
+ /**
222
+ * A release string that is at least TOUCH_ID_STORM_FIXED_SINCE, or a side-by-side
223
+ * dev build (`0.0.0-dev.*`) which tracks main and therefore carries the fix.
224
+ * Non-semver junk never qualifies as "fixed" — better to leave a weird copy
225
+ * alone than delete the only working install.
226
+ */
227
+ export declare function isTouchIdStormFixedVersion(version: string): boolean;
228
+ /**
229
+ * Classify discovered installs that doctor --fix / upgrade may delete.
230
+ *
231
+ * Never marks the running package root. Auto-purge is limited to copies that
232
+ * cannot be the intended primary install:
233
+ * - npx-cache trees (ephemeral)
234
+ * - pre-atomic-helper-installer trees ("unsafe legacy helper installer")
235
+ * - pre-TOUCH_ID_STORM_FIXED_SINCE trees, but only when at least one fixed
236
+ * copy already exists on the box (so we never strand the machine)
237
+ *
238
+ * A pre-fixed copy that is also the only install stays — the user must upgrade
239
+ * it in place rather than delete it.
240
+ */
241
+ export declare function classifyRemovableAgentsCliInstalls(runningRoot: string, installs: AgentsCliInstall[], opts?: {
242
+ fixedSince?: string;
243
+ }): RemovableAgentsCliInstall[];
244
+ /**
245
+ * Delete classified removable package roots from disk. Re-reads package.json
246
+ * immediately before the unlink so a path that is no longer @phnx-labs/agents-cli
247
+ * is never removed. Best-effort: one failure does not stop the rest.
248
+ */
249
+ export declare function purgeRemovableAgentsCliInstalls(candidates: RemovableAgentsCliInstall[], opts?: {
250
+ dryRun?: boolean;
251
+ runningRoot?: string;
252
+ }): PurgeRemovableInstallsResult;
253
+ /**
254
+ * Scan + classify + purge in one call. Used by `agents doctor --fix` and
255
+ * `agents upgrade` so both paths remediate the same set of latent copies.
256
+ */
257
+ export declare function remediateStaleAgentsCliInstalls(opts: {
258
+ runningRoot: string;
259
+ runningVersion?: string;
260
+ pathEnv?: string;
261
+ findOpts?: FindAgentsCliInstallsOptions;
262
+ dryRun?: boolean;
263
+ }): PurgeRemovableInstallsResult & {
264
+ inventory: MultiInstallInventoryEntry[];
265
+ candidates: RemovableAgentsCliInstall[];
266
+ };
159
267
  /**
160
268
  * Resolve every `agents` entrypoint on PATH, then inspect the bounded global
161
269
  * install layouts used by NVM, fnm, Volta, Bun, npm, and npx. More than one