@phnx-labs/agents-cli 1.22.35 → 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 (487) hide show
  1. package/CHANGELOG.md +666 -2
  2. package/README.md +75 -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 +67 -0
  94. package/dist/commands/share.js +275 -12
  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/commands.d.ts +2 -0
  161. package/dist/lib/commands.js +2 -0
  162. package/dist/lib/computer/sessions-list.d.ts +150 -0
  163. package/dist/lib/computer/sessions-list.js +363 -0
  164. package/dist/lib/config-keys.d.ts +86 -0
  165. package/dist/lib/config-keys.js +193 -0
  166. package/dist/lib/config-machine-keys.d.ts +12 -0
  167. package/dist/lib/config-machine-keys.js +17 -0
  168. package/dist/lib/config-transfer.js +3 -4
  169. package/dist/lib/crabbox/cli.d.ts +2 -2
  170. package/dist/lib/crabbox/cli.js +3 -3
  171. package/dist/lib/daemon-health.d.ts +22 -0
  172. package/dist/lib/daemon-health.js +33 -3
  173. package/dist/lib/daemon-services.d.ts +50 -0
  174. package/dist/lib/daemon-services.js +147 -0
  175. package/dist/lib/daemon-ticks.d.ts +35 -66
  176. package/dist/lib/daemon-ticks.js +77 -159
  177. package/dist/lib/daemon.d.ts +72 -4
  178. package/dist/lib/daemon.js +792 -202
  179. package/dist/lib/deeplink/register.d.ts +49 -0
  180. package/dist/lib/deeplink/register.js +253 -0
  181. package/dist/lib/deeplink/url.d.ts +34 -0
  182. package/dist/lib/deeplink/url.js +78 -0
  183. package/dist/lib/device-config.d.ts +124 -29
  184. package/dist/lib/device-config.js +346 -141
  185. package/dist/lib/devices/config-migration.d.ts +42 -0
  186. package/dist/lib/devices/config-migration.js +203 -0
  187. package/dist/lib/devices/connect.js +14 -7
  188. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  189. package/dist/lib/devices/doctor-findings.js +20 -1
  190. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  191. package/dist/lib/devices/harness-inventory.js +0 -0
  192. package/dist/lib/devices/health.d.ts +1 -1
  193. package/dist/lib/devices/health.js +1 -1
  194. package/dist/lib/devices/pending.d.ts +22 -1
  195. package/dist/lib/devices/pending.js +67 -2
  196. package/dist/lib/devices/registry.d.ts +0 -25
  197. package/dist/lib/devices/registry.js +2 -83
  198. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  199. package/dist/lib/devices/resolve-profile.js +44 -0
  200. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  201. package/dist/lib/devices/rollout-verify.js +193 -0
  202. package/dist/lib/devices/ssh-config.js +10 -6
  203. package/dist/lib/event-families.d.ts +28 -0
  204. package/dist/lib/event-families.js +159 -0
  205. package/dist/lib/event-stream.d.ts +9 -1
  206. package/dist/lib/event-stream.js +26 -9
  207. package/dist/lib/events.d.ts +9 -1
  208. package/dist/lib/events.js +21 -6
  209. package/dist/lib/exec.d.ts +30 -0
  210. package/dist/lib/exec.js +219 -121
  211. package/dist/lib/feed-broadcast.d.ts +25 -0
  212. package/dist/lib/feed-broadcast.js +33 -0
  213. package/dist/lib/feed.d.ts +1 -1
  214. package/dist/lib/feed.js +12 -2
  215. package/dist/lib/fleet/capture.js +15 -0
  216. package/dist/lib/fleet/manifest.js +9 -0
  217. package/dist/lib/fleet/types.d.ts +9 -0
  218. package/dist/lib/fleet-status.js +10 -8
  219. package/dist/lib/git.d.ts +20 -6
  220. package/dist/lib/git.js +121 -17
  221. package/dist/lib/hosts/dispatch.d.ts +8 -3
  222. package/dist/lib/hosts/dispatch.js +29 -3
  223. package/dist/lib/hosts/logs.d.ts +2 -2
  224. package/dist/lib/hosts/logs.js +2 -2
  225. package/dist/lib/hosts/option.js +1 -1
  226. package/dist/lib/hosts/passthrough.d.ts +2 -3
  227. package/dist/lib/hosts/passthrough.js +10 -24
  228. package/dist/lib/hosts/progress.js +2 -2
  229. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  230. package/dist/lib/hosts/providers/devices.js +18 -12
  231. package/dist/lib/hosts/ready.d.ts +5 -1
  232. package/dist/lib/hosts/ready.js +9 -3
  233. package/dist/lib/hosts/reconcile.d.ts +2 -2
  234. package/dist/lib/hosts/reconcile.js +2 -2
  235. package/dist/lib/hosts/registry.js +14 -9
  236. package/dist/lib/hosts/remote-cmd.js +1 -1
  237. package/dist/lib/hosts/remote-os.d.ts +9 -6
  238. package/dist/lib/hosts/remote-os.js +13 -6
  239. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  240. package/dist/lib/hosts/routing-flag.js +41 -0
  241. package/dist/lib/hosts/run-target.js +1 -1
  242. package/dist/lib/hosts/session-index.js +1 -1
  243. package/dist/lib/hosts/tasks.d.ts +6 -6
  244. package/dist/lib/hosts/tasks.js +4 -4
  245. package/dist/lib/hosts/types.js +1 -2
  246. package/dist/lib/installations/resolve.js +2 -8
  247. package/dist/lib/isolation-boundary-report.js +0 -1
  248. package/dist/lib/linear-cache.d.ts +7 -0
  249. package/dist/lib/linear-cache.js +31 -4
  250. package/dist/lib/linear-project-counts.d.ts +1 -1
  251. package/dist/lib/linear-project-counts.js +2 -3
  252. package/dist/lib/linear-projects.js +1 -1
  253. package/dist/lib/loop.d.ts +2 -2
  254. package/dist/lib/loop.js +1 -1
  255. package/dist/lib/mailbox-target.d.ts +1 -1
  256. package/dist/lib/mailbox-target.js +1 -1
  257. package/dist/lib/manifest.js +7 -4
  258. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  259. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  260. package/dist/lib/menubar/snapshot.d.ts +3 -2
  261. package/dist/lib/menubar/snapshot.js +6 -2
  262. package/dist/lib/migrate-fold.d.ts +33 -0
  263. package/dist/lib/migrate-fold.js +130 -0
  264. package/dist/lib/migrate.d.ts +34 -34
  265. package/dist/lib/migrate.js +106 -128
  266. package/dist/lib/model-tier-overrides.d.ts +1 -1
  267. package/dist/lib/model-tier-overrides.js +15 -2
  268. package/dist/lib/monitors/config.d.ts +17 -3
  269. package/dist/lib/monitors/config.js +52 -18
  270. package/dist/lib/monitors/engine.d.ts +32 -1
  271. package/dist/lib/monitors/engine.js +94 -11
  272. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  273. package/dist/lib/monitors/fingerprint.js +100 -0
  274. package/dist/lib/monitors/remote.d.ts +47 -0
  275. package/dist/lib/monitors/remote.js +81 -0
  276. package/dist/lib/monitors/state.d.ts +39 -0
  277. package/dist/lib/monitors/state.js +56 -0
  278. package/dist/lib/onepassword.d.ts +17 -0
  279. package/dist/lib/onepassword.js +52 -22
  280. package/dist/lib/open-url.js +1 -1
  281. package/dist/lib/picker.d.ts +14 -2
  282. package/dist/lib/picker.js +35 -13
  283. package/dist/lib/placement.d.ts +1 -1
  284. package/dist/lib/placement.js +1 -1
  285. package/dist/lib/pr-land-detach.d.ts +32 -0
  286. package/dist/lib/pr-land-detach.js +79 -0
  287. package/dist/lib/profiles-presets.js +13 -0
  288. package/dist/lib/profiles.d.ts +2 -0
  289. package/dist/lib/profiles.js +44 -1
  290. package/dist/lib/project-focus.d.ts +1 -1
  291. package/dist/lib/project-focus.js +1 -1
  292. package/dist/lib/project-probe.d.ts +4 -1
  293. package/dist/lib/project-probe.js +5 -4
  294. package/dist/lib/project-resources.js +2 -18
  295. package/dist/lib/project-root.d.ts +16 -0
  296. package/dist/lib/project-root.js +20 -2
  297. package/dist/lib/projects.d.ts +20 -1
  298. package/dist/lib/projects.js +78 -1
  299. package/dist/lib/refresh-coordinator.d.ts +24 -0
  300. package/dist/lib/refresh-coordinator.js +52 -0
  301. package/dist/lib/registry.d.ts +2 -2
  302. package/dist/lib/registry.js +1 -1
  303. package/dist/lib/resource-aliases.d.ts +13 -0
  304. package/dist/lib/resource-aliases.js +26 -0
  305. package/dist/lib/resources/types.d.ts +1 -1
  306. package/dist/lib/resources.d.ts +16 -0
  307. package/dist/lib/resources.js +66 -10
  308. package/dist/lib/rotate.d.ts +3 -4
  309. package/dist/lib/rotate.js +4 -5
  310. package/dist/lib/routine-activation.d.ts +22 -2
  311. package/dist/lib/routine-activation.js +63 -16
  312. package/dist/lib/routine-context.d.ts +9 -2
  313. package/dist/lib/routine-context.js +21 -6
  314. package/dist/lib/routines-project.d.ts +58 -48
  315. package/dist/lib/routines-project.js +190 -159
  316. package/dist/lib/routines.d.ts +41 -6
  317. package/dist/lib/routines.js +92 -34
  318. package/dist/lib/run-defaults.d.ts +5 -0
  319. package/dist/lib/run-defaults.js +11 -1
  320. package/dist/lib/runner.d.ts +10 -8
  321. package/dist/lib/runner.js +122 -39
  322. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  323. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  324. package/dist/lib/secrets/agent.d.ts +10 -3
  325. package/dist/lib/secrets/agent.js +43 -8
  326. package/dist/lib/secrets/bundles.d.ts +1 -0
  327. package/dist/lib/secrets/bundles.js +92 -80
  328. package/dist/lib/secrets/index.js +32 -9
  329. package/dist/lib/secrets/install-helper.d.ts +4 -4
  330. package/dist/lib/secrets/install-helper.js +4 -4
  331. package/dist/lib/secrets/push.d.ts +40 -6
  332. package/dist/lib/secrets/push.js +58 -11
  333. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  334. package/dist/lib/secrets/read-backoff.js +1 -1
  335. package/dist/lib/secrets/remote.d.ts +24 -0
  336. package/dist/lib/secrets/remote.js +54 -4
  337. package/dist/lib/self-update.d.ts +108 -0
  338. package/dist/lib/self-update.js +276 -1
  339. package/dist/lib/session/active.d.ts +89 -5
  340. package/dist/lib/session/active.js +165 -10
  341. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  342. package/dist/lib/session/actor-sidecar.js +2 -1
  343. package/dist/lib/session/db.d.ts +176 -2
  344. package/dist/lib/session/db.js +484 -17
  345. package/dist/lib/session/discover.js +27 -4
  346. package/dist/lib/session/hook-sessions.js +2 -2
  347. package/dist/lib/session/host-link.d.ts +2 -2
  348. package/dist/lib/session/host-link.js +2 -2
  349. package/dist/lib/session/pid-registry.d.ts +21 -0
  350. package/dist/lib/session/pid-registry.js +57 -0
  351. package/dist/lib/session/remote-active.js +15 -1
  352. package/dist/lib/session/remote.js +2 -2
  353. package/dist/lib/session/session-cache.d.ts +14 -7
  354. package/dist/lib/session/session-cache.js +51 -9
  355. package/dist/lib/session/state.d.ts +2 -2
  356. package/dist/lib/session/state.js +1 -1
  357. package/dist/lib/session/sync/config.d.ts +10 -10
  358. package/dist/lib/session/sync/config.js +10 -10
  359. package/dist/lib/session/sync/r2.d.ts +34 -0
  360. package/dist/lib/session/sync/r2.js +123 -0
  361. package/dist/lib/session/throughput.d.ts +1 -1
  362. package/dist/lib/session/throughput.js +1 -1
  363. package/dist/lib/session/types.d.ts +23 -1
  364. package/dist/lib/session/types.js +15 -0
  365. package/dist/lib/session/viewing-in.d.ts +1 -1
  366. package/dist/lib/session/viewing-in.js +1 -1
  367. package/dist/lib/session/watch.d.ts +101 -0
  368. package/dist/lib/session/watch.js +242 -0
  369. package/dist/lib/share/config.d.ts +4 -0
  370. package/dist/lib/share/config.js +1 -0
  371. package/dist/lib/share/provision.d.ts +38 -0
  372. package/dist/lib/share/provision.js +50 -0
  373. package/dist/lib/share/publish.d.ts +40 -1
  374. package/dist/lib/share/publish.js +116 -3
  375. package/dist/lib/share/worker-template.js +71 -6
  376. package/dist/lib/shims.d.ts +17 -3
  377. package/dist/lib/shims.js +98 -26
  378. package/dist/lib/signin-badge.js +3 -2
  379. package/dist/lib/skills.js +2 -0
  380. package/dist/lib/smart-launch.d.ts +8 -8
  381. package/dist/lib/smart-launch.js +80 -59
  382. package/dist/lib/ssh-exec.d.ts +1 -1
  383. package/dist/lib/ssh-exec.js +1 -1
  384. package/dist/lib/staleness/prune.d.ts +88 -0
  385. package/dist/lib/staleness/prune.js +69 -0
  386. package/dist/lib/staleness/registry.d.ts +1 -1
  387. package/dist/lib/staleness/writers/commands.js +34 -2
  388. package/dist/lib/staleness/writers/hooks.js +16 -0
  389. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  390. package/dist/lib/staleness/writers/skills.js +19 -0
  391. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  392. package/dist/lib/staleness/writers/subagents.js +0 -4
  393. package/dist/lib/staleness/writers/types.d.ts +32 -0
  394. package/dist/lib/startup/command-registry.d.ts +6 -12
  395. package/dist/lib/startup/command-registry.js +11 -31
  396. package/dist/lib/startup/dev-build.d.ts +10 -0
  397. package/dist/lib/startup/dev-build.js +13 -1
  398. package/dist/lib/startup/spellcheck.d.ts +18 -0
  399. package/dist/lib/startup/spellcheck.js +45 -0
  400. package/dist/lib/state.d.ts +36 -9
  401. package/dist/lib/state.js +96 -46
  402. package/dist/lib/subagents-registry.d.ts +0 -7
  403. package/dist/lib/subagents-registry.js +38 -65
  404. package/dist/lib/subagents.d.ts +0 -33
  405. package/dist/lib/subagents.js +0 -75
  406. package/dist/lib/sync-umbrella.js +1 -1
  407. package/dist/lib/teams/agents.d.ts +41 -1
  408. package/dist/lib/teams/agents.js +187 -9
  409. package/dist/lib/teams/api.d.ts +11 -1
  410. package/dist/lib/teams/api.js +11 -2
  411. package/dist/lib/teams/delivery.d.ts +41 -0
  412. package/dist/lib/teams/delivery.js +60 -0
  413. package/dist/lib/teams/registry.d.ts +14 -0
  414. package/dist/lib/teams/registry.js +51 -1
  415. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  416. package/dist/lib/teams/remoteWorktree.js +29 -0
  417. package/dist/lib/teams/scheduler.d.ts +1 -1
  418. package/dist/lib/teams/scheduler.js +1 -1
  419. package/dist/lib/teams/worktree.d.ts +24 -0
  420. package/dist/lib/teams/worktree.js +42 -0
  421. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  422. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  423. package/dist/lib/terminal/engine.d.ts +4 -0
  424. package/dist/lib/terminal/engine.js +8 -2
  425. package/dist/lib/terminal/types.d.ts +21 -2
  426. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  427. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  428. package/dist/lib/tickets/list.d.ts +53 -0
  429. package/dist/lib/tickets/list.js +153 -0
  430. package/dist/lib/tmux/orphan-reap.d.ts +320 -0
  431. package/dist/lib/tmux/orphan-reap.js +644 -0
  432. package/dist/lib/tmux/session.d.ts +68 -3
  433. package/dist/lib/tmux/session.js +95 -5
  434. package/dist/lib/triggers/handlers.d.ts +20 -0
  435. package/dist/lib/triggers/handlers.js +6 -1
  436. package/dist/lib/types.d.ts +46 -34
  437. package/dist/lib/usage-fleet.d.ts +32 -0
  438. package/dist/lib/usage-fleet.js +125 -0
  439. package/dist/lib/usage-refresh.d.ts +3 -3
  440. package/dist/lib/usage-refresh.js +19 -16
  441. package/dist/lib/usage.d.ts +51 -47
  442. package/dist/lib/usage.js +145 -153
  443. package/dist/lib/version-duplicates.js +2 -2
  444. package/dist/lib/versions.d.ts +56 -13
  445. package/dist/lib/versions.js +195 -45
  446. package/dist/lib/watchdog/log.d.ts +1 -1
  447. package/dist/lib/watchdog/log.js +3 -3
  448. package/dist/lib/watchdog/rotate.d.ts +6 -6
  449. package/dist/lib/watchdog/rotate.js +6 -6
  450. package/dist/lib/workflows.d.ts +1 -1
  451. package/dist/lib/yaml-io.d.ts +47 -0
  452. package/dist/lib/yaml-io.js +55 -0
  453. package/package.json +2 -1
  454. package/scripts/install-helper.js +2 -2
  455. package/scripts/postinstall.js +23 -20
  456. package/dist/commands/defaults.d.ts +0 -7
  457. package/dist/commands/defaults.js +0 -107
  458. package/dist/commands/export.d.ts +0 -11
  459. package/dist/commands/export.js +0 -215
  460. package/dist/commands/helper.d.ts +0 -12
  461. package/dist/commands/helper.js +0 -87
  462. package/dist/commands/hosts.d.ts +0 -11
  463. package/dist/commands/hosts.js +0 -330
  464. package/dist/commands/lock.d.ts +0 -12
  465. package/dist/commands/lock.js +0 -70
  466. package/dist/commands/pull.d.ts +0 -17
  467. package/dist/commands/pull.js +0 -39
  468. package/dist/commands/push.d.ts +0 -14
  469. package/dist/commands/push.js +0 -30
  470. package/dist/commands/wallet.d.ts +0 -20
  471. package/dist/commands/wallet.js +0 -216
  472. package/dist/commands/worktree.d.ts +0 -19
  473. package/dist/commands/worktree.js +0 -272
  474. package/dist/lib/account-labels.d.ts +0 -24
  475. package/dist/lib/account-labels.js +0 -72
  476. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  477. package/dist/lib/auto-dispatch-linear.js +0 -107
  478. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  479. package/dist/lib/auto-dispatch-provider.js +0 -30
  480. package/dist/lib/auto-dispatch.d.ts +0 -93
  481. package/dist/lib/auto-dispatch.js +0 -128
  482. package/dist/lib/export.d.ts +0 -72
  483. package/dist/lib/export.js +0 -269
  484. package/dist/lib/lock.d.ts +0 -93
  485. package/dist/lib/lock.js +0 -207
  486. package/dist/lib/wallet/index.d.ts +0 -78
  487. package/dist/lib/wallet/index.js +0 -253
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Interactive, task-first `agents computer sessions` / `agents sessions
3
+ * --computer` view (RUSH-2432) — the computer counterpart of
4
+ * `browser-sessions-picker.ts` (RUSH-2407). Backs the TTY path only —
5
+ * non-TTY, `--json`, and `--no-interactive` all fall straight through to the
6
+ * flat printer in `lib/computer/sessions-list.ts` (unchanged, so `--json`
7
+ * stays a stable surface).
8
+ *
9
+ * Reuses the same `itemPicker` + `buildPreview` primitives as the ordinary
10
+ * session picker (`sessions-picker.ts`) and the browser task picker — same
11
+ * search/filter/quit help, and the preview pane for a linked run IS the
12
+ * canonical session digest, not a second renderer. Unlike a browser task, a
13
+ * computer run has no on-disk artifact of its own to open (see
14
+ * `lib/computer/sessions-list.ts`'s module docblock), so `enter` prints the
15
+ * run's full action list rather than opening a file, and the picker keeps
16
+ * browsing afterward instead of exiting.
17
+ */
18
+ import chalk from 'chalk';
19
+ import { itemPicker } from '../lib/picker.js';
20
+ import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
21
+ import { buildPreview } from './sessions-picker.js';
22
+ import { runComputerSessions, printComputerSessionRows, buildComputerSessionRows, matchesComputerSessionRow, formatRowActions, } from '../lib/computer/sessions-list.js';
23
+ import { formatRelativeTime } from '../lib/session/relative-time.js';
24
+ /** True when the interactive picker should open instead of the printed table:
25
+ * a real TTY, no `--json`, and `--no-interactive` not set. */
26
+ export function shouldOpenInteractiveComputerSessions(opts, isTTY) {
27
+ return opts.interactive !== false && !opts.json && isTTY;
28
+ }
29
+ /**
30
+ * Shared entry point for `agents computer sessions` and `agents sessions
31
+ * --computer`. Mirrors `runBrowserSessionsCommand`'s interactive-routing
32
+ * split so both call sites stay in lockstep.
33
+ */
34
+ export async function runComputerSessionsCommand(opts) {
35
+ if (!shouldOpenInteractiveComputerSessions(opts, isInteractiveTerminal())) {
36
+ if (opts.rows)
37
+ printComputerSessionRows(opts.rows, { limit: opts.limit, json: opts.json });
38
+ else
39
+ runComputerSessions({ machine: opts.machine, limit: opts.limit, json: opts.json });
40
+ return;
41
+ }
42
+ const rows = opts.rows ?? buildComputerSessionRows({ machine: opts.machine });
43
+ if (rows.length === 0) {
44
+ console.log(`No computer actions recorded${opts.machine ? ` for machine "${opts.machine}"` : ''}.`);
45
+ return;
46
+ }
47
+ await browseComputerSessions(rows);
48
+ }
49
+ function rowLinkSummary(row) {
50
+ if (row.linkStatus === 'linked' && row.linkedSession) {
51
+ const s = row.linkedSession;
52
+ return chalk.cyan(s.agent) + ' — ' + (s.label || s.topic || s.shortId);
53
+ }
54
+ if (row.linkStatus === 'unresolved') {
55
+ return chalk.yellow(`owner ${row.agent ?? 'unknown'} (session not indexed here)`);
56
+ }
57
+ return chalk.gray('unlinked');
58
+ }
59
+ function formatRowLabel(row) {
60
+ // Pad the raw text first, THEN colorize — padEnd on an already-chalked
61
+ // string counts the ANSI escape bytes as width and misaligns the column.
62
+ const rawName = row.task ?? row.bundle ?? (row.pid ? `pid ${row.pid}` : 'recovered run');
63
+ const name = rawName.slice(0, 40).padEnd(40);
64
+ const coloredName = row.task ? name : chalk.gray(name);
65
+ const where = (row.remoteHost ? `${row.machine} -> ${row.remoteHost}` : row.machine).padEnd(24);
66
+ const age = formatRelativeTime(new Date(row.endMs).toISOString());
67
+ const counts = formatRowActions(row);
68
+ return [coloredName, where, age.padEnd(11), counts.padEnd(24), rowLinkSummary(row)].join(' ');
69
+ }
70
+ const PREVIEW_ACTION_LIMIT = 12;
71
+ function buildRowPreview(row) {
72
+ const parts = [];
73
+ if (row.linkStatus === 'linked' && row.linkedSession) {
74
+ parts.push(buildPreview(row.linkedSession));
75
+ }
76
+ else if (row.linkStatus === 'unresolved') {
77
+ parts.push(chalk.yellow(`owner ${row.agent ?? 'unknown'} — session ${row.sessionId ?? row.launchId} has no indexed session on this machine.`));
78
+ }
79
+ else {
80
+ parts.push(chalk.gray('Unlinked — no owning agent session is known for this run (no session/launch identity recorded).'));
81
+ }
82
+ if (row.task) {
83
+ parts.push('');
84
+ parts.push(chalk.bold('Task:') + ` ${row.task}`);
85
+ }
86
+ parts.push('');
87
+ parts.push(chalk.bold(`Actions (${row.recoveredActionCount ?? row.actions.length})`) + ` ${formatRowActions(row)}`);
88
+ for (const a of row.actions.slice(0, PREVIEW_ACTION_LIMIT)) {
89
+ parts.push(` ${formatActionLabel(a)}`);
90
+ }
91
+ const more = row.actions.length - PREVIEW_ACTION_LIMIT;
92
+ if (more > 0)
93
+ parts.push(chalk.gray(` … (${more} more)`));
94
+ return parts.join('\n');
95
+ }
96
+ function formatActionLabel(a) {
97
+ const age = formatRelativeTime(new Date(a.tsMs).toISOString());
98
+ const target = a.bundle ?? (a.targetPid != null ? `pid ${a.targetPid}` : '-');
99
+ return `${age.padEnd(11)} ${a.verb.padEnd(14)} ${target}`;
100
+ }
101
+ /** Print one run's full action list (no truncation) — the `enter` action,
102
+ * since a computer run has no on-disk artifact to open. */
103
+ function printRunDetail(row) {
104
+ console.log('');
105
+ console.log(chalk.bold(row.task ?? row.bundle ?? `pid ${row.pid}`));
106
+ console.log(row.remoteHost ? `${row.machine} -> ${row.remoteHost}` : row.machine);
107
+ console.log('');
108
+ for (const a of row.actions)
109
+ console.log(formatActionLabel(a));
110
+ if (row.actions.length === 0)
111
+ console.log('(no driving actions recorded)');
112
+ console.log('');
113
+ }
114
+ /** Run-level picker with an action-list preview. Loops until the user quits
115
+ * (esc) so a session's whole run history can be browsed repeatedly in one
116
+ * sitting — mirroring `browseAndOpen`'s loop, minus the artifact drill-down
117
+ * a computer run has none of. */
118
+ async function browseComputerSessions(rows) {
119
+ for (;;) {
120
+ let picked;
121
+ try {
122
+ picked = await itemPicker({
123
+ message: 'Computer sessions:',
124
+ items: rows,
125
+ filter: (query) => (query.trim() ? rows.filter((r) => matchesComputerSessionRow(r, query)) : rows),
126
+ labelFor: (row) => formatRowLabel(row),
127
+ buildPreview: (row) => buildRowPreview(row),
128
+ emptyMessage: 'No computer sessions match.',
129
+ enterHint: 'view actions',
130
+ });
131
+ }
132
+ catch (err) {
133
+ if (isPromptCancelled(err))
134
+ return;
135
+ throw err;
136
+ }
137
+ if (!picked)
138
+ return;
139
+ printRunDetail(picked.item);
140
+ }
141
+ }
@@ -38,6 +38,22 @@ export declare function reconcileScreenshotExt(outPath: string, buf: Buffer): {
38
38
  export declare function registerComputerCommand(program: Command): void;
39
39
  export declare function registerComputerSubcommands(program: Command): void;
40
40
  export declare function buildRestartTaskScript(taskName: string, exeName: string): string;
41
+ /**
42
+ * Emit a `computer.action` marker for `computer run`'s whole loop process, so
43
+ * `agents computer sessions` groups every verb the loop drives under one
44
+ * task-labeled row instead of a bare pid with no task text (see
45
+ * lib/computer/sessions-list.ts's "Grouping key" docblock note). The task
46
+ * text is bounded to `TASK_PREVIEW_MAX_CHARS` — never the full unbounded
47
+ * `--task` string — matching that module's retention/privacy note. Exported
48
+ * so the truncation behavior is directly unit-testable against the real
49
+ * event ledger, the same seam `computer-actions.test.ts` already uses for
50
+ * `emitComputerAction`.
51
+ */
52
+ export declare function emitComputerRunTaskMarker(opts: {
53
+ task: string;
54
+ bundle?: string;
55
+ host?: string;
56
+ }): void;
41
57
  /**
42
58
  * Install the macOS helper locally: resolve (or download + verify) the signed,
43
59
  * notarized .app, copy it to /Applications, verify the destination signature,
@@ -11,6 +11,9 @@ import { registerActionCommands, withClient, unwrap, pickTarget, emitComputerAct
11
11
  import { runComputerLoop } from '../lib/computer/loop.js';
12
12
  import { makeVerbDispatcher } from '../lib/computer/dispatch.js';
13
13
  import { makeClaudeResponder, resolveApiKey, DEFAULT_CLAUDE_MODEL, DEFAULT_CLAUDE_BASE_URL } from '../lib/computer/model.js';
14
+ import { TASK_PREVIEW_MAX_CHARS } from '../lib/computer/sessions-list.js';
15
+ import { runComputerSessionsCommand } from './computer-sessions-picker.js';
16
+ import { truncate } from '../lib/events.js';
14
17
  // Help groups — mirror `agents browser` so the mental model carries over.
15
18
  const COMPUTER_HELP_GROUPS = [
16
19
  { title: 'Installation', names: ['setup'] },
@@ -18,6 +21,7 @@ const COMPUTER_HELP_GROUPS = [
18
21
  { title: 'Autonomous', names: ['run'] },
19
22
  { title: 'Observe', names: ['apps', 'describe', 'screenshot', 'get-text'] },
20
23
  { title: 'Interact', names: ['launch', 'raise', 'click', 'right-click', 'type', 'type-text', 'key', 'drag', 'scroll', 'ax-action', 'focus', 'wait'] },
24
+ { title: 'History and discovery', names: ['sessions'] },
21
25
  ];
22
26
  // Subcommands that manage the `--host` remote path themselves (provisioning /
23
27
  // tunnel lifecycle, or daemon-state reporting that must degrade gracefully
@@ -109,6 +113,7 @@ export function registerComputerSubcommands(program) {
109
113
  registerRunCommand(program);
110
114
  registerScreenshotCommand(program);
111
115
  registerActionCommands(program);
116
+ registerSessionsCommand(program);
112
117
  registerCommandGroups(program, COMPUTER_HELP_GROUPS);
113
118
  }
114
119
  function registerStatusCommand(program) {
@@ -300,6 +305,7 @@ function registerRunCommand(program) {
300
305
  model: opts.model,
301
306
  maxTokens: opts.maxTokens,
302
307
  });
308
+ emitComputerRunTaskMarker({ task: opts.task, bundle: opts.bundle, host: opts.host });
303
309
  await withClient(async (client) => {
304
310
  const dispatch = makeVerbDispatcher(client, { host: opts.host });
305
311
  const targetInput = opts.bundle ? { bundle: opts.bundle } : {};
@@ -324,6 +330,37 @@ function registerRunCommand(program) {
324
330
  });
325
331
  });
326
332
  }
333
+ // sessions — task-first history over the computer.action event ledger (RUSH-2432),
334
+ // the computer counterpart of `agents browser sessions` (RUSH-2407). `agents
335
+ // sessions --computer` (sessions.ts) routes to the same runComputerSessionsCommand.
336
+ function registerSessionsCommand(program) {
337
+ program
338
+ .command('sessions')
339
+ .description('Browse computer-driving history, grouped by run — one row per `agents computer` invocation')
340
+ .option('--machine <name>', 'Only rows invoked from/driving this machine (hostname, machineId, or --host device)')
341
+ .option('--limit <n>', 'Cap the flat/--no-interactive table at this many rows (default 50; --json is unbounded)', (v) => parseInt(v, 10))
342
+ .option('--json', 'Emit machine-readable JSON')
343
+ .option('--no-interactive', 'Print the flat listing instead of opening the interactive run browser')
344
+ .action(async (opts) => {
345
+ await runComputerSessionsCommand({ machine: opts.machine, limit: opts.limit, json: opts.json, interactive: opts.interactive });
346
+ });
347
+ }
348
+ /**
349
+ * Emit a `computer.action` marker for `computer run`'s whole loop process, so
350
+ * `agents computer sessions` groups every verb the loop drives under one
351
+ * task-labeled row instead of a bare pid with no task text (see
352
+ * lib/computer/sessions-list.ts's "Grouping key" docblock note). The task
353
+ * text is bounded to `TASK_PREVIEW_MAX_CHARS` — never the full unbounded
354
+ * `--task` string — matching that module's retention/privacy note. Exported
355
+ * so the truncation behavior is directly unit-testable against the real
356
+ * event ledger, the same seam `computer-actions.test.ts` already uses for
357
+ * `emitComputerAction`.
358
+ */
359
+ export function emitComputerRunTaskMarker(opts) {
360
+ emitComputerAction('run', undefined, { bundle: opts.bundle, host: opts.host }, {
361
+ task: truncate(opts.task, TASK_PREVIEW_MAX_CHARS),
362
+ });
363
+ }
327
364
  // Fold the target bundle into the task text so the model biases toward it.
328
365
  function describeTaskWithTarget(task, bundle) {
329
366
  return bundle ? `${task}\n(Target app bundle id: ${bundle})` : task;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Unified configuration command barrel.
3
+ *
4
+ * `agents config` consolidates the fragmented config surface into one namespace:
5
+ * - run defaults (model, mode, effort)
6
+ * - tier overrides (folded into the run namespace)
7
+ * - interactive host
8
+ * - usage primary host
9
+ * - browser profile
10
+ * - local projects root
11
+ * - per-device config keys
12
+ *
13
+ * The underlying YAML schema is unchanged; this command translates the new key
14
+ * grammar into reads/writes of the existing stores.
15
+ */
16
+ import type { Command } from 'commander';
17
+ export declare function registerConfigCommand(program: Command): void;
@@ -0,0 +1,401 @@
1
+ /**
2
+ * Unified configuration command barrel.
3
+ *
4
+ * `agents config` consolidates the fragmented config surface into one namespace:
5
+ * - run defaults (model, mode, effort)
6
+ * - tier overrides (folded into the run namespace)
7
+ * - interactive host
8
+ * - usage primary host
9
+ * - browser profile
10
+ * - local projects root
11
+ * - per-device config keys
12
+ *
13
+ * The underlying YAML schema is unchanged; this command translates the new key
14
+ * grammar into reads/writes of the existing stores.
15
+ */
16
+ import chalk from 'chalk';
17
+ import { setHelpSections } from '../lib/help.js';
18
+ import { parseConfigKey, formatAgentVersion, devicePropertyToConfigName, configKeyStorageHint, } from '../lib/config-keys.js';
19
+ import { resolveRunDefaults, setRunDefaultModel, setRunDefaultMode, setRunDefaultEffort, unsetRunDefault, } from '../lib/run-defaults.js';
20
+ import { resolveTierOverride, setTierOverride, clearTierOverride } from '../lib/model-tier-overrides.js';
21
+ import { getConfigValue, setConfigValue, unsetConfigValue, listConfig, } from '../lib/device-config.js';
22
+ import { readMeta, updateMeta } from '../lib/state.js';
23
+ import { MODEL_TIERS } from '../lib/model-tiers.js';
24
+ import { machineId } from '../lib/machine-id.js';
25
+ import { getProjectRoot, setProjectRoot } from '../lib/project-root.js';
26
+ /** Parse a boolean value the same way `agents devices configure` does. */
27
+ function parseBool(value, key) {
28
+ const v = value.trim().toLowerCase();
29
+ if (v === 'on' || v === 'true')
30
+ return true;
31
+ if (v === 'off' || v === 'false')
32
+ return false;
33
+ throw new Error(`Config key '${key}' expects a boolean ('on' or 'off'), got '${value}'.`);
34
+ }
35
+ /** Parse the value for a given key, enforcing type rules. */
36
+ function parseValue(key, parsed, raw) {
37
+ switch (parsed.scope) {
38
+ case 'run':
39
+ return raw.trim();
40
+ case 'interactive':
41
+ return raw.trim();
42
+ case 'usage':
43
+ return raw.trim();
44
+ case 'browser':
45
+ return raw.trim();
46
+ case 'project':
47
+ return raw.trim();
48
+ case 'device': {
49
+ switch (parsed.property) {
50
+ case 'max-agents':
51
+ if (!/^\d+$/.test(raw.trim())) {
52
+ throw new Error(`Config key '${key}' expects an integer, got '${raw}'.`);
53
+ }
54
+ return Number.parseInt(raw.trim(), 10);
55
+ case 'scheduler':
56
+ case 'daemon':
57
+ case 'watchdog':
58
+ case 'browser.remote-control':
59
+ return parseBool(raw, key);
60
+ case 'notes':
61
+ return raw.trim();
62
+ case 'browser.profile':
63
+ return raw.trim();
64
+ }
65
+ }
66
+ }
67
+ }
68
+ /** Write a value for a parsed config key. */
69
+ function setConfig(parsed, value) {
70
+ switch (parsed.scope) {
71
+ case 'run': {
72
+ const selector = `${parsed.agent}:${parsed.version}`;
73
+ if (parsed.property === 'tier') {
74
+ setTierOverride(selector, parsed.tier, value);
75
+ return;
76
+ }
77
+ if (parsed.property === 'model') {
78
+ setRunDefaultModel(selector, value);
79
+ }
80
+ else if (parsed.property === 'mode') {
81
+ setRunDefaultMode(selector, value);
82
+ }
83
+ else {
84
+ setRunDefaultEffort(selector, value);
85
+ }
86
+ return;
87
+ }
88
+ case 'interactive': {
89
+ setConfigValue('interactive.host', value);
90
+ return;
91
+ }
92
+ case 'usage': {
93
+ setConfigValue('usage.primary-host', value);
94
+ return;
95
+ }
96
+ case 'browser': {
97
+ // Device-local default lives in the central fleet.devices.<name>.config
98
+ // block (same store `agents devices config` / getConfigValue use). Bare
99
+ // browser.profile targets this machine; devices.<name>.browser.profile
100
+ // targets a peer.
101
+ setConfigValue('browser.profile', value, parsed.device ? { device: parsed.device } : undefined);
102
+ return;
103
+ }
104
+ case 'project':
105
+ setProjectRoot(value);
106
+ return;
107
+ case 'device': {
108
+ const configName = devicePropertyToConfigName(parsed.property);
109
+ if (parsed.property === 'notes') {
110
+ const existing = getConfigValue('notes', { device: parsed.device }).value ?? [];
111
+ setConfigValue('notes', [...existing, value], { device: parsed.device });
112
+ }
113
+ else {
114
+ setConfigValue(configName, value, { device: parsed.device });
115
+ }
116
+ return;
117
+ }
118
+ }
119
+ }
120
+ /** Unset a parsed config key. */
121
+ function unsetConfig(parsed) {
122
+ switch (parsed.scope) {
123
+ case 'run': {
124
+ const selector = `${parsed.agent}:${parsed.version}`;
125
+ if (parsed.property === 'tier') {
126
+ return clearTierOverride(selector, parsed.tier);
127
+ }
128
+ return unsetRunDefault(selector);
129
+ }
130
+ case 'interactive': {
131
+ const had = getConfigValue('interactive.host').value !== undefined;
132
+ unsetConfigValue('interactive.host');
133
+ return had;
134
+ }
135
+ case 'usage': {
136
+ const had = getConfigValue('usage.primary-host').value !== undefined;
137
+ unsetConfigValue('usage.primary-host');
138
+ return had;
139
+ }
140
+ case 'browser': {
141
+ const target = parsed.device ? { device: parsed.device } : undefined;
142
+ const had = getConfigValue('browser.profile', target).value !== undefined;
143
+ unsetConfigValue('browser.profile', target);
144
+ return had;
145
+ }
146
+ case 'project': {
147
+ const had = getProjectRoot() !== undefined;
148
+ updateMeta((meta) => {
149
+ const { projectRoot: _projectRoot, ...rest } = meta;
150
+ return rest;
151
+ });
152
+ return had;
153
+ }
154
+ case 'device': {
155
+ const configName = devicePropertyToConfigName(parsed.property);
156
+ const had = getConfigValue(configName, { device: parsed.device }).value !== undefined;
157
+ unsetConfigValue(configName, { device: parsed.device });
158
+ return had;
159
+ }
160
+ }
161
+ }
162
+ /** Read the stored value for a parsed config key. */
163
+ function getConfig(parsed) {
164
+ switch (parsed.scope) {
165
+ case 'run': {
166
+ const defaults = resolveRunDefaults(parsed.agent, parsed.version);
167
+ if (parsed.property === 'tier') {
168
+ return resolveTierOverride(parsed.agent, parsed.version)[parsed.tier];
169
+ }
170
+ return defaults[parsed.property];
171
+ }
172
+ case 'interactive':
173
+ return getConfigValue('interactive.host').value;
174
+ case 'usage':
175
+ return getConfigValue('usage.primary-host').value;
176
+ case 'browser': {
177
+ return getConfigValue('browser.profile', parsed.device ? { device: parsed.device } : undefined).value;
178
+ }
179
+ case 'project':
180
+ return getProjectRoot();
181
+ case 'device': {
182
+ const configName = devicePropertyToConfigName(parsed.property);
183
+ return getConfigValue(configName, { device: parsed.device }).value;
184
+ }
185
+ }
186
+ }
187
+ /** Format a config value for display. */
188
+ function formatValue(value) {
189
+ if (value === undefined)
190
+ return chalk.gray('(unset)');
191
+ if (typeof value === 'boolean')
192
+ return value ? chalk.green('true') : chalk.red('false');
193
+ return chalk.cyan(JSON.stringify(value));
194
+ }
195
+ /** Collect all set config entries for a given device scope (self or peer). */
196
+ function* listRunConfigEntries() {
197
+ const meta = readMeta();
198
+ for (const [selector, defaults] of Object.entries(meta.run?.defaults ?? {})) {
199
+ const [agent, version] = selector.split(':');
200
+ if (!agent || !version)
201
+ continue;
202
+ const base = `run.${formatAgentVersion(agent, version)}`;
203
+ const d = defaults;
204
+ for (const prop of ['model', 'mode', 'effort']) {
205
+ if (d[prop] !== undefined) {
206
+ const key = `${base}.${prop}`;
207
+ yield { key, value: d[prop], hint: configKeyStorageHint(parseConfigKey(key)) };
208
+ }
209
+ }
210
+ }
211
+ for (const [selector, tiers] of Object.entries(meta.model?.tiers ?? {})) {
212
+ const [agent, version] = selector.split(':');
213
+ if (!agent || !version)
214
+ continue;
215
+ const base = `run.${formatAgentVersion(agent, version)}.tier`;
216
+ for (const tier of MODEL_TIERS) {
217
+ const value = tiers[tier];
218
+ if (value !== undefined) {
219
+ const key = `${base}.${tier}`;
220
+ yield { key, value, hint: configKeyStorageHint(parseConfigKey(key)) };
221
+ }
222
+ }
223
+ }
224
+ }
225
+ /** Collect central non-run config entries. */
226
+ function* listCentralConfigEntries() {
227
+ const meta = readMeta();
228
+ if (meta.config?.interactiveHost !== undefined) {
229
+ yield { key: 'interactive.host', value: meta.config.interactiveHost, hint: 'config.interactiveHost' };
230
+ }
231
+ if (meta.config?.usagePrimaryHost !== undefined) {
232
+ yield { key: 'usage.primary-host', value: meta.config.usagePrimaryHost, hint: 'config.usagePrimaryHost' };
233
+ }
234
+ if (meta.projectRoot !== undefined) {
235
+ yield { key: 'project.root', value: meta.projectRoot, hint: 'devices.<self>.projectRoot' };
236
+ }
237
+ // This machine's default browser profile lives in fleet.devices.<self>.config
238
+ // (device-config), not the legacy top-level Meta.defaultBrowserProfile field.
239
+ const browserProfile = getConfigValue('browser.profile').value;
240
+ if (browserProfile !== undefined) {
241
+ const key = 'browser.profile';
242
+ yield { key, value: browserProfile, hint: configKeyStorageHint(parseConfigKey(key)) };
243
+ }
244
+ }
245
+ /** Collect device-scope config entries. */
246
+ function* listDeviceConfigEntries(device) {
247
+ for (const entry of listConfig({ device })) {
248
+ if (entry.value === undefined)
249
+ continue;
250
+ const prefix = `devices.${device}.`;
251
+ let key;
252
+ switch (entry.spec.name) {
253
+ case 'agents.max-concurrent':
254
+ key = `${prefix}max-agents`;
255
+ break;
256
+ case 'scheduler.enabled':
257
+ key = `${prefix}scheduler`;
258
+ break;
259
+ case 'daemon.enabled':
260
+ key = `${prefix}daemon`;
261
+ break;
262
+ case 'watchdog.enabled':
263
+ key = `${prefix}watchdog`;
264
+ break;
265
+ case 'browser.remote-control':
266
+ key = `${prefix}browser.remote-control`;
267
+ break;
268
+ case 'notes':
269
+ key = `${prefix}notes`;
270
+ break;
271
+ case 'browser.profile':
272
+ // The self device's default browser profile is already surfaced as the
273
+ // top-level `browser.profile` key; skip it here to avoid duplication.
274
+ if (device === machineId())
275
+ continue;
276
+ key = `${prefix}browser.profile`;
277
+ break;
278
+ default:
279
+ continue;
280
+ }
281
+ yield { key, value: entry.value, hint: configKeyStorageHint(parseConfigKey(key)) };
282
+ }
283
+ }
284
+ export function registerConfigCommand(program) {
285
+ const config = program
286
+ .command('config')
287
+ .description('Get, set, list, and unset run defaults, tier overrides, the projects root, and device options.');
288
+ setHelpSections(config, {
289
+ examples: `
290
+ agents config set run.claude@*.model best
291
+ agents config set run.claude@*.tier.best claude-opus-4-8
292
+ agents config set run.claude@2.1.45.model claude-opus-4-8
293
+ agents config set run.claude@*.mode auto
294
+ agents config set interactive.host zion
295
+ agents config set usage.primary-host zion
296
+ agents config set browser.profile work
297
+ agents config set project.root ~/src/github.com/<you>
298
+ agents config set devices.mac-mini.max-agents 4
299
+ agents config get run.claude@*.model
300
+ agents config get usage.primary-host
301
+ agents config unset run.claude@*.tier.best
302
+ agents config unset usage.primary-host
303
+ agents config list
304
+ `,
305
+ notes: `
306
+ Every agent/harness reference uses agent@version. Use * for all versions.
307
+ Tier overrides are part of the run namespace: run.<agent@version>.tier.<tier>.
308
+ Project root is auto-inferred from the current Git repository when unset.
309
+ `,
310
+ });
311
+ config
312
+ .command('list')
313
+ .description('List configured config keys and their values')
314
+ .option('--device <name>', 'List config for a specific device instead of this machine')
315
+ .option('--json', 'Output machine-readable JSON')
316
+ .action((opts) => {
317
+ try {
318
+ const entries = [];
319
+ if (!opts.device) {
320
+ entries.push(...listRunConfigEntries());
321
+ entries.push(...listCentralConfigEntries());
322
+ entries.push(...listDeviceConfigEntries(machineId()));
323
+ }
324
+ else {
325
+ entries.push(...listDeviceConfigEntries(opts.device));
326
+ }
327
+ entries.sort((a, b) => a.key.localeCompare(b.key));
328
+ if (opts.json) {
329
+ process.stdout.write(JSON.stringify(entries, null, 2) + '\n');
330
+ return;
331
+ }
332
+ if (entries.length === 0) {
333
+ console.log(chalk.gray('No config values set.'));
334
+ console.log(chalk.gray("Set one with: agents config set run.claude@*.model best"));
335
+ return;
336
+ }
337
+ console.log(chalk.bold('Config\n'));
338
+ for (const { key, value, hint } of entries) {
339
+ console.log(` ${chalk.cyan(key.padEnd(42))} ${formatValue(value)}`);
340
+ console.log(` ${''.padEnd(42)} ${chalk.gray(hint)}`);
341
+ }
342
+ }
343
+ catch (err) {
344
+ console.error(chalk.red(err.message));
345
+ process.exit(1);
346
+ }
347
+ });
348
+ config
349
+ .command('get <key>')
350
+ .description('Get the current value of a config key')
351
+ .option('--json', 'Output machine-readable JSON')
352
+ .action((key, opts) => {
353
+ try {
354
+ const parsed = parseConfigKey(key);
355
+ const value = getConfig(parsed);
356
+ if (opts.json) {
357
+ process.stdout.write(JSON.stringify({ key, value: value ?? null }, null, 2) + '\n');
358
+ return;
359
+ }
360
+ console.log(`${chalk.cyan(key)} = ${formatValue(value)}`);
361
+ }
362
+ catch (err) {
363
+ console.error(chalk.red(err.message));
364
+ process.exit(1);
365
+ }
366
+ });
367
+ config
368
+ .command('set <key> <value>')
369
+ .description('Set a config key')
370
+ .action((key, value) => {
371
+ try {
372
+ const parsed = parseConfigKey(key);
373
+ const typed = parseValue(key, parsed, value);
374
+ setConfig(parsed, typed);
375
+ console.log(chalk.green('Set:') + ` ${chalk.cyan(key)} = ${formatValue(typed)}`);
376
+ }
377
+ catch (err) {
378
+ console.error(chalk.red(err.message));
379
+ process.exit(1);
380
+ }
381
+ });
382
+ config
383
+ .command('unset <key>')
384
+ .description('Unset a config key (restore default behavior)')
385
+ .action((key) => {
386
+ try {
387
+ const parsed = parseConfigKey(key);
388
+ const removed = unsetConfig(parsed);
389
+ if (removed) {
390
+ console.log(chalk.green(`Unset ${key}`));
391
+ }
392
+ else {
393
+ console.log(chalk.gray(`No value set for ${key}`));
394
+ }
395
+ }
396
+ catch (err) {
397
+ console.error(chalk.red(err.message));
398
+ process.exit(1);
399
+ }
400
+ });
401
+ }