@phnx-labs/agents-cli 1.22.35 → 1.22.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/CHANGELOG.md +708 -2
  2. package/README.md +83 -43
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1212 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/artifacts-setup.d.ts +53 -0
  9. package/dist/commands/artifacts-setup.js +161 -0
  10. package/dist/commands/artifacts.d.ts +18 -0
  11. package/dist/commands/artifacts.js +58 -0
  12. package/dist/commands/attach.js +17 -4
  13. package/dist/commands/audit.d.ts +8 -8
  14. package/dist/commands/audit.js +57 -47
  15. package/dist/commands/browser.js +17 -11
  16. package/dist/commands/cloud.js +1 -1
  17. package/dist/commands/commands.js +0 -11
  18. package/dist/commands/computer-actions.js +33 -0
  19. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  20. package/dist/commands/computer-sessions-picker.js +141 -0
  21. package/dist/commands/computer.d.ts +16 -0
  22. package/dist/commands/computer.js +37 -0
  23. package/dist/commands/config.d.ts +17 -0
  24. package/dist/commands/config.js +401 -0
  25. package/dist/commands/cp.d.ts +84 -0
  26. package/dist/commands/cp.js +231 -0
  27. package/dist/commands/daemon.js +243 -14
  28. package/dist/commands/detach-core.d.ts +1 -1
  29. package/dist/commands/detach-core.js +12 -2
  30. package/dist/commands/detach.js +1 -1
  31. package/dist/commands/doctor.js +64 -5
  32. package/dist/commands/events.d.ts +24 -12
  33. package/dist/commands/events.js +144 -28
  34. package/dist/commands/exec.js +86 -42
  35. package/dist/commands/feed.d.ts +1 -1
  36. package/dist/commands/feed.js +16 -8
  37. package/dist/commands/focus.d.ts +33 -1
  38. package/dist/commands/focus.js +177 -17
  39. package/dist/commands/funnel.d.ts +1 -1
  40. package/dist/commands/go.js +9 -8
  41. package/dist/commands/harness-wizard.d.ts +1 -0
  42. package/dist/commands/harness-wizard.js +18 -20
  43. package/dist/commands/harness.d.ts +2 -0
  44. package/dist/commands/harness.js +59 -26
  45. package/dist/commands/hooks.js +0 -11
  46. package/dist/commands/inspect.d.ts +94 -1
  47. package/dist/commands/inspect.js +866 -40
  48. package/dist/commands/lease.d.ts +4 -4
  49. package/dist/commands/lease.js +6 -6
  50. package/dist/commands/login.js +0 -13
  51. package/dist/commands/logs.d.ts +2 -2
  52. package/dist/commands/logs.js +2 -2
  53. package/dist/commands/mcp.js +7 -2
  54. package/dist/commands/memory.js +7 -2
  55. package/dist/commands/message.d.ts +1 -1
  56. package/dist/commands/message.js +37 -6
  57. package/dist/commands/models.js +71 -0
  58. package/dist/commands/monitors.d.ts +0 -1
  59. package/dist/commands/monitors.js +199 -16
  60. package/dist/commands/open.d.ts +18 -0
  61. package/dist/commands/open.js +57 -0
  62. package/dist/commands/packages.js +2 -107
  63. package/dist/commands/plugins.js +6 -3
  64. package/dist/commands/profiles.d.ts +1 -0
  65. package/dist/commands/profiles.js +16 -160
  66. package/dist/commands/projects.d.ts +28 -0
  67. package/dist/commands/projects.js +125 -5
  68. package/dist/commands/reconnect.js +9 -3
  69. package/dist/commands/repo.js +42 -1
  70. package/dist/commands/resource-view.d.ts +17 -0
  71. package/dist/commands/resource-view.js +36 -14
  72. package/dist/commands/resume.js +9 -2
  73. package/dist/commands/routines.d.ts +0 -2
  74. package/dist/commands/routines.js +473 -289
  75. package/dist/commands/secrets.js +52 -9
  76. package/dist/commands/sessions-export.d.ts +47 -0
  77. package/dist/commands/sessions-export.js +116 -6
  78. package/dist/commands/sessions-import.d.ts +17 -0
  79. package/dist/commands/sessions-import.js +114 -6
  80. package/dist/commands/sessions-migrate.d.ts +27 -0
  81. package/dist/commands/sessions-migrate.js +50 -9
  82. package/dist/commands/sessions-picker.js +23 -4
  83. package/dist/commands/sessions-resume.d.ts +5 -3
  84. package/dist/commands/sessions-resume.js +30 -8
  85. package/dist/commands/sessions-watch.d.ts +2 -0
  86. package/dist/commands/sessions-watch.js +53 -0
  87. package/dist/commands/sessions.d.ts +66 -3
  88. package/dist/commands/sessions.js +298 -47
  89. package/dist/commands/setup-browser.js +2 -2
  90. package/dist/commands/setup-mine.js +0 -1
  91. package/dist/commands/setup-preferences.js +1 -1
  92. package/dist/commands/setup.d.ts +5 -0
  93. package/dist/commands/setup.js +31 -5
  94. package/dist/commands/share.d.ts +87 -7
  95. package/dist/commands/share.js +320 -58
  96. package/dist/commands/skills.js +0 -11
  97. package/dist/commands/snapshot.js +1 -1
  98. package/dist/commands/ssh.d.ts +18 -0
  99. package/dist/commands/ssh.js +549 -210
  100. package/dist/commands/sync.d.ts +5 -0
  101. package/dist/commands/sync.js +212 -32
  102. package/dist/commands/teams.d.ts +13 -0
  103. package/dist/commands/teams.js +187 -30
  104. package/dist/commands/tickets.d.ts +2 -0
  105. package/dist/commands/tickets.js +43 -0
  106. package/dist/commands/update.js +2 -4
  107. package/dist/commands/usage.js +5 -3
  108. package/dist/commands/versions.js +11 -5
  109. package/dist/commands/view.js +15 -7
  110. package/dist/commands/webhook.d.ts +2 -2
  111. package/dist/commands/webhook.js +7 -7
  112. package/dist/index.d.ts +18 -2
  113. package/dist/index.js +53 -1264
  114. package/dist/lib/account-catalog.d.ts +18 -0
  115. package/dist/lib/account-catalog.js +38 -0
  116. package/dist/lib/account-provider-registry.d.ts +18 -0
  117. package/dist/lib/account-provider-registry.js +59 -0
  118. package/dist/lib/account-registry.d.ts +40 -0
  119. package/dist/lib/account-registry.js +239 -0
  120. package/dist/lib/account-schema.d.ts +44 -0
  121. package/dist/lib/account-schema.js +91 -0
  122. package/dist/lib/account-state-service.d.ts +21 -0
  123. package/dist/lib/account-state-service.js +60 -0
  124. package/dist/lib/activity.d.ts +1 -1
  125. package/dist/lib/activity.js +8 -1
  126. package/dist/lib/add-dir.d.ts +80 -0
  127. package/dist/lib/add-dir.js +241 -0
  128. package/dist/lib/agent-cli-commands.d.ts +11 -0
  129. package/dist/lib/agent-cli-commands.js +30 -0
  130. package/dist/lib/agents.js +44 -36
  131. package/dist/lib/answer-router.js +1 -1
  132. package/dist/lib/audit/log.d.ts +10 -27
  133. package/dist/lib/audit/log.js +20 -33
  134. package/dist/lib/auth-health.d.ts +9 -2
  135. package/dist/lib/auth-health.js +42 -9
  136. package/dist/lib/auto-pull-worker.js +7 -3
  137. package/dist/lib/auto-pull.d.ts +44 -3
  138. package/dist/lib/auto-pull.js +88 -5
  139. package/dist/lib/binary-shadow.d.ts +28 -0
  140. package/dist/lib/binary-shadow.js +121 -0
  141. package/dist/lib/brand.js +9 -3
  142. package/dist/lib/browser/hygiene.d.ts +90 -0
  143. package/dist/lib/browser/hygiene.js +146 -0
  144. package/dist/lib/browser/ipc.d.ts +30 -0
  145. package/dist/lib/browser/ipc.js +93 -4
  146. package/dist/lib/browser/profiles.d.ts +3 -2
  147. package/dist/lib/browser/profiles.js +65 -22
  148. package/dist/lib/browser/service.d.ts +79 -1
  149. package/dist/lib/browser/service.js +231 -14
  150. package/dist/lib/browser/sessions-list.d.ts +22 -2
  151. package/dist/lib/browser/sessions-list.js +54 -6
  152. package/dist/lib/browser/stream.d.ts +2 -0
  153. package/dist/lib/browser/stream.js +1 -0
  154. package/dist/lib/browser/types.d.ts +63 -1
  155. package/dist/lib/byok-usage.d.ts +9 -2
  156. package/dist/lib/byok-usage.js +133 -31
  157. package/dist/lib/cli-entry.d.ts +11 -0
  158. package/dist/lib/cli-entry.js +46 -0
  159. package/dist/lib/cloud/host.d.ts +1 -1
  160. package/dist/lib/cloud/host.js +2 -2
  161. package/dist/lib/cloud/registry.js +1 -1
  162. package/dist/lib/cloud/types.d.ts +1 -1
  163. package/dist/lib/commands.d.ts +2 -0
  164. package/dist/lib/commands.js +2 -0
  165. package/dist/lib/computer/sessions-list.d.ts +150 -0
  166. package/dist/lib/computer/sessions-list.js +363 -0
  167. package/dist/lib/config-keys.d.ts +86 -0
  168. package/dist/lib/config-keys.js +193 -0
  169. package/dist/lib/config-machine-keys.d.ts +12 -0
  170. package/dist/lib/config-machine-keys.js +17 -0
  171. package/dist/lib/config-transfer.js +3 -4
  172. package/dist/lib/crabbox/cli.d.ts +2 -2
  173. package/dist/lib/crabbox/cli.js +3 -3
  174. package/dist/lib/daemon-health.d.ts +22 -0
  175. package/dist/lib/daemon-health.js +33 -3
  176. package/dist/lib/daemon-services.d.ts +50 -0
  177. package/dist/lib/daemon-services.js +147 -0
  178. package/dist/lib/daemon-ticks.d.ts +35 -66
  179. package/dist/lib/daemon-ticks.js +77 -159
  180. package/dist/lib/daemon.d.ts +72 -4
  181. package/dist/lib/daemon.js +792 -202
  182. package/dist/lib/deeplink/register.d.ts +49 -0
  183. package/dist/lib/deeplink/register.js +253 -0
  184. package/dist/lib/deeplink/url.d.ts +34 -0
  185. package/dist/lib/deeplink/url.js +78 -0
  186. package/dist/lib/device-config.d.ts +124 -29
  187. package/dist/lib/device-config.js +346 -141
  188. package/dist/lib/devices/config-migration.d.ts +42 -0
  189. package/dist/lib/devices/config-migration.js +203 -0
  190. package/dist/lib/devices/connect.js +14 -7
  191. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  192. package/dist/lib/devices/doctor-findings.js +20 -1
  193. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  194. package/dist/lib/devices/harness-inventory.js +0 -0
  195. package/dist/lib/devices/health.d.ts +1 -1
  196. package/dist/lib/devices/health.js +1 -1
  197. package/dist/lib/devices/pending.d.ts +22 -1
  198. package/dist/lib/devices/pending.js +67 -2
  199. package/dist/lib/devices/registry.d.ts +0 -25
  200. package/dist/lib/devices/registry.js +2 -83
  201. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  202. package/dist/lib/devices/resolve-profile.js +44 -0
  203. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  204. package/dist/lib/devices/rollout-verify.js +193 -0
  205. package/dist/lib/devices/ssh-config.js +10 -6
  206. package/dist/lib/event-families.d.ts +28 -0
  207. package/dist/lib/event-families.js +159 -0
  208. package/dist/lib/event-stream.d.ts +9 -1
  209. package/dist/lib/event-stream.js +26 -9
  210. package/dist/lib/events.d.ts +9 -1
  211. package/dist/lib/events.js +21 -6
  212. package/dist/lib/exec.d.ts +30 -0
  213. package/dist/lib/exec.js +219 -121
  214. package/dist/lib/feed-broadcast.d.ts +25 -0
  215. package/dist/lib/feed-broadcast.js +33 -0
  216. package/dist/lib/feed.d.ts +1 -1
  217. package/dist/lib/feed.js +12 -2
  218. package/dist/lib/fleet/capture.js +15 -0
  219. package/dist/lib/fleet/manifest.js +9 -0
  220. package/dist/lib/fleet/types.d.ts +9 -0
  221. package/dist/lib/fleet-status.js +10 -8
  222. package/dist/lib/git.d.ts +21 -7
  223. package/dist/lib/git.js +122 -18
  224. package/dist/lib/hosts/dispatch.d.ts +8 -3
  225. package/dist/lib/hosts/dispatch.js +29 -3
  226. package/dist/lib/hosts/logs.d.ts +2 -2
  227. package/dist/lib/hosts/logs.js +2 -2
  228. package/dist/lib/hosts/option.js +1 -1
  229. package/dist/lib/hosts/passthrough.d.ts +2 -3
  230. package/dist/lib/hosts/passthrough.js +10 -24
  231. package/dist/lib/hosts/progress.js +2 -2
  232. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  233. package/dist/lib/hosts/providers/devices.js +18 -12
  234. package/dist/lib/hosts/ready.d.ts +5 -1
  235. package/dist/lib/hosts/ready.js +9 -3
  236. package/dist/lib/hosts/reconcile.d.ts +2 -2
  237. package/dist/lib/hosts/reconcile.js +2 -2
  238. package/dist/lib/hosts/registry.js +14 -9
  239. package/dist/lib/hosts/remote-cmd.js +1 -1
  240. package/dist/lib/hosts/remote-os.d.ts +9 -6
  241. package/dist/lib/hosts/remote-os.js +13 -6
  242. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  243. package/dist/lib/hosts/routing-flag.js +41 -0
  244. package/dist/lib/hosts/run-target.js +1 -1
  245. package/dist/lib/hosts/session-index.js +1 -1
  246. package/dist/lib/hosts/tasks.d.ts +6 -6
  247. package/dist/lib/hosts/tasks.js +4 -4
  248. package/dist/lib/hosts/types.js +1 -2
  249. package/dist/lib/installations/resolve.js +2 -8
  250. package/dist/lib/isolation-boundary-report.js +0 -1
  251. package/dist/lib/linear-cache.d.ts +7 -0
  252. package/dist/lib/linear-cache.js +31 -4
  253. package/dist/lib/linear-project-counts.d.ts +1 -1
  254. package/dist/lib/linear-project-counts.js +2 -3
  255. package/dist/lib/linear-projects.js +1 -1
  256. package/dist/lib/loop.d.ts +2 -2
  257. package/dist/lib/loop.js +1 -1
  258. package/dist/lib/mailbox-target.d.ts +1 -1
  259. package/dist/lib/mailbox-target.js +1 -1
  260. package/dist/lib/manifest.js +7 -4
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  262. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  263. package/dist/lib/menubar/snapshot.d.ts +3 -2
  264. package/dist/lib/menubar/snapshot.js +6 -2
  265. package/dist/lib/migrate-fold.d.ts +33 -0
  266. package/dist/lib/migrate-fold.js +130 -0
  267. package/dist/lib/migrate.d.ts +34 -34
  268. package/dist/lib/migrate.js +106 -128
  269. package/dist/lib/model-tier-overrides.d.ts +1 -1
  270. package/dist/lib/model-tier-overrides.js +15 -2
  271. package/dist/lib/monitors/config.d.ts +17 -3
  272. package/dist/lib/monitors/config.js +52 -18
  273. package/dist/lib/monitors/engine.d.ts +32 -1
  274. package/dist/lib/monitors/engine.js +94 -11
  275. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  276. package/dist/lib/monitors/fingerprint.js +100 -0
  277. package/dist/lib/monitors/remote.d.ts +47 -0
  278. package/dist/lib/monitors/remote.js +81 -0
  279. package/dist/lib/monitors/state.d.ts +39 -0
  280. package/dist/lib/monitors/state.js +56 -0
  281. package/dist/lib/onepassword.d.ts +17 -0
  282. package/dist/lib/onepassword.js +52 -22
  283. package/dist/lib/open-url.js +1 -1
  284. package/dist/lib/picker.d.ts +14 -2
  285. package/dist/lib/picker.js +35 -13
  286. package/dist/lib/placement.d.ts +1 -1
  287. package/dist/lib/placement.js +1 -1
  288. package/dist/lib/pr-land-detach.d.ts +32 -0
  289. package/dist/lib/pr-land-detach.js +79 -0
  290. package/dist/lib/profiles-presets.js +13 -0
  291. package/dist/lib/profiles.d.ts +2 -0
  292. package/dist/lib/profiles.js +44 -1
  293. package/dist/lib/project-focus.d.ts +1 -1
  294. package/dist/lib/project-focus.js +1 -1
  295. package/dist/lib/project-probe.d.ts +4 -1
  296. package/dist/lib/project-probe.js +5 -4
  297. package/dist/lib/project-resources.js +2 -18
  298. package/dist/lib/project-root.d.ts +16 -0
  299. package/dist/lib/project-root.js +20 -2
  300. package/dist/lib/projects.d.ts +20 -1
  301. package/dist/lib/projects.js +78 -1
  302. package/dist/lib/refresh-coordinator.d.ts +24 -0
  303. package/dist/lib/refresh-coordinator.js +52 -0
  304. package/dist/lib/registry.d.ts +2 -2
  305. package/dist/lib/registry.js +1 -1
  306. package/dist/lib/resource-aliases.d.ts +13 -0
  307. package/dist/lib/resource-aliases.js +26 -0
  308. package/dist/lib/resources/types.d.ts +1 -1
  309. package/dist/lib/resources.d.ts +16 -0
  310. package/dist/lib/resources.js +66 -10
  311. package/dist/lib/rotate.d.ts +3 -4
  312. package/dist/lib/rotate.js +4 -5
  313. package/dist/lib/routine-activation.d.ts +22 -2
  314. package/dist/lib/routine-activation.js +63 -16
  315. package/dist/lib/routine-context.d.ts +9 -2
  316. package/dist/lib/routine-context.js +21 -6
  317. package/dist/lib/routines-project.d.ts +58 -48
  318. package/dist/lib/routines-project.js +190 -159
  319. package/dist/lib/routines.d.ts +44 -7
  320. package/dist/lib/routines.js +92 -34
  321. package/dist/lib/run-defaults.d.ts +5 -0
  322. package/dist/lib/run-defaults.js +11 -1
  323. package/dist/lib/runner.d.ts +10 -8
  324. package/dist/lib/runner.js +122 -39
  325. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  326. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  327. package/dist/lib/secrets/agent.d.ts +10 -3
  328. package/dist/lib/secrets/agent.js +43 -8
  329. package/dist/lib/secrets/bundles.d.ts +1 -0
  330. package/dist/lib/secrets/bundles.js +92 -80
  331. package/dist/lib/secrets/index.js +32 -9
  332. package/dist/lib/secrets/install-helper.d.ts +4 -4
  333. package/dist/lib/secrets/install-helper.js +4 -4
  334. package/dist/lib/secrets/push.d.ts +40 -6
  335. package/dist/lib/secrets/push.js +58 -11
  336. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  337. package/dist/lib/secrets/read-backoff.js +1 -1
  338. package/dist/lib/secrets/remote.d.ts +24 -0
  339. package/dist/lib/secrets/remote.js +54 -4
  340. package/dist/lib/self-update.d.ts +108 -0
  341. package/dist/lib/self-update.js +276 -1
  342. package/dist/lib/session/active.d.ts +89 -5
  343. package/dist/lib/session/active.js +165 -10
  344. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  345. package/dist/lib/session/actor-sidecar.js +2 -1
  346. package/dist/lib/session/db.d.ts +176 -2
  347. package/dist/lib/session/db.js +484 -17
  348. package/dist/lib/session/discover.js +27 -4
  349. package/dist/lib/session/hook-sessions.js +2 -2
  350. package/dist/lib/session/host-link.d.ts +2 -2
  351. package/dist/lib/session/host-link.js +2 -2
  352. package/dist/lib/session/pid-registry.d.ts +21 -0
  353. package/dist/lib/session/pid-registry.js +57 -0
  354. package/dist/lib/session/remote-active.js +15 -1
  355. package/dist/lib/session/remote.js +2 -2
  356. package/dist/lib/session/session-cache.d.ts +14 -7
  357. package/dist/lib/session/session-cache.js +51 -9
  358. package/dist/lib/session/state.d.ts +2 -2
  359. package/dist/lib/session/state.js +1 -1
  360. package/dist/lib/session/sync/config.d.ts +10 -10
  361. package/dist/lib/session/sync/config.js +10 -10
  362. package/dist/lib/session/sync/r2.d.ts +34 -0
  363. package/dist/lib/session/sync/r2.js +123 -0
  364. package/dist/lib/session/throughput.d.ts +1 -1
  365. package/dist/lib/session/throughput.js +1 -1
  366. package/dist/lib/session/types.d.ts +23 -1
  367. package/dist/lib/session/types.js +15 -0
  368. package/dist/lib/session/viewing-in.d.ts +1 -1
  369. package/dist/lib/session/viewing-in.js +1 -1
  370. package/dist/lib/session/watch.d.ts +101 -0
  371. package/dist/lib/session/watch.js +242 -0
  372. package/dist/lib/share/analytics.js +1 -1
  373. package/dist/lib/share/capture.d.ts +1 -1
  374. package/dist/lib/share/capture.js +3 -3
  375. package/dist/lib/share/config.d.ts +6 -2
  376. package/dist/lib/share/config.js +6 -5
  377. package/dist/lib/share/delete.js +3 -3
  378. package/dist/lib/share/provision.d.ts +38 -0
  379. package/dist/lib/share/provision.js +51 -1
  380. package/dist/lib/share/publish.d.ts +40 -1
  381. package/dist/lib/share/publish.js +119 -6
  382. package/dist/lib/share/worker-template.d.ts +12 -1
  383. package/dist/lib/share/worker-template.js +83 -7
  384. package/dist/lib/shims.d.ts +17 -3
  385. package/dist/lib/shims.js +98 -26
  386. package/dist/lib/signin-badge.js +3 -2
  387. package/dist/lib/skills.js +2 -0
  388. package/dist/lib/smart-launch.d.ts +8 -8
  389. package/dist/lib/smart-launch.js +80 -59
  390. package/dist/lib/ssh-exec.d.ts +1 -1
  391. package/dist/lib/ssh-exec.js +1 -1
  392. package/dist/lib/staleness/prune.d.ts +88 -0
  393. package/dist/lib/staleness/prune.js +69 -0
  394. package/dist/lib/staleness/registry.d.ts +1 -1
  395. package/dist/lib/staleness/writers/commands.js +34 -2
  396. package/dist/lib/staleness/writers/hooks.js +16 -0
  397. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  398. package/dist/lib/staleness/writers/skills.js +19 -0
  399. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  400. package/dist/lib/staleness/writers/subagents.js +0 -4
  401. package/dist/lib/staleness/writers/types.d.ts +32 -0
  402. package/dist/lib/startup/command-registry.d.ts +16 -14
  403. package/dist/lib/startup/command-registry.js +26 -37
  404. package/dist/lib/startup/dev-build.d.ts +10 -0
  405. package/dist/lib/startup/dev-build.js +13 -1
  406. package/dist/lib/startup/spellcheck.d.ts +18 -0
  407. package/dist/lib/startup/spellcheck.js +45 -0
  408. package/dist/lib/state.d.ts +36 -9
  409. package/dist/lib/state.js +96 -46
  410. package/dist/lib/subagents-registry.d.ts +0 -7
  411. package/dist/lib/subagents-registry.js +38 -65
  412. package/dist/lib/subagents.d.ts +0 -33
  413. package/dist/lib/subagents.js +0 -75
  414. package/dist/lib/sync-umbrella.js +1 -1
  415. package/dist/lib/teams/agents.d.ts +41 -1
  416. package/dist/lib/teams/agents.js +187 -9
  417. package/dist/lib/teams/api.d.ts +11 -1
  418. package/dist/lib/teams/api.js +11 -2
  419. package/dist/lib/teams/delivery.d.ts +41 -0
  420. package/dist/lib/teams/delivery.js +60 -0
  421. package/dist/lib/teams/registry.d.ts +14 -0
  422. package/dist/lib/teams/registry.js +51 -1
  423. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  424. package/dist/lib/teams/remoteWorktree.js +29 -0
  425. package/dist/lib/teams/scheduler.d.ts +1 -1
  426. package/dist/lib/teams/scheduler.js +1 -1
  427. package/dist/lib/teams/worktree.d.ts +24 -0
  428. package/dist/lib/teams/worktree.js +42 -0
  429. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  430. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  431. package/dist/lib/terminal/engine.d.ts +4 -0
  432. package/dist/lib/terminal/engine.js +8 -2
  433. package/dist/lib/terminal/types.d.ts +21 -2
  434. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  435. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  436. package/dist/lib/tickets/list.d.ts +53 -0
  437. package/dist/lib/tickets/list.js +153 -0
  438. package/dist/lib/tmux/orphan-reap.d.ts +316 -0
  439. package/dist/lib/tmux/orphan-reap.js +638 -0
  440. package/dist/lib/tmux/session.d.ts +68 -3
  441. package/dist/lib/tmux/session.js +96 -5
  442. package/dist/lib/triggers/handlers.d.ts +20 -0
  443. package/dist/lib/triggers/handlers.js +16 -1
  444. package/dist/lib/triggers/webhook.js +10 -0
  445. package/dist/lib/types.d.ts +47 -35
  446. package/dist/lib/usage-fleet.d.ts +32 -0
  447. package/dist/lib/usage-fleet.js +125 -0
  448. package/dist/lib/usage-refresh.d.ts +3 -3
  449. package/dist/lib/usage-refresh.js +19 -16
  450. package/dist/lib/usage.d.ts +51 -47
  451. package/dist/lib/usage.js +145 -153
  452. package/dist/lib/version-duplicates.js +2 -2
  453. package/dist/lib/versions.d.ts +56 -13
  454. package/dist/lib/versions.js +195 -45
  455. package/dist/lib/watchdog/log.d.ts +1 -1
  456. package/dist/lib/watchdog/log.js +3 -3
  457. package/dist/lib/watchdog/rotate.d.ts +6 -6
  458. package/dist/lib/watchdog/rotate.js +6 -6
  459. package/dist/lib/workflows.d.ts +1 -1
  460. package/dist/lib/yaml-io.d.ts +47 -0
  461. package/dist/lib/yaml-io.js +55 -0
  462. package/package.json +2 -1
  463. package/scripts/install-helper.js +2 -2
  464. package/scripts/postinstall.js +23 -20
  465. package/dist/commands/defaults.d.ts +0 -7
  466. package/dist/commands/defaults.js +0 -107
  467. package/dist/commands/export.d.ts +0 -11
  468. package/dist/commands/export.js +0 -215
  469. package/dist/commands/helper.d.ts +0 -12
  470. package/dist/commands/helper.js +0 -87
  471. package/dist/commands/hosts.d.ts +0 -11
  472. package/dist/commands/hosts.js +0 -330
  473. package/dist/commands/lock.d.ts +0 -12
  474. package/dist/commands/lock.js +0 -70
  475. package/dist/commands/pull.d.ts +0 -17
  476. package/dist/commands/pull.js +0 -39
  477. package/dist/commands/push.d.ts +0 -14
  478. package/dist/commands/push.js +0 -30
  479. package/dist/commands/set.d.ts +0 -15
  480. package/dist/commands/set.js +0 -79
  481. package/dist/commands/setup-share.d.ts +0 -17
  482. package/dist/commands/setup-share.js +0 -85
  483. package/dist/commands/wallet.d.ts +0 -20
  484. package/dist/commands/wallet.js +0 -216
  485. package/dist/commands/worktree.d.ts +0 -19
  486. package/dist/commands/worktree.js +0 -272
  487. package/dist/lib/account-labels.d.ts +0 -24
  488. package/dist/lib/account-labels.js +0 -72
  489. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  490. package/dist/lib/auto-dispatch-linear.js +0 -107
  491. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  492. package/dist/lib/auto-dispatch-provider.js +0 -30
  493. package/dist/lib/auto-dispatch.d.ts +0 -93
  494. package/dist/lib/auto-dispatch.js +0 -128
  495. package/dist/lib/export.d.ts +0 -72
  496. package/dist/lib/export.js +0 -269
  497. package/dist/lib/lock.d.ts +0 -93
  498. package/dist/lib/lock.js +0 -207
  499. package/dist/lib/wallet/index.d.ts +0 -78
  500. package/dist/lib/wallet/index.js +0 -253
@@ -79,6 +79,7 @@ const IMPORTABLE_FIELD_TYPES = new Set([
79
79
  'URL', 'url',
80
80
  ]);
81
81
  const SKIP_FIELD_LABELS = new Set(['username', 'notesPlain', 'notes']);
82
+ const NOTES_FIELD_LABELS = new Set(['notesplain', 'notes']);
82
83
  function pickBestField(fields) {
83
84
  const dominated = fields.filter((f) => IMPORTABLE_FIELD_TYPES.has(f.type) &&
84
85
  f.value &&
@@ -97,6 +98,52 @@ function pickBestField(fields) {
97
98
  // Fall back to first importable field
98
99
  return dominated[0];
99
100
  }
101
+ /**
102
+ * The item's notes, if any — a NOTES-purpose field (1Password's `notesPlain`)
103
+ * or a field labelled notes/notesPlain, whichever carries a non-empty value.
104
+ * Returns undefined when the item has no notes. This is descriptive metadata
105
+ * only; it is deliberately independent of value selection and is never picked
106
+ * as the secret value (see SKIP_FIELD_LABELS / pickBestField).
107
+ */
108
+ function pickNotes(fields) {
109
+ const notes = fields.find((f) => f.value != null &&
110
+ f.value.trim() !== '' &&
111
+ (f.purpose?.toUpperCase() === 'NOTES' ||
112
+ NOTES_FIELD_LABELS.has(f.label?.toLowerCase() || '')));
113
+ const value = notes?.value?.trim();
114
+ return value ? value : undefined;
115
+ }
116
+ /**
117
+ * Pure transform from a fetched 1Password item to an importable secret (or the
118
+ * reason it was skipped). Split out of extractSecrets so the field-selection
119
+ * and notes-extraction logic is exercised directly by tests without shelling
120
+ * out to `op`.
121
+ */
122
+ export function itemToSecret(item) {
123
+ const field = pickBestField(item.fields || []);
124
+ if (!field) {
125
+ return { skipped: { itemTitle: item.title, fieldLabel: '*', reason: 'no importable fields' } };
126
+ }
127
+ if (field.value.includes('\n')) {
128
+ return {
129
+ skipped: {
130
+ itemTitle: item.title,
131
+ fieldLabel: field.label,
132
+ reason: 'contains newlines (keychain limitation)',
133
+ },
134
+ };
135
+ }
136
+ const secret = {
137
+ envKey: toEnvKey(item.title),
138
+ itemTitle: item.title,
139
+ fieldLabel: field.label,
140
+ value: field.value,
141
+ };
142
+ const description = pickNotes(item.fields || []);
143
+ if (description)
144
+ secret.description = description;
145
+ return { secret };
146
+ }
100
147
  export function extractSecrets(items, vaultName) {
101
148
  const secrets = [];
102
149
  const skipped = [];
@@ -113,30 +160,13 @@ export function extractSecrets(items, vaultName) {
113
160
  });
114
161
  continue;
115
162
  }
116
- const field = pickBestField(item.fields || []);
117
- if (!field) {
118
- skipped.push({
119
- itemTitle: item.title,
120
- fieldLabel: '*',
121
- reason: 'no importable fields',
122
- });
123
- continue;
163
+ const result = itemToSecret(item);
164
+ if ('skipped' in result) {
165
+ skipped.push(result.skipped);
124
166
  }
125
- if (field.value.includes('\n')) {
126
- skipped.push({
127
- itemTitle: item.title,
128
- fieldLabel: field.label,
129
- reason: 'contains newlines (keychain limitation)',
130
- });
131
- continue;
167
+ else {
168
+ secrets.push(result.secret);
132
169
  }
133
- const envKey = toEnvKey(item.title);
134
- secrets.push({
135
- envKey,
136
- itemTitle: item.title,
137
- fieldLabel: field.label,
138
- value: field.value,
139
- });
140
170
  }
141
171
  return { secrets, skipped };
142
172
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Open a URL in the user's default browser, cross-platform. Best-effort and
3
- * detached — never throws and never blocks the caller. Shared by `agents lease`
3
+ * detached — never throws and never blocks the caller. Shared by `agents devices lease`
4
4
  * (Hetzner console) and `agents fleet login` (the local login dashboard).
5
5
  */
6
6
  import { spawn } from 'child_process';
@@ -5,13 +5,25 @@
5
5
  * for selecting items in the terminal. Used by session picker, command
6
6
  * picker, and other interactive selection flows.
7
7
  */
8
+ /**
9
+ * Custom inquirer prompt for searchable, scrollable selection lists.
10
+ *
11
+ * Extends @inquirer/core to support type-ahead filtering, column-aligned
12
+ * display, and keyboard navigation. Used by sessions, teams, and other
13
+ * interactive pickers throughout the CLI.
14
+ */
15
+ import { Separator } from '@inquirer/core';
8
16
  /** Configuration for the interactive picker prompt. */
9
17
  export interface PickerConfig<T> {
10
18
  message: string;
11
19
  /** Optional dim hint line rendered directly under the header (above the rows). */
12
20
  subtitle?: string;
13
- items: T[];
14
- filter: (query: string) => T[];
21
+ /**
22
+ * The row pool. A {@link Separator} entry renders as a non-selectable divider
23
+ * (used for group headers) — navigation skips it and it is never returned.
24
+ */
25
+ items: Array<T | Separator>;
26
+ filter: (query: string) => Array<T | Separator>;
15
27
  labelFor: (item: T, query: string) => string;
16
28
  buildPreview?: (item: T) => string;
17
29
  shortIdFor?: (item: T) => string;
@@ -139,17 +139,39 @@ export function itemPicker(config) {
139
139
  const prefix = usePrefix({ status, theme });
140
140
  const results = useMemo(() => {
141
141
  const filtered = cfg.filter(searchTerm).slice(0, 50);
142
- return filtered.map((item) => ({
143
- value: item,
144
- label: cfg.labelFor(item, searchTerm),
145
- }));
142
+ return filtered.map((item) => Separator.isSeparator(item)
143
+ ? item
144
+ : { value: item, label: cfg.labelFor(item, searchTerm) });
146
145
  }, [searchTerm]);
146
+ // A row is selectable unless it is a divider (Separator). Navigation and the
147
+ // initial cursor skip dividers, and enter never resolves one.
148
+ const isSelectable = (i) => i >= 0 && i < results.length && !Separator.isSeparator(results[i]);
149
+ const firstSelectable = () => {
150
+ for (let i = 0; i < results.length; i++)
151
+ if (isSelectable(i))
152
+ return i;
153
+ return -1;
154
+ };
155
+ const nextSelectable = (from, dir) => {
156
+ if (results.length === 0)
157
+ return -1;
158
+ let i = from;
159
+ for (let n = 0; n < results.length; n++) {
160
+ i = (i + dir + results.length) % results.length;
161
+ if (isSelectable(i))
162
+ return i;
163
+ }
164
+ return -1;
165
+ };
147
166
  const [active, setActive] = useState(0);
167
+ // Keep the cursor on a selectable row: after a filter change the old index can
168
+ // land past the end or on a divider, so snap to the first selectable row.
148
169
  useEffect(() => {
149
- if (active >= results.length)
150
- setActive(0);
170
+ if (!isSelectable(active))
171
+ setActive(firstSelectable());
151
172
  }, [results]);
152
- const selected = results[active];
173
+ const activeRow = results[active];
174
+ const selected = activeRow && !Separator.isSeparator(activeRow) ? activeRow : undefined;
153
175
  useKeypress((key, rl) => {
154
176
  if (isEnterKey(key)) {
155
177
  if (selected) {
@@ -165,16 +187,16 @@ export function itemPicker(config) {
165
187
  }
166
188
  if (isUpKey(key)) {
167
189
  rl.clearLine(0);
168
- if (results.length > 0) {
169
- setActive((active - 1 + results.length) % results.length);
170
- }
190
+ const target = nextSelectable(active, -1);
191
+ if (target >= 0)
192
+ setActive(target);
171
193
  return;
172
194
  }
173
195
  if (isDownKey(key)) {
174
196
  rl.clearLine(0);
175
- if (results.length > 0) {
176
- setActive((active + 1) % results.length);
177
- }
197
+ const target = nextSelectable(active, 1);
198
+ if (target >= 0)
199
+ setActive(target);
178
200
  return;
179
201
  }
180
202
  setSearchTerm(rl.line);
@@ -81,6 +81,6 @@ export declare function placementFromHostStrategy(strategy: 'local' | 'host' | '
81
81
  /** One-line human form for logs / help. */
82
82
  export declare function formatPlacement(p: Placement): string;
83
83
  /**
84
- * Short matrix for help footers and docs. Keep in sync with 00-concepts.md.
84
+ * Short matrix for help footers and docs. Keep in sync with concepts.md.
85
85
  */
86
86
  export declare const PLACEMENT_MATRIX: string;
@@ -176,7 +176,7 @@ export function formatPlacement(p) {
176
176
  return p.kind;
177
177
  }
178
178
  /**
179
- * Short matrix for help footers and docs. Keep in sync with 00-concepts.md.
179
+ * Short matrix for help footers and docs. Keep in sync with concepts.md.
180
180
  */
181
181
  export const PLACEMENT_MATRIX = `
182
182
  Intent Flag / path
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Snapshot of the current branch's open PR (if any), for the headless-exit
3
+ * fail-loud path. Returns null when there is no open PR or `gh` cannot answer.
4
+ */
5
+ export interface BranchOpenPr {
6
+ number: number;
7
+ url: string;
8
+ state: string;
9
+ }
10
+ /**
11
+ * Pure classifier: should the exit path warn about this open PR?
12
+ * Warn when the PR exists and is still OPEN.
13
+ */
14
+ export declare function shouldWarnOrphanedOpenPr(pr: BranchOpenPr | null): boolean;
15
+ /** Human-readable warning for an open PR the exiting run left unattended. */
16
+ export declare function formatOrphanedOpenPrWarning(pr: BranchOpenPr): string;
17
+ /**
18
+ * Probe `cwd` for an open PR on the current branch via `gh pr view`.
19
+ * Fail-open: any error / missing gh → null (never block the run's exit).
20
+ */
21
+ export declare function getBranchOpenPr(cwd: string, execFileAsync: (file: string, args: string[], opts: {
22
+ cwd: string;
23
+ timeout: number;
24
+ maxBuffer: number;
25
+ }) => Promise<{
26
+ stdout: string;
27
+ }>): Promise<BranchOpenPr | null>;
28
+ /**
29
+ * Headless-exit fail-loud: if the cwd's branch has an OPEN PR, print a loud
30
+ * stderr warning. Never throws.
31
+ */
32
+ export declare function warnOrphanedOpenPr(cwd?: string): Promise<void>;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Headless-exit warning for an open PR left behind by a run (RUSH-2394).
3
+ *
4
+ * A headless agent that backgrounds `gh pr checks --watch` and exits strands its
5
+ * own PR: that watcher is a child of the agent's process tree, so it dies with
6
+ * the agent and nothing merges on green. This module is the fail-loud half of
7
+ * that story — it probes the run's branch for an OPEN PR on exit and says so.
8
+ *
9
+ * The `agents pr land --detach` lander this warning used to point at was removed
10
+ * with the `agents pr` command group (RUSH-2472): merge-on-green is a monitor
11
+ * (`agents monitors`), not a bespoke command with its own scheduler. The
12
+ * reusable CI/review polling it will run on lives in lib/teams/pr-watch.ts, so
13
+ * this module keeps only the exit-path warning and names no specific command.
14
+ */
15
+ import { execFile } from 'child_process';
16
+ import { promisify } from 'util';
17
+ const execFileAsyncDefault = promisify(execFile);
18
+ /**
19
+ * Pure classifier: should the exit path warn about this open PR?
20
+ * Warn when the PR exists and is still OPEN.
21
+ */
22
+ export function shouldWarnOrphanedOpenPr(pr) {
23
+ if (!pr)
24
+ return false;
25
+ return pr.state.toUpperCase() === 'OPEN';
26
+ }
27
+ /** Human-readable warning for an open PR the exiting run left unattended. */
28
+ export function formatOrphanedOpenPrWarning(pr) {
29
+ const lines = [
30
+ '',
31
+ chalkRed('WARNING: open PR left unattended (RUSH-2394)'),
32
+ ` ${pr.url}`,
33
+ ` PR #${pr.number} is still OPEN and nothing is watching it. A background`,
34
+ ' `gh pr checks --watch` child dies when a headless agent exits, so the PR',
35
+ ' will sit green and unmerged.',
36
+ ' Merge it once CI is green and a non-author review has cleared it, or set up',
37
+ ' a merge-on-green monitor (`agents monitors`) that outlives this process.',
38
+ '',
39
+ ];
40
+ return lines.join('\n');
41
+ }
42
+ /** Tiny chalk-free red for environments where chalk is not wanted on the exit path. */
43
+ function chalkRed(s) {
44
+ // Match warn-unpushed: bold red when stderr is a TTY; plain otherwise.
45
+ if (process.stderr.isTTY)
46
+ return `\u001b[1m\u001b[31m${s}\u001b[0m`;
47
+ return s;
48
+ }
49
+ /**
50
+ * Probe `cwd` for an open PR on the current branch via `gh pr view`.
51
+ * Fail-open: any error / missing gh → null (never block the run's exit).
52
+ */
53
+ export async function getBranchOpenPr(cwd, execFileAsync) {
54
+ try {
55
+ const { stdout } = await execFileAsync('gh', ['pr', 'view', '--json', 'number,url,state'], { cwd, timeout: 5000, maxBuffer: 512 * 1024 });
56
+ const raw = JSON.parse(stdout);
57
+ if (!raw?.number || !raw?.url || !raw?.state)
58
+ return null;
59
+ return { number: Number(raw.number), url: String(raw.url), state: String(raw.state) };
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ /**
66
+ * Headless-exit fail-loud: if the cwd's branch has an OPEN PR, print a loud
67
+ * stderr warning. Never throws.
68
+ */
69
+ export async function warnOrphanedOpenPr(cwd = process.cwd()) {
70
+ try {
71
+ const pr = await getBranchOpenPr(cwd, (file, args, opts) => execFileAsyncDefault(file, args, opts).then((r) => ({ stdout: String(r.stdout ?? '') })));
72
+ if (!shouldWarnOrphanedOpenPr(pr))
73
+ return;
74
+ process.stderr.write(formatOrphanedOpenPrWarning(pr));
75
+ }
76
+ catch {
77
+ // Advisory only — never break the run's exit.
78
+ }
79
+ }
@@ -190,6 +190,19 @@ export const PRESETS = [
190
190
  ANTHROPIC_SMALL_FAST_MODEL: 'claude-3-5-haiku-latest',
191
191
  },
192
192
  },
193
+ {
194
+ name: 'deepinfra',
195
+ description: 'DeepInfra direct API through its OpenAI-compatible endpoint, hosted by Codex.',
196
+ provider: 'deepinfra',
197
+ host: 'codex',
198
+ authEnvVar: 'OPENAI_API_KEY',
199
+ signupUrl: 'https://deepinfra.com/dash/api_keys',
200
+ docPath: 'deepinfra',
201
+ env: {
202
+ OPENAI_BASE_URL: 'https://api.deepinfra.com/v1/openai',
203
+ OPENAI_MODEL: 'deepseek-ai/DeepSeek-V3',
204
+ },
205
+ },
193
206
  // ----- Gateway / enterprise / self-hosted -----
194
207
  {
195
208
  name: 'proxy',
@@ -16,6 +16,8 @@ export interface Profile {
16
16
  version?: string;
17
17
  };
18
18
  env: Record<string, string>;
19
+ /** Default durable credential account. A per-run --account overrides it. */
20
+ account?: string;
19
21
  auth?: {
20
22
  envVar: string;
21
23
  keychainItem: string;
@@ -7,11 +7,15 @@
7
7
  */
8
8
  import * as fs from 'fs';
9
9
  import * as path from 'path';
10
+ import * as crypto from 'node:crypto';
10
11
  import * as yaml from 'yaml';
11
12
  import { getUserAgentsDir } from './state.js';
12
- import { getKeychainToken, hasKeychainToken, keychainItemName } from './secrets/profiles.js';
13
+ import { deleteKeychainToken, getKeychainToken, hasKeychainToken, keychainItemName } from './secrets/profiles.js';
13
14
  import { getPreset } from './profiles-presets.js';
14
15
  import { MODEL_TIERS, isTierToken } from './model-tiers.js';
16
+ import { addAccount, findAccount, resolveCredentialAccount } from './account-registry.js';
17
+ import { atomicWriteFileSync } from './fs-atomic.js';
18
+ import { listAccountProviders } from './account-provider-registry.js';
15
19
  const PROFILE_NAME_PATTERN = /^[a-z0-9][a-z0-9-_]{0,48}$/i;
16
20
  /** Get the directory where profile YAML files are stored. */
17
21
  export function getProfilesDir() {
@@ -55,8 +59,43 @@ export function readProfile(name) {
55
59
  if (!parsed.env || typeof parsed.env !== 'object') {
56
60
  parsed.env = {};
57
61
  }
62
+ migrateLegacyProfileAuth(parsed, file);
58
63
  return parsed;
59
64
  }
65
+ function migrateLegacyProfileAuth(profile, file) {
66
+ if (!profile.auth || profile.account)
67
+ return;
68
+ if (!profile.provider) {
69
+ throw new Error(`Profile '${profile.name}' owns a legacy credential without a provider. Add a durable account with 'agents accounts add', then set account: <name> in ${file}.`);
70
+ }
71
+ const provider = listAccountProviders().includes(profile.provider) ? profile.provider : 'proxy';
72
+ const suffix = crypto.createHash('sha256').update(profile.auth.keychainItem).digest('hex').slice(0, 8);
73
+ const accountName = `legacy-${profile.provider}-${suffix}`;
74
+ if (!findAccount(accountName)) {
75
+ const kind = profile.auth.envVar.includes('BEARER_TOKEN') ? 'bearer-token' : 'api-key';
76
+ addAccount(accountName, provider, kind, getKeychainToken(profile.auth.keychainItem));
77
+ }
78
+ const migratedAccount = findAccount(accountName);
79
+ const oldItem = profile.auth.keychainItem;
80
+ profile.account = migratedAccount.id;
81
+ profile.provider = provider;
82
+ delete profile.auth;
83
+ delete profile.authOptional;
84
+ atomicWriteFileSync(file, yaml.stringify(profile));
85
+ const stillReferenced = fs.readdirSync(path.dirname(file))
86
+ .filter(entry => /\.ya?ml$/.test(entry) && path.join(path.dirname(file), entry) !== file)
87
+ .some(entry => {
88
+ try {
89
+ const other = yaml.parse(fs.readFileSync(path.join(path.dirname(file), entry), 'utf8'));
90
+ return other?.auth?.keychainItem === oldItem;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ });
96
+ if (!stillReferenced)
97
+ deleteKeychainToken(oldItem);
98
+ }
60
99
  /** Write a profile to disk atomically (write-to-tmp then rename). */
61
100
  export function writeProfile(profile) {
62
101
  validateProfileName(profile.name);
@@ -437,6 +476,10 @@ export function renameProfile(oldName, newName) {
437
476
  */
438
477
  export function resolveProfileEnv(profile) {
439
478
  const env = { ...profile.env };
479
+ if (profile.account) {
480
+ const account = resolveCredentialAccount(profile.account, profile.host.agent, profile.provider);
481
+ Object.assign(env, account.env);
482
+ }
440
483
  if (profile.auth) {
441
484
  // Optional auth (host manages its own login) with no stored token: inject
442
485
  // nothing and let the host use its own credentials. Only required auth
@@ -46,6 +46,6 @@ export declare function formatFocusCount(n: number): string;
46
46
  * One scannable focus line: path + count, with a single unit trailer so the
47
47
  * bare integer is never mistaken for commits or minutes.
48
48
  *
49
- * apps/cli/src 2.3k · apps/cli/docs 302 · apps/factory/src 245 file-touches (7d)
49
+ * apps/cli/src 2.3k · apps/cli/docs 302 · apps/ext/src 245 file-touches (7d)
50
50
  */
51
51
  export declare function formatFocusAreas(areas: FocusArea[], windowDays: number): string;
@@ -92,7 +92,7 @@ export function formatFocusCount(n) {
92
92
  * One scannable focus line: path + count, with a single unit trailer so the
93
93
  * bare integer is never mistaken for commits or minutes.
94
94
  *
95
- * apps/cli/src 2.3k · apps/cli/docs 302 · apps/factory/src 245 file-touches (7d)
95
+ * apps/cli/src 2.3k · apps/cli/docs 302 · apps/ext/src 245 file-touches (7d)
96
96
  */
97
97
  export function formatFocusAreas(areas, windowDays) {
98
98
  if (areas.length === 0)
@@ -11,7 +11,7 @@
11
11
  * and offline-safe. The fleet half (`--fleet`) just runs this probe on every
12
12
  * peer via the canonical `remote-agents-json` SSH fan-out.
13
13
  */
14
- import type { ProjectDef } from './projects.js';
14
+ import { type ProjectDef } from './projects.js';
15
15
  /** The on-disk state of one workspace repo on one machine. */
16
16
  export interface RepoWorkspaceStatus {
17
17
  /** The probed path, echoed home-relative (re-roots per machine). */
@@ -52,6 +52,9 @@ export declare function probeProjectWorkspaces(paths: string[]): RepoWorkspaceSt
52
52
  * probe echoes, so a hand-edited def (absolute path under home, trailing
53
53
  * slash) matches its probe rows exactly — `writeProjectDef` normalizes on
54
54
  * write, but defs are hand-editable YAML and never silently drop a row.
55
+ *
56
+ * The walk itself lives in `projects.ts` so the probe and the spawn grants read
57
+ * one definition of "the project's directories" instead of two that drift.
55
58
  */
56
59
  export declare function workspaceTargetsForDef(def: ProjectDef): string[];
57
60
  /**
@@ -16,6 +16,7 @@ import * as path from 'path';
16
16
  import { execFileSync } from 'child_process';
17
17
  import chalk from 'chalk';
18
18
  import { expandLocalHome, toHomeRelative } from './project-root.js';
19
+ import { projectProbeTargets } from './projects.js';
19
20
  /** Per-call git budget. A read-only git call taking >3s is wedged by any
20
21
  * definition (NFS stall, index lock) — and the fleet fan-out SIGKILLs the SSH
21
22
  * hop at 12s, so a probe must fit inside that budget to avoid a slow peer
@@ -87,12 +88,12 @@ export function probeProjectWorkspaces(paths) {
87
88
  * probe echoes, so a hand-edited def (absolute path under home, trailing
88
89
  * slash) matches its probe rows exactly — `writeProjectDef` normalizes on
89
90
  * write, but defs are hand-editable YAML and never silently drop a row.
91
+ *
92
+ * The walk itself lives in `projects.ts` so the probe and the spawn grants read
93
+ * one definition of "the project's directories" instead of two that drift.
90
94
  */
91
95
  export function workspaceTargetsForDef(def) {
92
- const targets = [def.root, ...(def.repos ?? []).map((r) => r.path)]
93
- .filter((p) => typeof p === 'string' && p.length > 0)
94
- .map((p) => toHomeRelative(expandLocalHome(p)));
95
- return [...new Set(targets)];
96
+ return projectProbeTargets(def);
96
97
  }
97
98
  /**
98
99
  * Parse a peer's `projects probe --json` stdout, tagging each row with the
@@ -30,7 +30,7 @@ export function syncProjectResourcesToAgent(agent, version, projectAgentsDir) {
30
30
  }
31
31
  syncProjectCommands(agent, version, projectAgentsDir, agentRoot, result, next);
32
32
  syncProjectSkills(agent, version, projectAgentsDir, agentRoot, result, next);
33
- syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot, manifest, result, next);
33
+ syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot, result, next);
34
34
  syncProjectWorkflows(agent, version, projectAgentsDir, projectRoot, agentRoot, result, next);
35
35
  if (next.size > 0 || manifest) {
36
36
  writeProjectManifest(agentRoot, Array.from(next).sort());
@@ -258,7 +258,7 @@ function readProjectSubagents(projectAgentsDir) {
258
258
  }
259
259
  return map;
260
260
  }
261
- function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot, manifest, result, manifestPaths) {
261
+ function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, agentRoot, result, manifestPaths) {
262
262
  if (!supports(agent, 'subagents', version).ok)
263
263
  return;
264
264
  const target = subagentTarget(agent);
@@ -266,8 +266,6 @@ function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, age
266
266
  return;
267
267
  const all = readProjectSubagents(projectAgentsDir);
268
268
  const dir = target.dir(projectRoot);
269
- const targetDirRel = toPosixRel(path.relative(agentRoot, dir));
270
- const hadManagedTarget = manifest?.paths.some((rel) => rel === targetDirRel || rel.startsWith(targetDirRel + '/')) ?? false;
271
269
  for (const sub of all.values()) {
272
270
  const occupied = target.occupied(dir, sub.name);
273
271
  const existing = occupied.find((entry) => pathExists(entry.path));
@@ -283,20 +281,6 @@ function syncProjectSubagents(agent, version, projectAgentsDir, projectRoot, age
283
281
  // Malformed source or unsupported transform; skip this item.
284
282
  }
285
283
  }
286
- const syncedNames = result.synced
287
- .filter((name) => name.startsWith('subagents/'))
288
- .map((name) => name.slice('subagents/'.length))
289
- .filter((name) => all.has(name))
290
- .map((name) => all.get(name));
291
- if (target.finalize && (syncedNames.length > 0 || hadManagedTarget)) {
292
- target.finalize(dir, syncedNames);
293
- for (const entry of target.finalizeOccupied?.(dir) ?? []) {
294
- // Same normalization as record(): this is the one manifest write that
295
- // doesn't funnel through it (the parent subagent index, e.g. Kimi's
296
- // agents/_agents-cli.yaml).
297
- manifestPaths.add(toPosixRel(path.relative(agentRoot, entry.path)));
298
- }
299
- }
300
284
  }
301
285
  function workflowManagedRelPaths(agent, projectRoot, name, workflowDir) {
302
286
  if (agent === 'kimi')
@@ -110,3 +110,19 @@ export declare function resolveProjectRef(ref: string, opts: {
110
110
  forRemote: boolean;
111
111
  cwd?: string;
112
112
  }): Promise<string>;
113
+ /**
114
+ * Resolve a `--project` ref to the cwd an agent lands in PLUS the other
115
+ * directories that project binds, so a spawn can grant them.
116
+ *
117
+ * `cwd` is exactly what `resolveProjectRef` returns — this never changes where
118
+ * an agent starts. `extraDirs` is every other `repos[].path`, and is empty for
119
+ * a convention-resolved project (no definition means no bound repos) and for a
120
+ * definition that binds only its primary checkout.
121
+ */
122
+ export declare function resolveProjectDirs(ref: string, opts: {
123
+ forRemote: boolean;
124
+ cwd?: string;
125
+ }): Promise<{
126
+ cwd: string;
127
+ extraDirs: string[];
128
+ }>;
@@ -17,7 +17,7 @@ import * as fs from 'fs';
17
17
  import { readMeta, updateMeta } from './state.js';
18
18
  import { getMainRepoRoot } from './git.js';
19
19
  import { toPosix } from './platform/index.js';
20
- import { loadProjectDef, resolveDefinedProjectPath } from './projects.js';
20
+ import { loadProjectDef, projectDirsAbs, resolveDefinedProjectPath } from './projects.js';
21
21
  import { shellQuote } from './ssh-exec.js';
22
22
  const HOME = process.env.HOME ?? os.homedir();
23
23
  /** Rewrite an absolute path under the local home to a `~/`-relative string; pass others through. */
@@ -157,7 +157,7 @@ export async function ensureProjectRoot(cwd) {
157
157
  if (!inferred) {
158
158
  throw new Error('Could not determine your projects root. Run once from inside a project ' +
159
159
  '(a git repo under your projects dir) so it can be inferred, or set it:\n' +
160
- ' agents defaults project-root ~/src/github.com/<you>');
160
+ ' agents config set project.root ~/src/github.com/<you>');
161
161
  }
162
162
  updateMeta({ projectRoot: inferred });
163
163
  process.stderr.write(`[project] cached projects root: ${inferred}\n`);
@@ -216,3 +216,21 @@ export async function resolveProjectRef(ref, opts) {
216
216
  }
217
217
  return resolved;
218
218
  }
219
+ /**
220
+ * Resolve a `--project` ref to the cwd an agent lands in PLUS the other
221
+ * directories that project binds, so a spawn can grant them.
222
+ *
223
+ * `cwd` is exactly what `resolveProjectRef` returns — this never changes where
224
+ * an agent starts. `extraDirs` is every other `repos[].path`, and is empty for
225
+ * a convention-resolved project (no definition means no bound repos) and for a
226
+ * definition that binds only its primary checkout.
227
+ */
228
+ export async function resolveProjectDirs(ref, opts) {
229
+ const resolved = await resolveProjectRef(ref, opts);
230
+ const { slug } = parseProjectRef(ref);
231
+ const def = slug ? loadProjectDef(slug) : undefined;
232
+ if (!def)
233
+ return { cwd: resolved, extraDirs: [] };
234
+ const all = projectDirsAbs(def, { forRemote: opts.forRemote, primary: resolved });
235
+ return { cwd: resolved, extraDirs: all.filter((d) => d !== resolved) };
236
+ }
@@ -151,6 +151,25 @@ export declare function removeProjectDef(name: string): boolean;
151
151
  * expanded against the local home. Returns undefined when neither is set.
152
152
  */
153
153
  export declare function projectBasePath(def: ProjectDef, forRemote: boolean): string | undefined;
154
+ /**
155
+ * The directories `projects status` probes across the fleet: the repo root plus
156
+ * every bound checkout, home-relative so each host re-roots them, and including
157
+ * directories absent here so a peer can still answer `✗ missing` for them.
158
+ */
159
+ export declare function projectProbeTargets(def: ProjectDef): string[];
160
+ /**
161
+ * The directories an agent spawned on this project should reach: the cwd first
162
+ * (`resolveDefinedProjectPath`, so cwd behavior is unchanged), then every other
163
+ * bound repo. `forRemote` keeps them `~/…` so the remote shell re-roots them at
164
+ * its own `$HOME`; locally they are absolute and filtered to what exists.
165
+ *
166
+ * Callers pass the resolved primary so a `--project slug@worktree` run grants
167
+ * the sibling repos alongside the worktree it actually landed in.
168
+ */
169
+ export declare function projectDirsAbs(def: ProjectDef, opts: {
170
+ forRemote: boolean;
171
+ primary?: string;
172
+ }): string[];
154
173
  /**
155
174
  * Which defined project a session belongs to, derived from its working
156
175
  * directory. A session whose `cwd` sits inside a project's repo root (or a
@@ -162,7 +181,7 @@ export declare function projectBasePath(def: ProjectDef, forRemote: boolean): st
162
181
  * with `expandLocalHome` and resolved, so this matches sessions whose cwd shares
163
182
  * this machine's home layout. A session recorded on a different-home machine
164
183
  * (`/Users/x/…` vs `/home/x/…`) will not match until the fleet-wide,
165
- * home-relative variant lands (see the deferred item in docs/11-projects.md).
184
+ * home-relative variant lands (see the deferred item in docs/projects.md).
166
185
  */
167
186
  export declare function projectNameForCwd(cwd: string | undefined, defs: ProjectDef[]): string | undefined;
168
187
  /**