@phnx-labs/agents-cli 1.22.34 → 1.22.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (493) hide show
  1. package/CHANGELOG.md +672 -2
  2. package/README.md +82 -35
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1211 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/attach.js +17 -4
  9. package/dist/commands/audit.d.ts +8 -8
  10. package/dist/commands/audit.js +57 -47
  11. package/dist/commands/browser.js +15 -11
  12. package/dist/commands/cloud.js +1 -1
  13. package/dist/commands/commands.js +0 -11
  14. package/dist/commands/computer-actions.js +33 -0
  15. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  16. package/dist/commands/computer-sessions-picker.js +141 -0
  17. package/dist/commands/computer.d.ts +16 -0
  18. package/dist/commands/computer.js +37 -0
  19. package/dist/commands/config.d.ts +17 -0
  20. package/dist/commands/config.js +401 -0
  21. package/dist/commands/cp.d.ts +84 -0
  22. package/dist/commands/cp.js +231 -0
  23. package/dist/commands/daemon.js +243 -14
  24. package/dist/commands/detach-core.d.ts +1 -1
  25. package/dist/commands/detach-core.js +12 -2
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +64 -5
  28. package/dist/commands/events.d.ts +24 -12
  29. package/dist/commands/events.js +144 -28
  30. package/dist/commands/exec.js +85 -41
  31. package/dist/commands/feed.d.ts +1 -1
  32. package/dist/commands/feed.js +16 -8
  33. package/dist/commands/focus.d.ts +33 -1
  34. package/dist/commands/focus.js +177 -17
  35. package/dist/commands/funnel.d.ts +1 -1
  36. package/dist/commands/go.js +9 -8
  37. package/dist/commands/harness-wizard.d.ts +1 -0
  38. package/dist/commands/harness-wizard.js +18 -20
  39. package/dist/commands/harness.d.ts +2 -0
  40. package/dist/commands/harness.js +59 -26
  41. package/dist/commands/hooks.js +0 -11
  42. package/dist/commands/inspect.d.ts +94 -1
  43. package/dist/commands/inspect.js +866 -40
  44. package/dist/commands/lease.d.ts +4 -4
  45. package/dist/commands/lease.js +6 -6
  46. package/dist/commands/login.js +0 -13
  47. package/dist/commands/logs.d.ts +2 -2
  48. package/dist/commands/logs.js +2 -2
  49. package/dist/commands/mcp.js +7 -2
  50. package/dist/commands/memory.js +7 -2
  51. package/dist/commands/message.d.ts +1 -1
  52. package/dist/commands/message.js +37 -6
  53. package/dist/commands/models.js +4 -0
  54. package/dist/commands/monitors.d.ts +0 -1
  55. package/dist/commands/monitors.js +199 -16
  56. package/dist/commands/open.d.ts +18 -0
  57. package/dist/commands/open.js +57 -0
  58. package/dist/commands/packages.js +2 -107
  59. package/dist/commands/plugins.js +6 -3
  60. package/dist/commands/profiles.d.ts +1 -0
  61. package/dist/commands/profiles.js +16 -160
  62. package/dist/commands/projects.d.ts +28 -0
  63. package/dist/commands/projects.js +125 -5
  64. package/dist/commands/reconnect.js +9 -3
  65. package/dist/commands/repo.js +42 -1
  66. package/dist/commands/resource-view.d.ts +17 -0
  67. package/dist/commands/resource-view.js +36 -14
  68. package/dist/commands/resume.js +9 -2
  69. package/dist/commands/routines.d.ts +0 -2
  70. package/dist/commands/routines.js +473 -289
  71. package/dist/commands/secrets.js +52 -9
  72. package/dist/commands/sessions-export.d.ts +47 -0
  73. package/dist/commands/sessions-export.js +116 -6
  74. package/dist/commands/sessions-import.d.ts +17 -0
  75. package/dist/commands/sessions-import.js +114 -6
  76. package/dist/commands/sessions-migrate.d.ts +27 -0
  77. package/dist/commands/sessions-migrate.js +50 -9
  78. package/dist/commands/sessions-picker.js +23 -4
  79. package/dist/commands/sessions-resume.d.ts +5 -3
  80. package/dist/commands/sessions-resume.js +30 -8
  81. package/dist/commands/sessions-watch.d.ts +2 -0
  82. package/dist/commands/sessions-watch.js +53 -0
  83. package/dist/commands/sessions.d.ts +66 -3
  84. package/dist/commands/sessions.js +298 -47
  85. package/dist/commands/set.d.ts +1 -1
  86. package/dist/commands/set.js +2 -2
  87. package/dist/commands/setup-browser.js +2 -2
  88. package/dist/commands/setup-mine.js +0 -1
  89. package/dist/commands/setup-preferences.js +1 -1
  90. package/dist/commands/setup-share.js +34 -4
  91. package/dist/commands/setup.d.ts +5 -0
  92. package/dist/commands/setup.js +26 -0
  93. package/dist/commands/share.d.ts +85 -0
  94. package/dist/commands/share.js +379 -8
  95. package/dist/commands/skills.js +0 -11
  96. package/dist/commands/snapshot.js +1 -1
  97. package/dist/commands/ssh.d.ts +18 -0
  98. package/dist/commands/ssh.js +549 -210
  99. package/dist/commands/sync.d.ts +5 -0
  100. package/dist/commands/sync.js +212 -32
  101. package/dist/commands/teams.d.ts +13 -0
  102. package/dist/commands/teams.js +187 -30
  103. package/dist/commands/tickets.d.ts +2 -0
  104. package/dist/commands/tickets.js +43 -0
  105. package/dist/commands/update.js +2 -4
  106. package/dist/commands/usage.js +5 -3
  107. package/dist/commands/versions.js +11 -5
  108. package/dist/commands/view.js +15 -7
  109. package/dist/commands/webhook.d.ts +2 -2
  110. package/dist/commands/webhook.js +7 -7
  111. package/dist/index.d.ts +18 -2
  112. package/dist/index.js +53 -1264
  113. package/dist/lib/account-catalog.d.ts +18 -0
  114. package/dist/lib/account-catalog.js +38 -0
  115. package/dist/lib/account-provider-registry.d.ts +18 -0
  116. package/dist/lib/account-provider-registry.js +59 -0
  117. package/dist/lib/account-registry.d.ts +40 -0
  118. package/dist/lib/account-registry.js +239 -0
  119. package/dist/lib/account-schema.d.ts +44 -0
  120. package/dist/lib/account-schema.js +91 -0
  121. package/dist/lib/account-state-service.d.ts +21 -0
  122. package/dist/lib/account-state-service.js +60 -0
  123. package/dist/lib/activity.d.ts +1 -1
  124. package/dist/lib/activity.js +8 -1
  125. package/dist/lib/add-dir.d.ts +80 -0
  126. package/dist/lib/add-dir.js +241 -0
  127. package/dist/lib/agent-cli-commands.d.ts +11 -0
  128. package/dist/lib/agent-cli-commands.js +30 -0
  129. package/dist/lib/agents.js +44 -36
  130. package/dist/lib/answer-router.js +1 -1
  131. package/dist/lib/audit/log.d.ts +10 -27
  132. package/dist/lib/audit/log.js +20 -33
  133. package/dist/lib/auth-health.d.ts +9 -2
  134. package/dist/lib/auth-health.js +42 -9
  135. package/dist/lib/auto-pull-worker.js +7 -3
  136. package/dist/lib/auto-pull.d.ts +44 -3
  137. package/dist/lib/auto-pull.js +88 -5
  138. package/dist/lib/binary-shadow.d.ts +28 -0
  139. package/dist/lib/binary-shadow.js +121 -0
  140. package/dist/lib/brand.js +9 -3
  141. package/dist/lib/browser/ipc.d.ts +30 -0
  142. package/dist/lib/browser/ipc.js +81 -4
  143. package/dist/lib/browser/profiles.d.ts +3 -2
  144. package/dist/lib/browser/profiles.js +65 -22
  145. package/dist/lib/browser/service.d.ts +4 -0
  146. package/dist/lib/browser/service.js +30 -3
  147. package/dist/lib/browser/sessions-list.d.ts +22 -2
  148. package/dist/lib/browser/sessions-list.js +54 -6
  149. package/dist/lib/browser/stream.d.ts +2 -0
  150. package/dist/lib/browser/stream.js +1 -0
  151. package/dist/lib/browser/types.d.ts +19 -0
  152. package/dist/lib/byok-usage.d.ts +9 -2
  153. package/dist/lib/byok-usage.js +133 -31
  154. package/dist/lib/cli-entry.d.ts +11 -0
  155. package/dist/lib/cli-entry.js +46 -0
  156. package/dist/lib/cloud/host.d.ts +1 -1
  157. package/dist/lib/cloud/host.js +2 -2
  158. package/dist/lib/cloud/registry.js +1 -1
  159. package/dist/lib/cloud/types.d.ts +1 -1
  160. package/dist/lib/codex-policy.d.ts +9 -1
  161. package/dist/lib/codex-policy.js +17 -2
  162. package/dist/lib/commands.d.ts +2 -0
  163. package/dist/lib/commands.js +2 -0
  164. package/dist/lib/computer/sessions-list.d.ts +150 -0
  165. package/dist/lib/computer/sessions-list.js +363 -0
  166. package/dist/lib/config-keys.d.ts +86 -0
  167. package/dist/lib/config-keys.js +193 -0
  168. package/dist/lib/config-machine-keys.d.ts +12 -0
  169. package/dist/lib/config-machine-keys.js +17 -0
  170. package/dist/lib/config-transfer.js +3 -4
  171. package/dist/lib/crabbox/cli.d.ts +2 -2
  172. package/dist/lib/crabbox/cli.js +3 -3
  173. package/dist/lib/daemon-health.d.ts +22 -0
  174. package/dist/lib/daemon-health.js +33 -3
  175. package/dist/lib/daemon-services.d.ts +50 -0
  176. package/dist/lib/daemon-services.js +147 -0
  177. package/dist/lib/daemon-ticks.d.ts +35 -66
  178. package/dist/lib/daemon-ticks.js +77 -159
  179. package/dist/lib/daemon.d.ts +72 -4
  180. package/dist/lib/daemon.js +792 -202
  181. package/dist/lib/deeplink/register.d.ts +49 -0
  182. package/dist/lib/deeplink/register.js +253 -0
  183. package/dist/lib/deeplink/url.d.ts +34 -0
  184. package/dist/lib/deeplink/url.js +78 -0
  185. package/dist/lib/device-config.d.ts +124 -29
  186. package/dist/lib/device-config.js +346 -141
  187. package/dist/lib/devices/config-migration.d.ts +42 -0
  188. package/dist/lib/devices/config-migration.js +203 -0
  189. package/dist/lib/devices/connect.js +14 -7
  190. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  191. package/dist/lib/devices/doctor-findings.js +20 -1
  192. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  193. package/dist/lib/devices/harness-inventory.js +0 -0
  194. package/dist/lib/devices/health.d.ts +1 -1
  195. package/dist/lib/devices/health.js +1 -1
  196. package/dist/lib/devices/pending.d.ts +22 -1
  197. package/dist/lib/devices/pending.js +67 -2
  198. package/dist/lib/devices/registry.d.ts +0 -25
  199. package/dist/lib/devices/registry.js +2 -83
  200. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  201. package/dist/lib/devices/resolve-profile.js +44 -0
  202. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  203. package/dist/lib/devices/rollout-verify.js +193 -0
  204. package/dist/lib/devices/ssh-config.js +10 -6
  205. package/dist/lib/event-families.d.ts +28 -0
  206. package/dist/lib/event-families.js +159 -0
  207. package/dist/lib/event-stream.d.ts +9 -1
  208. package/dist/lib/event-stream.js +26 -9
  209. package/dist/lib/events.d.ts +9 -1
  210. package/dist/lib/events.js +21 -6
  211. package/dist/lib/exec.d.ts +30 -0
  212. package/dist/lib/exec.js +220 -122
  213. package/dist/lib/feed-broadcast.d.ts +25 -0
  214. package/dist/lib/feed-broadcast.js +33 -0
  215. package/dist/lib/feed.d.ts +1 -1
  216. package/dist/lib/feed.js +12 -2
  217. package/dist/lib/fleet/capture.js +15 -0
  218. package/dist/lib/fleet/manifest.js +9 -0
  219. package/dist/lib/fleet/types.d.ts +9 -0
  220. package/dist/lib/fleet-status.js +10 -8
  221. package/dist/lib/git.d.ts +20 -6
  222. package/dist/lib/git.js +121 -17
  223. package/dist/lib/hosts/dispatch.d.ts +8 -3
  224. package/dist/lib/hosts/dispatch.js +29 -3
  225. package/dist/lib/hosts/logs.d.ts +2 -2
  226. package/dist/lib/hosts/logs.js +2 -2
  227. package/dist/lib/hosts/option.js +1 -1
  228. package/dist/lib/hosts/passthrough.d.ts +2 -3
  229. package/dist/lib/hosts/passthrough.js +10 -24
  230. package/dist/lib/hosts/progress.js +2 -2
  231. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  232. package/dist/lib/hosts/providers/devices.js +18 -12
  233. package/dist/lib/hosts/ready.d.ts +5 -1
  234. package/dist/lib/hosts/ready.js +9 -3
  235. package/dist/lib/hosts/reconcile.d.ts +2 -2
  236. package/dist/lib/hosts/reconcile.js +2 -2
  237. package/dist/lib/hosts/registry.js +14 -9
  238. package/dist/lib/hosts/remote-cmd.js +1 -1
  239. package/dist/lib/hosts/remote-os.d.ts +9 -6
  240. package/dist/lib/hosts/remote-os.js +13 -6
  241. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  242. package/dist/lib/hosts/routing-flag.js +41 -0
  243. package/dist/lib/hosts/run-target.js +1 -1
  244. package/dist/lib/hosts/session-index.js +1 -1
  245. package/dist/lib/hosts/tasks.d.ts +6 -6
  246. package/dist/lib/hosts/tasks.js +4 -4
  247. package/dist/lib/hosts/types.js +1 -2
  248. package/dist/lib/installations/resolve.js +2 -8
  249. package/dist/lib/isolation-boundary-report.js +0 -1
  250. package/dist/lib/linear-cache.d.ts +7 -0
  251. package/dist/lib/linear-cache.js +31 -4
  252. package/dist/lib/linear-project-counts.d.ts +1 -1
  253. package/dist/lib/linear-project-counts.js +2 -3
  254. package/dist/lib/linear-projects.js +1 -1
  255. package/dist/lib/loop.d.ts +2 -2
  256. package/dist/lib/loop.js +1 -1
  257. package/dist/lib/mailbox-target.d.ts +1 -1
  258. package/dist/lib/mailbox-target.js +1 -1
  259. package/dist/lib/manifest.js +7 -4
  260. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  262. package/dist/lib/menubar/snapshot.d.ts +3 -2
  263. package/dist/lib/menubar/snapshot.js +6 -2
  264. package/dist/lib/migrate-fold.d.ts +33 -0
  265. package/dist/lib/migrate-fold.js +130 -0
  266. package/dist/lib/migrate.d.ts +34 -34
  267. package/dist/lib/migrate.js +106 -128
  268. package/dist/lib/model-tier-overrides.d.ts +1 -1
  269. package/dist/lib/model-tier-overrides.js +15 -2
  270. package/dist/lib/monitors/config.d.ts +17 -3
  271. package/dist/lib/monitors/config.js +52 -18
  272. package/dist/lib/monitors/engine.d.ts +32 -1
  273. package/dist/lib/monitors/engine.js +94 -11
  274. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  275. package/dist/lib/monitors/fingerprint.js +100 -0
  276. package/dist/lib/monitors/remote.d.ts +47 -0
  277. package/dist/lib/monitors/remote.js +81 -0
  278. package/dist/lib/monitors/state.d.ts +39 -0
  279. package/dist/lib/monitors/state.js +56 -0
  280. package/dist/lib/onepassword.d.ts +17 -0
  281. package/dist/lib/onepassword.js +52 -22
  282. package/dist/lib/open-url.js +1 -1
  283. package/dist/lib/picker.d.ts +14 -2
  284. package/dist/lib/picker.js +35 -13
  285. package/dist/lib/placement.d.ts +1 -1
  286. package/dist/lib/placement.js +1 -1
  287. package/dist/lib/pr-land-detach.d.ts +32 -0
  288. package/dist/lib/pr-land-detach.js +79 -0
  289. package/dist/lib/profiles-presets.js +13 -0
  290. package/dist/lib/profiles.d.ts +2 -0
  291. package/dist/lib/profiles.js +44 -1
  292. package/dist/lib/project-focus.d.ts +1 -1
  293. package/dist/lib/project-focus.js +1 -1
  294. package/dist/lib/project-key.d.ts +17 -0
  295. package/dist/lib/project-key.js +26 -0
  296. package/dist/lib/project-probe.d.ts +4 -1
  297. package/dist/lib/project-probe.js +5 -4
  298. package/dist/lib/project-resources.js +2 -18
  299. package/dist/lib/project-root.d.ts +16 -0
  300. package/dist/lib/project-root.js +20 -2
  301. package/dist/lib/projects.d.ts +20 -1
  302. package/dist/lib/projects.js +78 -1
  303. package/dist/lib/refresh-coordinator.d.ts +24 -0
  304. package/dist/lib/refresh-coordinator.js +52 -0
  305. package/dist/lib/registry.d.ts +2 -2
  306. package/dist/lib/registry.js +1 -1
  307. package/dist/lib/resource-aliases.d.ts +13 -0
  308. package/dist/lib/resource-aliases.js +26 -0
  309. package/dist/lib/resources/types.d.ts +1 -1
  310. package/dist/lib/resources.d.ts +16 -0
  311. package/dist/lib/resources.js +66 -10
  312. package/dist/lib/rotate.d.ts +3 -4
  313. package/dist/lib/rotate.js +4 -5
  314. package/dist/lib/routine-activation.d.ts +22 -2
  315. package/dist/lib/routine-activation.js +63 -16
  316. package/dist/lib/routine-context.d.ts +9 -2
  317. package/dist/lib/routine-context.js +21 -6
  318. package/dist/lib/routines-project.d.ts +58 -48
  319. package/dist/lib/routines-project.js +190 -159
  320. package/dist/lib/routines.d.ts +41 -6
  321. package/dist/lib/routines.js +92 -34
  322. package/dist/lib/run-defaults.d.ts +5 -0
  323. package/dist/lib/run-defaults.js +11 -1
  324. package/dist/lib/runner.d.ts +10 -8
  325. package/dist/lib/runner.js +122 -39
  326. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  327. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  328. package/dist/lib/secrets/agent.d.ts +10 -3
  329. package/dist/lib/secrets/agent.js +43 -8
  330. package/dist/lib/secrets/bundles.d.ts +1 -0
  331. package/dist/lib/secrets/bundles.js +92 -80
  332. package/dist/lib/secrets/index.js +32 -9
  333. package/dist/lib/secrets/install-helper.d.ts +4 -4
  334. package/dist/lib/secrets/install-helper.js +4 -4
  335. package/dist/lib/secrets/push.d.ts +40 -6
  336. package/dist/lib/secrets/push.js +58 -11
  337. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  338. package/dist/lib/secrets/read-backoff.js +1 -1
  339. package/dist/lib/secrets/remote.d.ts +24 -0
  340. package/dist/lib/secrets/remote.js +54 -4
  341. package/dist/lib/self-update.d.ts +108 -0
  342. package/dist/lib/self-update.js +276 -1
  343. package/dist/lib/session/active.d.ts +89 -5
  344. package/dist/lib/session/active.js +165 -10
  345. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  346. package/dist/lib/session/actor-sidecar.js +2 -1
  347. package/dist/lib/session/db.d.ts +176 -2
  348. package/dist/lib/session/db.js +484 -17
  349. package/dist/lib/session/discover.js +27 -4
  350. package/dist/lib/session/hook-sessions.js +2 -2
  351. package/dist/lib/session/host-link.d.ts +2 -2
  352. package/dist/lib/session/host-link.js +2 -2
  353. package/dist/lib/session/pid-registry.d.ts +21 -0
  354. package/dist/lib/session/pid-registry.js +57 -0
  355. package/dist/lib/session/remote-active.js +15 -1
  356. package/dist/lib/session/remote.js +2 -2
  357. package/dist/lib/session/session-cache.d.ts +14 -7
  358. package/dist/lib/session/session-cache.js +51 -9
  359. package/dist/lib/session/state.d.ts +2 -2
  360. package/dist/lib/session/state.js +1 -1
  361. package/dist/lib/session/sync/config.d.ts +10 -10
  362. package/dist/lib/session/sync/config.js +10 -10
  363. package/dist/lib/session/sync/r2.d.ts +34 -0
  364. package/dist/lib/session/sync/r2.js +123 -0
  365. package/dist/lib/session/throughput.d.ts +1 -1
  366. package/dist/lib/session/throughput.js +1 -1
  367. package/dist/lib/session/types.d.ts +23 -1
  368. package/dist/lib/session/types.js +15 -0
  369. package/dist/lib/session/viewing-in.d.ts +1 -1
  370. package/dist/lib/session/viewing-in.js +1 -1
  371. package/dist/lib/session/watch.d.ts +101 -0
  372. package/dist/lib/session/watch.js +242 -0
  373. package/dist/lib/share/config.d.ts +4 -0
  374. package/dist/lib/share/config.js +1 -0
  375. package/dist/lib/share/delete.d.ts +93 -0
  376. package/dist/lib/share/delete.js +127 -0
  377. package/dist/lib/share/provision.d.ts +38 -0
  378. package/dist/lib/share/provision.js +50 -0
  379. package/dist/lib/share/publish.d.ts +40 -1
  380. package/dist/lib/share/publish.js +116 -3
  381. package/dist/lib/share/worker-template.js +71 -6
  382. package/dist/lib/shims.d.ts +17 -3
  383. package/dist/lib/shims.js +136 -27
  384. package/dist/lib/signin-badge.js +3 -2
  385. package/dist/lib/skills.js +2 -0
  386. package/dist/lib/smart-launch.d.ts +8 -8
  387. package/dist/lib/smart-launch.js +80 -59
  388. package/dist/lib/ssh-exec.d.ts +1 -1
  389. package/dist/lib/ssh-exec.js +1 -1
  390. package/dist/lib/staleness/prune.d.ts +88 -0
  391. package/dist/lib/staleness/prune.js +69 -0
  392. package/dist/lib/staleness/registry.d.ts +1 -1
  393. package/dist/lib/staleness/writers/commands.js +34 -2
  394. package/dist/lib/staleness/writers/hooks.js +16 -0
  395. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  396. package/dist/lib/staleness/writers/skills.js +19 -0
  397. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  398. package/dist/lib/staleness/writers/subagents.js +0 -4
  399. package/dist/lib/staleness/writers/types.d.ts +32 -0
  400. package/dist/lib/startup/command-registry.d.ts +6 -12
  401. package/dist/lib/startup/command-registry.js +14 -31
  402. package/dist/lib/startup/dev-build.d.ts +10 -0
  403. package/dist/lib/startup/dev-build.js +13 -1
  404. package/dist/lib/startup/spellcheck.d.ts +18 -0
  405. package/dist/lib/startup/spellcheck.js +45 -0
  406. package/dist/lib/state.d.ts +36 -9
  407. package/dist/lib/state.js +96 -46
  408. package/dist/lib/subagents-registry.d.ts +0 -7
  409. package/dist/lib/subagents-registry.js +38 -65
  410. package/dist/lib/subagents.d.ts +0 -33
  411. package/dist/lib/subagents.js +0 -75
  412. package/dist/lib/sync-umbrella.js +1 -1
  413. package/dist/lib/teams/agents.d.ts +41 -1
  414. package/dist/lib/teams/agents.js +187 -9
  415. package/dist/lib/teams/api.d.ts +11 -1
  416. package/dist/lib/teams/api.js +11 -2
  417. package/dist/lib/teams/delivery.d.ts +41 -0
  418. package/dist/lib/teams/delivery.js +60 -0
  419. package/dist/lib/teams/registry.d.ts +14 -0
  420. package/dist/lib/teams/registry.js +51 -1
  421. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  422. package/dist/lib/teams/remoteWorktree.js +29 -0
  423. package/dist/lib/teams/scheduler.d.ts +1 -1
  424. package/dist/lib/teams/scheduler.js +1 -1
  425. package/dist/lib/teams/worktree.d.ts +24 -0
  426. package/dist/lib/teams/worktree.js +42 -0
  427. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  428. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  429. package/dist/lib/terminal/engine.d.ts +4 -0
  430. package/dist/lib/terminal/engine.js +8 -2
  431. package/dist/lib/terminal/types.d.ts +21 -2
  432. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  433. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  434. package/dist/lib/tickets/list.d.ts +53 -0
  435. package/dist/lib/tickets/list.js +153 -0
  436. package/dist/lib/tmux/orphan-reap.d.ts +320 -0
  437. package/dist/lib/tmux/orphan-reap.js +644 -0
  438. package/dist/lib/tmux/session.d.ts +68 -3
  439. package/dist/lib/tmux/session.js +95 -5
  440. package/dist/lib/triggers/handlers.d.ts +20 -0
  441. package/dist/lib/triggers/handlers.js +6 -1
  442. package/dist/lib/types.d.ts +46 -34
  443. package/dist/lib/usage-fleet.d.ts +32 -0
  444. package/dist/lib/usage-fleet.js +125 -0
  445. package/dist/lib/usage-refresh.d.ts +3 -3
  446. package/dist/lib/usage-refresh.js +19 -16
  447. package/dist/lib/usage.d.ts +51 -47
  448. package/dist/lib/usage.js +145 -153
  449. package/dist/lib/version-duplicates.js +2 -2
  450. package/dist/lib/versions.d.ts +56 -13
  451. package/dist/lib/versions.js +195 -45
  452. package/dist/lib/watchdog/log.d.ts +1 -1
  453. package/dist/lib/watchdog/log.js +3 -3
  454. package/dist/lib/watchdog/rotate.d.ts +6 -6
  455. package/dist/lib/watchdog/rotate.js +6 -6
  456. package/dist/lib/workflows.d.ts +1 -1
  457. package/dist/lib/yaml-io.d.ts +47 -0
  458. package/dist/lib/yaml-io.js +55 -0
  459. package/package.json +2 -1
  460. package/scripts/install-helper.js +2 -2
  461. package/scripts/postinstall.js +23 -20
  462. package/dist/commands/defaults.d.ts +0 -7
  463. package/dist/commands/defaults.js +0 -107
  464. package/dist/commands/export.d.ts +0 -11
  465. package/dist/commands/export.js +0 -215
  466. package/dist/commands/helper.d.ts +0 -12
  467. package/dist/commands/helper.js +0 -87
  468. package/dist/commands/hosts.d.ts +0 -11
  469. package/dist/commands/hosts.js +0 -330
  470. package/dist/commands/lock.d.ts +0 -12
  471. package/dist/commands/lock.js +0 -70
  472. package/dist/commands/pull.d.ts +0 -17
  473. package/dist/commands/pull.js +0 -39
  474. package/dist/commands/push.d.ts +0 -14
  475. package/dist/commands/push.js +0 -30
  476. package/dist/commands/wallet.d.ts +0 -20
  477. package/dist/commands/wallet.js +0 -216
  478. package/dist/commands/worktree.d.ts +0 -19
  479. package/dist/commands/worktree.js +0 -272
  480. package/dist/lib/account-labels.d.ts +0 -24
  481. package/dist/lib/account-labels.js +0 -72
  482. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  483. package/dist/lib/auto-dispatch-linear.js +0 -107
  484. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  485. package/dist/lib/auto-dispatch-provider.js +0 -30
  486. package/dist/lib/auto-dispatch.d.ts +0 -93
  487. package/dist/lib/auto-dispatch.js +0 -128
  488. package/dist/lib/export.d.ts +0 -72
  489. package/dist/lib/export.js +0 -269
  490. package/dist/lib/lock.d.ts +0 -93
  491. package/dist/lib/lock.js +0 -207
  492. package/dist/lib/wallet/index.d.ts +0 -78
  493. package/dist/lib/wallet/index.js +0 -253
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Read-only task/run history over the `computer.action` event ledger
3
+ * (`~/.agents/.history/events/YYYY-MM-DD/events.jsonl`, see `../events.ts`) —
4
+ * the durable, already-existing audit log every `agents computer <verb>`
5
+ * invocation (the explicit CLI verbs in `commands/computer-actions.ts`, and
6
+ * the embedded `computer run` loop in `computer/dispatch.ts`) writes through
7
+ * `emitComputerAction()`. Backs both `agents computer sessions` and the
8
+ * `agents sessions --computer` alias.
9
+ *
10
+ * There is no separate capture directory the way browser tasks have
11
+ * `.cache/browser/<profile>/sessions/<task>/` — a computer action drives a
12
+ * live GUI in place and leaves no artifact of its own, so the event ledger
13
+ * IS the canonical execution source for this history (RUSH-2432, the
14
+ * computer counterpart of `../browser/sessions-list.ts`'s RUSH-2407
15
+ * task-first grouping).
16
+ *
17
+ * Retention/privacy: `events.ts` bounds and prunes the LEDGER
18
+ * (`DEFAULT_RETENTION_DAYS` / `DEFAULT_MAX_STORAGE_BYTES` — 7 days / 50 MiB
19
+ * by default, gzip-rotated at 10 MiB) and nothing here changes that policy or
20
+ * re-prunes that log. The durable `computer_sessions` table added in RUSH-2549
21
+ * is a SECOND store with its OWN, much longer bound
22
+ * (`TOOL_SESSION_MAX_AGE_DAYS`, swept by `pruneToolSessions` from the listing
23
+ * path below) — that is deliberate, since the table exists precisely to outlive
24
+ * the ledger's 7 days, and one row per CLI process would otherwise grow without
25
+ * limit. It is metadata only. Nothing sensitive is persisted: `type` /
26
+ * `type-text` events already carry only `textLength`, never the typed text
27
+ * (see `commands/computer-actions.ts` `emitComputerAction` call sites) — the
28
+ * mission this module fulfils changes NONE of that. A `run --task`
29
+ * description is the agent's OWN instruction, not typed-into-a-target-app
30
+ * content (the same class of thing `agents sessions` already stores
31
+ * unredacted as a session prompt) — it is kept, but bounded to
32
+ * {@link TASK_PREVIEW_MAX_CHARS} via `events.ts`'s `truncate()` before it is
33
+ * ever written (see `computer.ts` `registerRunCommand`), never the full
34
+ * unbounded text, and it is not the wire-shape `prompt` field so it is a
35
+ * deliberate exception to (not a bypass of) the automatic prompt-redaction
36
+ * path in `events.ts` `sanitizePayload`.
37
+ *
38
+ * Grouping key: `emitComputerAction()` stamps one random `invocationId` for
39
+ * the lifetime of the emitting CLI process. The event's own `pid` field is the emitting
40
+ * CLI PROCESS's pid, never the target app's (that's `targetPid` — see
41
+ * `computer-actions.ts` `emitComputerAction`, and its `#11` test guarding
42
+ * this). One `agents computer <verb>` invocation is one process, and
43
+ * `computer run`'s whole embedded observe/act/verify loop is ALSO one
44
+ * process. Grouping by `invocationId` gives exactly one row per CLI invocation without
45
+ * conflating unrelated processes when the OS later reuses a pid: a
46
+ * single explicit verb collapses to a one-action row, and a `run --task`
47
+ * loop collapses to one row holding every verb the model drove. That row is
48
+ * the "run" a task-first view groups by.
49
+ *
50
+ * Session identity: unlike a browser task (which only ever learns its
51
+ * `launchId`, requiring the join `buildLaunchSessionIndex`/
52
+ * `resolveLaunchSession` perform), a `computer.action` event is emitted
53
+ * IN-PROCESS by the CLI invocation itself, so `stampProvenance()`
54
+ * (`../event-provenance.ts`) already stamps its own `sessionId` directly
55
+ * onto the record — no join needed for the common case. This module still
56
+ * falls back to the shared launchId join — imported from
57
+ * `../browser/sessions-list.ts`, never duplicated — for the case where
58
+ * `sessionId` doesn't resolve (a rotated/unindexed session) but `launchId`
59
+ * still does via the more authoritative pid registry.
60
+ */
61
+ import { query, truncate } from '../events.js';
62
+ import { formatRelativeTime } from '../session/relative-time.js';
63
+ import { getSessionById, listComputerSessionRecords, pruneToolSessions } from '../session/db.js';
64
+ import { buildLaunchSessionIndex, resolveLaunchSession, } from '../browser/sessions-list.js';
65
+ /** Max chars of a `run --task` description persisted to the ledger — see the
66
+ * module docblock's retention/privacy note. */
67
+ export const TASK_PREVIEW_MAX_CHARS = 200;
68
+ /** Cap on how many raw ledger rows a single read scans/returns. `query()`
69
+ * already reads newest-first and stops at this cutoff mid-scan, so raising
70
+ * it only ever costs as much as the history actually holds. */
71
+ const DEFAULT_ACTION_LIMIT = 5000;
72
+ function recordToAction(r) {
73
+ if (typeof r.command !== 'string' || typeof r.pid !== 'number')
74
+ return null;
75
+ const tsMs = Date.parse(r.ts);
76
+ if (Number.isNaN(tsMs))
77
+ return null;
78
+ return {
79
+ verb: r.command,
80
+ ts: r.ts,
81
+ tsMs,
82
+ pid: r.pid,
83
+ invocationId: typeof r.invocationId === 'string' ? r.invocationId : undefined,
84
+ targetPid: typeof r.targetPid === 'number' ? r.targetPid : undefined,
85
+ bundle: typeof r.bundle === 'string' ? r.bundle : undefined,
86
+ host: typeof r.host === 'string' ? r.host : undefined,
87
+ task: typeof r.task === 'string' ? r.task : undefined,
88
+ sessionId: typeof r.sessionId === 'string' ? r.sessionId : undefined,
89
+ launchId: typeof r.launchId === 'string' ? r.launchId : undefined,
90
+ agent: typeof r.agent === 'string' ? r.agent : undefined,
91
+ machineId: typeof r.machineId === 'string' ? r.machineId : undefined,
92
+ hostname: typeof r.hostname === 'string' ? r.hostname : undefined,
93
+ };
94
+ }
95
+ /** Read `computer.action` events straight from the durable event ledger,
96
+ * newest first, bounded by `limit`. Malformed/legacy records (missing
97
+ * `command` or `pid`, or an unparseable `ts`) are skipped, never thrown —
98
+ * the ledger is a plain rotated JSONL file another process can be mid-write
99
+ * or mid-rotate against. */
100
+ export function listComputerActions(opts = {}) {
101
+ const records = query({ eventTypes: ['computer.action'], limit: opts.limit ?? DEFAULT_ACTION_LIMIT });
102
+ const out = [];
103
+ for (const r of records) {
104
+ const a = recordToAction(r);
105
+ if (a)
106
+ out.push(a);
107
+ }
108
+ return out;
109
+ }
110
+ /**
111
+ * Group flat ledger actions into task-first rows, newest first. Pure:
112
+ * session resolvers are passed in, so this has no filesystem/session-index
113
+ * dependency and is unit-testable with synthetic data (see
114
+ * {@link buildComputerSessionRows} for the impure disk/index-reading caller).
115
+ */
116
+ export function groupIntoComputerRuns(actions, resolveSession, resolveLaunch) {
117
+ const byInvocation = new Map();
118
+ for (const [index, a] of actions.entries()) {
119
+ // Legacy rows have no trustworthy process identity. Pids are recyclable,
120
+ // so preserve each event separately instead of inventing a relationship.
121
+ const key = a.invocationId ?? `legacy:${a.pid}:${a.tsMs}:${index}`;
122
+ const list = byInvocation.get(key) ?? [];
123
+ list.push(a);
124
+ byInvocation.set(key, list);
125
+ }
126
+ const rows = [];
127
+ for (const group of byInvocation.values()) {
128
+ const pid = group[0].pid;
129
+ group.sort((a, b) => b.tsMs - a.tsMs); // newest first
130
+ const marker = group.find((a) => a.verb === 'run');
131
+ const driving = group.filter((a) => a.verb !== 'run');
132
+ const counts = {};
133
+ for (const a of driving)
134
+ counts[a.verb] = (counts[a.verb] ?? 0) + 1;
135
+ const bundle = group.find((a) => a.bundle)?.bundle;
136
+ const remoteHost = group.find((a) => a.host)?.host;
137
+ const identity = group.find((a) => a.sessionId || a.launchId) ?? group[0];
138
+ const machine = group.find((a) => a.hostname)?.hostname ?? 'unknown';
139
+ const machineId = group.find((a) => a.machineId)?.machineId;
140
+ let linkedSession = null;
141
+ if (identity.sessionId)
142
+ linkedSession = resolveSession?.(identity.sessionId) ?? null;
143
+ if (!linkedSession && identity.launchId)
144
+ linkedSession = resolveLaunch?.(identity.launchId) ?? null;
145
+ const times = group.map((a) => a.tsMs);
146
+ rows.push({
147
+ pid,
148
+ invocationId: group[0].invocationId,
149
+ task: marker?.task,
150
+ machine,
151
+ machineId,
152
+ remoteHost,
153
+ bundle,
154
+ agent: identity.agent,
155
+ sessionId: identity.sessionId,
156
+ launchId: identity.launchId,
157
+ linkStatus: linkedSession ? 'linked' : (identity.sessionId || identity.launchId) ? 'unresolved' : 'unlinked',
158
+ linkedSession: linkedSession ?? undefined,
159
+ actions: driving,
160
+ counts,
161
+ startMs: Math.min(...times),
162
+ endMs: Math.max(...times),
163
+ });
164
+ }
165
+ rows.sort((a, b) => b.endMs - a.endMs);
166
+ return rows;
167
+ }
168
+ /**
169
+ * Add runs the event ledger no longer holds, from the durable
170
+ * `computer_sessions` table (RUSH-2549).
171
+ *
172
+ * The ledger is deliberately bounded — it prunes at 7 days / 50 MiB — so before
173
+ * this, a run simply disappeared from `agents sessions --computer` on day 8 even
174
+ * though it had happened and its identity was known. The DB row is metadata
175
+ * only, so a recovered row carries its identity, timing and action COUNT but no
176
+ * per-verb breakdown: those individual actions lived in the pruned ledger and
177
+ * are genuinely gone. It is listed as a real run with an empty `actions` list
178
+ * rather than silently omitted, and never fabricated back.
179
+ *
180
+ * Ledger rows win on collision: while both exist the ledger is richer.
181
+ */
182
+ function appendPrunedRunsFromDb(rows, limit) {
183
+ const seen = new Set(rows.map((r) => r.invocationId));
184
+ // Ask the DB for what the ledger CANNOT still hold — everything older than
185
+ // the oldest action the ledger returned. Reading the newest N instead is
186
+ // self-defeating: those are precisely the rows `seen` discards, so once the
187
+ // table exceeds the read limit the recovery returns nothing and history
188
+ // disappears past the ledger window again — the exact bug this recovery
189
+ // exists to prevent. With no ledger rows at all there is nothing to exclude,
190
+ // so every stored row is recoverable.
191
+ const startedBeforeMs = rows.length > 0
192
+ ? Math.min(...rows.map((r) => r.startMs))
193
+ : undefined;
194
+ for (const record of listComputerSessionRecords({ limit, startedBeforeMs })) {
195
+ // The dedup is LOAD-BEARING — do not delete it as redundant with the WHERE
196
+ // clause above. A run's DB `started_at` is its TRUE start and is never
197
+ // updated, while the ledger row's `startMs` is only its oldest RETAINED
198
+ // action. So a long `computer run` that began before the ledger window but
199
+ // kept acting inside it sits below the cutoff, is selected by the SQL, and
200
+ // is already present as a ledger row. This is what drops the duplicate.
201
+ if (seen.has(record.invocationId))
202
+ continue;
203
+ const linked = record.sessionId ? getSessionById(record.sessionId) : null;
204
+ rows.push({
205
+ // No pid: the process is long gone and the ledger entry that knew it has
206
+ // been pruned. Fabricating `0` rendered rows labelled "pid 0" (see the
207
+ // label fallbacks in this file and computer-sessions-picker.ts).
208
+ pid: undefined,
209
+ invocationId: record.invocationId,
210
+ task: record.taskPreview,
211
+ // machineId() form ("zion"), the same normalized id the DB stored; the
212
+ // ledger path records the raw os.hostname() ("Zion.local") in `machine`.
213
+ // Setting BOTH from the one value we have keeps `--machine` substring
214
+ // filtering working on either spelling instead of silently missing
215
+ // recovered rows (events.ts documents the hostname/machineId split).
216
+ machine: record.machine,
217
+ machineId: record.machine,
218
+ bundle: undefined,
219
+ remoteHost: undefined,
220
+ agent: undefined,
221
+ sessionId: record.sessionId,
222
+ launchId: record.launchId,
223
+ linkStatus: linked ? 'linked' : (record.sessionId || record.launchId) ? 'unresolved' : 'unlinked',
224
+ linkedSession: linked ?? undefined,
225
+ // The per-verb breakdown lived in the pruned ledger and is genuinely gone
226
+ // — it is never reconstructed. The TOTAL survives in the row, so report
227
+ // it as an explicit total rather than dropping it: a 40-action run must
228
+ // not render identically to one that did nothing.
229
+ actions: [],
230
+ counts: {},
231
+ recoveredActionCount: record.actionCount,
232
+ startMs: record.startedAt,
233
+ endMs: record.lastActivity ?? record.startedAt,
234
+ });
235
+ }
236
+ }
237
+ /** Build task-first rows from the real ledger, resolving each row's owning
238
+ * session against the live indexes. The interactive picker's (and the
239
+ * flat/`--json` printer's) data source. `machine` narrows to rows whose
240
+ * invoking hostname, machineId, or `--host` target contains the substring. */
241
+ export function buildComputerSessionRows(opts = {}) {
242
+ const actions = listComputerActions({ limit: opts.limit });
243
+ const index = buildLaunchSessionIndex();
244
+ const rows = groupIntoComputerRuns(actions, (sessionId) => getSessionById(sessionId), (launchId) => resolveLaunchSession(index, launchId));
245
+ // Retention runs here, on the listing path, never on the action hot path:
246
+ // one row per `agents computer` CLI process means the table would otherwise
247
+ // grow without bound. Best-effort — a read-only DB must not break a listing.
248
+ try {
249
+ pruneToolSessions();
250
+ }
251
+ catch { /* listing must not fail on retention */ }
252
+ appendPrunedRunsFromDb(rows, opts.limit);
253
+ rows.sort((a, b) => b.endMs - a.endMs);
254
+ if (!opts.machine)
255
+ return rows;
256
+ const q = opts.machine.toLowerCase();
257
+ return rows.filter((r) => r.machine.toLowerCase().includes(q) ||
258
+ r.remoteHost?.toLowerCase().includes(q) ||
259
+ r.machineId?.toLowerCase().includes(q));
260
+ }
261
+ /**
262
+ * Search predicate for the interactive picker: task text, machine/remote
263
+ * host, target bundle, the linked session's agent/topic/label, or any
264
+ * driven verb in the row.
265
+ */
266
+ export function matchesComputerSessionRow(row, queryText) {
267
+ const q = queryText.trim().toLowerCase();
268
+ if (!q)
269
+ return true;
270
+ if (row.task?.toLowerCase().includes(q))
271
+ return true;
272
+ if (row.machine.toLowerCase().includes(q))
273
+ return true;
274
+ if (row.remoteHost?.toLowerCase().includes(q))
275
+ return true;
276
+ if (row.bundle?.toLowerCase().includes(q))
277
+ return true;
278
+ const s = row.linkedSession;
279
+ if (s && (s.agent.toLowerCase().includes(q) || s.topic?.toLowerCase().includes(q) || s.label?.toLowerCase().includes(q))) {
280
+ return true;
281
+ }
282
+ return row.actions.some((a) => a.verb.toLowerCase().includes(q));
283
+ }
284
+ /** Human one-line summary of a row's per-verb action counts, most frequent
285
+ * first — shared by the flat table and the interactive picker's label. */
286
+ /**
287
+ * One row's action summary — the single renderer every surface should use.
288
+ *
289
+ * A run recovered from the DB after the ledger pruned has no per-verb detail,
290
+ * only a total. Rendering it through the per-verb formatter printed
291
+ * "(no actions)", which is indistinguishable from a run that did nothing — so a
292
+ * 40-action run read as empty. Report the surviving total, and say plainly that
293
+ * the breakdown is gone rather than implying we still have it.
294
+ */
295
+ export function formatRowActions(row) {
296
+ if (row.recoveredActionCount !== undefined) {
297
+ const n = row.recoveredActionCount;
298
+ return `${n} action${n === 1 ? '' : 's'} (per-verb detail pruned from the event log)`;
299
+ }
300
+ return formatActionCounts(row.counts);
301
+ }
302
+ export function formatActionCounts(counts) {
303
+ const parts = Object.entries(counts)
304
+ .sort((a, b) => b[1] - a[1])
305
+ .map(([verb, n]) => `${verb} ${n}`);
306
+ return parts.join(', ') || '(no actions)';
307
+ }
308
+ /** Human table for the CLI. Returns lines (no trailing newline). */
309
+ export function renderComputerSessionRows(rows) {
310
+ if (rows.length === 0)
311
+ return 'No computer actions recorded.';
312
+ const lines = [];
313
+ for (const r of rows) {
314
+ const when = formatRelativeTime(new Date(r.endMs).toISOString());
315
+ const where = r.remoteHost ? `${r.machine} -> ${r.remoteHost}` : r.machine;
316
+ const label = r.task ? truncate(r.task, 60) : (r.bundle ?? `pid ${r.pid}`);
317
+ const link = r.linkStatus === 'linked' && r.linkedSession
318
+ ? `${r.linkedSession.agent} — ${r.linkedSession.label || r.linkedSession.topic || r.linkedSession.shortId}`
319
+ : r.linkStatus === 'unresolved'
320
+ ? 'unresolved (session not indexed here)'
321
+ : 'unlinked';
322
+ lines.push(`${when.padEnd(12)} ${where.padEnd(24)} ${String(label ?? '').padEnd(40)} ${link}`);
323
+ lines.push(` ${formatRowActions(r)}`);
324
+ }
325
+ return lines.join('\n');
326
+ }
327
+ /** Default row cap for the flat/non-interactive table. A computer row is
328
+ * much finer-grained than a browser task — real usage is mostly one
329
+ * standalone verb per CLI invocation, not a `run --task` loop, so an
330
+ * unbounded flat dump against real history reads as hundreds of one-action
331
+ * rows (confirmed against a real machine's history while building this).
332
+ * The interactive picker has no such cap (it's searchable); only the
333
+ * static table needs one. `--limit` overrides. */
334
+ export const DEFAULT_ROW_DISPLAY_LIMIT = 50;
335
+ /** Slice `rows` to at most `limit` (newest first, rows are already sorted),
336
+ * and report how many were dropped — pure, so the cap arithmetic and the
337
+ * trailer condition are unit-testable without a console spy. */
338
+ export function applyRowDisplayLimit(rows, limit = DEFAULT_ROW_DISPLAY_LIMIT) {
339
+ const shown = rows.slice(0, limit);
340
+ return { shown, more: rows.length - shown.length };
341
+ }
342
+ /**
343
+ * Shared CLI action for `agents computer sessions` and `agents sessions
344
+ * --computer`. Non-interactive by design (the interactive routing decision
345
+ * lives in `commands/computer-sessions-picker.ts`, mirroring
346
+ * `runBrowserSessions`/`runBrowserSessionsCommand`'s split).
347
+ */
348
+ export function runComputerSessions(opts) {
349
+ const rows = buildComputerSessionRows({ machine: opts.machine });
350
+ printComputerSessionRows(rows, opts);
351
+ }
352
+ /** Print already-collected rows. Fleet callers use this after merging local and
353
+ * remote JSON so text, limits, and JSON keep exactly one renderer. */
354
+ export function printComputerSessionRows(rows, opts) {
355
+ if (opts.json) {
356
+ console.log(JSON.stringify(rows, null, 2));
357
+ return;
358
+ }
359
+ const { shown, more } = applyRowDisplayLimit(rows, opts.limit ?? DEFAULT_ROW_DISPLAY_LIMIT);
360
+ console.log(renderComputerSessionRows(shown));
361
+ if (more > 0)
362
+ console.log(`\n… (${more} more; --limit ${rows.length} or --json to see all, --machine to narrow)`);
363
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Unified config key grammar for `agents config`.
3
+ *
4
+ * Translates user-facing dotted keys like `run.claude@*.tier.best` into the
5
+ * existing storage locations (run.defaults, model.tiers, config.*,
6
+ * defaultBrowserProfile, deviceConfig.*) so the new command barrel can sit on
7
+ * top of the current YAML schema without a migration.
8
+ */
9
+ import type { AgentId } from './types.js';
10
+ import { type ModelTier } from './model-tiers.js';
11
+ /** The top-level scope of a unified config key. */
12
+ export type ConfigScope = 'run' | 'interactive' | 'usage' | 'browser' | 'project' | 'device';
13
+ /** A run-time default key: model, mode, effort, or tier override. */
14
+ export interface ParsedRunConfigKey {
15
+ scope: 'run';
16
+ agent: AgentId;
17
+ version: string;
18
+ property: 'model' | 'mode' | 'effort' | 'tier';
19
+ tier?: ModelTier;
20
+ }
21
+ /** The interactive host pin. */
22
+ export interface ParsedInteractiveConfigKey {
23
+ scope: 'interactive';
24
+ property: 'host';
25
+ }
26
+ /** The host whose usage snapshots are authoritative for fleet-wide reporting. */
27
+ export interface ParsedUsageConfigKey {
28
+ scope: 'usage';
29
+ property: 'primary-host';
30
+ }
31
+ /** The default browser profile (device-scope, self or peer). */
32
+ export interface ParsedBrowserConfigKey {
33
+ scope: 'browser';
34
+ property: 'profile';
35
+ device?: string;
36
+ }
37
+ export interface ParsedProjectConfigKey {
38
+ scope: 'project';
39
+ property: 'root';
40
+ }
41
+ /** A per-device configuration key. */
42
+ export interface ParsedDeviceConfigKey {
43
+ scope: 'device';
44
+ device: string;
45
+ property: DeviceConfigProperty;
46
+ }
47
+ export type ParsedConfigKey = ParsedRunConfigKey | ParsedInteractiveConfigKey | ParsedUsageConfigKey | ParsedBrowserConfigKey | ParsedProjectConfigKey | ParsedDeviceConfigKey;
48
+ export type DeviceConfigProperty = 'max-agents' | 'scheduler' | 'daemon' | 'watchdog' | 'browser.remote-control' | 'notes' | 'browser.profile';
49
+ /** Normalize agent@version to use `@` consistently. */
50
+ export declare function formatAgentVersion(agent: AgentId, version: string): string;
51
+ /**
52
+ * Parse a unified config key into its structured representation.
53
+ *
54
+ * Supported forms:
55
+ * run.<agent@version>.model
56
+ * run.<agent@version>.mode
57
+ * run.<agent@version>.effort
58
+ * run.<agent@version>.tier.<cheap|default|best|ultra>
59
+ * interactive.host
60
+ * usage.primary-host
61
+ * browser.profile
62
+ * project.root
63
+ * devices.<name>.max-agents
64
+ * devices.<name>.scheduler
65
+ * devices.<name>.daemon
66
+ * devices.<name>.watchdog
67
+ * devices.<name>.browser.remote-control
68
+ * devices.<name>.notes
69
+ * devices.<name>.browser.profile
70
+ */
71
+ export declare function parseConfigKey(key: string): ParsedConfigKey;
72
+ /** Render a parsed key back to its canonical dotted string. */
73
+ export declare function formatConfigKey(parsed: ParsedConfigKey): string;
74
+ /** List every canonical key the command documents, with wildcards expanded to a concrete example. */
75
+ export declare function listKnownConfigKeys(): string[];
76
+ /**
77
+ * Map a parsed device property to the internal device-config key name.
78
+ * This is the bridge between the friendly `agents config` surface and the
79
+ * existing CONFIG_KEYS registry in lib/device-config.ts.
80
+ */
81
+ export declare function devicePropertyToConfigName(property: DeviceConfigProperty): string;
82
+ /**
83
+ * Map a parsed key to the human-readable "where is this stored" note.
84
+ * Useful for `agents config list --source` output.
85
+ */
86
+ export declare function configKeyStorageHint(parsed: ParsedConfigKey): string;
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Unified config key grammar for `agents config`.
3
+ *
4
+ * Translates user-facing dotted keys like `run.claude@*.tier.best` into the
5
+ * existing storage locations (run.defaults, model.tiers, config.*,
6
+ * defaultBrowserProfile, deviceConfig.*) so the new command barrel can sit on
7
+ * top of the current YAML schema without a migration.
8
+ */
9
+ import { AGENTS } from './agents.js';
10
+ import { MODEL_TIERS } from './model-tiers.js';
11
+ import { VERSION_RE } from './run-defaults.js';
12
+ const DEVICE_CONFIG_PROPERTIES = [
13
+ 'max-agents',
14
+ 'scheduler',
15
+ 'daemon',
16
+ 'watchdog',
17
+ 'browser.remote-control',
18
+ 'notes',
19
+ 'browser.profile',
20
+ ];
21
+ /** Split an agent@version token into its parts. Accepts both `@` and `:`. */
22
+ function parseAgentVersion(token) {
23
+ const sep = token.includes('@') ? '@' : ':';
24
+ const [agentPart, versionPart = '*'] = token.split(sep);
25
+ const agent = agentPart.toLowerCase();
26
+ if (!(agent in AGENTS)) {
27
+ throw new Error(`Unknown agent '${agentPart}'. Known agents: ${Object.keys(AGENTS).join(', ')}.`);
28
+ }
29
+ if (!VERSION_RE.test(versionPart)) {
30
+ throw new Error(`Invalid version '${versionPart}' in '${token}'. Use *, latest, or [A-Za-z0-9._+-]{1,64}.`);
31
+ }
32
+ return { agent: agent, version: versionPart };
33
+ }
34
+ /** Normalize agent@version to use `@` consistently. */
35
+ export function formatAgentVersion(agent, version) {
36
+ return `${agent}@${version}`;
37
+ }
38
+ /**
39
+ * Parse a unified config key into its structured representation.
40
+ *
41
+ * Supported forms:
42
+ * run.<agent@version>.model
43
+ * run.<agent@version>.mode
44
+ * run.<agent@version>.effort
45
+ * run.<agent@version>.tier.<cheap|default|best|ultra>
46
+ * interactive.host
47
+ * usage.primary-host
48
+ * browser.profile
49
+ * project.root
50
+ * devices.<name>.max-agents
51
+ * devices.<name>.scheduler
52
+ * devices.<name>.daemon
53
+ * devices.<name>.watchdog
54
+ * devices.<name>.browser.remote-control
55
+ * devices.<name>.notes
56
+ * devices.<name>.browser.profile
57
+ */
58
+ export function parseConfigKey(key) {
59
+ const raw = key.trim();
60
+ if (!raw)
61
+ throw new Error('Config key is required.');
62
+ const runMatch = raw.match(/^run\.(.+)\.(model|mode|effort)$/);
63
+ if (runMatch) {
64
+ const { agent, version } = parseAgentVersion(runMatch[1]);
65
+ return { scope: 'run', agent, version, property: runMatch[2] };
66
+ }
67
+ const tierMatch = raw.match(/^run\.(.+)\.tier\.(cheap|default|best|ultra)$/i);
68
+ if (tierMatch) {
69
+ const { agent, version } = parseAgentVersion(tierMatch[1]);
70
+ return { scope: 'run', agent, version, property: 'tier', tier: tierMatch[2].toLowerCase() };
71
+ }
72
+ if (raw === 'interactive.host') {
73
+ return { scope: 'interactive', property: 'host' };
74
+ }
75
+ if (raw === 'usage.primary-host') {
76
+ return { scope: 'usage', property: 'primary-host' };
77
+ }
78
+ if (raw === 'browser.profile') {
79
+ return { scope: 'browser', property: 'profile' };
80
+ }
81
+ if (raw === 'project.root') {
82
+ return { scope: 'project', property: 'root' };
83
+ }
84
+ const deviceMatch = raw.match(/^devices\.(.+)\.(max-agents|scheduler|daemon|watchdog|notes|browser\.remote-control|browser\.profile)$/);
85
+ if (deviceMatch) {
86
+ return {
87
+ scope: 'device',
88
+ device: deviceMatch[1],
89
+ property: deviceMatch[2],
90
+ };
91
+ }
92
+ // Provide helpful errors for common mistakes.
93
+ if (raw.startsWith('run.')) {
94
+ throw new Error(`Invalid run config key '${key}'. Expected run.<agent@version>.<model|mode|effort> or run.<agent@version>.tier.<cheap|default|best|ultra>.`);
95
+ }
96
+ if (raw.startsWith('interactive.')) {
97
+ throw new Error(`Invalid interactive config key '${key}'. Use interactive.host.`);
98
+ }
99
+ if (raw.startsWith('usage.')) {
100
+ throw new Error(`Invalid usage config key '${key}'. Use usage.primary-host.`);
101
+ }
102
+ if (raw.startsWith('browser.')) {
103
+ throw new Error(`Invalid browser config key '${key}'. Use browser.profile.`);
104
+ }
105
+ if (raw.startsWith('project.')) {
106
+ throw new Error(`Invalid project config key '${key}'. Use project.root.`);
107
+ }
108
+ if (raw.startsWith('devices.')) {
109
+ throw new Error(`Invalid device config key '${key}'. Expected devices.<name>.<${DEVICE_CONFIG_PROPERTIES.join('|')}>.`);
110
+ }
111
+ throw new Error(`Unknown config scope in '${key}'. Use one of: run, interactive, usage, browser, project, devices.`);
112
+ }
113
+ /** Render a parsed key back to its canonical dotted string. */
114
+ export function formatConfigKey(parsed) {
115
+ switch (parsed.scope) {
116
+ case 'run':
117
+ if (parsed.property === 'tier') {
118
+ return `run.${formatAgentVersion(parsed.agent, parsed.version)}.tier.${parsed.tier}`;
119
+ }
120
+ return `run.${formatAgentVersion(parsed.agent, parsed.version)}.${parsed.property}`;
121
+ case 'interactive':
122
+ return 'interactive.host';
123
+ case 'usage':
124
+ return 'usage.primary-host';
125
+ case 'browser':
126
+ return parsed.device ? `devices.${parsed.device}.browser.profile` : 'browser.profile';
127
+ case 'project':
128
+ return 'project.root';
129
+ case 'device':
130
+ return `devices.${parsed.device}.${parsed.property}`;
131
+ }
132
+ }
133
+ /** List every canonical key the command documents, with wildcards expanded to a concrete example. */
134
+ export function listKnownConfigKeys() {
135
+ const keys = [];
136
+ keys.push('run.<agent@version>.model', 'run.<agent@version>.mode', 'run.<agent@version>.effort');
137
+ for (const tier of MODEL_TIERS) {
138
+ keys.push(`run.<agent@version>.tier.${tier}`);
139
+ }
140
+ keys.push('interactive.host', 'usage.primary-host', 'browser.profile', 'project.root');
141
+ for (const prop of DEVICE_CONFIG_PROPERTIES) {
142
+ keys.push(`devices.<name>.${prop}`);
143
+ }
144
+ return keys;
145
+ }
146
+ /**
147
+ * Map a parsed device property to the internal device-config key name.
148
+ * This is the bridge between the friendly `agents config` surface and the
149
+ * existing CONFIG_KEYS registry in lib/device-config.ts.
150
+ */
151
+ export function devicePropertyToConfigName(property) {
152
+ switch (property) {
153
+ case 'max-agents':
154
+ return 'agents.max-concurrent';
155
+ case 'scheduler':
156
+ return 'scheduler.enabled';
157
+ case 'daemon':
158
+ return 'daemon.enabled';
159
+ case 'watchdog':
160
+ return 'watchdog.enabled';
161
+ case 'browser.remote-control':
162
+ return 'browser.remote-control';
163
+ case 'notes':
164
+ return 'notes';
165
+ case 'browser.profile':
166
+ return 'browser.profile';
167
+ }
168
+ }
169
+ /**
170
+ * Map a parsed key to the human-readable "where is this stored" note.
171
+ * Useful for `agents config list --source` output.
172
+ */
173
+ export function configKeyStorageHint(parsed) {
174
+ switch (parsed.scope) {
175
+ case 'run':
176
+ if (parsed.property === 'tier') {
177
+ return `model.tiers.${parsed.agent}:${parsed.version}.${parsed.tier}`;
178
+ }
179
+ return `run.defaults.${parsed.agent}:${parsed.version}.${parsed.property}`;
180
+ case 'interactive':
181
+ return 'config.interactiveHost';
182
+ case 'usage':
183
+ return 'config.usagePrimaryHost';
184
+ case 'browser':
185
+ return parsed.device
186
+ ? `fleet.devices.${parsed.device}.config.defaultBrowserProfile`
187
+ : 'fleet.devices.<self>.config.defaultBrowserProfile';
188
+ case 'project':
189
+ return 'devices.<self>.projectRoot';
190
+ case 'device':
191
+ return `fleet.devices.${parsed.device}.config ${devicePropertyToConfigName(parsed.property)}`;
192
+ }
193
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The YAML keys of every machine-visibility config key — the ones that live in
3
+ * the owning box's own `devices/<machine>/agents.yaml` and must never reach the
4
+ * fleet-shared `agents.yaml`.
5
+ *
6
+ * This is a ZERO-DEPENDENCY leaf on purpose. The authority is `CONFIG_KEYS` in
7
+ * `lib/device-config.ts`, but that module imports `devices/config-migration.ts`,
8
+ * so the migration cannot import it back without a cycle. Same shape as the
9
+ * `agent-cli-commands` leaf: duplicated here, pinned equal to the registry by a
10
+ * test (`device-config.test.ts`), so the two cannot drift silently.
11
+ */
12
+ export declare const MACHINE_LOCAL_YAML_KEYS: ReadonlySet<string>;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The YAML keys of every machine-visibility config key — the ones that live in
3
+ * the owning box's own `devices/<machine>/agents.yaml` and must never reach the
4
+ * fleet-shared `agents.yaml`.
5
+ *
6
+ * This is a ZERO-DEPENDENCY leaf on purpose. The authority is `CONFIG_KEYS` in
7
+ * `lib/device-config.ts`, but that module imports `devices/config-migration.ts`,
8
+ * so the migration cannot import it back without a cycle. Same shape as the
9
+ * `agent-cli-commands` leaf: duplicated here, pinned equal to the registry by a
10
+ * test (`device-config.test.ts`), so the two cannot drift silently.
11
+ */
12
+ export const MACHINE_LOCAL_YAML_KEYS = new Set([
13
+ 'defaultBrowserProfile', // browser.profile
14
+ 'browserRemoteControl', // browser.remote-control — a consent flag; syncing it is a leak
15
+ 'schedulerEnabled', // scheduler.enabled
16
+ 'daemonEnabled', // daemon.enabled
17
+ ]);