@phnx-labs/agents-cli 1.22.39 → 1.22.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (554) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +111 -70
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +45 -26
  5. package/dist/browser.js +2 -2
  6. package/dist/cli/command-registry.d.ts +135 -0
  7. package/dist/cli/command-registry.js +260 -0
  8. package/dist/commands/accounts.d.ts +20 -0
  9. package/dist/commands/accounts.js +186 -25
  10. package/dist/commands/apply.d.ts +3 -3
  11. package/dist/commands/apply.js +20 -63
  12. package/dist/commands/browser.js +206 -94
  13. package/dist/commands/budget.d.ts +7 -6
  14. package/dist/commands/budget.js +8 -7
  15. package/dist/commands/cloud.js +17 -20
  16. package/dist/commands/commands.js +1 -1
  17. package/dist/commands/computer-actions.d.ts +1 -35
  18. package/dist/commands/computer-actions.js +13 -181
  19. package/dist/commands/computer.d.ts +28 -3
  20. package/dist/commands/computer.js +93 -65
  21. package/dist/commands/config.js +16 -3
  22. package/dist/commands/cost.d.ts +2 -1
  23. package/dist/commands/cost.js +7 -6
  24. package/dist/commands/daemon.js +151 -4
  25. package/dist/commands/detach.js +1 -1
  26. package/dist/commands/doctor.js +19 -11
  27. package/dist/commands/events.js +1 -1
  28. package/dist/commands/exec.d.ts +2 -50
  29. package/dist/commands/exec.js +160 -215
  30. package/dist/commands/factory.js +1 -1
  31. package/dist/commands/feed.d.ts +2 -2
  32. package/dist/commands/feed.js +9 -12
  33. package/dist/commands/fleet-capture.js +25 -27
  34. package/dist/commands/focus.d.ts +2 -3
  35. package/dist/commands/focus.js +34 -9
  36. package/dist/commands/go.js +15 -5
  37. package/dist/commands/harness.d.ts +3 -3
  38. package/dist/commands/harness.js +53 -5
  39. package/dist/commands/hooks.js +1 -1
  40. package/dist/commands/import.js +2 -2
  41. package/dist/commands/insights.d.ts +5 -5
  42. package/dist/commands/insights.js +15 -9
  43. package/dist/commands/inspect.d.ts +2 -3
  44. package/dist/commands/inspect.js +4 -16
  45. package/dist/commands/logs.d.ts +2 -2
  46. package/dist/commands/logs.js +9 -9
  47. package/dist/commands/mcp.js +2 -2
  48. package/dist/commands/memory.js +1 -1
  49. package/dist/commands/message.d.ts +1 -1
  50. package/dist/commands/message.js +7 -7
  51. package/dist/commands/mine.d.ts +11 -8
  52. package/dist/commands/mine.js +11 -10
  53. package/dist/commands/models.js +1 -1
  54. package/dist/commands/modes.js +1 -1
  55. package/dist/commands/monitors.js +23 -6
  56. package/dist/commands/output.d.ts +7 -6
  57. package/dist/commands/output.js +11 -10
  58. package/dist/commands/packages.js +4 -4
  59. package/dist/commands/perf.js +1 -1
  60. package/dist/commands/permissions.js +49 -32
  61. package/dist/commands/plugins.d.ts +1 -1
  62. package/dist/commands/plugins.js +3 -3
  63. package/dist/commands/profiles.d.ts +6 -9
  64. package/dist/commands/profiles.js +8 -321
  65. package/dist/commands/projects.d.ts +9 -0
  66. package/dist/commands/projects.js +140 -8
  67. package/dist/commands/prune.js +5 -13
  68. package/dist/commands/refresh-rules.js +1 -1
  69. package/dist/commands/repo.d.ts +5 -7
  70. package/dist/commands/repo.js +34 -18
  71. package/dist/commands/resource-view.js +4 -0
  72. package/dist/commands/resume.d.ts +11 -7
  73. package/dist/commands/resume.js +82 -98
  74. package/dist/commands/route.d.ts +12 -0
  75. package/dist/commands/route.js +261 -0
  76. package/dist/commands/routines.d.ts +2 -3
  77. package/dist/commands/routines.js +120 -145
  78. package/dist/commands/rules.js +1 -1
  79. package/dist/commands/run-account-picker.d.ts +1 -1
  80. package/dist/commands/run-account-picker.js +2 -2
  81. package/dist/commands/run-broadcast.d.ts +21 -0
  82. package/dist/commands/run-broadcast.js +89 -0
  83. package/dist/commands/run-cloud.js +1 -1
  84. package/dist/commands/secrets-vault.d.ts +10 -0
  85. package/dist/commands/{login.js → secrets-vault.js} +34 -14
  86. package/dist/commands/secrets.d.ts +4 -4
  87. package/dist/commands/secrets.js +72 -63
  88. package/dist/commands/sessions-backfill.js +1 -1
  89. package/dist/commands/sessions-browser.d.ts +1 -1
  90. package/dist/commands/sessions-browser.js +9 -5
  91. package/dist/commands/sessions-export.js +2 -2
  92. package/dist/commands/sessions-inject.js +4 -5
  93. package/dist/commands/sessions-migrate.js +16 -27
  94. package/dist/commands/sessions-picker.d.ts +13 -0
  95. package/dist/commands/sessions-picker.js +182 -8
  96. package/dist/commands/sessions-resume.d.ts +7 -3
  97. package/dist/commands/sessions-resume.js +81 -33
  98. package/dist/commands/sessions-stats.js +2 -2
  99. package/dist/commands/sessions.d.ts +75 -68
  100. package/dist/commands/sessions.js +142 -180
  101. package/dist/commands/setup-computer.js +1 -1
  102. package/dist/commands/setup-fleet.js +3 -0
  103. package/dist/commands/setup-mine.d.ts +7 -3
  104. package/dist/commands/setup-mine.js +13 -8
  105. package/dist/commands/setup-secrets.js +2 -2
  106. package/dist/commands/setup-watchdog.js +2 -2
  107. package/dist/commands/setup.js +7 -2
  108. package/dist/commands/share.d.ts +65 -0
  109. package/dist/commands/share.js +253 -20
  110. package/dist/commands/skills.js +3 -3
  111. package/dist/commands/snapshot.d.ts +2 -2
  112. package/dist/commands/snapshot.js +9 -9
  113. package/dist/commands/ssh.d.ts +1 -1
  114. package/dist/commands/ssh.js +186 -64
  115. package/dist/commands/subagents.js +1 -1
  116. package/dist/commands/sync.js +24 -9
  117. package/dist/commands/teams.d.ts +2 -2
  118. package/dist/commands/teams.js +9 -18
  119. package/dist/commands/tmux.js +5 -1
  120. package/dist/commands/trash.js +1 -1
  121. package/dist/commands/usage.d.ts +1 -1
  122. package/dist/commands/usage.js +2 -2
  123. package/dist/commands/utils.d.ts +4 -14
  124. package/dist/commands/utils.js +6 -27
  125. package/dist/commands/versions.js +2 -2
  126. package/dist/commands/view.d.ts +9 -77
  127. package/dist/commands/view.js +23 -8
  128. package/dist/commands/watchdog.js +1 -1
  129. package/dist/commands/webhook.js +11 -25
  130. package/dist/commands/workflows.js +1 -1
  131. package/dist/index.js +1 -1
  132. package/dist/lib/account-capabilities.d.ts +39 -0
  133. package/dist/lib/account-capabilities.js +59 -0
  134. package/dist/lib/account-catalog.js +1 -1
  135. package/dist/lib/account-registry.d.ts +66 -0
  136. package/dist/lib/account-registry.js +151 -5
  137. package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
  138. package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
  139. package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
  140. package/dist/lib/{usage.js → accounting/usage.js} +11 -11
  141. package/dist/lib/agent-spec/provider.js +1 -1
  142. package/dist/lib/agents.d.ts +72 -4
  143. package/dist/lib/agents.js +231 -199
  144. package/dist/lib/answer-router.d.ts +2 -2
  145. package/dist/lib/ask-classifier.d.ts +1 -1
  146. package/dist/lib/ask-classifier.js +1 -1
  147. package/dist/lib/audit/log.js +1 -1
  148. package/dist/lib/auth-health.d.ts +1 -1
  149. package/dist/lib/auth-health.js +2 -2
  150. package/dist/lib/brand.js +1 -1
  151. package/dist/lib/browser/caller-identity.d.ts +28 -0
  152. package/dist/lib/browser/caller-identity.js +156 -0
  153. package/dist/lib/browser/cdp.js +1 -1
  154. package/dist/lib/browser/drivers/ssh.d.ts +1 -1
  155. package/dist/lib/browser/drivers/ssh.js +2 -2
  156. package/dist/lib/browser/hygiene.d.ts +10 -2
  157. package/dist/lib/browser/hygiene.js +7 -4
  158. package/dist/lib/browser/ipc.d.ts +22 -2
  159. package/dist/lib/browser/ipc.js +185 -21
  160. package/dist/lib/browser/profiles.d.ts +67 -3
  161. package/dist/lib/browser/profiles.js +129 -7
  162. package/dist/lib/browser/remote-control.d.ts +2 -2
  163. package/dist/lib/browser/remote-control.js +3 -3
  164. package/dist/lib/browser/runtime-state.d.ts +79 -0
  165. package/dist/lib/browser/runtime-state.js +119 -1
  166. package/dist/lib/browser/service.d.ts +113 -1
  167. package/dist/lib/browser/service.js +454 -40
  168. package/dist/lib/browser/sessions-list.d.ts +2 -1
  169. package/dist/lib/browser/sessions-list.js +4 -13
  170. package/dist/lib/browser/types.d.ts +18 -0
  171. package/dist/lib/budget/config.js +1 -1
  172. package/dist/lib/budget/ledger.js +1 -1
  173. package/dist/lib/byok-usage.js +1 -1
  174. package/dist/lib/capabilities.js +3 -15
  175. package/dist/lib/catchup.d.ts +1 -1
  176. package/dist/lib/catchup.js +1 -1
  177. package/dist/lib/cloud/dispatch.js +1 -1
  178. package/dist/lib/cloud/host.d.ts +3 -3
  179. package/dist/lib/cloud/host.js +5 -5
  180. package/dist/lib/cloud/rush.d.ts +9 -21
  181. package/dist/lib/cloud/rush.js +33 -120
  182. package/dist/lib/cloud/types.d.ts +2 -2
  183. package/dist/lib/commands.js +3 -13
  184. package/dist/lib/computer/actions.d.ts +36 -0
  185. package/dist/lib/computer/actions.js +162 -0
  186. package/dist/lib/computer/dispatch.d.ts +2 -2
  187. package/dist/lib/computer/dispatch.js +2 -2
  188. package/dist/lib/computer/sessions-list.d.ts +3 -3
  189. package/dist/lib/computer/sessions-list.js +2 -2
  190. package/dist/lib/config-keys.d.ts +2 -1
  191. package/dist/lib/config-keys.js +8 -4
  192. package/dist/lib/config-machine-keys.d.ts +4 -2
  193. package/dist/lib/config-machine-keys.js +5 -2
  194. package/dist/lib/crabbox/lease.js +9 -1
  195. package/dist/lib/crabbox/runtimes.d.ts +32 -7
  196. package/dist/lib/crabbox/runtimes.js +72 -30
  197. package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
  198. package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
  199. package/dist/lib/daemon-services.d.ts +1 -1
  200. package/dist/lib/daemon-services.js +5 -0
  201. package/dist/lib/daemon-ticks.d.ts +25 -0
  202. package/dist/lib/daemon-ticks.js +31 -1
  203. package/dist/lib/daemon-webhooks.d.ts +102 -0
  204. package/dist/lib/daemon-webhooks.js +210 -0
  205. package/dist/lib/device-config.d.ts +85 -75
  206. package/dist/lib/device-config.js +279 -141
  207. package/dist/lib/devices/config-migration.d.ts +29 -34
  208. package/dist/lib/devices/config-migration.js +209 -130
  209. package/dist/lib/devices/connect.d.ts +2 -2
  210. package/dist/lib/devices/connect.js +2 -2
  211. package/dist/lib/devices/discovery-policy.d.ts +30 -0
  212. package/dist/lib/devices/discovery-policy.js +101 -0
  213. package/dist/lib/devices/fleet-inventory.js +8 -3
  214. package/dist/lib/devices/harness-inventory.d.ts +1 -1
  215. package/dist/lib/devices/harness-inventory.js +12 -3
  216. package/dist/lib/devices/known-hosts.js +1 -1
  217. package/dist/lib/devices/pool.d.ts +10 -5
  218. package/dist/lib/devices/pool.js +5 -7
  219. package/dist/lib/devices/registry.d.ts +1 -1
  220. package/dist/lib/devices/registry.js +1 -1
  221. package/dist/lib/devices/resolve-profile.d.ts +2 -2
  222. package/dist/lib/devices/resolve-profile.js +2 -2
  223. package/dist/lib/devices/resolve-target.d.ts +1 -1
  224. package/dist/lib/devices/resolve-target.js +4 -4
  225. package/dist/lib/devices/self-host.d.ts +1 -1
  226. package/dist/lib/devices/self-host.js +3 -3
  227. package/dist/lib/devices/ssh-config.d.ts +1 -1
  228. package/dist/lib/devices/stats-cache.js +1 -1
  229. package/dist/lib/devices/sync.d.ts +3 -1
  230. package/dist/lib/devices/sync.js +3 -3
  231. package/dist/lib/doctor-diff.js +4 -4
  232. package/dist/lib/drift-sync.js +2 -2
  233. package/dist/lib/drift.js +2 -2
  234. package/dist/lib/event-families.d.ts +1 -1
  235. package/dist/lib/event-stream.d.ts +1 -1
  236. package/dist/lib/event-stream.js +2 -2
  237. package/dist/lib/events-ingest.js +2 -2
  238. package/dist/lib/exec.d.ts +4 -4
  239. package/dist/lib/exec.js +11 -11
  240. package/dist/lib/factory/snapshot.d.ts +1 -1
  241. package/dist/lib/factory/snapshot.js +1 -1
  242. package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
  243. package/dist/lib/{activity.js → feed/activity.js} +7 -7
  244. package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
  245. package/dist/lib/{events.js → feed/events.js} +5 -5
  246. package/dist/lib/{feed.js → feed/feed.js} +4 -4
  247. package/dist/lib/feed-outcome.d.ts +1 -1
  248. package/dist/lib/feed-policy.d.ts +1 -1
  249. package/dist/lib/feed-policy.js +1 -1
  250. package/dist/lib/feed-post.d.ts +1 -1
  251. package/dist/lib/feed-post.js +1 -1
  252. package/dist/lib/feed-ranking.d.ts +1 -1
  253. package/dist/lib/fleet/apply.d.ts +0 -6
  254. package/dist/lib/fleet/apply.js +18 -45
  255. package/dist/lib/fleet/auth-sync.d.ts +16 -35
  256. package/dist/lib/fleet/auth-sync.js +16 -75
  257. package/dist/lib/fleet/capture.js +8 -6
  258. package/dist/lib/fleet/manifest.js +23 -11
  259. package/dist/lib/fleet/types.d.ts +19 -7
  260. package/dist/lib/fleet-cache.d.ts +1 -1
  261. package/dist/lib/fleet-cache.js +1 -1
  262. package/dist/lib/format.d.ts +19 -0
  263. package/dist/lib/format.js +44 -1
  264. package/dist/lib/friction-heuristics.d.ts +1 -1
  265. package/dist/lib/git.d.ts +24 -1
  266. package/dist/lib/git.js +82 -38
  267. package/dist/lib/heal.js +3 -3
  268. package/dist/lib/hooks.d.ts +18 -0
  269. package/dist/lib/hooks.js +113 -1
  270. package/dist/lib/hosts/credentials.d.ts +30 -10
  271. package/dist/lib/hosts/credentials.js +38 -26
  272. package/dist/lib/hosts/dispatch.d.ts +3 -3
  273. package/dist/lib/hosts/dispatch.js +3 -3
  274. package/dist/lib/hosts/option.d.ts +3 -3
  275. package/dist/lib/hosts/option.js +7 -8
  276. package/dist/lib/hosts/passthrough.d.ts +17 -17
  277. package/dist/lib/hosts/passthrough.js +67 -50
  278. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  279. package/dist/lib/hosts/providers/devices.js +1 -1
  280. package/dist/lib/hosts/reconcile.d.ts +1 -1
  281. package/dist/lib/hosts/reconcile.js +1 -1
  282. package/dist/lib/hosts/reconnect.d.ts +1 -1
  283. package/dist/lib/hosts/reconnect.js +2 -2
  284. package/dist/lib/hosts/registry.d.ts +5 -5
  285. package/dist/lib/hosts/registry.js +5 -5
  286. package/dist/lib/hosts/remote-cmd.d.ts +10 -10
  287. package/dist/lib/hosts/remote-cmd.js +25 -18
  288. package/dist/lib/hosts/remote-os.d.ts +4 -4
  289. package/dist/lib/hosts/remote-os.js +4 -4
  290. package/dist/lib/hosts/remote-session-id.d.ts +2 -2
  291. package/dist/lib/hosts/remote-session-id.js +2 -2
  292. package/dist/lib/hosts/routing-flag.d.ts +3 -3
  293. package/dist/lib/hosts/routing-flag.js +4 -5
  294. package/dist/lib/hosts/run-target.d.ts +4 -4
  295. package/dist/lib/hosts/run-target.js +4 -4
  296. package/dist/lib/hosts/session-index.d.ts +2 -2
  297. package/dist/lib/hosts/session-index.js +1 -1
  298. package/dist/lib/hosts/session-marker.d.ts +1 -1
  299. package/dist/lib/hosts/session-marker.js +1 -1
  300. package/dist/lib/hosts/types.d.ts +2 -2
  301. package/dist/lib/hosts/types.js +2 -2
  302. package/dist/lib/import.js +1 -1
  303. package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
  304. package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
  305. package/dist/lib/installations/resolve.js +1 -1
  306. package/dist/lib/installations/strategies.js +1 -1
  307. package/dist/lib/installations/update.js +2 -2
  308. package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
  309. package/dist/lib/{versions.js → installations/versions.js} +51 -31
  310. package/dist/lib/isolation-boundary-report.js +1 -1
  311. package/dist/lib/linear-projects.d.ts +28 -0
  312. package/dist/lib/linear-projects.js +30 -0
  313. package/dist/lib/loop.js +1 -1
  314. package/dist/lib/mailbox-gc.js +1 -1
  315. package/dist/lib/mailbox.js +1 -1
  316. package/dist/lib/mcp-registry.d.ts +62 -0
  317. package/dist/lib/mcp-registry.js +177 -0
  318. package/dist/lib/mcp.d.ts +5 -0
  319. package/dist/lib/mcp.js +124 -307
  320. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  321. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  322. package/dist/lib/menubar/install-menubar.d.ts +7 -0
  323. package/dist/lib/menubar/install-menubar.js +24 -6
  324. package/dist/lib/menubar/snapshot.d.ts +7 -0
  325. package/dist/lib/menubar/snapshot.js +8 -6
  326. package/dist/lib/models.js +1 -1
  327. package/dist/lib/monitors/config.d.ts +12 -0
  328. package/dist/lib/monitors/config.js +3 -0
  329. package/dist/lib/monitors/dispatch.js +26 -5
  330. package/dist/lib/monitors/engine.js +10 -0
  331. package/dist/lib/monitors/sources/webhook.d.ts +1 -1
  332. package/dist/lib/monitors/state.d.ts +42 -0
  333. package/dist/lib/monitors/state.js +30 -0
  334. package/dist/lib/notify.d.ts +1 -1
  335. package/dist/lib/observe-aliases.d.ts +2 -2
  336. package/dist/lib/observe-aliases.js +2 -11
  337. package/dist/lib/output/git-output.js +2 -2
  338. package/dist/lib/overdue.d.ts +1 -1
  339. package/dist/lib/overdue.js +1 -1
  340. package/dist/lib/permissions-registry.d.ts +65 -0
  341. package/dist/lib/permissions-registry.js +599 -0
  342. package/dist/lib/permissions.d.ts +24 -13
  343. package/dist/lib/permissions.js +52 -271
  344. package/dist/lib/picker.d.ts +16 -0
  345. package/dist/lib/picker.js +33 -3
  346. package/dist/lib/placement.d.ts +1 -1
  347. package/dist/lib/placement.js +4 -4
  348. package/dist/lib/platform/paths.d.ts +8 -0
  349. package/dist/lib/platform/paths.js +11 -0
  350. package/dist/lib/platform/posixpath.js +3 -3
  351. package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
  352. package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
  353. package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
  354. package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
  355. package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
  356. package/dist/lib/{skills.js → plugins/skills.js} +7 -7
  357. package/dist/lib/pricing/cost.d.ts +1 -1
  358. package/dist/lib/pricing/cost.js +1 -1
  359. package/dist/lib/profiles-presets.d.ts +1 -1
  360. package/dist/lib/profiles-presets.js +1 -1
  361. package/dist/lib/profiles.js +2 -2
  362. package/dist/lib/project-import.js +4 -1
  363. package/dist/lib/project-launch.d.ts +1 -1
  364. package/dist/lib/project-launch.js +3 -3
  365. package/dist/lib/project-pull.d.ts +128 -0
  366. package/dist/lib/project-pull.js +384 -0
  367. package/dist/lib/project-root.d.ts +2 -2
  368. package/dist/lib/project-root.js +2 -2
  369. package/dist/lib/project-status.js +1 -1
  370. package/dist/lib/projects.d.ts +23 -0
  371. package/dist/lib/projects.js +29 -6
  372. package/dist/lib/refresh.d.ts +12 -1
  373. package/dist/lib/refresh.js +16 -9
  374. package/dist/lib/registry.d.ts +9 -2
  375. package/dist/lib/registry.js +11 -4
  376. package/dist/lib/resources.d.ts +2 -2
  377. package/dist/lib/resources.js +2 -2
  378. package/dist/lib/routers.d.ts +81 -0
  379. package/dist/lib/routers.js +153 -0
  380. package/dist/lib/routine-context.d.ts +1 -0
  381. package/dist/lib/routine-context.js +7 -2
  382. package/dist/lib/routine-notify-owner.d.ts +1 -1
  383. package/dist/lib/routine-notify.d.ts +1 -1
  384. package/dist/lib/routine-notify.js +1 -1
  385. package/dist/lib/routine-process-cleanup.d.ts +1 -1
  386. package/dist/lib/routine-readiness.d.ts +1 -1
  387. package/dist/lib/routine-readiness.js +11 -4
  388. package/dist/lib/routines-placement.d.ts +12 -2
  389. package/dist/lib/routines-placement.js +20 -3
  390. package/dist/lib/routines-project.d.ts +1 -1
  391. package/dist/lib/routines-project.js +1 -1
  392. package/dist/lib/rules/compile.d.ts +1 -0
  393. package/dist/lib/rules/compile.js +10 -2
  394. package/dist/lib/rules/rules.js +1 -1
  395. package/dist/lib/run-notify.js +1 -1
  396. package/dist/lib/runner.d.ts +80 -2
  397. package/dist/lib/runner.js +241 -62
  398. package/dist/lib/sandbox.d.ts +1 -1
  399. package/dist/lib/scheduler.d.ts +1 -1
  400. package/dist/lib/scheduler.js +1 -1
  401. package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
  402. package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
  403. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  404. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  405. package/dist/lib/secrets/agent.js +2 -2
  406. package/dist/lib/secrets/audit.js +1 -1
  407. package/dist/lib/secrets/bundles.d.ts +3 -3
  408. package/dist/lib/secrets/bundles.js +7 -7
  409. package/dist/lib/secrets/index.js +1 -1
  410. package/dist/lib/secrets/list-filter.d.ts +1 -1
  411. package/dist/lib/secrets/list-filter.js +2 -2
  412. package/dist/lib/secrets/push.d.ts +1 -1
  413. package/dist/lib/secrets/push.js +10 -12
  414. package/dist/lib/secrets/remote.d.ts +12 -10
  415. package/dist/lib/secrets/remote.js +21 -14
  416. package/dist/lib/secrets/vault.js +2 -2
  417. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  418. package/dist/lib/self-heal/checks/shims.js +1 -1
  419. package/dist/lib/self-update.d.ts +39 -4
  420. package/dist/lib/self-update.js +78 -25
  421. package/dist/lib/serve/control.d.ts +1 -1
  422. package/dist/lib/serve/control.js +4 -4
  423. package/dist/lib/serve/data.d.ts +1 -1
  424. package/dist/lib/serve/data.js +1 -1
  425. package/dist/lib/serve/stream.js +1 -1
  426. package/dist/lib/service-manifest.d.ts +29 -0
  427. package/dist/lib/service-manifest.js +80 -0
  428. package/dist/lib/session/active.d.ts +59 -7
  429. package/dist/lib/session/active.js +158 -17
  430. package/dist/lib/session/bash-command.js +1 -1
  431. package/dist/lib/session/claude-accounts.d.ts +1 -1
  432. package/dist/lib/session/claude-accounts.js +1 -1
  433. package/dist/lib/session/db.d.ts +10 -2
  434. package/dist/lib/session/db.js +25 -6
  435. package/dist/lib/session/discover.d.ts +77 -0
  436. package/dist/lib/session/discover.js +130 -25
  437. package/dist/lib/session/fork.js +1 -1
  438. package/dist/lib/session/inject.d.ts +1 -1
  439. package/dist/lib/session/insights.d.ts +1 -1
  440. package/dist/lib/session/insights.js +1 -1
  441. package/dist/lib/session/live-metadata.d.ts +15 -0
  442. package/dist/lib/session/live-metadata.js +76 -0
  443. package/dist/lib/session/migrate-targets.d.ts +1 -1
  444. package/dist/lib/session/recovery.d.ts +1 -1
  445. package/dist/lib/session/recovery.js +2 -2
  446. package/dist/lib/session/remote-active.d.ts +10 -1
  447. package/dist/lib/session/remote-active.js +8 -3
  448. package/dist/lib/session/remote-bundle.d.ts +1 -1
  449. package/dist/lib/session/remote-bundle.js +2 -2
  450. package/dist/lib/session/remote-list.d.ts +15 -4
  451. package/dist/lib/session/remote-list.js +40 -3
  452. package/dist/lib/session/remote.d.ts +5 -5
  453. package/dist/lib/session/remote.js +13 -17
  454. package/dist/lib/session/resume-command.d.ts +3 -2
  455. package/dist/lib/session/resume-command.js +4 -3
  456. package/dist/lib/session/resume-owner.d.ts +3 -3
  457. package/dist/lib/session/resume-owner.js +3 -3
  458. package/dist/lib/session/session-cache.d.ts +12 -0
  459. package/dist/lib/session/session-cache.js +2 -0
  460. package/dist/lib/session/shell-programs.js +1 -1
  461. package/dist/lib/session/state.js +5 -5
  462. package/dist/lib/session/team-filter.d.ts +1 -1
  463. package/dist/lib/session/team-filter.js +1 -1
  464. package/dist/lib/session/types.d.ts +3 -3
  465. package/dist/lib/session/width.d.ts +2 -2
  466. package/dist/lib/session/width.js +2 -2
  467. package/dist/lib/share/delete.d.ts +21 -0
  468. package/dist/lib/share/delete.js +42 -0
  469. package/dist/lib/share/publish.d.ts +82 -0
  470. package/dist/lib/share/publish.js +170 -18
  471. package/dist/lib/share/worker-template.js +172 -9
  472. package/dist/lib/shims.js +35 -7
  473. package/dist/lib/smart-launch.d.ts +4 -4
  474. package/dist/lib/smart-launch.js +6 -4
  475. package/dist/lib/snapshot.d.ts +4 -4
  476. package/dist/lib/snapshot.js +2 -2
  477. package/dist/lib/ssh-exec.d.ts +1 -1
  478. package/dist/lib/ssh-exec.js +2 -2
  479. package/dist/lib/ssh-tunnel.d.ts +10 -10
  480. package/dist/lib/ssh-tunnel.js +12 -12
  481. package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
  482. package/dist/lib/staleness/checkers/hooks.js +1 -1
  483. package/dist/lib/staleness/detectors/permissions.js +0 -23
  484. package/dist/lib/staleness/detectors/plugins.js +1 -1
  485. package/dist/lib/staleness/fingerprint.js +1 -1
  486. package/dist/lib/staleness/layers.d.ts +1 -1
  487. package/dist/lib/staleness/layers.js +1 -1
  488. package/dist/lib/staleness/writers/mcp.js +3 -1
  489. package/dist/lib/staleness/writers/plugins.js +1 -1
  490. package/dist/lib/staleness/writers/types.d.ts +8 -0
  491. package/dist/lib/startup/command-registry.d.ts +5 -147
  492. package/dist/lib/startup/command-registry.js +38 -303
  493. package/dist/lib/startup/dev-build.d.ts +0 -21
  494. package/dist/lib/startup/dev-build.js +29 -8
  495. package/dist/lib/state.d.ts +19 -1
  496. package/dist/lib/state.js +120 -51
  497. package/dist/lib/subagents.js +1 -1
  498. package/dist/lib/sync-status.js +1 -1
  499. package/dist/lib/sync-umbrella.d.ts +6 -1
  500. package/dist/lib/sync-umbrella.js +9 -4
  501. package/dist/lib/teams/agents.js +2 -2
  502. package/dist/lib/teams/registry.js +1 -1
  503. package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
  504. package/dist/lib/terminal/engine.js +1 -1
  505. package/dist/lib/terminal/index.d.ts +4 -0
  506. package/dist/lib/terminal/index.js +3 -0
  507. package/dist/lib/terminal/inject.d.ts +2 -2
  508. package/dist/lib/terminal/inject.js +2 -2
  509. package/dist/lib/terminal/transport.js +1 -1
  510. package/dist/lib/tmux/index.d.ts +1 -1
  511. package/dist/lib/tmux/index.js +1 -1
  512. package/dist/lib/tmux/session.d.ts +21 -5
  513. package/dist/lib/tmux/session.js +76 -22
  514. package/dist/lib/triggers/handlers.d.ts +1 -1
  515. package/dist/lib/triggers/handlers.js +2 -2
  516. package/dist/lib/triggers/webhook.d.ts +36 -2
  517. package/dist/lib/triggers/webhook.js +97 -42
  518. package/dist/lib/types.d.ts +18 -6
  519. package/dist/lib/usage-fleet.d.ts +1 -1
  520. package/dist/lib/usage-fleet.js +1 -1
  521. package/dist/lib/usage-refresh.d.ts +1 -1
  522. package/dist/lib/usage-refresh.js +3 -3
  523. package/dist/lib/version-duplicates.js +2 -2
  524. package/dist/lib/view-types.d.ts +56 -0
  525. package/dist/lib/view-types.js +1 -0
  526. package/dist/lib/watchdog/rotate.d.ts +2 -2
  527. package/dist/lib/watchdog/rotate.js +3 -3
  528. package/dist/lib/watchdog/runner.d.ts +2 -3
  529. package/dist/lib/watchdog/runner.js +3 -4
  530. package/dist/lib/workflows.js +1 -1
  531. package/package.json +2 -1
  532. package/scripts/postinstall.js +2 -2
  533. package/dist/commands/bench.d.ts +0 -2
  534. package/dist/commands/bench.js +0 -101
  535. package/dist/commands/cp.d.ts +0 -84
  536. package/dist/commands/cp.js +0 -231
  537. package/dist/commands/login.d.ts +0 -2
  538. package/dist/lib/resources/commands.d.ts +0 -46
  539. package/dist/lib/resources/commands.js +0 -211
  540. package/dist/lib/resources/hooks.d.ts +0 -16
  541. package/dist/lib/resources/hooks.js +0 -153
  542. package/dist/lib/resources/mcp.d.ts +0 -34
  543. package/dist/lib/resources/mcp.js +0 -250
  544. package/dist/lib/resources/memory.d.ts +0 -15
  545. package/dist/lib/resources/memory.js +0 -46
  546. package/dist/lib/resources/permissions.d.ts +0 -13
  547. package/dist/lib/resources/permissions.js +0 -202
  548. package/dist/lib/resources/rules.d.ts +0 -46
  549. package/dist/lib/resources/rules.js +0 -179
  550. package/dist/lib/resources/skills.d.ts +0 -37
  551. package/dist/lib/resources/skills.js +0 -247
  552. package/dist/lib/resources/subagents.d.ts +0 -46
  553. package/dist/lib/resources/subagents.js +0 -202
  554. /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
@@ -30,7 +30,7 @@
30
30
  import * as fs from 'fs';
31
31
  import * as path from 'path';
32
32
  import { readMeta, writeMeta } from '../state.js';
33
- import { collectHarnessCandidates, classifyHarnessCandidates, pickHarnessWeighted, earliestResetAcross, formatNoHealthyHarnessError, } from '../rotate.js';
33
+ import { collectHarnessCandidates, classifyHarnessCandidates, pickHarnessWeighted, earliestResetAcross, formatNoHealthyHarnessError, } from '../accounting/rotate.js';
34
34
  import { resolveWatchdogSessionPath } from './read.js';
35
35
  // --- detection ---------------------------------------------------------------
36
36
  /**
@@ -160,7 +160,7 @@ export function exitSequenceFor(agent) {
160
160
  * host (affinity) → harness (cross-harness headroom) → account (balanced) and
161
161
  * exits nonzero when every layer is exhausted. Ported from apps/ext
162
162
  * autoRotate.ts buildAutoRotateLaunchCommand. A terminal on a REMOTE device
163
- * rotates ON that device (`--host`); a local terminal omits it. `--session-id`
163
+ * rotates ON that device (`--device`); a local terminal omits it. `--session-id`
164
164
  * is honored only when the CLI picks claude (existing claude-only semantics)
165
165
  * and ignored otherwise — passing it unconditionally keeps the terminal's
166
166
  * AGENT_SESSION_ID aligned with the session Claude actually creates.
@@ -168,7 +168,7 @@ export function exitSequenceFor(agent) {
168
168
  export function buildRotateLaunchCommand(opts) {
169
169
  let cmd = 'agents run auto --interactive';
170
170
  if (opts.host) {
171
- cmd += ` --host ${shellQuoteHost(opts.host)}`;
171
+ cmd += ` --device ${shellQuoteHost(opts.host)}`;
172
172
  }
173
173
  cmd += ` --session-id ${opts.sessionId}`;
174
174
  return cmd;
@@ -32,10 +32,9 @@
32
32
  */
33
33
  import type { ActiveSession } from '../session/active.js';
34
34
  import { type PresenceTransition } from '../session/presence.js';
35
- import { type InjectRail } from '../terminal/resolve.js';
36
- import { type InjectResult, type InjectTarget } from '../terminal/inject.js';
35
+ import { type InjectRail, type InjectResult, type InjectTarget } from '../terminal/index.js';
37
36
  import { type StallStatus, type WatchdogCandidate } from './watchdog.js';
38
- import { type OpenBlock } from '../feed.js';
37
+ import { type OpenBlock } from '../feed/feed.js';
39
38
  import { type RotateGateResult, type RotatePhase, type RotateState } from './rotate.js';
40
39
  /** Per-session policy sentinel. `keep` is the default (watchdog may nudge). */
41
40
  export type WatchdogPolicy = 'off' | 'keep' | 'handsoff';
@@ -35,8 +35,7 @@ import * as path from 'path';
35
35
  import * as crypto from 'crypto';
36
36
  import { getActiveSessions } from '../session/active.js';
37
37
  import { reconcilePresence, loadPresence, savePresence, observedFromActive, } from '../session/presence.js';
38
- import { resolveInjectTargetForSession, } from '../terminal/resolve.js';
39
- import { injectIntoTerminal } from '../terminal/inject.js';
38
+ import { resolveInjectTargetForSession, injectIntoTerminal, } from '../terminal/index.js';
40
39
  import { classifyTerminal, isLikelyTrulyBlocked, renderWatchdogPrompt, parseWatchdogResponse, } from './watchdog.js';
41
40
  import { readWatchdogTail, WATCHDOG_STALL_MS, WATCHDOG_COOLDOWN_MS, WATCHDOG_DORMANT_MS, WATCHDOG_TAIL_LINES, } from './read.js';
42
41
  import { getRuntimeStateDir } from '../state.js';
@@ -44,7 +43,7 @@ import { withFileLock, atomicWriteFileSync, ensureLockTarget } from '../fs-atomi
44
43
  import { resolveAnswerRoute, isOpenQuestionBlock } from '../answer-router.js';
45
44
  import { enqueue, mailboxDir } from '../mailbox.js';
46
45
  import { mailboxIdForActiveSession } from '../mailbox-target.js';
47
- import { readBlock, blockIdForSession, buildDeclaredBlock, publishBlock } from '../feed.js';
46
+ import { readBlock, blockIdForSession, buildDeclaredBlock, publishBlock } from '../feed/feed.js';
48
47
  import { summarizeWatchdogTail } from './watchdogTail.js';
49
48
  import { appendWatchdogEvents } from './log.js';
50
49
  import { buildRotateLaunchCommand, buildRotateReplayText, classifyTailForRotate, defaultRotateGate, defaultTuiLiveFor, exitSequenceFor, isInflightPhase, isWatchdogRotateEnabled, listInflightRotates, readRotateState, recordRotateSkip, shouldLogRotateSkip, writeRotateState, DEFAULT_ROTATE_READINESS_MS, DEFAULT_ROTATE_SKIP_COOLDOWN_MS, DEFAULT_ROTATE_FAILED_COOLDOWN_MS, } from './rotate.js';
@@ -239,7 +238,7 @@ async function deliverViaResume(session, text) {
239
238
  return { ok: false, error: 'no session id to resume' };
240
239
  try {
241
240
  const [{ getAgentsInvocation }, { spawn }] = await Promise.all([
242
- import('../daemon.js'),
241
+ import('../daemon/daemon.js'),
243
242
  import('child_process'),
244
243
  ]);
245
244
  const inv = getAgentsInvocation(['run', session.kind, '--resume', sid, '--', text]);
@@ -11,7 +11,7 @@ import * as path from 'path';
11
11
  import * as yaml from 'yaml';
12
12
  import { capableAgents, supports } from './capabilities.js';
13
13
  import { getProjectAgentsDir, getSystemWorkflowsDir, getUserWorkflowsDir, getTrashWorkflowsDir, getEnabledExtraRepos, getPluginsDir, getSystemPluginsDir, getProjectPluginsDir, } from './state.js';
14
- import { listInstalledVersions, getVersionHomePath } from './versions.js';
14
+ import { listInstalledVersions, getVersionHomePath } from './installations/versions.js';
15
15
  /**
16
16
  * Hard upper bound on items a single `for_each` expands, absent an explicit
17
17
  * `max_items`. A guard against a runaway producer spawning unbounded teammates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phnx-labs/agents-cli",
3
- "version": "1.22.39",
3
+ "version": "1.22.40",
4
4
  "description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,6 +24,7 @@
24
24
  "dist/**/*.js",
25
25
  "dist/**/*.d.ts",
26
26
  "dist/**/*.json",
27
+ "dist/**/*.sh",
27
28
  "dist/bin/**",
28
29
  "dist/lib/secrets/Agents CLI.app/**",
29
30
  "dist/lib/menubar/MenubarHelper.app/**",
@@ -291,7 +291,7 @@ To enable version-aware shims, add this to your shell config:
291
291
  * non-interactive login shell's PATH, so `bash -lc 'agents …'` fails with
292
292
  * command-not-found — which breaks `agents secrets export --host` (it runs
293
293
  * `bash -lc 'agents secrets import …'` on the remote) and the routines daemon
294
- * (src/lib/daemon.ts falls back to bare `agents`). This is the POSIX symmetric
294
+ * (src/lib/daemon/daemon.ts falls back to bare `agents`). This is the POSIX symmetric
295
295
  * counterpart of the Windows branch in main() that registers npm's global-bin
296
296
  * dir on the user PATH.
297
297
  *
@@ -406,7 +406,7 @@ async function healLongRunningProcesses() {
406
406
  // starts (SING-4a). If it was already running under a disable, stop and leave
407
407
  // it down so upgrade does not resurrect a killed switch.
408
408
  try {
409
- const d = await import('../dist/lib/daemon.js');
409
+ const d = await import('../dist/lib/daemon/daemon.js');
410
410
  const { isDaemonEnabled } = await import('../dist/lib/device-config.js');
411
411
  const wasRunning = Boolean(d.isDaemonRunning?.());
412
412
  const enabled = typeof isDaemonEnabled === 'function' ? isDaemonEnabled() : true;
@@ -1,2 +0,0 @@
1
- import type { Command } from "commander";
2
- export declare function registerBenchCommand(program: Command): void;
@@ -1,101 +0,0 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
- import { fileURLToPath } from "url";
4
- import { detectSignedInRuntimes } from "../lib/crabbox/runtimes.js";
5
- import { listRuns, loadRun, loadTask, runCells, saveRun, } from "../lib/bench/index.js";
6
- import { setHelpSections } from "../lib/help.js";
7
- const TASKS_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../bench/tasks");
8
- function csv(value) {
9
- return (value
10
- ?.split(",")
11
- .map((item) => item.trim())
12
- .filter(Boolean) ?? []);
13
- }
14
- function taskIds(root = TASKS_ROOT) {
15
- if (!fs.existsSync(root))
16
- return [];
17
- return fs
18
- .readdirSync(root, { withFileTypes: true })
19
- .filter((entry) => entry.isDirectory() &&
20
- fs.existsSync(path.join(root, entry.name, "task.json")))
21
- .map((entry) => entry.name)
22
- .sort();
23
- }
24
- function renderResult(result) {
25
- console.log(`Run ${result.run_id}${result.task_id ? ` · ${result.task_id}` : ""}`);
26
- for (const cell of result.cells)
27
- console.log(`${cell.status === "passed" ? "PASS" : "FAIL"} ${cell.agent}${cell.model ? `/${cell.model}` : ""} ${cell.wall_ms} ms exit ${cell.exit ?? "spawn-error"}`);
28
- }
29
- export function registerBenchCommand(program) {
30
- const bench = program
31
- .command("bench")
32
- .description("Run the same task across agent and model cells, with isolated fixtures and durable JSON results.");
33
- setHelpSections(bench, {
34
- examples: `agents bench list\nagents bench run hello-repo --agent claude,codex --model cheap,default\nagents bench results --json`,
35
- notes: `Task definitions live under apps/cli/bench/tasks/<id>/task.json. Custom harness names accepted by agents run are valid --agent values.`,
36
- });
37
- bench
38
- .command("list")
39
- .description("List available benchmark tasks.")
40
- .option("--json", "Emit JSON.")
41
- .action((options) => {
42
- const tasks = taskIds();
43
- if (options.json)
44
- console.log(JSON.stringify(tasks, null, 2));
45
- else if (tasks.length === 0)
46
- console.log("No benchmark tasks installed.");
47
- else
48
- tasks.forEach((id) => console.log(id));
49
- });
50
- bench
51
- .command("results [run-id]")
52
- .description("Show one saved run, or list saved runs newest first.")
53
- .option("--json", "Emit JSON.")
54
- .action((runId, options) => {
55
- const value = runId ? loadRun(runId) : listRuns();
56
- if (options.json)
57
- console.log(JSON.stringify(value, null, 2));
58
- else if (Array.isArray(value)) {
59
- if (value.length === 0)
60
- console.log("No benchmark results yet.");
61
- else
62
- value.forEach(renderResult);
63
- }
64
- else
65
- renderResult(value);
66
- });
67
- bench
68
- .command("run [task-id]")
69
- .description("Run one task or prompt across an agent × model matrix.")
70
- .option("--prompt <text>", "Prompt to benchmark instead of a house task.")
71
- .option("--agent <names>", "Comma-separated native agents or custom harness names. Defaults to signed-in native agents.")
72
- .option("--model <models>", "Comma-separated model tiers or concrete model ids.")
73
- .option("--concurrency <n>", "Maximum cells running at once.", "3")
74
- .option("--json", "Emit the saved JSON result.")
75
- .action(async (taskId, options) => {
76
- if (!!taskId === !!options.prompt)
77
- throw new Error("Pass exactly one of <task-id> or --prompt.");
78
- const task = taskId ? loadTask(taskId, TASKS_ROOT) : undefined;
79
- const prompt = options.prompt ?? task.prompt;
80
- let agents = csv(options.agent);
81
- if (agents.length === 0)
82
- agents = (await detectSignedInRuntimes())
83
- .filter((runtime) => runtime.signedIn)
84
- .map((runtime) => runtime.id);
85
- if (agents.length === 0)
86
- throw new Error("No signed-in native agents found. Pass --agent <name>.");
87
- const models = csv(options.model);
88
- const cells = agents.flatMap((agent) => models.length > 0
89
- ? models.map((model) => ({ agent, model }))
90
- : [{ agent }]);
91
- const concurrency = Number(options.concurrency);
92
- const result = await runCells({ task, prompt, cells, concurrency });
93
- saveRun(result);
94
- if (options.json)
95
- console.log(JSON.stringify(result, null, 2));
96
- else
97
- renderResult(result);
98
- if (result.cells.some((cell) => cell.status === "failed"))
99
- process.exitCode = 1;
100
- });
101
- }
@@ -1,84 +0,0 @@
1
- /**
2
- * `agents cp <src> <dst>` — first-class fleet file transfer.
3
- *
4
- * Accepts `host:path` on either side (local = bare absolute path). Resolves
5
- * `~` and `$HOME` remote paths ON the remote before transfer so a `$HOME` in
6
- * the remote spec can never silently expand to the local user's home directory
7
- * — the documented silent-failure class in `remote-dispatch-mutation-safety`.
8
- *
9
- * Reuses the same SSH fabric (SSH_OPTS, deviceIdentityArgs, resolveDeviceTarget)
10
- * that `agents ssh` and `--host` dispatch use.
11
- */
12
- import type { Command } from 'commander';
13
- /**
14
- * A remote endpoint — host (device name or user@device) and a path on that
15
- * host. The path may begin with `~` or `$HOME`; {@link resolveRemotePath}
16
- * expands those on the remote before transfer.
17
- */
18
- export interface RemoteEndpoint {
19
- isRemote: true;
20
- /** Device name, user@device, or ad-hoc host literal. */
21
- host: string;
22
- /** Path as given by the caller — may contain `~` or `$HOME`. */
23
- path: string;
24
- }
25
- /** A local endpoint — an absolute local path. */
26
- export interface LocalEndpoint {
27
- isRemote: false;
28
- /** Absolute local path. */
29
- path: string;
30
- }
31
- export type Endpoint = RemoteEndpoint | LocalEndpoint;
32
- /**
33
- * Parse one CLI token into an {@link Endpoint}.
34
- *
35
- * Grammar: `host:path` is remote; anything else is local. The host part must
36
- * not contain a `/` (that would be a local absolute path with a colon in it —
37
- * unusual but valid; the colon test covers the common fleet pattern and rejects
38
- * the almost-never-seen edge case in favour of local-path semantics).
39
- *
40
- * Windows drive letters (`C:path`) are excluded by requiring the host part to
41
- * be at least two characters and not a single capital letter.
42
- */
43
- export declare function parseEndpoint(token: string): Endpoint;
44
- /**
45
- * Resolve the remote HOME directory in one SSH round-trip. Returns the
46
- * absolute path (always starts with `/`), or throws on failure.
47
- */
48
- export declare function resolveRemoteHome(target: string, extraSshArgs: string[]): Promise<string>;
49
- /**
50
- * Pure home-prefix expansion. Given a remote HOME (already resolved on the
51
- * remote) and a raw path token, substitute a leading `~` or `$HOME`. Paths
52
- * without those prefixes are returned unchanged. Never consults
53
- * `process.env.HOME` — the local home must not leak into a remote path.
54
- */
55
- export declare function expandRemoteHomePrefix(rawPath: string, remoteHome: string): string;
56
- /**
57
- * Expand a remote path's leading `~` or literal `$HOME` to an absolute path
58
- * resolved **on the remote**, not locally. A path that already starts with `/`
59
- * is returned unchanged (no round-trip).
60
- *
61
- * This is the safeguard against the silent-failure class: a `$HOME` or `~`
62
- * that would expand to the **local** user's home if left in a shell command.
63
- */
64
- export declare function resolveRemotePath(rawPath: string, target: string, extraSshArgs: string[]): Promise<string>;
65
- /**
66
- * Build the argv for the `scp` invocation. Pure — no spawning — so it is
67
- * unit-testable.
68
- *
69
- * `scp` accepts ssh `-o` options, so `SSH_OPTS` flows through unchanged.
70
- * Identity args (`-i key -o IdentitiesOnly=yes`) are included only when a
71
- * single remote device is involved; for two-remote transfers the identity
72
- * applies to both connections, which works when the fleet uses a shared key.
73
- *
74
- * Remote endpoints are formatted as `user@host:path` (or bare `host:path`),
75
- * local endpoints as their absolute path. Paths have already been resolved
76
- * (no `~` or `$HOME`) by the time this is called.
77
- */
78
- export declare function buildScpArgv({ srcSpec, dstSpec, identityArgs, recursive, }: {
79
- srcSpec: string;
80
- dstSpec: string;
81
- identityArgs: string[];
82
- recursive: boolean;
83
- }): string[];
84
- export declare function registerCpCommand(program: Command): void;
@@ -1,231 +0,0 @@
1
- /**
2
- * `agents cp <src> <dst>` — first-class fleet file transfer.
3
- *
4
- * Accepts `host:path` on either side (local = bare absolute path). Resolves
5
- * `~` and `$HOME` remote paths ON the remote before transfer so a `$HOME` in
6
- * the remote spec can never silently expand to the local user's home directory
7
- * — the documented silent-failure class in `remote-dispatch-mutation-safety`.
8
- *
9
- * Reuses the same SSH fabric (SSH_OPTS, deviceIdentityArgs, resolveDeviceTarget)
10
- * that `agents ssh` and `--host` dispatch use.
11
- */
12
- import { spawnSync } from 'child_process';
13
- import chalk from 'chalk';
14
- import { setHelpSections } from '../lib/help.js';
15
- import { resolveDeviceTarget } from '../lib/devices/resolve-target.js';
16
- import { sshTargetFor, deviceIdentityArgs } from '../lib/devices/connect.js';
17
- import { sshExec, SSH_OPTS } from '../lib/ssh-exec.js';
18
- /**
19
- * Parse one CLI token into an {@link Endpoint}.
20
- *
21
- * Grammar: `host:path` is remote; anything else is local. The host part must
22
- * not contain a `/` (that would be a local absolute path with a colon in it —
23
- * unusual but valid; the colon test covers the common fleet pattern and rejects
24
- * the almost-never-seen edge case in favour of local-path semantics).
25
- *
26
- * Windows drive letters (`C:path`) are excluded by requiring the host part to
27
- * be at least two characters and not a single capital letter.
28
- */
29
- export function parseEndpoint(token) {
30
- const colonIdx = token.indexOf(':');
31
- if (colonIdx > 1 && !token.startsWith('/')) {
32
- const host = token.slice(0, colonIdx);
33
- const path = token.slice(colonIdx + 1);
34
- // A bare single uppercase letter before `:` looks like a Windows drive
35
- // letter — treat as local to avoid a confusing error.
36
- if (!/^[A-Z]$/.test(host) && !host.includes('/')) {
37
- return { isRemote: true, host, path };
38
- }
39
- }
40
- return { isRemote: false, path: token };
41
- }
42
- // ---------------------------------------------------------------------------
43
- // Remote path resolution — the core safeguard
44
- // ---------------------------------------------------------------------------
45
- /**
46
- * Resolve the remote HOME directory in one SSH round-trip. Returns the
47
- * absolute path (always starts with `/`), or throws on failure.
48
- */
49
- export async function resolveRemoteHome(target, extraSshArgs) {
50
- const res = sshExec(target, 'printf "%s" "$HOME"', {
51
- extraSshArgs,
52
- timeoutMs: 10_000,
53
- });
54
- if (res.code !== 0) {
55
- throw new Error(`Cannot resolve remote $HOME on ${target}: ${res.stderr.trim() || 'ssh exited ' + String(res.code)}`);
56
- }
57
- const home = res.stdout.trim();
58
- if (!home || !home.startsWith('/')) {
59
- throw new Error(`Remote $HOME on ${target} is not an absolute path: ${JSON.stringify(home)}`);
60
- }
61
- return home;
62
- }
63
- /**
64
- * Pure home-prefix expansion. Given a remote HOME (already resolved on the
65
- * remote) and a raw path token, substitute a leading `~` or `$HOME`. Paths
66
- * without those prefixes are returned unchanged. Never consults
67
- * `process.env.HOME` — the local home must not leak into a remote path.
68
- */
69
- export function expandRemoteHomePrefix(rawPath, remoteHome) {
70
- if (rawPath === '~' || rawPath.startsWith('~/')) {
71
- return rawPath === '~' ? remoteHome : remoteHome + rawPath.slice(1);
72
- }
73
- if (rawPath === '$HOME' || rawPath.startsWith('$HOME/')) {
74
- return rawPath === '$HOME' ? remoteHome : remoteHome + rawPath.slice(5);
75
- }
76
- return rawPath;
77
- }
78
- /**
79
- * Expand a remote path's leading `~` or literal `$HOME` to an absolute path
80
- * resolved **on the remote**, not locally. A path that already starts with `/`
81
- * is returned unchanged (no round-trip).
82
- *
83
- * This is the safeguard against the silent-failure class: a `$HOME` or `~`
84
- * that would expand to the **local** user's home if left in a shell command.
85
- */
86
- export async function resolveRemotePath(rawPath, target, extraSshArgs) {
87
- if (rawPath === '~' ||
88
- rawPath.startsWith('~/') ||
89
- rawPath === '$HOME' ||
90
- rawPath.startsWith('$HOME/')) {
91
- const home = await resolveRemoteHome(target, extraSshArgs);
92
- return expandRemoteHomePrefix(rawPath, home);
93
- }
94
- return rawPath;
95
- }
96
- // ---------------------------------------------------------------------------
97
- // scp invocation
98
- // ---------------------------------------------------------------------------
99
- /**
100
- * Build the argv for the `scp` invocation. Pure — no spawning — so it is
101
- * unit-testable.
102
- *
103
- * `scp` accepts ssh `-o` options, so `SSH_OPTS` flows through unchanged.
104
- * Identity args (`-i key -o IdentitiesOnly=yes`) are included only when a
105
- * single remote device is involved; for two-remote transfers the identity
106
- * applies to both connections, which works when the fleet uses a shared key.
107
- *
108
- * Remote endpoints are formatted as `user@host:path` (or bare `host:path`),
109
- * local endpoints as their absolute path. Paths have already been resolved
110
- * (no `~` or `$HOME`) by the time this is called.
111
- */
112
- export function buildScpArgv({ srcSpec, dstSpec, identityArgs, recursive, }) {
113
- const opts = [...SSH_OPTS, ...identityArgs];
114
- if (recursive)
115
- opts.push('-r');
116
- // Two-remote transfers route through the local machine (-3) to avoid
117
- // requiring direct SSH access between the two fleet boxes.
118
- if (srcSpec.includes(':') && dstSpec.includes(':'))
119
- opts.push('-3');
120
- return [...opts, srcSpec, dstSpec];
121
- }
122
- async function resolveEndpoint(ep) {
123
- if (!ep.isRemote) {
124
- return { spec: ep.path, identityArgs: [] };
125
- }
126
- const device = await resolveDeviceTarget(ep.host);
127
- if (!device) {
128
- throw new Error(`Unknown device ${JSON.stringify(ep.host)}. Register it with \`agents devices add\` or check \`agents devices\`.`);
129
- }
130
- const target = sshTargetFor(device);
131
- const idArgs = deviceIdentityArgs(device);
132
- const resolvedPath = await resolveRemotePath(ep.path, target, idArgs);
133
- if (!resolvedPath.startsWith('/')) {
134
- throw new Error(`Remote path on ${ep.host} must be absolute after expansion, got: ${JSON.stringify(resolvedPath)}. Use an absolute path or start with ~/`);
135
- }
136
- return { spec: `${target}:${resolvedPath}`, identityArgs: idArgs };
137
- }
138
- // ---------------------------------------------------------------------------
139
- // Validation
140
- // ---------------------------------------------------------------------------
141
- /** Validate a local path: must be absolute. */
142
- function validateLocalPath(raw) {
143
- if (!raw.startsWith('/')) {
144
- throw new Error(`Local path must be absolute, got: ${JSON.stringify(raw)}`);
145
- }
146
- }
147
- /** Validate a remote path: non-empty. */
148
- function validateRemotePath(raw, host) {
149
- if (!raw) {
150
- throw new Error(`Remote path for ${JSON.stringify(host)} is empty. Expected: ${host}:/abs/path`);
151
- }
152
- }
153
- // ---------------------------------------------------------------------------
154
- // Command registration
155
- // ---------------------------------------------------------------------------
156
- export function registerCpCommand(program) {
157
- const cmd = program
158
- .command('cp <src> <dst>')
159
- .description('Copy a file or directory between fleet hosts. Either endpoint may be host:path (remote) or an absolute local path.')
160
- .option('-r, --recursive', 'Copy directories recursively')
161
- .action(async (srcToken, dstToken, opts) => {
162
- const recursive = opts.recursive ?? false;
163
- const srcEp = parseEndpoint(srcToken);
164
- const dstEp = parseEndpoint(dstToken);
165
- if (!srcEp.isRemote && !dstEp.isRemote) {
166
- process.stderr.write(chalk.red('error:') +
167
- ' At least one endpoint must be remote (host:path). For local-only copies use `cp`.\n');
168
- process.exit(1);
169
- }
170
- let srcResolved;
171
- let dstResolved;
172
- try {
173
- // Validate shapes before any network calls.
174
- if (!srcEp.isRemote)
175
- validateLocalPath(srcEp.path);
176
- if (srcEp.isRemote)
177
- validateRemotePath(srcEp.path, srcEp.host);
178
- if (!dstEp.isRemote)
179
- validateLocalPath(dstEp.path);
180
- if (dstEp.isRemote)
181
- validateRemotePath(dstEp.path, dstEp.host);
182
- [srcResolved, dstResolved] = await Promise.all([
183
- resolveEndpoint(srcEp),
184
- resolveEndpoint(dstEp),
185
- ]);
186
- }
187
- catch (err) {
188
- process.stderr.write(chalk.red('error:') + ' ' + err.message + '\n');
189
- process.exit(1);
190
- }
191
- // Merge identity args: for two-remote transfers, omit per-device identity
192
- // args (they apply to both connections via -3; a conflict would need
193
- // separate -i per connection which scp doesn't support). A shared fleet
194
- // key works without explicit -i.
195
- const identityArgs = srcResolved.identityArgs.length > 0 && dstResolved.identityArgs.length === 0
196
- ? srcResolved.identityArgs
197
- : dstResolved.identityArgs.length > 0 && srcResolved.identityArgs.length === 0
198
- ? dstResolved.identityArgs
199
- : srcResolved.identityArgs.join(',') === dstResolved.identityArgs.join(',')
200
- ? srcResolved.identityArgs
201
- : []; // two remotes with different keys — skip per-device flag, use agent's default key
202
- const argv = buildScpArgv({
203
- srcSpec: srcResolved.spec,
204
- dstSpec: dstResolved.spec,
205
- identityArgs,
206
- recursive,
207
- });
208
- const res = spawnSync('scp', argv, { stdio: 'inherit' });
209
- const code = typeof res.status === 'number' ? res.status : 1;
210
- if (code !== 0) {
211
- // scp already printed a diagnostic; just exit non-zero.
212
- process.exit(code);
213
- }
214
- });
215
- setHelpSections(cmd, {
216
- examples: `
217
- agents cp yosemite-s0:/abs/data.json /tmp/data.json # download a file from a fleet host
218
- agents cp /tmp/build.tar.gz mac-mini:/abs/deploy/ # upload a local file to a fleet host
219
- agents cp -r yosemite-s0:/abs/src/ mac-mini:/abs/dst/ # copy a directory between two fleet hosts
220
- agents cp yosemite-s0:~/logs/run.log /tmp/run.log # ~ is resolved on the remote host
221
- `,
222
- notes: `
223
- Local paths must be absolute (use /abs/path, not ./relative).
224
- Remote paths must be absolute after ~ / $HOME expansion.
225
- Remote $HOME is resolved on the remote host — never in the local shell.
226
- Both local-to-remote and remote-to-local transfers are supported.
227
- Remote-to-remote transfers route through the local machine (-3).
228
- Devices must be registered: 'agents devices' to list, 'agents devices add' to enroll.
229
- `,
230
- });
231
- }
@@ -1,2 +0,0 @@
1
- import type { Command } from 'commander';
2
- export declare function registerLoginCommands(program: Command): void;
@@ -1,46 +0,0 @@
1
- /**
2
- * Commands resource handler.
3
- *
4
- * Commands are slash-command definitions stored as .md files (Claude/Codex/Cursor/OpenCode)
5
- * or .toml files (Gemini). This handler resolves commands across layers (project > user > system),
6
- * handles format conversion during sync, and provides consistent list/resolve/sync behavior.
7
- */
8
- import type { AgentId, ResolvedItem, ResourceHandler, ResourceKind } from './types.js';
9
- /** Command item metadata. */
10
- export interface CommandItem {
11
- name: string;
12
- description: string;
13
- content: string;
14
- format: 'md' | 'toml';
15
- }
16
- /**
17
- * Commands resource handler implementing ResourceHandler<CommandItem>.
18
- */
19
- export declare class CommandsHandler implements ResourceHandler<CommandItem> {
20
- readonly kind: ResourceKind;
21
- /**
22
- * List all commands across layers, with higher layer winning on name conflict.
23
- * Returns a union of all commands, deduplicated by name.
24
- */
25
- listAll(agent: AgentId, cwd?: string): ResolvedItem<CommandItem>[];
26
- /**
27
- * Resolve a single command by name.
28
- * Returns the winning layer's version, or null if not found.
29
- */
30
- resolve(agent: AgentId, name: string, cwd?: string): ResolvedItem<CommandItem> | null;
31
- /**
32
- * Sync resolved commands to the agent's version home directory.
33
- * Copies/transforms commands as needed for the agent's expected format.
34
- */
35
- sync(agent: AgentId, versionHome: string, cwd?: string): void;
36
- /**
37
- * Get the file format this resource uses for a given agent.
38
- */
39
- format(agent: AgentId): 'md' | 'toml';
40
- /**
41
- * Get the target directory name in the agent's version home.
42
- */
43
- targetDir(agent: AgentId): string;
44
- }
45
- /** Singleton instance of the commands handler. */
46
- export declare const commandsHandler: CommandsHandler;