@phnx-labs/agents-cli 1.22.39 → 1.22.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (569) hide show
  1. package/CHANGELOG.md +316 -0
  2. package/README.md +116 -70
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +45 -27
  5. package/dist/browser.js +2 -2
  6. package/dist/cli/command-registry.d.ts +135 -0
  7. package/dist/cli/command-registry.js +259 -0
  8. package/dist/commands/accounts.d.ts +20 -0
  9. package/dist/commands/accounts.js +186 -25
  10. package/dist/commands/apply.d.ts +3 -3
  11. package/dist/commands/apply.js +20 -63
  12. package/dist/commands/browser.d.ts +15 -0
  13. package/dist/commands/browser.js +318 -131
  14. package/dist/commands/budget.d.ts +7 -6
  15. package/dist/commands/budget.js +8 -7
  16. package/dist/commands/cloud.js +17 -20
  17. package/dist/commands/commands.js +1 -1
  18. package/dist/commands/computer-actions.d.ts +1 -35
  19. package/dist/commands/computer-actions.js +13 -181
  20. package/dist/commands/computer.d.ts +28 -3
  21. package/dist/commands/computer.js +93 -65
  22. package/dist/commands/config.js +16 -3
  23. package/dist/commands/cost.d.ts +2 -1
  24. package/dist/commands/cost.js +7 -6
  25. package/dist/commands/daemon.js +151 -4
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +19 -11
  28. package/dist/commands/events.js +1 -1
  29. package/dist/commands/exec.d.ts +2 -50
  30. package/dist/commands/exec.js +160 -215
  31. package/dist/commands/factory.js +1 -1
  32. package/dist/commands/feed.d.ts +2 -2
  33. package/dist/commands/feed.js +12 -23
  34. package/dist/commands/fleet-capture.js +25 -27
  35. package/dist/commands/focus.d.ts +2 -3
  36. package/dist/commands/focus.js +34 -9
  37. package/dist/commands/go.js +15 -5
  38. package/dist/commands/harness.d.ts +3 -3
  39. package/dist/commands/harness.js +53 -5
  40. package/dist/commands/hooks.js +1 -1
  41. package/dist/commands/import.js +2 -2
  42. package/dist/commands/insights.d.ts +5 -5
  43. package/dist/commands/insights.js +15 -9
  44. package/dist/commands/inspect.d.ts +2 -3
  45. package/dist/commands/inspect.js +4 -16
  46. package/dist/commands/logs.d.ts +2 -2
  47. package/dist/commands/logs.js +9 -9
  48. package/dist/commands/mcp.js +2 -2
  49. package/dist/commands/memory.js +1 -1
  50. package/dist/commands/message.d.ts +1 -1
  51. package/dist/commands/message.js +7 -7
  52. package/dist/commands/mine.d.ts +11 -8
  53. package/dist/commands/mine.js +11 -10
  54. package/dist/commands/models.js +1 -1
  55. package/dist/commands/modes.js +1 -1
  56. package/dist/commands/monitors.js +23 -6
  57. package/dist/commands/output.d.ts +7 -6
  58. package/dist/commands/output.js +11 -10
  59. package/dist/commands/packages.js +4 -4
  60. package/dist/commands/perf.js +1 -1
  61. package/dist/commands/permissions.js +49 -32
  62. package/dist/commands/plugins.d.ts +1 -1
  63. package/dist/commands/plugins.js +3 -3
  64. package/dist/commands/profiles.d.ts +6 -9
  65. package/dist/commands/profiles.js +8 -321
  66. package/dist/commands/projects.d.ts +9 -0
  67. package/dist/commands/projects.js +140 -8
  68. package/dist/commands/prune.js +5 -13
  69. package/dist/commands/refresh-rules.js +1 -1
  70. package/dist/commands/repo.d.ts +5 -7
  71. package/dist/commands/repo.js +34 -18
  72. package/dist/commands/resource-view.js +4 -0
  73. package/dist/commands/resume.d.ts +11 -7
  74. package/dist/commands/resume.js +82 -98
  75. package/dist/commands/route.d.ts +12 -0
  76. package/dist/commands/route.js +261 -0
  77. package/dist/commands/routines.d.ts +2 -3
  78. package/dist/commands/routines.js +120 -145
  79. package/dist/commands/rules.js +1 -1
  80. package/dist/commands/run-account-picker.d.ts +1 -1
  81. package/dist/commands/run-account-picker.js +2 -2
  82. package/dist/commands/run-broadcast.d.ts +21 -0
  83. package/dist/commands/run-broadcast.js +89 -0
  84. package/dist/commands/run-cloud.js +1 -1
  85. package/dist/commands/secrets-vault.d.ts +10 -0
  86. package/dist/commands/{login.js → secrets-vault.js} +34 -14
  87. package/dist/commands/secrets.d.ts +4 -4
  88. package/dist/commands/secrets.js +158 -159
  89. package/dist/commands/sessions-backfill.js +1 -1
  90. package/dist/commands/sessions-browser.d.ts +1 -1
  91. package/dist/commands/sessions-browser.js +9 -5
  92. package/dist/commands/sessions-export.js +2 -2
  93. package/dist/commands/sessions-inject.js +4 -5
  94. package/dist/commands/sessions-migrate.js +16 -27
  95. package/dist/commands/sessions-picker.d.ts +14 -0
  96. package/dist/commands/sessions-picker.js +209 -13
  97. package/dist/commands/sessions-resume.d.ts +7 -3
  98. package/dist/commands/sessions-resume.js +81 -33
  99. package/dist/commands/sessions-share.d.ts +25 -0
  100. package/dist/commands/sessions-share.js +166 -0
  101. package/dist/commands/sessions-stats.js +2 -2
  102. package/dist/commands/sessions.d.ts +75 -68
  103. package/dist/commands/sessions.js +144 -180
  104. package/dist/commands/setup-browser.js +1 -1
  105. package/dist/commands/setup-computer.js +1 -1
  106. package/dist/commands/setup-fleet.js +3 -0
  107. package/dist/commands/setup-mine.d.ts +7 -3
  108. package/dist/commands/setup-mine.js +13 -8
  109. package/dist/commands/setup-preferences.js +2 -2
  110. package/dist/commands/setup-secrets.js +2 -2
  111. package/dist/commands/setup-watchdog.js +2 -2
  112. package/dist/commands/setup.js +7 -2
  113. package/dist/commands/share.d.ts +65 -0
  114. package/dist/commands/share.js +253 -20
  115. package/dist/commands/skills.js +3 -3
  116. package/dist/commands/snapshot.d.ts +2 -2
  117. package/dist/commands/snapshot.js +9 -9
  118. package/dist/commands/ssh.d.ts +1 -1
  119. package/dist/commands/ssh.js +186 -64
  120. package/dist/commands/subagents.js +1 -1
  121. package/dist/commands/sync.js +24 -9
  122. package/dist/commands/teams.d.ts +2 -2
  123. package/dist/commands/teams.js +9 -18
  124. package/dist/commands/tmux.js +5 -1
  125. package/dist/commands/trash.js +1 -1
  126. package/dist/commands/usage.d.ts +1 -1
  127. package/dist/commands/usage.js +2 -2
  128. package/dist/commands/utils.d.ts +4 -14
  129. package/dist/commands/utils.js +6 -27
  130. package/dist/commands/versions.js +2 -2
  131. package/dist/commands/view.d.ts +9 -77
  132. package/dist/commands/view.js +23 -8
  133. package/dist/commands/watchdog.js +1 -1
  134. package/dist/commands/webhook.js +25 -34
  135. package/dist/commands/workflows.js +1 -1
  136. package/dist/index.js +1 -1
  137. package/dist/lib/account-capabilities.d.ts +39 -0
  138. package/dist/lib/account-capabilities.js +59 -0
  139. package/dist/lib/account-catalog.js +1 -1
  140. package/dist/lib/account-registry.d.ts +66 -0
  141. package/dist/lib/account-registry.js +151 -5
  142. package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
  143. package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
  144. package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
  145. package/dist/lib/{usage.js → accounting/usage.js} +11 -11
  146. package/dist/lib/agent-spec/provider.js +1 -1
  147. package/dist/lib/agents.d.ts +72 -4
  148. package/dist/lib/agents.js +231 -199
  149. package/dist/lib/answer-router.d.ts +2 -2
  150. package/dist/lib/ask-classifier.d.ts +1 -1
  151. package/dist/lib/ask-classifier.js +1 -1
  152. package/dist/lib/audit/log.js +1 -1
  153. package/dist/lib/auth-health.d.ts +1 -1
  154. package/dist/lib/auth-health.js +2 -2
  155. package/dist/lib/brand.js +1 -1
  156. package/dist/lib/browser/caller-identity.d.ts +28 -0
  157. package/dist/lib/browser/caller-identity.js +156 -0
  158. package/dist/lib/browser/cdp.js +5 -1
  159. package/dist/lib/browser/chrome.js +12 -1
  160. package/dist/lib/browser/drivers/ssh.d.ts +1 -1
  161. package/dist/lib/browser/drivers/ssh.js +3 -2
  162. package/dist/lib/browser/hygiene.d.ts +10 -2
  163. package/dist/lib/browser/hygiene.js +7 -4
  164. package/dist/lib/browser/ipc.d.ts +22 -2
  165. package/dist/lib/browser/ipc.js +185 -21
  166. package/dist/lib/browser/profiles.d.ts +69 -5
  167. package/dist/lib/browser/profiles.js +135 -13
  168. package/dist/lib/browser/remote-control.d.ts +2 -2
  169. package/dist/lib/browser/remote-control.js +3 -3
  170. package/dist/lib/browser/runtime-state.d.ts +79 -0
  171. package/dist/lib/browser/runtime-state.js +119 -1
  172. package/dist/lib/browser/service.d.ts +137 -2
  173. package/dist/lib/browser/service.js +492 -54
  174. package/dist/lib/browser/sessions-list.d.ts +2 -1
  175. package/dist/lib/browser/sessions-list.js +4 -13
  176. package/dist/lib/browser/types.d.ts +19 -1
  177. package/dist/lib/budget/config.js +1 -1
  178. package/dist/lib/budget/ledger.js +1 -1
  179. package/dist/lib/byok-usage.js +1 -1
  180. package/dist/lib/capabilities.js +3 -15
  181. package/dist/lib/catchup.d.ts +1 -1
  182. package/dist/lib/catchup.js +1 -1
  183. package/dist/lib/cloud/dispatch.js +1 -1
  184. package/dist/lib/cloud/host.d.ts +3 -3
  185. package/dist/lib/cloud/host.js +5 -5
  186. package/dist/lib/cloud/rush.d.ts +9 -21
  187. package/dist/lib/cloud/rush.js +33 -120
  188. package/dist/lib/cloud/types.d.ts +2 -2
  189. package/dist/lib/commands.js +3 -13
  190. package/dist/lib/computer/actions.d.ts +36 -0
  191. package/dist/lib/computer/actions.js +162 -0
  192. package/dist/lib/computer/dispatch.d.ts +2 -2
  193. package/dist/lib/computer/dispatch.js +2 -2
  194. package/dist/lib/computer/sessions-list.d.ts +3 -3
  195. package/dist/lib/computer/sessions-list.js +2 -2
  196. package/dist/lib/config-keys.d.ts +2 -1
  197. package/dist/lib/config-keys.js +8 -4
  198. package/dist/lib/config-machine-keys.d.ts +4 -2
  199. package/dist/lib/config-machine-keys.js +5 -2
  200. package/dist/lib/crabbox/lease.js +9 -1
  201. package/dist/lib/crabbox/runtimes.d.ts +32 -7
  202. package/dist/lib/crabbox/runtimes.js +72 -30
  203. package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
  204. package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
  205. package/dist/lib/daemon-services.d.ts +1 -1
  206. package/dist/lib/daemon-services.js +5 -0
  207. package/dist/lib/daemon-ticks.d.ts +25 -0
  208. package/dist/lib/daemon-ticks.js +31 -1
  209. package/dist/lib/daemon-webhooks.d.ts +104 -0
  210. package/dist/lib/daemon-webhooks.js +215 -0
  211. package/dist/lib/device-config.d.ts +85 -75
  212. package/dist/lib/device-config.js +280 -142
  213. package/dist/lib/devices/config-migration.d.ts +29 -34
  214. package/dist/lib/devices/config-migration.js +209 -130
  215. package/dist/lib/devices/connect.d.ts +2 -2
  216. package/dist/lib/devices/connect.js +2 -2
  217. package/dist/lib/devices/discovery-policy.d.ts +30 -0
  218. package/dist/lib/devices/discovery-policy.js +101 -0
  219. package/dist/lib/devices/fleet-inventory.js +8 -3
  220. package/dist/lib/devices/harness-inventory.d.ts +1 -1
  221. package/dist/lib/devices/harness-inventory.js +12 -3
  222. package/dist/lib/devices/known-hosts.js +1 -1
  223. package/dist/lib/devices/pool.d.ts +10 -5
  224. package/dist/lib/devices/pool.js +5 -7
  225. package/dist/lib/devices/registry.d.ts +1 -1
  226. package/dist/lib/devices/registry.js +1 -1
  227. package/dist/lib/devices/resolve-profile.d.ts +2 -2
  228. package/dist/lib/devices/resolve-profile.js +2 -2
  229. package/dist/lib/devices/resolve-target.d.ts +1 -1
  230. package/dist/lib/devices/resolve-target.js +4 -4
  231. package/dist/lib/devices/self-host.d.ts +1 -1
  232. package/dist/lib/devices/self-host.js +3 -3
  233. package/dist/lib/devices/ssh-config.d.ts +1 -1
  234. package/dist/lib/devices/stats-cache.js +1 -1
  235. package/dist/lib/devices/sync.d.ts +3 -1
  236. package/dist/lib/devices/sync.js +3 -3
  237. package/dist/lib/doctor-diff.js +4 -4
  238. package/dist/lib/drift-sync.js +2 -2
  239. package/dist/lib/drift.js +2 -2
  240. package/dist/lib/event-families.d.ts +1 -1
  241. package/dist/lib/event-stream.d.ts +1 -1
  242. package/dist/lib/event-stream.js +2 -2
  243. package/dist/lib/events-ingest.js +2 -2
  244. package/dist/lib/exec.d.ts +4 -4
  245. package/dist/lib/exec.js +11 -11
  246. package/dist/lib/factory/snapshot.d.ts +1 -1
  247. package/dist/lib/factory/snapshot.js +1 -1
  248. package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
  249. package/dist/lib/{activity.js → feed/activity.js} +7 -7
  250. package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
  251. package/dist/lib/{events.js → feed/events.js} +5 -5
  252. package/dist/lib/{feed.js → feed/feed.js} +4 -4
  253. package/dist/lib/feed-outcome.d.ts +1 -1
  254. package/dist/lib/feed-policy.d.ts +1 -1
  255. package/dist/lib/feed-policy.js +1 -1
  256. package/dist/lib/feed-post.d.ts +1 -1
  257. package/dist/lib/feed-post.js +1 -1
  258. package/dist/lib/feed-ranking.d.ts +1 -1
  259. package/dist/lib/fleet/apply.d.ts +0 -6
  260. package/dist/lib/fleet/apply.js +18 -45
  261. package/dist/lib/fleet/auth-sync.d.ts +16 -35
  262. package/dist/lib/fleet/auth-sync.js +16 -75
  263. package/dist/lib/fleet/capture.js +8 -6
  264. package/dist/lib/fleet/manifest.js +23 -11
  265. package/dist/lib/fleet/types.d.ts +19 -7
  266. package/dist/lib/fleet-cache.d.ts +1 -1
  267. package/dist/lib/fleet-cache.js +1 -1
  268. package/dist/lib/format.d.ts +19 -0
  269. package/dist/lib/format.js +44 -1
  270. package/dist/lib/friction-heuristics.d.ts +1 -1
  271. package/dist/lib/git.d.ts +24 -1
  272. package/dist/lib/git.js +82 -38
  273. package/dist/lib/heal.js +3 -3
  274. package/dist/lib/hooks.d.ts +18 -0
  275. package/dist/lib/hooks.js +113 -1
  276. package/dist/lib/hosts/credentials.d.ts +30 -10
  277. package/dist/lib/hosts/credentials.js +38 -26
  278. package/dist/lib/hosts/dispatch.d.ts +3 -3
  279. package/dist/lib/hosts/dispatch.js +3 -3
  280. package/dist/lib/hosts/option.d.ts +3 -3
  281. package/dist/lib/hosts/option.js +7 -8
  282. package/dist/lib/hosts/passthrough.d.ts +17 -17
  283. package/dist/lib/hosts/passthrough.js +67 -50
  284. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  285. package/dist/lib/hosts/providers/devices.js +1 -1
  286. package/dist/lib/hosts/reconcile.d.ts +1 -1
  287. package/dist/lib/hosts/reconcile.js +1 -1
  288. package/dist/lib/hosts/reconnect.d.ts +1 -1
  289. package/dist/lib/hosts/reconnect.js +2 -2
  290. package/dist/lib/hosts/registry.d.ts +5 -5
  291. package/dist/lib/hosts/registry.js +5 -5
  292. package/dist/lib/hosts/remote-cmd.d.ts +10 -10
  293. package/dist/lib/hosts/remote-cmd.js +25 -18
  294. package/dist/lib/hosts/remote-os.d.ts +4 -4
  295. package/dist/lib/hosts/remote-os.js +4 -4
  296. package/dist/lib/hosts/remote-session-id.d.ts +2 -2
  297. package/dist/lib/hosts/remote-session-id.js +2 -2
  298. package/dist/lib/hosts/routing-flag.d.ts +3 -3
  299. package/dist/lib/hosts/routing-flag.js +4 -5
  300. package/dist/lib/hosts/run-target.d.ts +4 -4
  301. package/dist/lib/hosts/run-target.js +4 -4
  302. package/dist/lib/hosts/session-index.d.ts +2 -2
  303. package/dist/lib/hosts/session-index.js +1 -1
  304. package/dist/lib/hosts/session-marker.d.ts +1 -1
  305. package/dist/lib/hosts/session-marker.js +1 -1
  306. package/dist/lib/hosts/types.d.ts +2 -2
  307. package/dist/lib/hosts/types.js +2 -2
  308. package/dist/lib/import.js +1 -1
  309. package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
  310. package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
  311. package/dist/lib/installations/resolve.js +1 -1
  312. package/dist/lib/installations/strategies.js +1 -1
  313. package/dist/lib/installations/update.js +2 -2
  314. package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
  315. package/dist/lib/{versions.js → installations/versions.js} +51 -31
  316. package/dist/lib/isolation-boundary-report.js +1 -1
  317. package/dist/lib/linear-projects.d.ts +28 -0
  318. package/dist/lib/linear-projects.js +30 -0
  319. package/dist/lib/loop.js +1 -1
  320. package/dist/lib/mailbox-gc.js +1 -1
  321. package/dist/lib/mailbox.js +1 -1
  322. package/dist/lib/mcp-registry.d.ts +62 -0
  323. package/dist/lib/mcp-registry.js +177 -0
  324. package/dist/lib/mcp.d.ts +5 -0
  325. package/dist/lib/mcp.js +124 -307
  326. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  327. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  328. package/dist/lib/menubar/install-menubar.d.ts +7 -0
  329. package/dist/lib/menubar/install-menubar.js +24 -6
  330. package/dist/lib/menubar/snapshot.d.ts +7 -0
  331. package/dist/lib/menubar/snapshot.js +8 -6
  332. package/dist/lib/models.js +1 -1
  333. package/dist/lib/monitors/config.d.ts +12 -0
  334. package/dist/lib/monitors/config.js +3 -0
  335. package/dist/lib/monitors/dispatch.js +26 -5
  336. package/dist/lib/monitors/engine.js +10 -0
  337. package/dist/lib/monitors/sources/webhook.d.ts +1 -1
  338. package/dist/lib/monitors/state.d.ts +42 -0
  339. package/dist/lib/monitors/state.js +30 -0
  340. package/dist/lib/notify.d.ts +1 -1
  341. package/dist/lib/observe-aliases.d.ts +3 -3
  342. package/dist/lib/observe-aliases.js +3 -21
  343. package/dist/lib/output/git-output.js +2 -2
  344. package/dist/lib/overdue.d.ts +1 -1
  345. package/dist/lib/overdue.js +1 -1
  346. package/dist/lib/permissions-registry.d.ts +65 -0
  347. package/dist/lib/permissions-registry.js +599 -0
  348. package/dist/lib/permissions.d.ts +24 -13
  349. package/dist/lib/permissions.js +52 -271
  350. package/dist/lib/picker.d.ts +16 -0
  351. package/dist/lib/picker.js +33 -3
  352. package/dist/lib/placement.d.ts +1 -1
  353. package/dist/lib/placement.js +4 -4
  354. package/dist/lib/platform/paths.d.ts +8 -0
  355. package/dist/lib/platform/paths.js +11 -0
  356. package/dist/lib/platform/posixpath.js +3 -3
  357. package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
  358. package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
  359. package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
  360. package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
  361. package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
  362. package/dist/lib/{skills.js → plugins/skills.js} +7 -7
  363. package/dist/lib/pricing/cost.d.ts +1 -1
  364. package/dist/lib/pricing/cost.js +1 -1
  365. package/dist/lib/profiles-presets.d.ts +1 -1
  366. package/dist/lib/profiles-presets.js +1 -1
  367. package/dist/lib/profiles.js +2 -2
  368. package/dist/lib/project-import.js +4 -1
  369. package/dist/lib/project-key.js +7 -0
  370. package/dist/lib/project-launch.d.ts +1 -1
  371. package/dist/lib/project-launch.js +3 -3
  372. package/dist/lib/project-pull.d.ts +128 -0
  373. package/dist/lib/project-pull.js +384 -0
  374. package/dist/lib/project-root.d.ts +2 -2
  375. package/dist/lib/project-root.js +2 -2
  376. package/dist/lib/project-status.js +1 -1
  377. package/dist/lib/projects.d.ts +23 -0
  378. package/dist/lib/projects.js +29 -6
  379. package/dist/lib/refresh.d.ts +12 -1
  380. package/dist/lib/refresh.js +16 -9
  381. package/dist/lib/registry.d.ts +9 -2
  382. package/dist/lib/registry.js +11 -4
  383. package/dist/lib/resources.d.ts +2 -2
  384. package/dist/lib/resources.js +2 -2
  385. package/dist/lib/routers.d.ts +81 -0
  386. package/dist/lib/routers.js +153 -0
  387. package/dist/lib/routine-context.d.ts +1 -0
  388. package/dist/lib/routine-context.js +7 -2
  389. package/dist/lib/routine-notify-owner.d.ts +1 -1
  390. package/dist/lib/routine-notify.d.ts +1 -1
  391. package/dist/lib/routine-notify.js +1 -1
  392. package/dist/lib/routine-process-cleanup.d.ts +1 -1
  393. package/dist/lib/routine-readiness.d.ts +1 -1
  394. package/dist/lib/routine-readiness.js +11 -4
  395. package/dist/lib/routines-placement.d.ts +12 -2
  396. package/dist/lib/routines-placement.js +20 -3
  397. package/dist/lib/routines-project.d.ts +1 -1
  398. package/dist/lib/routines-project.js +1 -1
  399. package/dist/lib/rules/compile.d.ts +1 -0
  400. package/dist/lib/rules/compile.js +10 -2
  401. package/dist/lib/rules/rules.js +1 -1
  402. package/dist/lib/run-notify.js +1 -1
  403. package/dist/lib/runner.d.ts +80 -2
  404. package/dist/lib/runner.js +261 -67
  405. package/dist/lib/sandbox.d.ts +1 -1
  406. package/dist/lib/scheduler.d.ts +1 -1
  407. package/dist/lib/scheduler.js +1 -1
  408. package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
  409. package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
  410. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  411. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  412. package/dist/lib/secrets/agent.js +2 -2
  413. package/dist/lib/secrets/audit.js +1 -1
  414. package/dist/lib/secrets/bundles.d.ts +4 -4
  415. package/dist/lib/secrets/bundles.js +8 -8
  416. package/dist/lib/secrets/headless.d.ts +16 -0
  417. package/dist/lib/secrets/headless.js +21 -0
  418. package/dist/lib/secrets/index.js +1 -1
  419. package/dist/lib/secrets/list-filter.d.ts +1 -1
  420. package/dist/lib/secrets/list-filter.js +2 -2
  421. package/dist/lib/secrets/push.d.ts +1 -1
  422. package/dist/lib/secrets/push.js +10 -12
  423. package/dist/lib/secrets/remote.d.ts +21 -17
  424. package/dist/lib/secrets/remote.js +39 -23
  425. package/dist/lib/secrets/vault.js +2 -2
  426. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  427. package/dist/lib/self-heal/checks/shims.js +1 -1
  428. package/dist/lib/self-update.d.ts +39 -4
  429. package/dist/lib/self-update.js +78 -25
  430. package/dist/lib/serve/control.d.ts +1 -1
  431. package/dist/lib/serve/control.js +4 -4
  432. package/dist/lib/serve/data.d.ts +1 -1
  433. package/dist/lib/serve/data.js +1 -1
  434. package/dist/lib/serve/stream.js +1 -1
  435. package/dist/lib/service-manifest.d.ts +29 -0
  436. package/dist/lib/service-manifest.js +80 -0
  437. package/dist/lib/session/active.d.ts +59 -7
  438. package/dist/lib/session/active.js +158 -17
  439. package/dist/lib/session/bash-command.js +1 -1
  440. package/dist/lib/session/claude-accounts.d.ts +1 -1
  441. package/dist/lib/session/claude-accounts.js +1 -1
  442. package/dist/lib/session/db.d.ts +10 -2
  443. package/dist/lib/session/db.js +25 -6
  444. package/dist/lib/session/discover.d.ts +77 -0
  445. package/dist/lib/session/discover.js +130 -25
  446. package/dist/lib/session/fork.js +1 -1
  447. package/dist/lib/session/inject.d.ts +1 -1
  448. package/dist/lib/session/insights.d.ts +1 -1
  449. package/dist/lib/session/insights.js +1 -1
  450. package/dist/lib/session/live-metadata.d.ts +15 -0
  451. package/dist/lib/session/live-metadata.js +76 -0
  452. package/dist/lib/session/migrate-targets.d.ts +1 -1
  453. package/dist/lib/session/recovery.d.ts +1 -1
  454. package/dist/lib/session/recovery.js +2 -2
  455. package/dist/lib/session/remote-active.d.ts +10 -1
  456. package/dist/lib/session/remote-active.js +8 -3
  457. package/dist/lib/session/remote-bundle.d.ts +1 -1
  458. package/dist/lib/session/remote-bundle.js +2 -2
  459. package/dist/lib/session/remote-list.d.ts +15 -4
  460. package/dist/lib/session/remote-list.js +40 -3
  461. package/dist/lib/session/remote.d.ts +5 -5
  462. package/dist/lib/session/remote.js +13 -17
  463. package/dist/lib/session/resume-command.d.ts +3 -2
  464. package/dist/lib/session/resume-command.js +4 -3
  465. package/dist/lib/session/resume-owner.d.ts +3 -3
  466. package/dist/lib/session/resume-owner.js +3 -3
  467. package/dist/lib/session/session-cache.d.ts +12 -0
  468. package/dist/lib/session/session-cache.js +2 -0
  469. package/dist/lib/session/share-html.d.ts +55 -0
  470. package/dist/lib/session/share-html.js +319 -0
  471. package/dist/lib/session/shell-programs.js +1 -1
  472. package/dist/lib/session/state.js +5 -5
  473. package/dist/lib/session/team-filter.d.ts +1 -1
  474. package/dist/lib/session/team-filter.js +1 -1
  475. package/dist/lib/session/types.d.ts +3 -3
  476. package/dist/lib/session/width.d.ts +2 -2
  477. package/dist/lib/session/width.js +2 -2
  478. package/dist/lib/settings-manifest.d.ts +2 -0
  479. package/dist/lib/settings-manifest.js +81 -3
  480. package/dist/lib/share/delete.d.ts +21 -0
  481. package/dist/lib/share/delete.js +42 -0
  482. package/dist/lib/share/publish.d.ts +120 -0
  483. package/dist/lib/share/publish.js +243 -18
  484. package/dist/lib/share/worker-template.js +172 -9
  485. package/dist/lib/shims.js +35 -7
  486. package/dist/lib/smart-launch.d.ts +4 -4
  487. package/dist/lib/smart-launch.js +6 -4
  488. package/dist/lib/snapshot.d.ts +4 -4
  489. package/dist/lib/snapshot.js +2 -2
  490. package/dist/lib/ssh-exec.d.ts +1 -1
  491. package/dist/lib/ssh-exec.js +2 -2
  492. package/dist/lib/ssh-tunnel.d.ts +10 -10
  493. package/dist/lib/ssh-tunnel.js +12 -12
  494. package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
  495. package/dist/lib/staleness/checkers/hooks.js +1 -1
  496. package/dist/lib/staleness/detectors/permissions.js +0 -23
  497. package/dist/lib/staleness/detectors/plugins.js +1 -1
  498. package/dist/lib/staleness/fingerprint.js +1 -1
  499. package/dist/lib/staleness/layers.d.ts +1 -1
  500. package/dist/lib/staleness/layers.js +1 -1
  501. package/dist/lib/staleness/writers/mcp.js +3 -1
  502. package/dist/lib/staleness/writers/plugins.js +1 -1
  503. package/dist/lib/staleness/writers/types.d.ts +8 -0
  504. package/dist/lib/startup/command-registry.d.ts +6 -147
  505. package/dist/lib/startup/command-registry.js +40 -303
  506. package/dist/lib/startup/dev-build.d.ts +0 -21
  507. package/dist/lib/startup/dev-build.js +29 -8
  508. package/dist/lib/state.d.ts +19 -1
  509. package/dist/lib/state.js +120 -51
  510. package/dist/lib/subagents.js +1 -1
  511. package/dist/lib/sync-status.js +1 -1
  512. package/dist/lib/sync-umbrella.d.ts +6 -1
  513. package/dist/lib/sync-umbrella.js +9 -4
  514. package/dist/lib/teams/agents.js +2 -2
  515. package/dist/lib/teams/registry.js +1 -1
  516. package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
  517. package/dist/lib/terminal/engine.js +1 -1
  518. package/dist/lib/terminal/index.d.ts +4 -0
  519. package/dist/lib/terminal/index.js +3 -0
  520. package/dist/lib/terminal/inject.d.ts +2 -2
  521. package/dist/lib/terminal/inject.js +2 -2
  522. package/dist/lib/terminal/transport.js +1 -1
  523. package/dist/lib/tmux/index.d.ts +1 -1
  524. package/dist/lib/tmux/index.js +1 -1
  525. package/dist/lib/tmux/session.d.ts +21 -5
  526. package/dist/lib/tmux/session.js +76 -22
  527. package/dist/lib/triggers/handlers.d.ts +38 -3
  528. package/dist/lib/triggers/handlers.js +58 -7
  529. package/dist/lib/triggers/webhook.d.ts +113 -5
  530. package/dist/lib/triggers/webhook.js +223 -44
  531. package/dist/lib/types.d.ts +19 -7
  532. package/dist/lib/usage-fleet.d.ts +1 -1
  533. package/dist/lib/usage-fleet.js +1 -1
  534. package/dist/lib/usage-refresh.d.ts +1 -1
  535. package/dist/lib/usage-refresh.js +3 -3
  536. package/dist/lib/version-duplicates.js +2 -2
  537. package/dist/lib/view-types.d.ts +56 -0
  538. package/dist/lib/view-types.js +1 -0
  539. package/dist/lib/watchdog/rotate.d.ts +2 -2
  540. package/dist/lib/watchdog/rotate.js +3 -3
  541. package/dist/lib/watchdog/runner.d.ts +2 -3
  542. package/dist/lib/watchdog/runner.js +3 -4
  543. package/dist/lib/workflows.js +1 -1
  544. package/dist/lib/wrap.d.ts +33 -0
  545. package/dist/lib/wrap.js +70 -0
  546. package/package.json +2 -1
  547. package/scripts/postinstall.js +2 -2
  548. package/dist/commands/bench.d.ts +0 -2
  549. package/dist/commands/bench.js +0 -101
  550. package/dist/commands/cp.d.ts +0 -84
  551. package/dist/commands/cp.js +0 -231
  552. package/dist/commands/login.d.ts +0 -2
  553. package/dist/lib/resources/commands.d.ts +0 -46
  554. package/dist/lib/resources/commands.js +0 -211
  555. package/dist/lib/resources/hooks.d.ts +0 -16
  556. package/dist/lib/resources/hooks.js +0 -153
  557. package/dist/lib/resources/mcp.d.ts +0 -34
  558. package/dist/lib/resources/mcp.js +0 -250
  559. package/dist/lib/resources/memory.d.ts +0 -15
  560. package/dist/lib/resources/memory.js +0 -46
  561. package/dist/lib/resources/permissions.d.ts +0 -13
  562. package/dist/lib/resources/permissions.js +0 -202
  563. package/dist/lib/resources/rules.d.ts +0 -46
  564. package/dist/lib/resources/rules.js +0 -179
  565. package/dist/lib/resources/skills.d.ts +0 -37
  566. package/dist/lib/resources/skills.js +0 -247
  567. package/dist/lib/resources/subagents.d.ts +0 -46
  568. package/dist/lib/resources/subagents.js +0 -202
  569. /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
@@ -3,8 +3,53 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { IS_WINDOWS, ipcEndpoint } from '../platform/index.js';
5
5
  import { getHelpersDir } from '../state.js';
6
- import { startDaemon, stopDaemon } from '../daemon.js';
6
+ import { resolveBrowserTaskIdleMs } from '../device-config.js';
7
+ import { startDaemon, stopDaemon } from '../daemon/daemon.js';
7
8
  import { getCliVersion } from '../version.js';
9
+ import { compareVersions } from '../agent-spec/primitives.js';
10
+ import { getDaemonLogPath } from '../daemon/daemon.js';
11
+ import { resolveCallerIdentity } from './caller-identity.js';
12
+ import { actionable } from './service.js';
13
+ /**
14
+ * Verbs that imply a page and may CREATE a task when none resolves.
15
+ * Observation-only verbs (console/logs/…) resolve but never create — an
16
+ * empty `agents browser logs` must not open a browser just to return [].
17
+ */
18
+ const PAGE_CREATE_VERBS = new Set([
19
+ 'navigate',
20
+ 'tab-add',
21
+ 'evaluate',
22
+ 'screenshot',
23
+ 'pdf',
24
+ 'refs',
25
+ 'click',
26
+ 'type',
27
+ 'press',
28
+ 'hover',
29
+ 'scroll',
30
+ 'set-viewport',
31
+ 'set-device',
32
+ 'wait',
33
+ 'set-download-path',
34
+ 'wait-download',
35
+ 'upload',
36
+ 'record-start',
37
+ ]);
38
+ /** Task-scoped verbs that resolve identity but never create. */
39
+ const PAGE_RESOLVE_VERBS = new Set([
40
+ ...PAGE_CREATE_VERBS,
41
+ 'tab-focus',
42
+ 'tab-close',
43
+ 'tab-list',
44
+ 'console',
45
+ 'errors',
46
+ 'requests',
47
+ 'response-body',
48
+ 'getAppLogs',
49
+ 'record-stop',
50
+ ]);
51
+ /** Close verbs never create a task. */
52
+ const CLOSE_VERBS = new Set(['done', 'stop']);
8
53
  const SOCKET_NAME = 'browser.sock';
9
54
  /**
10
55
  * Backstop for {@link BrowserIPCServer.stop} — how long to wait for the socket
@@ -102,7 +147,8 @@ export class BrowserIPCConnection {
102
147
  });
103
148
  }
104
149
  request(request) {
105
- const result = this.tail.then(() => this.requestOnce(request));
150
+ const stamped = stampCallerIdentity(request);
151
+ const result = this.tail.then(() => this.requestOnce(stamped));
106
152
  this.tail = result.then(() => undefined, () => undefined);
107
153
  return result;
108
154
  }
@@ -318,6 +364,44 @@ export class BrowserIPCServer {
318
364
  this.connections.clear();
319
365
  });
320
366
  }
367
+ /**
368
+ * Resolve `request.task` from caller identity when omitted. Page verbs may
369
+ * create; done/stop never create. Returns an error response to short-circuit
370
+ * the action, or undefined when the request is ready (task filled in).
371
+ */
372
+ async bindTask(request) {
373
+ const createIfMissing = PAGE_CREATE_VERBS.has(request.action);
374
+ const isClose = CLOSE_VERBS.has(request.action);
375
+ // stop with --profile only (no task) is handled by the stop case itself.
376
+ if (request.action === 'stop' && request.profile && !request.task)
377
+ return undefined;
378
+ try {
379
+ const resolved = await this.service.resolveOrCreateTask({
380
+ task: request.task,
381
+ profile: request.profile,
382
+ actor: request.actor,
383
+ launchId: request.launchId,
384
+ sessionId: request.sessionId,
385
+ createIfMissing,
386
+ title: request.title,
387
+ url: request.url,
388
+ });
389
+ if (!resolved) {
390
+ if (isClose) {
391
+ return { ok: true, message: 'nothing to close' };
392
+ }
393
+ return {
394
+ ok: false,
395
+ error: actionable('No browser task for this session.', 'Next: agents browser navigate <url> | agents browser start'),
396
+ };
397
+ }
398
+ request.task = resolved.task.name;
399
+ return undefined;
400
+ }
401
+ catch (err) {
402
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
403
+ }
404
+ }
321
405
  async handleRequest(request) {
322
406
  if (request.action === 'upload-stage') {
323
407
  const source = request.source;
@@ -327,13 +411,19 @@ export class BrowserIPCServer {
327
411
  const result = this.service.stageUpload(source);
328
412
  return { ok: true, path: result.path };
329
413
  }
414
+ // Task-scoped actions: resolve identity / create / refuse once here.
415
+ if (PAGE_RESOLVE_VERBS.has(request.action) || CLOSE_VERBS.has(request.action)) {
416
+ const early = await this.bindTask(request);
417
+ if (early)
418
+ return early;
419
+ }
330
420
  switch (request.action) {
331
421
  case 'version': {
332
422
  return { ok: true, version: getCliVersion() };
333
423
  }
334
424
  case 'start': {
335
425
  if (!request.profile) {
336
- return { ok: false, error: 'Profile required' };
426
+ return { ok: false, error: actionable('Profile required.', 'Next: agents browser profiles list') };
337
427
  }
338
428
  const result = await this.service.start(request.profile, {
339
429
  taskName: request.taskName,
@@ -344,6 +434,7 @@ export class BrowserIPCServer {
344
434
  actor: request.actor,
345
435
  launchId: request.launchId,
346
436
  sessionId: request.sessionId,
437
+ title: request.title,
347
438
  });
348
439
  return {
349
440
  ok: true,
@@ -358,29 +449,48 @@ export class BrowserIPCServer {
358
449
  // only reach `reapAbandoned` through IPC. The daemon's own periodic tick
359
450
  // calls the service method directly.
360
451
  case 'gc': {
361
- const reaped = await this.service.reapAbandoned({
362
- idleMs: request.idleMinutes !== undefined ? request.idleMinutes * 60_000 : undefined,
363
- dryRun: request.dryRun,
364
- });
452
+ // 0 is the "disable idle reaping" signal (browser.task-idle-minutes),
453
+ // not a zero-ms window translate it to reapAbandoned's `null` rather
454
+ // than let it hit the idleMs<=0 guard. Omitting the flag falls back to
455
+ // this box's own configured default (or 30 minutes when unset).
456
+ const idleMs = request.idleMinutes !== undefined
457
+ ? (request.idleMinutes === 0 ? null : request.idleMinutes * 60_000)
458
+ : resolveBrowserTaskIdleMs();
459
+ const reaped = await this.service.reapAbandoned({ idleMs, dryRun: request.dryRun });
365
460
  return { ok: true, reaped };
366
461
  }
367
462
  case 'done': {
368
463
  if (!request.task) {
369
- return { ok: false, error: 'Task required' };
464
+ return { ok: true, message: 'nothing to close' };
370
465
  }
371
466
  const result = await this.service.done(request.task);
372
- return { ok: result.ok, error: result.ok ? undefined : 'Task not found' };
467
+ return {
468
+ ok: result.ok,
469
+ error: result.ok
470
+ ? undefined
471
+ : actionable(`Task "${request.task}" not found.`, 'Next: agents browser status'),
472
+ task: result.ok ? request.task : undefined,
473
+ };
373
474
  }
374
475
  case 'stop': {
375
476
  if (request.task) {
376
477
  const result = await this.service.stop(request.task);
377
- return { ok: result.ok, error: result.ok ? undefined : 'Task not found' };
478
+ return {
479
+ ok: result.ok,
480
+ error: result.ok
481
+ ? undefined
482
+ : actionable(`Task "${request.task}" not found.`, 'Next: agents browser status'),
483
+ task: result.ok ? request.task : undefined,
484
+ };
378
485
  }
379
486
  if (request.profile) {
380
487
  await this.service.stopProfile(request.profile);
381
488
  return { ok: true };
382
489
  }
383
- return { ok: false, error: 'Task or profile required' };
490
+ return {
491
+ ok: false,
492
+ error: actionable('Task or profile required.', 'Next: agents browser status | agents browser stop --profile <name>'),
493
+ };
384
494
  }
385
495
  case 'status': {
386
496
  const profiles = await this.service.status(request.profile);
@@ -391,11 +501,20 @@ export class BrowserIPCServer {
391
501
  return { ok: true, history };
392
502
  }
393
503
  case 'navigate': {
394
- if (!request.task || !request.url) {
395
- return { ok: false, error: 'Task and URL required' };
504
+ if (!request.url) {
505
+ return {
506
+ ok: false,
507
+ error: actionable('URL required.', 'Next: agents browser navigate <url>'),
508
+ };
509
+ }
510
+ if (!request.task) {
511
+ return {
512
+ ok: false,
513
+ error: actionable('No browser task for this session.', 'Next: agents browser navigate <url> | agents browser start'),
514
+ };
396
515
  }
397
516
  const result = await this.service.navigate(request.task, request.url, request.profile);
398
- return { ok: true, tabId: result.tabId };
517
+ return { ok: true, tabId: result.tabId, task: request.task };
399
518
  }
400
519
  case 'tab-add': {
401
520
  if (!request.task || !request.url) {
@@ -460,10 +579,20 @@ export class BrowserIPCServer {
460
579
  }
461
580
  case 'screenshot': {
462
581
  if (!request.task) {
463
- return { ok: false, error: 'Task required' };
582
+ return {
583
+ ok: false,
584
+ error: actionable('No browser task for this session.', 'Next: agents browser navigate <url> | agents browser start'),
585
+ };
464
586
  }
465
587
  const shot = await this.service.screenshot(request.task, request.tabId, request.path, request.quality);
466
- return { ok: true, path: shot.path, bytes: shot.bytes, width: shot.width, height: shot.height };
588
+ return {
589
+ ok: true,
590
+ path: shot.path,
591
+ bytes: shot.bytes,
592
+ width: shot.width,
593
+ height: shot.height,
594
+ task: request.task,
595
+ };
467
596
  }
468
597
  case 'pdf': {
469
598
  if (!request.task) {
@@ -658,15 +787,32 @@ export class BrowserIPCServer {
658
787
  }
659
788
  let versionReconciledThisProcess = false;
660
789
  /**
661
- * Decide whether a running daemon is stale and must be restarted. A daemon
662
- * is stale when it reports a concrete version that differs from this CLI's.
790
+ * Decide whether a running daemon is stale and must be restarted.
791
+ *
792
+ * FORWARD ONLY: restart when the daemon is *older* than this CLI so a newer
793
+ * install loads current code. An older CLI rides a newer daemon instead of
794
+ * evicting it — two installs sharing one daemon dir (keyed off $HOME) must
795
+ * not flap the daemon indefinitely.
796
+ *
663
797
  * `undefined`/`'unknown'` means the daemon is too old to answer the `version`
664
798
  * action reliably — don't churn it on that ambiguous signal.
799
+ *
800
+ * When numeric compare cannot order two distinct strings (e.g. two
801
+ * `0.0.0-dev.*` builds), treat the mismatch as a restart so a concrete
802
+ * code change still loads.
665
803
  */
666
804
  export function shouldRestartStaleDaemon(daemonVersion, clientVersion) {
667
805
  if (!daemonVersion || daemonVersion === 'unknown')
668
806
  return false;
669
- return daemonVersion !== clientVersion;
807
+ if (daemonVersion === clientVersion)
808
+ return false;
809
+ const cmp = compareVersions(daemonVersion, clientVersion);
810
+ if (cmp < 0)
811
+ return true; // daemon older than client → upgrade forward
812
+ if (cmp > 0)
813
+ return false; // daemon newer → older CLI rides it
814
+ // cmp === 0 but strings differ (unorderable tails like 0.0.0-dev.abc)
815
+ return true;
670
816
  }
671
817
  /**
672
818
  * Reconcile the running daemon's version with ours. If the daemon is serving
@@ -700,7 +846,25 @@ async function reconcileDaemonVersion(socketPath) {
700
846
  await new Promise((r) => setTimeout(r, 300));
701
847
  }
702
848
  export async function sendIPCRequest(request, opts = {}) {
703
- return sendRawIPCRequest(request, opts);
849
+ // Stamp caller identity ONCE here so the 28+ call sites don't each have to.
850
+ // The daemon cannot resolve the caller's actor/session itself.
851
+ const stamped = stampCallerIdentity(request);
852
+ return sendRawIPCRequest(stamped, opts);
853
+ }
854
+ /**
855
+ * Fill actor / launchId / sessionId from the calling process when the request
856
+ * left them blank. Explicit values on the request always win.
857
+ */
858
+ export function stampCallerIdentity(request) {
859
+ if (request.actor && request.launchId && request.sessionId)
860
+ return request;
861
+ const id = resolveCallerIdentity();
862
+ return {
863
+ ...request,
864
+ actor: request.actor ?? id.actor,
865
+ launchId: request.launchId ?? id.launchId,
866
+ sessionId: request.sessionId ?? id.sessionId,
867
+ };
704
868
  }
705
869
  /**
706
870
  * Open one connection that can serve many browser operations. This uses the
@@ -776,7 +940,7 @@ async function prepareIPC(action, opts) {
776
940
  await waitForSocket(socketPath, 6000);
777
941
  }
778
942
  if (!(await isDaemonReachable())) {
779
- throw new Error('Failed to start browser daemon');
943
+ throw new Error(actionable('Failed to start browser daemon.', `Log: ${getDaemonLogPath()}`, 'Next: agents doctor (checks for a second agents-cli install)'));
780
944
  }
781
945
  await new Promise((r) => setTimeout(r, 300));
782
946
  }
@@ -1,13 +1,24 @@
1
1
  import type { BrowserProfile } from './types.js';
2
2
  export type { BrowserProfile } from './types.js';
3
3
  export declare const DEFAULT_BROWSER_PROFILE_NAME = "default";
4
+ /**
5
+ * Where a profile is stored, and therefore who sees it:
6
+ * - `local` — this machine's `devices/<machine>/agents.yaml` (`deviceBrowser`)
7
+ * - `fleet` — the synced `~/.agents/agents.yaml` (`browser`), visible on every box
8
+ */
9
+ export type ProfileScope = 'local' | 'fleet';
10
+ /** A profile plus the store it actually lives in. */
11
+ export interface ScopedBrowserProfile {
12
+ profile: BrowserProfile;
13
+ scope: ProfileScope;
14
+ }
4
15
  /**
5
16
  * The device-local configured default profile name (set via
6
- * `agents browser profiles set-default`), or undefined when unset. When set, it
17
+ * `agents browser use`), or undefined when unset. When set, it
7
18
  * is the profile `agents browser start` resolves to for BOTH the no-`--profile`
8
19
  * path and an explicit `--profile default`. Stored as this machine's
9
- * `browser.profile` device-config key (central `fleet.devices.<name>.config`
10
- * block — see lib/device-config.ts).
20
+ * `browser.profile` device-config key (the per-device doc's `config:` block —
21
+ * see lib/device-config.ts).
11
22
  */
12
23
  export declare function getConfiguredDefaultProfileName(): string | undefined;
13
24
  export declare function getBrowserRuntimeDir(): string;
@@ -26,6 +37,12 @@ export declare function getProfileDownloadsDir(name: string): string;
26
37
  */
27
38
  export declare function getProfileSessionsDir(name: string, task: string): string;
28
39
  export declare function listProfiles(): Promise<BrowserProfile[]>;
40
+ /**
41
+ * Every visible profile paired with the store it lives in. Same precedence as
42
+ * {@link listProfiles} — a machine-local entry wins a name collision, so a name
43
+ * present in both maps reports `local`, which is the copy that is actually used.
44
+ */
45
+ export declare function listProfilesWithScope(): Promise<ScopedBrowserProfile[]>;
29
46
  export declare function getProfile(name: string): Promise<BrowserProfile | null>;
30
47
  /**
31
48
  * True when `profile` can actually launch or attach on THIS machine.
@@ -45,7 +62,7 @@ export declare function isProfileLaunchableHere(profile: BrowserProfile): boolea
45
62
  * set-default <name>`) when it names an existing profile that can launch here;
46
63
  * (2) an existing `default` profile that can launch here; (3) auto-pick the
47
64
  * first installed Chromium-family browser per the platform priority list in
48
- * chrome.ts (macOS: chrome > brave > edge > chromium > comet; Linux: chrome >
65
+ * chrome.ts (macOS: chrome > brave > edge > chromium > comet > arc; Linux: chrome >
49
66
  * chromium > brave > edge; Windows: edge > chrome > brave > comet) and pin a
50
67
  * `default` profile to it. Throws an actionable error if none of those binaries
51
68
  * are installed.
@@ -77,9 +94,56 @@ export declare function effectiveLocalPort(profile: BrowserProfile): number | un
77
94
  * skip remote profiles in this scan.
78
95
  */
79
96
  export declare function findFreeProfilePort(): Promise<number>;
80
- export declare function createProfile(profile: BrowserProfile): Promise<void>;
97
+ /**
98
+ * Create a profile. **It lands in this machine's own store by default** — pass
99
+ * `{ fleet: true }` (the CLI's `--fleet`) to put it in the synced `agents.yaml`
100
+ * where every box will see it.
101
+ *
102
+ * Local-by-default is the RUSH-2716 fix. A profile is a local browser install
103
+ * (`binary:` is an absolute path for one OS) bound to a locally chosen free port,
104
+ * so the fleet-synced copy is wrong on every other machine to begin with; and
105
+ * because agents mint throwaway profiles freely, every ad-hoc one was syncing to
106
+ * every machine as junk that nothing cleaned up (`agents browser profiles prune`
107
+ * is the other half of that fix). Opting in with `--fleet` is for a profile that
108
+ * really is fleet config — a remote `ssh://` endpoint, or a named profile whose
109
+ * shape you want on every box.
110
+ *
111
+ * Existing profiles are NOT migrated: this only decides where a NEW entry is
112
+ * written, so a fleet profile created before this change keeps syncing.
113
+ */
114
+ export declare function createProfile(profile: BrowserProfile, opts?: {
115
+ fleet?: boolean;
116
+ }): Promise<void>;
81
117
  export declare function updateProfile(profile: BrowserProfile): Promise<void>;
82
118
  export declare function deleteProfile(name: string): Promise<void>;
119
+ /**
120
+ * Pad `text` to exactly `width` visible characters, truncating with an ellipsis
121
+ * when it does not fit. `padEnd` alone does NOT bound a long value — it returns
122
+ * the string unchanged when it already exceeds the width, which is what pushed
123
+ * every later column out of alignment on a name longer than 20 characters
124
+ * (RUSH-2710). Every column here goes through this, never a bare `padEnd`.
125
+ */
126
+ export declare function padColumn(text: string, width: number): string;
127
+ /**
128
+ * Render the `agents browser profiles list` table.
129
+ *
130
+ * Pure (no fs, no config reads) so the alignment and the default-marking rules
131
+ * are unit-testable without a configured machine.
132
+ *
133
+ * Two things used to be called "default" in this listing with no way to tell
134
+ * them apart (RUSH-2710): the profile literally NAMED `default` (the
135
+ * auto-detected one), and whichever profile this machine resolves a bare
136
+ * `agents browser start` to (`agents browser use <name>`). They
137
+ * are frequently different profiles. Now only the second is a marker — a `*` in
138
+ * a leading column, explained by a legend line — so the name column carries just
139
+ * the name and `default` in it always means the profile of that name.
140
+ *
141
+ * The SCOPE column is the RUSH-2716 companion: it says whether an entry lives on
142
+ * this machine only (`local`) or in the fleet-synced `agents.yaml` (`fleet`), so
143
+ * "why does this box have a profile I never made here?" is answerable at a
144
+ * glance.
145
+ */
146
+ export declare function formatProfilesTable(rows: ScopedBrowserProfile[], configuredDefault?: string): string[];
83
147
  /**
84
148
  * Resolve a profile's endpoint presets into a normalized map regardless of
85
149
  * whether the YAML uses the legacy `string[]` shape or the new map shape.
@@ -8,23 +8,28 @@ export const DEFAULT_BROWSER_PROFILE_NAME = 'default';
8
8
  * True for a profile whose contents only make sense on THIS machine, so it must
9
9
  * live in the per-machine doc rather than the fleet-synced agents.yaml.
10
10
  *
11
- * Only the auto-detected `default` qualifies: it is generated by probing local
11
+ * The auto-detected `default` always qualifies: it is generated by probing local
12
12
  * browser installs and a free local port, so its `binary:` is an absolute path
13
13
  * for one OS. Shared fleet-wide it caused a permanent rewrite loop — a macOS box
14
14
  * wrote `/Applications/...`, a Linux box rewrote `/usr/bin/chromium-browser`,
15
- * each on every `agents browser start`. Named profiles a user created are real
16
- * fleet config and keep syncing.
15
+ * each on every `agents browser start`.
16
+ *
17
+ * As of RUSH-2716 it is not the only one: EVERY newly created profile is
18
+ * machine-local unless the caller explicitly asks for the fleet-synced store
19
+ * (`createProfile(p, { fleet: true })` / `--fleet`). See {@link createProfile}.
20
+ * This predicate is what keeps an existing `default` that an older version wrote
21
+ * into central from being written back there by {@link updateProfile}.
17
22
  */
18
23
  function isMachineLocalProfile(name) {
19
24
  return name === DEFAULT_BROWSER_PROFILE_NAME;
20
25
  }
21
26
  /**
22
27
  * The device-local configured default profile name (set via
23
- * `agents browser profiles set-default`), or undefined when unset. When set, it
28
+ * `agents browser use`), or undefined when unset. When set, it
24
29
  * is the profile `agents browser start` resolves to for BOTH the no-`--profile`
25
30
  * path and an explicit `--profile default`. Stored as this machine's
26
- * `browser.profile` device-config key (central `fleet.devices.<name>.config`
27
- * block — see lib/device-config.ts).
31
+ * `browser.profile` device-config key (the per-device doc's `config:` block —
32
+ * see lib/device-config.ts).
28
33
  */
29
34
  export function getConfiguredDefaultProfileName() {
30
35
  return getConfigValue('browser.profile').value || undefined;
@@ -112,6 +117,19 @@ export async function listProfiles() {
112
117
  const configs = allProfileConfigs();
113
118
  return Object.entries(configs).map(([name, config]) => configToProfile(name, config));
114
119
  }
120
+ /**
121
+ * Every visible profile paired with the store it lives in. Same precedence as
122
+ * {@link listProfiles} — a machine-local entry wins a name collision, so a name
123
+ * present in both maps reports `local`, which is the copy that is actually used.
124
+ */
125
+ export async function listProfilesWithScope() {
126
+ const meta = readMeta();
127
+ const local = meta.deviceBrowser ?? {};
128
+ return Object.entries(allProfileConfigs()).map(([name, config]) => ({
129
+ profile: configToProfile(name, config),
130
+ scope: (local[name] ? 'local' : 'fleet'),
131
+ }));
132
+ }
115
133
  export async function getProfile(name) {
116
134
  const config = allProfileConfigs()[name];
117
135
  if (!config)
@@ -147,7 +165,7 @@ export function isProfileLaunchableHere(profile) {
147
165
  * set-default <name>`) when it names an existing profile that can launch here;
148
166
  * (2) an existing `default` profile that can launch here; (3) auto-pick the
149
167
  * first installed Chromium-family browser per the platform priority list in
150
- * chrome.ts (macOS: chrome > brave > edge > chromium > comet; Linux: chrome >
168
+ * chrome.ts (macOS: chrome > brave > edge > chromium > comet > arc; Linux: chrome >
151
169
  * chromium > brave > edge; Windows: edge > chrome > brave > comet) and pin a
152
170
  * `default` profile to it. Throws an actionable error if none of those binaries
153
171
  * are installed.
@@ -169,18 +187,18 @@ export async function ensureDefaultBrowserProfile() {
169
187
  console.warn(chosen
170
188
  ? `warning: configured default browser profile "${configured}" can't launch on this ` +
171
189
  `machine (its browser/binary isn't installed here); falling back to auto-detect. ` +
172
- `Fix with: agents browser profiles set-default <name> (or --unset)`
190
+ `Fix with: agents browser use <name> (or --unset)`
173
191
  : `warning: configured default browser profile "${configured}" no longer exists; ` +
174
- `falling back to auto-detect. Fix with: agents browser profiles set-default <name> (or --unset)`);
192
+ `falling back to auto-detect. Fix with: agents browser use <name> (or --unset)`);
175
193
  }
176
194
  const existing = await getProfile(DEFAULT_BROWSER_PROFILE_NAME);
177
195
  if (existing && isProfileLaunchableHere(existing))
178
196
  return existing;
179
197
  const detected = findFirstInstalledBrowser();
180
198
  if (!detected) {
181
- throw new Error('No supported browser found. Install one of: Chrome, Brave, Edge, Chromium, or Comet, ' +
199
+ throw new Error('No supported browser found. Install one of: Chrome, Brave, Edge, Chromium, Comet, or Arc, ' +
182
200
  'then re-run `agents browser start`. Or create a profile explicitly with ' +
183
- '`agents browser profiles create <name> --browser <chrome|comet|chromium|brave|edge|custom>`. ' +
201
+ '`agents browser profiles create <name> --browser <chrome|comet|chromium|brave|edge|arc|custom>`. ' +
184
202
  'Note: Safari and Firefox are not supported — agents browser drives over the ' +
185
203
  'Chrome DevTools Protocol, which they don\'t implement.');
186
204
  }
@@ -292,7 +310,24 @@ function hasSshEndpoint(endpoints) {
292
310
  }
293
311
  });
294
312
  }
295
- export async function createProfile(profile) {
313
+ /**
314
+ * Create a profile. **It lands in this machine's own store by default** — pass
315
+ * `{ fleet: true }` (the CLI's `--fleet`) to put it in the synced `agents.yaml`
316
+ * where every box will see it.
317
+ *
318
+ * Local-by-default is the RUSH-2716 fix. A profile is a local browser install
319
+ * (`binary:` is an absolute path for one OS) bound to a locally chosen free port,
320
+ * so the fleet-synced copy is wrong on every other machine to begin with; and
321
+ * because agents mint throwaway profiles freely, every ad-hoc one was syncing to
322
+ * every machine as junk that nothing cleaned up (`agents browser profiles prune`
323
+ * is the other half of that fix). Opting in with `--fleet` is for a profile that
324
+ * really is fleet config — a remote `ssh://` endpoint, or a named profile whose
325
+ * shape you want on every box.
326
+ *
327
+ * Existing profiles are NOT migrated: this only decides where a NEW entry is
328
+ * written, so a fleet profile created before this change keeps syncing.
329
+ */
330
+ export async function createProfile(profile, opts = {}) {
296
331
  const meta = readMeta();
297
332
  const existingConfigs = allProfileConfigs();
298
333
  if (existingConfigs[profile.name]) {
@@ -327,7 +362,11 @@ export async function createProfile(profile) {
327
362
  findBrowserPath(profile.browser, profile.binary);
328
363
  }
329
364
  const config = profileToConfig(profile);
330
- if (isMachineLocalProfile(profile.name)) {
365
+ // Machine-local unless the caller explicitly asked for the fleet store. The
366
+ // auto `default` is always local regardless of what a caller passes — its
367
+ // binary path and port are this box's, and fleet-syncing it is the rewrite
368
+ // loop RUSH-2161 fixed.
369
+ if (!opts.fleet || isMachineLocalProfile(profile.name)) {
331
370
  updateMeta((m) => ({ ...m, deviceBrowser: { ...m.deviceBrowser, [profile.name]: config } }));
332
371
  return;
333
372
  }
@@ -365,6 +404,89 @@ export async function deleteProfile(name) {
365
404
  return { ...m, browser: Object.keys(next).length > 0 ? next : undefined };
366
405
  });
367
406
  }
407
+ /** Widest NAME column we will grow to before truncating instead. */
408
+ const MAX_NAME_COLUMN = 28;
409
+ /**
410
+ * Pad `text` to exactly `width` visible characters, truncating with an ellipsis
411
+ * when it does not fit. `padEnd` alone does NOT bound a long value — it returns
412
+ * the string unchanged when it already exceeds the width, which is what pushed
413
+ * every later column out of alignment on a name longer than 20 characters
414
+ * (RUSH-2710). Every column here goes through this, never a bare `padEnd`.
415
+ */
416
+ export function padColumn(text, width) {
417
+ if (width <= 0)
418
+ return '';
419
+ if (text.length <= width)
420
+ return text.padEnd(width);
421
+ if (width === 1)
422
+ return '…';
423
+ return text.slice(0, width - 1) + '…';
424
+ }
425
+ /**
426
+ * Render the `agents browser profiles list` table.
427
+ *
428
+ * Pure (no fs, no config reads) so the alignment and the default-marking rules
429
+ * are unit-testable without a configured machine.
430
+ *
431
+ * Two things used to be called "default" in this listing with no way to tell
432
+ * them apart (RUSH-2710): the profile literally NAMED `default` (the
433
+ * auto-detected one), and whichever profile this machine resolves a bare
434
+ * `agents browser start` to (`agents browser use <name>`). They
435
+ * are frequently different profiles. Now only the second is a marker — a `*` in
436
+ * a leading column, explained by a legend line — so the name column carries just
437
+ * the name and `default` in it always means the profile of that name.
438
+ *
439
+ * The SCOPE column is the RUSH-2716 companion: it says whether an entry lives on
440
+ * this machine only (`local`) or in the fleet-synced `agents.yaml` (`fleet`), so
441
+ * "why does this box have a profile I never made here?" is answerable at a
442
+ * glance.
443
+ */
444
+ export function formatProfilesTable(rows, configuredDefault) {
445
+ const cells = rows.map(({ profile, scope }) => {
446
+ const presets = getEndpointPresets(profile);
447
+ const endpoints = Object.entries(presets)
448
+ .map(([name, ep]) => (name.startsWith('endpoint-') ? ep.target : `${name}=${ep.target}`))
449
+ .join(', ');
450
+ return {
451
+ marker: profile.name === configuredDefault ? '*' : ' ',
452
+ name: profile.name,
453
+ browser: profile.browser || '-',
454
+ scope,
455
+ description: profile.description ?? '',
456
+ endpoints,
457
+ };
458
+ });
459
+ const nameWidth = Math.min(MAX_NAME_COLUMN, Math.max('NAME'.length, ...cells.map((c) => c.name.length)));
460
+ const browserWidth = Math.max('BROWSER'.length, ...cells.map((c) => c.browser.length));
461
+ // 'local' / 'fleet' are both 5 chars, so the header is the widest value.
462
+ const scopeWidth = 'SCOPE'.length;
463
+ const hasDescriptions = cells.some((c) => c.description);
464
+ const descWidth = hasDescriptions
465
+ ? Math.min(36, Math.max('DESCRIPTION'.length, ...cells.map((c) => c.description.length)))
466
+ : 0;
467
+ const row = (marker, name, browser, scope, desc, endpoints) => `${marker} ` +
468
+ padColumn(name, nameWidth) + ' ' +
469
+ padColumn(browser, browserWidth) + ' ' +
470
+ padColumn(scope, scopeWidth) + ' ' +
471
+ (hasDescriptions ? padColumn(desc, descWidth) + ' ' : '') +
472
+ endpoints;
473
+ const header = row(' ', 'NAME', 'BROWSER', 'SCOPE', 'DESCRIPTION', 'ENDPOINTS');
474
+ const lines = [header, '-'.repeat(header.length)];
475
+ for (const c of cells) {
476
+ lines.push(row(c.marker, c.name, c.browser, c.scope, c.description, c.endpoints));
477
+ }
478
+ if (configuredDefault) {
479
+ lines.push('');
480
+ lines.push(`* = this machine's default profile (${configuredDefault}) — what a bare \`agents browser start\` uses.`);
481
+ }
482
+ lines.push(hasFleetRow(rows)
483
+ ? 'scope: local = this machine only · fleet = synced to every machine (agents.yaml).'
484
+ : 'scope: local = this machine only. Create a synced one with: agents browser profiles create <name> --fleet');
485
+ return lines;
486
+ }
487
+ function hasFleetRow(rows) {
488
+ return rows.some((r) => r.scope === 'fleet');
489
+ }
368
490
  /**
369
491
  * Resolve a profile's endpoint presets into a normalized map regardless of
370
492
  * whether the YAML uses the legacy `string[]` shape or the new map shape.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Consent gate for driving THIS machine's browser from another fleet machine.
3
3
  *
4
- * `browser --host <device>` routes a browser command to `<device>` over SSH (the
4
+ * `browser --device <device>` routes a browser command to `<device>` over SSH (the
5
5
  * fleet passthrough) and runs `agents browser ...` there. Every such remote
6
6
  * invocation carries the {@link FLEET_REMOTE_ENV} marker, set once at the fleet
7
7
  * dispatch site (`maybeRunOnHost`). A machine only accepts being driven when its
@@ -14,7 +14,7 @@
14
14
  */
15
15
  /** Env marker set on every remote `agents` invocation by `buildRemoteAgentsInvocation`. */
16
16
  export declare const FLEET_REMOTE_ENV = "AGENTS_FLEET_REMOTE";
17
- /** True when this process was dispatched to this machine by a fleet `--host` run. */
17
+ /** True when this process was dispatched to this machine by a fleet `--device` run. */
18
18
  export declare function isFleetRemoteInvocation(env?: NodeJS.ProcessEnv): boolean;
19
19
  /**
20
20
  * Whether this machine allows other fleet machines to drive its browser. Reads