@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
@@ -11,12 +11,13 @@ import { isTierToken } from '../lib/model-tiers.js';
11
11
  import { RUN_AUTO_KEYWORD } from '../lib/types.js';
12
12
  import { setHelpSections } from '../lib/help.js';
13
13
  import { isInteractiveTerminal, isPromptCancelled, requireInteractiveSelection } from './utils.js';
14
- import { getUserAgentsDir } from '../lib/state.js';
14
+ import { getUserAgentsDir, readMeta } from '../lib/state.js';
15
15
  import { parseLoopInterval } from '../lib/loop.js';
16
16
  import { AGENTS, resolveAgentName, isAgentHardDeprecated, hardDeprecationError } from '../lib/agents.js';
17
17
  import { recordDispatchedRun } from '../lib/audit/log.js';
18
18
  import { maybeShowStarNudge } from '../lib/star-nudge.js';
19
19
  import { warnUnpushedWork, shouldWarnUnpushed } from '../lib/warn-unpushed.js';
20
+ import { warnOrphanedOpenPr } from '../lib/pr-land-detach.js';
20
21
  import { isHostPinned, pinHostKey, managedKnownHostsPath } from '../lib/devices/known-hosts.js';
21
22
  import { sshResolve } from '../lib/hosts/ssh-config.js';
22
23
  import * as fs from 'fs';
@@ -401,6 +402,13 @@ export async function runWorkflowForEach(spec, opts) {
401
402
  * the directory and is mutually exclusive with `--cwd`/`--remote-cwd`; both the
402
403
  * main dispatch and the `--terminal` handoff need the same answer, so the rule
403
404
  * and its error live here once instead of in two places that can drift.
405
+ *
406
+ * A project that binds several directories also contributes the ones it is not
407
+ * landing in as `--add-dir` grants, so an agent on a multi-repo project can
408
+ * actually reach the sibling checkouts. Claude / Cursor / Kimi take the native
409
+ * flag; Codex folds them into workspace_roots; Grok widens its sandbox profile
410
+ * (and always injects a rules note). Other harnesses have no multi-root surface
411
+ * and ignore the grants (cwd only).
404
412
  */
405
413
  async function resolveRunCwd(options, opts) {
406
414
  if (!options.project)
@@ -409,9 +417,18 @@ async function resolveRunCwd(options, opts) {
409
417
  console.error(chalk.red('Pass --project alone — not with --cwd or --remote-cwd.'));
410
418
  process.exit(1);
411
419
  }
412
- const { resolveProjectRef } = await import('../lib/project-root.js');
420
+ const { resolveProjectDirs } = await import('../lib/project-root.js');
413
421
  try {
414
- return await resolveProjectRef(options.project, { forRemote: opts.forRemote });
422
+ const { cwd, extraDirs } = await resolveProjectDirs(options.project, {
423
+ forRemote: opts.forRemote,
424
+ });
425
+ // Explicit --add-dir values keep their position; a directory the project
426
+ // already contributes is not passed twice.
427
+ if (extraDirs.length > 0) {
428
+ const seen = new Set(options.addDir ?? []);
429
+ options.addDir = [...(options.addDir ?? []), ...extraDirs.filter((d) => !seen.has(d))];
430
+ }
431
+ return cwd;
415
432
  }
416
433
  catch (err) {
417
434
  console.error(chalk.red(err.message));
@@ -527,7 +544,7 @@ export function registerRunCommand(program) {
527
544
  .option('--allow-expired', 'Inject secrets even if their expiry date has passed (overrides the pre-run expiry abort).')
528
545
  .option('--cwd <dir>', 'Working directory for the agent (defaults to current directory). With --host, the directory ON the host.')
529
546
  .option('-P, --project <ref>', 'Project shorthand <slug>[@worktree], resolved against your projects root (auto-inferred, cached). Sets the cwd locally or on --host.')
530
- .option('--add-dir <dir>', 'Grant access to an additional directory outside the project (Claude and Codex, repeatable)', (val, prev) => [...prev, val], [])
547
+ .option('--add-dir <dir>', 'Grant access to an additional directory outside the project (Claude, Codex, Cursor, Kimi, Grok; repeatable)', (val, prev) => [...prev, val], [])
531
548
  .option('--json', 'Stream events as JSON lines (for parsing by other tools)')
532
549
  .option('--quiet', 'Suppress preamble (rotation banner, "Running:" line). Useful when piping JSON events to a parser.', false)
533
550
  .option('--headless', 'Force headless mode. Auto-enabled when a prompt is provided; pass explicitly to stay headless with no prompt (reads the prompt from stdin).', false)
@@ -535,7 +552,7 @@ export function registerRunCommand(program) {
535
552
  .option('-i, --interactive', 'Force interactive mode even when a prompt is provided. Mutually exclusive with --headless.')
536
553
  .option('--resume [id]', 'Recover a previous conversation on its origin device. The exact healthy origin uses native resume; otherwise a healthy version of the same harness replays via /continue. Pair with a prompt to continue headlessly.')
537
554
  .option('--session-id <id>', 'Force a NEW conversation to use this exact session UUID (Claude only). This CREATES a session — to resume an existing one, use --resume.')
538
- .option('--name <slug>', 'Name the run — seeds the session label so it shows up as `<name>` in `agents sessions` and resolves by it (and `agents hosts logs <name>` for --host runs) instead of an opaque id. An agent-generated title later refines the label; your name shows until then. Optional.')
555
+ .option('--name <slug>', 'Name the run — seeds the session label so it shows up as `<name>` in `agents sessions` and resolves by it (and `agents logs <name>` for --host runs) instead of an opaque id. An agent-generated title later refines the label; your name shows until then. Optional.')
539
556
  .option('--notify', 'Post a desktop notification when a headless run finishes. Fired by this process on exit, so it survives whatever launched the run (the menu bar dispatching it, a terminal you closed).')
540
557
  .option('--terminal [backend]', "Open this run in a real terminal tab instead of here. Without a value the terminal is detected from your live sessions (`agents sessions --active` host), so it lands where you already work — Ghostty for a Ghostty user, iTerm for an iTerm user. Name one to force it: iterm | ghostty | terminal | tmux | vscodium-agent. This is how the menu bar's New Session opens.")
541
558
  .option('--verbose', 'Show detailed execution logs')
@@ -546,7 +563,7 @@ export function registerRunCommand(program) {
546
563
  .option('--fallback <agents>', 'Comma-separated agents to try on rate-limit failure. Each entry accepts an optional @version pin (e.g., codex@0.116.0,antigravity). The primary runs first; if it exits with a rate-limit error, the next agent picks up via /continue handoff.')
547
564
  .option('-b, --balanced', 'Shortcut for --strategy balanced. Ignored when @version is pinned.')
548
565
  .option('--strategy <strategy>', 'Version/account selection strategy: pinned | available | balanced. Defaults to run.<agent>.strategy, then balanced (spreads load across healthy accounts and skips any that are rate-limited). (Legacy `rotate` accepted as alias for `balanced`.)')
549
- .option('--account <label>', 'Run a healthy installed version currently signed into this named account (never falls back to another identity)')
566
+ .option('--account <name>', 'Use this durable provider credential for the run')
550
567
  .option('--acp', 'Route through the Agent Client Protocol instead of direct exec. Supported for claude via @zed-industries/claude-code-acp adapter. Unified event stream; emits ndjson when --json.')
551
568
  .option('-y, --yes', 'Skip the interactive budget-confirm prompt (require_confirm_over). Never skips a hard budget block.', false)
552
569
  .option('--loop', 'Re-inject the prompt/entrypoint each iteration until a stop condition (issue #332). Guards (--max-iterations, --budget, --until) are enforced outside the agent. Writes a checkpoint after every iteration for --resume-checkpoint.')
@@ -555,11 +572,11 @@ export function registerRunCommand(program) {
555
572
  .option('--budget <tokens>', 'Loop token hard-cap: stop once cumulative tokens reach this (stoppedBy: budget), enforced outside the agent. Loop only.')
556
573
  .option('--until <signal>', 'Loop stop condition. `signal` reads <runDir>/loop-signal.json {continue,reason} each iteration; absent or continue:false stops (fail-closed). Loop only.')
557
574
  .option('--interval <dur>', 'Loop delay between iterations ("0" back-to-back, "30m" paces). Loop only.')
558
- .option('--where <spec>', 'Where this run\'s body executes (one placement door): local | device:<name> | auto | lease[:backend] | cloud[:provider]. Expands to --host/--lease/--cloud. Do not combine with those flags. See docs/00-concepts.md#placement.')
559
- .option('--host <name>', 'Offload this run onto another machine over SSH — a device name, registered host, or user@host. Pass "auto" to pick the least-loaded reachable device where the requested agent is installed and signed in, keeping the run local when no remote is better. Same as --where device:<name>. See `agents devices`.')
560
- .option('--device <name>', 'Alias of --host. Pass "auto" for affinity-based device pick (same as --where auto).')
575
+ .option('--where <spec>', 'Where this run\'s body executes (one placement door): local | device:<name> | auto | lease[:backend] | cloud[:provider]. Expands to --host/--lease/--cloud. Do not combine with those flags. See docs/concepts.md#placement.')
576
+ .option('--host <name>', 'Offload this run onto another machine over SSH — a device name, registered host, or user@host. Pass "auto" to pick the least-loaded reachable device with an eligible account; an unavailable or capped pool fails loud. Same as --where device:<name>. See `agents devices`.')
577
+ .option('--device <name>', 'Alias of --host. Pass "auto" for live health/account-aware device placement.')
561
578
  .option('--remote-cwd <dir>', "Explicit host working directory for --host runs, used VERBATIM (overrides --cwd; usually --cwd suffices — it re-roots a local-home path onto the remote home). Pass a single-quoted '$HOME/…' or a valid remote absolute path; a local ~ expands here and won't exist there (/Users/you vs /home/you).")
562
- .option('--no-follow', 'With --host, dispatch detached and return immediately (track via `agents hosts ps/logs`).')
579
+ .option('--no-follow', 'With --host, dispatch detached and return immediately (track via `agents devices ps` and `agents logs`).')
563
580
  .option('--any', 'With --host <cap> (a capability tag), pick any matching host instead of erroring when several match.')
564
581
  .option('--copy-creds', 'With --host, copy the picked runtime credentials (and Claude OAuth token) to the host, then shred them after the run. Opt-in per run.')
565
582
  .option('--lease [backend]', "Run on a cloud box (via crabbox) and tear it down after — reuses a warm box from the repo's profile pool when one is ready (--fresh forces a new box). Optional backend selects the cloud (hetzner/aws/do). Same as --where lease[:backend]. Unlike --host, no machine is registered.")
@@ -609,6 +626,7 @@ export function registerRunCommand(program) {
609
626
  # account headroom, then a balanced account on it
610
627
  agents run auto "fix the flaky test" --mode edit
611
628
  agents run auto --host yosemite-s0 "fix the flaky test" # pin the host
629
+ agents run auto --interactive --device auto --strategy balanced --mode auto
612
630
 
613
631
  # Placement (one door — where the body runs). Old flags still work.
614
632
  agents run claude "…" --where device:yosemite-s0 # = --host yosemite-s0
@@ -741,7 +759,7 @@ export function registerRunCommand(program) {
741
759
  }
742
760
  // Placement: --where expands into --host / --lease / --cloud before any
743
761
  // dispatch. One door for "where does the body run?" — old flags remain
744
- // aliases. See lib/placement.ts and docs/00-concepts.md#placement.
762
+ // aliases. See lib/placement.ts and docs/concepts.md#placement.
745
763
  {
746
764
  const { placementFromRunFlags, expandPlacementToRunFlags, PlacementError } = await import('../lib/placement.js');
747
765
  try {
@@ -862,8 +880,15 @@ export function registerRunCommand(program) {
862
880
  ? { kind: 'resolved', session: injectedSource }
863
881
  : await (await import('./sessions.js')).resolveSessionMetadataValue(selector);
864
882
  if (outcome.kind === 'partial') {
865
- console.error(chalk.red(`Could not resolve session while these devices were unavailable: ${outcome.failedPeers.join(', ')}`));
866
- process.exit(2);
883
+ // RUSH-2492: an unreachable peer is a warning, not a hard failure. The
884
+ // resolver already resolves an id found on the reachable fleet (SES-9a),
885
+ // so reaching here means the session was not found on any device we
886
+ // COULD reach — it may live on an unreachable peer we could not check.
887
+ const offline = outcome.failedPeers;
888
+ console.error(chalk.yellow(`Warning: ${offline.length} device(s) unreachable, not checked: ${offline.join(', ')}`));
889
+ console.error(chalk.red(`No session matching "${selector}" on any reachable device (${offline.length} unreachable, not checked).`));
890
+ console.error(chalk.gray(' If it lives on an offline box, wake it (agents devices) or run there: agents ssh <device>'));
891
+ process.exit(1);
867
892
  }
868
893
  if (outcome.kind === 'not-found') {
869
894
  console.error(chalk.red(`No session matching "${selector}".`));
@@ -953,7 +978,7 @@ export function registerRunCommand(program) {
953
978
  }
954
979
  // --device auto / --host auto (and deprecated --smart): live fleet pick.
955
980
  // Harness is always the agent the user typed — never auto-picked.
956
- // Affinity failure degrades to local (does not kill the run).
981
+ // Placement failure propagates; an automatic request never becomes local.
957
982
  {
958
983
  const { applyDeviceAutoToOptions } = await import('../lib/smart-launch.js');
959
984
  const result = await applyDeviceAutoToOptions(options, {
@@ -967,9 +992,6 @@ export function registerRunCommand(program) {
967
992
  if (!options.quiet && result.deprecationSmart) {
968
993
  process.stderr.write(chalk.yellow('[agents] --smart is deprecated; use --device auto\n'));
969
994
  }
970
- if (!options.quiet && result.skipped) {
971
- process.stderr.write(chalk.yellow(`[agents] device=auto skipped: ${result.skipped} (running local)\n`));
972
- }
973
995
  if (!options.quiet && result.banner) {
974
996
  const { hostLabel, deviceHint, acctNote } = result.banner;
975
997
  process.stderr.write(chalk.gray(`[agents] device=auto → ${hostLabel}` +
@@ -1014,7 +1036,7 @@ export function registerRunCommand(program) {
1014
1036
  const { runLeaseSetup } = await import('./lease.js');
1015
1037
  const ok = await runLeaseSetup({ provider: backend ?? 'hetzner' });
1016
1038
  if (!ok) {
1017
- console.error(chalk.yellow('Leasing needs a cloud provider set up. Run `agents lease setup` and retry.'));
1039
+ console.error(chalk.yellow('Leasing needs a cloud provider set up. Run `agents devices lease setup` and retry.'));
1018
1040
  process.exit(1);
1019
1041
  }
1020
1042
  }
@@ -1108,7 +1130,7 @@ export function registerRunCommand(program) {
1108
1130
  }
1109
1131
  if (!hasKey) {
1110
1132
  console.error(chalk.yellow('Tailscale requested but no auth key is configured — falling back to a public-IP lease.'));
1111
- console.error(chalk.gray('Set one up with `agents lease setup` (mint an EPHEMERAL, pre-authorized, tag:crabbox key), or store CRABBOX_TAILSCALE_AUTH_KEY in a secrets bundle.'));
1133
+ console.error(chalk.gray('Set one up with `agents devices lease setup` (mint an EPHEMERAL, pre-authorized, tag:crabbox key), or store CRABBOX_TAILSCALE_AUTH_KEY in a secrets bundle.'));
1112
1134
  netMode = 'public';
1113
1135
  }
1114
1136
  }
@@ -1331,7 +1353,7 @@ export function registerRunCommand(program) {
1331
1353
  process.stderr.write(chalk.dim(log.join('\n')) + '\n');
1332
1354
  }
1333
1355
  const keptAddr = boxAddress(box);
1334
- console.error(chalk.gray(toreDown ? `Box ${box.slug} destroyed.` : `Box ${box.slug} kept${keptAddr ? ` (${keptAddr})` : ''}. Stop it: agents lease stop ${box.slug}`));
1356
+ console.error(chalk.gray(toreDown ? `Box ${box.slug} destroyed.` : `Box ${box.slug} kept${keptAddr ? ` (${keptAddr})` : ''}. Stop it: agents devices lease stop ${box.slug}`));
1335
1357
  process.exit(exitCode === null ? 1 : exitCode);
1336
1358
  }
1337
1359
  catch (err) {
@@ -1567,6 +1589,9 @@ export function registerRunCommand(program) {
1567
1589
  const isRaw = options.raw || options.tmux === false || options.disableTmux === true;
1568
1590
  const { modeForRemoteDispatch } = await import('../lib/codex-policy.js');
1569
1591
  const forwardedMode = modeForRemoteDispatch(options.mode, command.getOptionValueSource('mode'));
1592
+ if (process.env.AGENTS_DISPATCH_DEBUG || options.verbose) {
1593
+ process.stderr.write(chalk.gray(`[hosts] dispatch interactive ${runAgent}${runVersion ? `@${runVersion}` : ''} -> ${host.name}\n`));
1594
+ }
1570
1595
  const exitCode = await runInteractiveOnHost(host, {
1571
1596
  agent: runAgent,
1572
1597
  version: resumeId ? undefined : runVersion,
@@ -1655,6 +1680,9 @@ export function registerRunCommand(program) {
1655
1680
  // registration all live in the shared helper (lib/hosts/run-target.ts).
1656
1681
  const { modeForRemoteDispatch } = await import('../lib/codex-policy.js');
1657
1682
  const forwardedMode = modeForRemoteDispatch(options.mode, command.getOptionValueSource('mode'));
1683
+ if (process.env.AGENTS_DISPATCH_DEBUG || options.verbose) {
1684
+ process.stderr.write(chalk.gray(`[hosts] dispatch headless ${runAgent}${runVersion ? `@${runVersion}` : ''} -> ${host.name}\n`));
1685
+ }
1658
1686
  const { task, exitCode } = await dispatchPromptToHost(host, {
1659
1687
  agent: runAgent,
1660
1688
  version: resumeId ? undefined : runVersion,
@@ -1694,7 +1722,7 @@ export function registerRunCommand(program) {
1694
1722
  const handle = task.name ?? task.id;
1695
1723
  console.log(chalk.green(`Dispatched to ${host.name}${task.name ? ` as "${task.name}"` : ''}.`) + '\n' +
1696
1724
  chalk.gray(` Status: agents sessions ${handle}`) + chalk.gray(' (compact digest — use this)') + '\n' +
1697
- chalk.gray(` Raw log: agents hosts logs ${handle} -f`) + chalk.gray(' (heavy, only if needed)'));
1725
+ chalk.gray(` Raw log: agents logs ${handle} -f`) + chalk.gray(' (heavy, only if needed)'));
1698
1726
  process.exit(0);
1699
1727
  }
1700
1728
  // -1 = the follow window closed but the run continues on the host (the
@@ -1796,12 +1824,16 @@ export function registerRunCommand(program) {
1796
1824
  cwd: resumeExec.cwd ?? process.cwd(),
1797
1825
  exitCode: resumeExit,
1798
1826
  });
1799
- // A resumed loop is always headless; surface any commits it left unpushed.
1800
- if (shouldWarnUnpushed(resumeExec.mode ?? 'auto', false))
1801
- await warnUnpushedWork(resumeExec.cwd ?? process.cwd());
1827
+ // A resumed loop is always headless; surface any commits it left unpushed
1828
+ // and any open PR it left unattended (RUSH-2394).
1829
+ if (shouldWarnUnpushed(resumeExec.mode ?? 'auto', false)) {
1830
+ const resumeCwd = resumeExec.cwd ?? process.cwd();
1831
+ await warnUnpushedWork(resumeCwd);
1832
+ await warnOrphanedOpenPr(resumeCwd);
1833
+ }
1802
1834
  process.exit(resumeExit);
1803
1835
  }
1804
- const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, implicitModeFor, headlessPlanStallCommand, nativeResume, resolveInteractive, inferredInteractiveWithoutTty }, { ALL_AGENT_IDS, ACCOUNT_INSPECTION_AGENT_IDS, agentLabel, supportsAccountInspection }, { profileExists, resolveProfileForRun }, { readAndResolveBundleEnv, describeBundle, assertRemoteBundleFlagsUnsupported }, { splitBundleRef, resolveHostSshTarget, remoteResolveEnv }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, shouldArmRotationFailover, RUN_STRATEGIES, collectHarnessCandidates, pickHarnessWeighted, classifyHarnessCandidates, formatHarnessPickBanner, formatNoHealthyHarnessError, formatNoHealthyAccountError, signInRecoverableCandidates }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents, ensureSubagentDispatchTool }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports, capableAgents }, { shareRuntimeEnv },] = await Promise.all([
1836
+ const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, implicitModeFor, headlessPlanStallCommand, nativeResume, resolveInteractive, inferredInteractiveWithoutTty }, { ALL_AGENT_IDS, ACCOUNT_INSPECTION_AGENT_IDS, agentLabel, supportsAccountInspection }, { profileExists, readProfile, resolveProfileForRun }, { readAndResolveBundleEnv, describeBundle, assertRemoteBundleFlagsUnsupported }, { splitBundleRef, resolveHostSshTarget, remoteResolveEnv }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, shouldArmRotationFailover, RUN_STRATEGIES, collectHarnessCandidates, pickHarnessWeighted, classifyHarnessCandidates, formatHarnessPickBanner, formatNoHealthyHarnessError, formatNoHealthyAccountError, signInRecoverableCandidates }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents, ensureSubagentDispatchTool }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports, capableAgents }, { shareRuntimeEnv },] = await Promise.all([
1805
1837
  import('../lib/exec.js'),
1806
1838
  import('../lib/agents.js'),
1807
1839
  import('../lib/profiles.js'),
@@ -1822,6 +1854,8 @@ export function registerRunCommand(program) {
1822
1854
  let agent;
1823
1855
  let version = rawVersion || undefined;
1824
1856
  let profileEnv;
1857
+ let accountEnv;
1858
+ let profileProvider;
1825
1859
  let fromProfile = false;
1826
1860
  let profileFallbackModel;
1827
1861
  let workflowModel;
@@ -1903,6 +1937,7 @@ export function registerRunCommand(program) {
1903
1937
  if (!version)
1904
1938
  version = resolved.version;
1905
1939
  profileEnv = resolved.env;
1940
+ profileProvider = readProfile(rawAgent).provider;
1906
1941
  profileFallbackModel = resolved.fallbackModel;
1907
1942
  fromProfile = true;
1908
1943
  process.stderr.write(chalk.gray(`Resolved custom harness '${resolved.profileName}' -> ${agent}${version ? `@${version}` : ''}\n`));
@@ -2154,17 +2189,16 @@ export function registerRunCommand(program) {
2154
2189
  }
2155
2190
  }
2156
2191
  version = resolveVersionAlias(agent, version);
2157
- if (options.account) {
2192
+ const { resolveAccountSelection } = await import('../lib/account-registry.js');
2193
+ const configuredAccount = resolveAccountSelection(options.account, agent, readMeta(), { useDefault: !fromProfile });
2194
+ if (configuredAccount) {
2158
2195
  if (options.cloud || options.provider || options.lease) {
2159
- console.error(chalk.red('--account selects a local installed identity and cannot be combined with cloud or lease placement.'));
2196
+ console.error(chalk.red('--account selects a device-local credential and cannot be combined with cloud or lease placement.'));
2160
2197
  process.exit(1);
2161
2198
  }
2162
- const { resolveAccountLabel } = await import('../lib/account-labels.js');
2199
+ const { resolveCredentialAccount } = await import('../lib/account-registry.js');
2163
2200
  try {
2164
- const selected = await resolveAccountLabel(agent, options.account);
2165
- if (version && version !== selected)
2166
- throw new Error(`${agent}@${version} is not a healthy match for account '${options.account}'.`);
2167
- version ??= selected;
2201
+ accountEnv = resolveCredentialAccount(configuredAccount, agent, profileProvider).env;
2168
2202
  }
2169
2203
  catch (err) {
2170
2204
  console.error(chalk.red(err.message));
@@ -2343,7 +2377,7 @@ export function registerRunCommand(program) {
2343
2377
  // the bare primary still resolves through the strategy — otherwise every
2344
2378
  // `agents run claude --fallback codex` run lands on the pinned default
2345
2379
  // account and account rotation silently stops (the gh-monitor heal bug).
2346
- if (!accountPickerRequested && !options.account && (strategy !== 'pinned' || options.balanced || explicitStrategy)) {
2380
+ if (!accountPickerRequested && !configuredAccount && (strategy !== 'pinned' || options.balanced || explicitStrategy)) {
2347
2381
  if (version) {
2348
2382
  process.stderr.write(chalk.yellow(`[agents] strategy ${strategy} ignored: version ${version} is pinned\n`));
2349
2383
  }
@@ -2661,14 +2695,14 @@ export function registerRunCommand(program) {
2661
2695
  const autoShareEnv = options.autoSecrets !== false
2662
2696
  ? shareRuntimeEnv()
2663
2697
  : undefined;
2664
- // Merge order (later wins): profile env < auto share token < secrets bundles < --env K=V.
2698
+ // Merge order (later wins): profile env < selected account < auto share token < secrets bundles < --env K=V.
2665
2699
  // Profile carries provider auth; secrets bundles carry user-defined
2666
2700
  // values; --env is the per-invocation override. The share token is
2667
2701
  // best-effort: if it is not already in env or an unlocked bundle, unrelated
2668
- // runs keep working, and `agents share` itself still fails loudly on use.
2669
- const hasOverrides = profileEnv || autoShareEnv || options.secrets.length > 0 || userEnv;
2702
+ // runs keep working, and `agents artifacts share` itself still fails loudly on use.
2703
+ const hasOverrides = profileEnv || accountEnv || autoShareEnv || options.secrets.length > 0 || userEnv;
2670
2704
  const env = hasOverrides
2671
- ? { ...(profileEnv ?? {}), ...(autoShareEnv ?? {}), ...secretsEnv, ...(userEnv ?? {}) }
2705
+ ? { ...(profileEnv ?? {}), ...(accountEnv ?? {}), ...(autoShareEnv ?? {}), ...secretsEnv, ...(userEnv ?? {}) }
2672
2706
  : undefined;
2673
2707
  const modelSource = runCmd.getOptionValueSource('model');
2674
2708
  let model = options.model
@@ -2839,9 +2873,12 @@ export function registerRunCommand(program) {
2839
2873
  // Governance chokepoint (#347): the --acp path exits here, bypassing
2840
2874
  // the normal finalize below — record its one audit entry.
2841
2875
  recordDispatchedRun({ agent, version: defaultVersion ?? 'unknown', mode, cwd, exitCode });
2842
- // ACP headless run always has a prompt; surface any unpushed commits.
2843
- if (shouldWarnUnpushed(mode, false))
2876
+ // ACP headless run always has a prompt; surface any unpushed commits
2877
+ // and any open PR left unattended (RUSH-2394).
2878
+ if (shouldWarnUnpushed(mode, false)) {
2844
2879
  await warnUnpushedWork(cwd);
2880
+ await warnOrphanedOpenPr(cwd);
2881
+ }
2845
2882
  process.exit(exitCode);
2846
2883
  }
2847
2884
  catch (err) {
@@ -2998,9 +3035,12 @@ export function registerRunCommand(program) {
2998
3035
  // the normal finalize below — record its one audit entry.
2999
3036
  const loopExit = loopExitCode(result.stoppedBy);
3000
3037
  recordDispatchedRun({ agent, version: defaultVersion ?? 'unknown', mode, cwd, exitCode: loopExit });
3001
- // A loop is always headless; surface any commits it left unpushed.
3002
- if (shouldWarnUnpushed(mode, false))
3038
+ // A loop is always headless; surface any commits it left unpushed
3039
+ // and any open PR left without a durable lander (RUSH-2394).
3040
+ if (shouldWarnUnpushed(mode, false)) {
3003
3041
  await warnUnpushedWork(cwd);
3042
+ await warnOrphanedOpenPr(cwd);
3043
+ }
3004
3044
  process.exit(loopExit);
3005
3045
  }
3006
3046
  catch (err) {
@@ -3045,11 +3085,14 @@ export function registerRunCommand(program) {
3045
3085
  cleanupWorkflowMcpConfig();
3046
3086
  cleanupWorkflowSubagents();
3047
3087
  // Surface committed-but-unpushed work a headless writable run left
3048
- // behind, so it isn't silently stranded in a worktree. Advisory only,
3088
+ // behind, so it isn't silently stranded in a worktree. Also warn when
3089
+ // the branch still has an OPEN PR (RUSH-2394) — a background
3090
+ // `gh pr checks --watch` dies with the agent. Advisory only,
3049
3091
  // never throws; skipped for interactive runs (the human sees the shell)
3050
3092
  // and read-only plan mode (can't commit).
3051
3093
  if (shouldWarnUnpushed(mode, resolveInteractive(execOptions))) {
3052
3094
  await warnUnpushedWork(cwd);
3095
+ await warnOrphanedOpenPr(cwd);
3053
3096
  }
3054
3097
  // Governance chokepoint (#347): every dispatched run finalizes here.
3055
3098
  // ONE tamper-evident audit record per run — non-fatal by contract.
@@ -3067,6 +3110,7 @@ export function registerRunCommand(program) {
3067
3110
  // matters most — warn before exiting the error path too.
3068
3111
  if (shouldWarnUnpushed(mode, resolveInteractive(execOptions))) {
3069
3112
  await warnUnpushedWork(cwd);
3113
+ await warnOrphanedOpenPr(cwd);
3070
3114
  }
3071
3115
  console.error(chalk.red(`Failed to execute ${agent}: ${err.message}`));
3072
3116
  process.exit(1);
@@ -20,7 +20,7 @@ import { type OpenBlock } from '../lib/feed.js';
20
20
  import { type OutcomeGroup, type SessionOutcomeHint } from '../lib/feed-outcome.js';
21
21
  import { filterBlocksForFeed } from '../lib/ask-classifier.js';
22
22
  import { type FeedSessionSignal } from '../lib/feed-ranking.js';
23
- export declare const FEED_POST_HELP = "\nExamples:\n # Title (subject) + body. Phone broadcasts put title first, body after a\n # blank line, then a \"Sent from agent/session on host\" footer.\n agents feed post --title \"CHANGELOG pushed\" \"Watching CI and mac-mini E2E\"\n agents feed post --title \"Cover ready\" \"render at ./out/cover.png\" --attach ./out/cover.png\n agents feed post --title \"Ready for review\" \"PR opened, waiting on prix-cloud\" --json\n\n # Worth interrupting someone over - reaches sinks gated on minLevel: important:\n agents feed post --title \"npm token expired\" \"Cannot publish the release\" --level important\n\n # Stuck: opens a needs-you block and always broadcasts at important:\n agents feed post --title \"Force-push denied\" \"git-guard blocked PR #1749\" --blocked\n agents feed post --title \"Publish or wait?\" \"npm publish now or after review\" --blocked --option publish --option wait\n agents feed post --title \"Delete preview env?\" \"stale preview still running\" --blocked --default \"leave it\"\n\n # Exhaust self-serve FIRST. A block is for what you genuinely cannot do:\n # a credential only the user holds, a decision only they can make, an\n # approval only they can give. Not \"should I do the obvious next step?\".\n\n # Outside a run, pass the session explicitly:\n agents feed post --title \"Manual note\" \"context for the next agent\" --session 00998b0e-2d15-4d2f-a58b-974a886c9b47\n\nIdentity (session, agent, host, runtime, pid, launchId) is stamped automatically\nand rides the phone footer of feed.broadcast {message}. Domain facts (tickets,\nPRs) are not CLI flags - the ticket is joined from the session index at post\ntime. No em-dashes in title/body - they are scrubbed on the way out.\n\nConfigure where a post is mirrored under feed.broadcast in agents.yaml - see\ndocs/06-observability.md. A milestone is always recorded, but it does not text\nthe owner when the sink has minLevel: important. Add --level important for a\nphone-worthy successful update. Use --blocked only when work cannot continue.\nThe owner destination comes from humans.yaml; do not duplicate it in agents.yaml.\n";
23
+ export declare const FEED_POST_HELP = "\nExamples:\n # Title (subject) + body. Phone broadcasts put title first, body after a\n # blank line, then a \"Sent from agent/session on host\" footer.\n agents feed post --title \"CHANGELOG pushed\" \"Watching CI and mac-mini E2E\"\n agents feed post --title \"Cover ready\" \"render at ./out/cover.png\" --attach ./out/cover.png\n agents feed post --title \"Ready for review\" \"PR opened, waiting on prix-cloud\" --json\n\n # Worth interrupting someone over - reaches sinks gated on minLevel: important:\n agents feed post --title \"npm token expired\" \"Cannot publish the release\" --level important\n\n # Also raise a local desktop banner on THIS machine (same notifier as run\n # --notify), on top of any configured broadcast - useful when you are at the box:\n agents feed post --title \"Build green\" \"all checks passed\" --notify\n\n # Stuck: opens a needs-you block and always broadcasts at important:\n agents feed post --title \"Force-push denied\" \"git-guard blocked PR #1749\" --blocked\n agents feed post --title \"Publish or wait?\" \"npm publish now or after review\" --blocked --option publish --option wait\n agents feed post --title \"Delete preview env?\" \"stale preview still running\" --blocked --default \"leave it\"\n\n # Exhaust self-serve FIRST. A block is for what you genuinely cannot do:\n # a credential only the user holds, a decision only they can make, an\n # approval only they can give. Not \"should I do the obvious next step?\".\n\n # Outside a run, pass the session explicitly:\n agents feed post --title \"Manual note\" \"context for the next agent\" --session 00998b0e-2d15-4d2f-a58b-974a886c9b47\n\nIdentity (session, agent, host, runtime, pid, launchId) is stamped automatically\nand rides the phone footer of feed.broadcast {message}. Domain facts (tickets,\nPRs) are not CLI flags - the ticket is joined from the session index at post\ntime. No em-dashes in title/body - they are scrubbed on the way out.\n\nConfigure where a post is mirrored under feed.broadcast in agents.yaml - see\ndocs/observability.md. A milestone is always recorded, but it does not text\nthe owner when the sink has minLevel: important. Add --level important for a\nphone-worthy successful update. Use --blocked only when work cannot continue.\nThe owner destination comes from humans.yaml; do not duplicate it in agents.yaml.\n";
24
24
  export declare const FEED_NO_FANOUT_ENV = "AGENTS_FEED_LOCAL";
25
25
  /** Right-hand masthead summary: `N blocks · M agents`. */
26
26
  export declare function formatFeedMastheadRight(blocks: OpenBlock[]): string;
@@ -3,7 +3,7 @@ import { ensureFeedPublishHook, listAskStats, listBlocks, recordNotified, buildD
3
3
  import { ensureActivityLogHook, readRecentActivity, formatActivityLine, formatProgressUpdate, mergeActivityEvents, parseActivityPayload, } from '../lib/activity.js';
4
4
  import { projectKeyFromCwd } from '../lib/project-key.js';
5
5
  import { postFeedStatus } from '../lib/feed-post.js';
6
- import { parseFeedPostLevel, planFeedBroadcast, runFeedBroadcast, effectiveBroadcastConfig, blockBroadcastContext, blockDeliveryFailure, } from '../lib/feed-broadcast.js';
6
+ import { parseFeedPostLevel, planFeedBroadcast, runFeedBroadcast, effectiveBroadcastConfig, withDesktopNotify, blockBroadcastContext, blockDeliveryFailure, } from '../lib/feed-broadcast.js';
7
7
  import { getSessionById } from '../lib/session/db.js';
8
8
  import { readMeta } from '../lib/state.js';
9
9
  import { enrichBlocksFromSessions, groupBlocksByOutcome, isUnambiguousOutcomeAnswer, openBlocksForOutcome, stampBlockOutcomes, } from '../lib/feed-outcome.js';
@@ -33,6 +33,10 @@ Examples:
33
33
  # Worth interrupting someone over - reaches sinks gated on minLevel: important:
34
34
  agents feed post --title "npm token expired" "Cannot publish the release" --level important
35
35
 
36
+ # Also raise a local desktop banner on THIS machine (same notifier as run
37
+ # --notify), on top of any configured broadcast - useful when you are at the box:
38
+ agents feed post --title "Build green" "all checks passed" --notify
39
+
36
40
  # Stuck: opens a needs-you block and always broadcasts at important:
37
41
  agents feed post --title "Force-push denied" "git-guard blocked PR #1749" --blocked
38
42
  agents feed post --title "Publish or wait?" "npm publish now or after review" --blocked --option publish --option wait
@@ -51,7 +55,7 @@ PRs) are not CLI flags - the ticket is joined from the session index at post
51
55
  time. No em-dashes in title/body - they are scrubbed on the way out.
52
56
 
53
57
  Configure where a post is mirrored under feed.broadcast in agents.yaml - see
54
- docs/06-observability.md. A milestone is always recorded, but it does not text
58
+ docs/observability.md. A milestone is always recorded, but it does not text
55
59
  the owner when the sink has minLevel: important. Add --level important for a
56
60
  phone-worthy successful update. Use --blocked only when work cannot continue.
57
61
  The owner destination comes from humans.yaml; do not duplicate it in agents.yaml.
@@ -331,6 +335,7 @@ export function registerFeedCommand(program) {
331
335
  .option('--blocked', 'You are STUCK and need the user. Opens an answerable block and always broadcasts at important - do not also pass --level.')
332
336
  .option('--option <label...>', 'With --blocked: an answer the user can pick; repeatable')
333
337
  .option('--default <answer>', 'With --blocked: a safe default policy may apply if nobody answers in time')
338
+ .option('--notify', 'Also raise a local desktop banner on THIS machine (the same notifier as `run --notify`), on top of any configured broadcast. Fires at any level.')
334
339
  .option('--json', 'Emit the written event as JSON')
335
340
  .addHelpText('after', FEED_POST_HELP)
336
341
  .action(async (textParts, opts, cmd) => {
@@ -345,6 +350,7 @@ export function registerFeedCommand(program) {
345
350
  blocked: Boolean(opts?.blocked ?? cmd?.opts?.()?.blocked),
346
351
  option: opts?.option ?? cmd?.opts?.()?.option,
347
352
  default: opts?.default ?? cmd?.opts?.()?.default,
353
+ notify: Boolean(opts?.notify ?? cmd?.opts?.()?.notify),
348
354
  json: Boolean(opts?.json ?? cmd?.opts?.()?.json ?? cmd?.parent?.opts?.()?.json),
349
355
  };
350
356
  try {
@@ -396,10 +402,10 @@ export function registerFeedCommand(program) {
396
402
  agent: event.agent,
397
403
  title: event.title,
398
404
  body: event.detail,
399
- }, meta);
405
+ }, meta, flags.notify);
400
406
  }
401
407
  else {
402
- outcomes = await broadcastPostedEvent(event, level, meta);
408
+ outcomes = await broadcastPostedEvent(event, level, meta, flags.notify);
403
409
  }
404
410
  // Fail loud when a block reached nobody. This is computed BEFORE the
405
411
  // --json early return: a machine caller is exactly the one that reads the
@@ -691,8 +697,10 @@ function registerFeedObserveAliases(program) {
691
697
  * and the delivery are pinned to one config snapshot, and so this is testable
692
698
  * against a real in-memory `Meta` without touching `~/.agents/agents.yaml`.
693
699
  */
694
- async function broadcastPostedEvent(event, level, meta) {
695
- const config = effectiveBroadcastConfig(meta.feed?.broadcast, level, meta);
700
+ async function broadcastPostedEvent(event, level, meta, notify = false) {
701
+ // `--notify` adds a local desktop banner on top of the configured sinks; it
702
+ // fires even for a milestone post that no configured sink would broadcast.
703
+ const config = withDesktopNotify(effectiveBroadcastConfig(meta.feed?.broadcast, level, meta), notify);
696
704
  if (!config)
697
705
  return [];
698
706
  const ticket = getSessionById(event.sessionId)?.ticketId;
@@ -720,8 +728,8 @@ async function broadcastPostedEvent(event, level, meta) {
720
728
  * `feed post`, while every `publishBlock` call wrote to the ledger and stopped
721
729
  * there — so a "needs you" record was durable and invisible at the same time.
722
730
  */
723
- async function broadcastBlock(block, extras, meta) {
724
- const config = effectiveBroadcastConfig(meta.feed?.broadcast, 'important', meta);
731
+ async function broadcastBlock(block, extras, meta, notify = false) {
732
+ const config = withDesktopNotify(effectiveBroadcastConfig(meta.feed?.broadcast, 'important', meta), notify);
725
733
  if (!config)
726
734
  return [];
727
735
  const ticket = getSessionById(block.sessionId)?.ticketId;
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import type { Command } from 'commander';
16
16
  import { probeAttachRail, type AttachRailLiveness, type UnreachableFallback } from './go.js';
17
- import type { ActiveSession } from '../lib/session/active.js';
17
+ import { type ActiveSession } from '../lib/session/active.js';
18
18
  import { type SessionMeta } from '../lib/session/types.js';
19
19
  import { type LiveStatusFilter } from './sessions.js';
20
20
  import { openSurfaces, type Backend } from '../lib/terminal/index.js';
@@ -74,6 +74,38 @@ export declare function selectFallback(attachOnly: boolean | undefined): Unreach
74
74
  export declare function focusAction(id: string | undefined, opts: FocusOptions): Promise<void>;
75
75
  /** A retained pane is not attachable merely because tmux can still display it. */
76
76
  export declare function isAttachableLiveSession(session: ActiveSession): boolean;
77
+ /**
78
+ * Collapse rows that are the SAME logical session.
79
+ *
80
+ * A transcript syncs across the fleet, so one session appears once per machine
81
+ * holding a copy. SES-IF-2a: "Synced copies sharing the same full id MUST count
82
+ * as one logical session." `fleetCandidatesByQuery` already groups this way, but
83
+ * this path filtered raw rows instead — so `focus <full-uuid>` answered
84
+ * "is ambiguous (2 sessions). Use more of the id." with no longer id to give.
85
+ * Measured on zion: one of the two rows had no transcript at all
86
+ * ("Session transcript not available (file no longer exists). Path: ").
87
+ */
88
+ export declare function dedupeSessionsByLogicalId(rows: SessionMeta[], self?: string): SessionMeta[];
89
+ export type TmuxAliasState = 'not-an-alias' | 'no-server' | 'absent' | 'dead' | 'live';
90
+ /** Shape of the tmux alias the CLI mints for an agent session: `ag-<agent>-<shortid>`.
91
+ * Delegates to the one canonical matcher beside the name parsers in active.ts. */
92
+ export declare function looksLikeTmuxAlias(selector: string): boolean;
93
+ /**
94
+ * Classify a selector against the live tmux server. Split from the attach so the
95
+ * decision is testable against a real tmux server without replacing the caller's
96
+ * shell (attaching is not something a test can undo).
97
+ */
98
+ export declare function resolveTmuxAliasState(selector: string, socket?: string): Promise<TmuxAliasState>;
99
+ /**
100
+ * The session to focus once an id/identity selector has resolved across the
101
+ * fleet. Prefer the already-gathered candidate-pool row (it carries the live
102
+ * status collected for the picker), but fall back to the resolver's own metadata
103
+ * when the resolved session is not in the filtered pool — a peer-owned, older, or
104
+ * other-project session that the display filters excluded. Returning the resolved
105
+ * session there (instead of rejecting it) is what lets `focus <id>` reach a
106
+ * peer-owned session without `--device`, matching `resume`/`preview`.
107
+ */
108
+ export declare function focusTargetForResolved(poolMatch: SessionMeta | undefined, resolved: SessionMeta): SessionMeta;
77
109
  /** Focus one row selected by the shared session browser through the same
78
110
  * attach/recover decision as `agents sessions focus <id>`. */
79
111
  export declare function focusSelectedSession(meta: SessionMeta, active: ActiveSession | undefined, self: string): Promise<void>;