@phnx-labs/agents-cli 1.22.119 → 1.22.121

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 (1603) hide show
  1. package/CHANGELOG.md +236 -0
  2. package/README.md +19 -2
  3. package/dist/bootstrap.d.ts +0 -15
  4. package/dist/bootstrap.js +10 -409
  5. package/dist/cli/command-registry.d.ts +0 -58
  6. package/dist/cli/command-registry.js +2 -74
  7. package/dist/commands/accounts.d.ts +0 -17
  8. package/dist/commands/accounts.js +1 -52
  9. package/dist/commands/alias.d.ts +0 -12
  10. package/dist/commands/alias.js +0 -6
  11. package/dist/commands/apply.d.ts +0 -15
  12. package/dist/commands/apply.js +0 -63
  13. package/dist/commands/audit.d.ts +0 -12
  14. package/dist/commands/audit.js +0 -13
  15. package/dist/commands/auth.js +4 -12
  16. package/dist/commands/beta.d.ts +0 -6
  17. package/dist/commands/beta.js +2 -6
  18. package/dist/commands/browser-sessions-picker.d.ts +0 -8
  19. package/dist/commands/browser-sessions-picker.js +0 -26
  20. package/dist/commands/browser.d.ts +0 -57
  21. package/dist/commands/browser.js +0 -80
  22. package/dist/commands/budget.d.ts +0 -13
  23. package/dist/commands/budget.js +0 -2
  24. package/dist/commands/cli.d.ts +0 -12
  25. package/dist/commands/cli.js +0 -4
  26. package/dist/commands/cloud.d.ts +0 -9
  27. package/dist/commands/cloud.js +0 -43
  28. package/dist/commands/commands.d.ts +0 -9
  29. package/dist/commands/commands.js +0 -18
  30. package/dist/commands/computer-sessions-picker.d.ts +0 -11
  31. package/dist/commands/computer-sessions-picker.js +0 -29
  32. package/dist/commands/computer.d.ts +0 -62
  33. package/dist/commands/computer.js +3 -114
  34. package/dist/commands/config.d.ts +0 -14
  35. package/dist/commands/config.js +21 -60
  36. package/dist/commands/cost.d.ts +0 -11
  37. package/dist/commands/cost.js +1 -17
  38. package/dist/commands/daemon-test-harness.d.ts +0 -32
  39. package/dist/commands/daemon-test-harness.js +1 -36
  40. package/dist/commands/daemon.d.ts +0 -46
  41. package/dist/commands/daemon.js +8 -255
  42. package/dist/commands/detach-core.d.ts +0 -28
  43. package/dist/commands/detach-core.js +0 -30
  44. package/dist/commands/detach.d.ts +1 -12
  45. package/dist/commands/detach.js +16 -52
  46. package/dist/commands/device-config-test-harness.js +0 -12
  47. package/dist/commands/doctor.d.ts +0 -103
  48. package/dist/commands/doctor.js +3 -279
  49. package/dist/commands/events.d.ts +0 -29
  50. package/dist/commands/events.js +1 -55
  51. package/dist/commands/exec.d.ts +0 -163
  52. package/dist/commands/exec.js +15 -964
  53. package/dist/commands/factory.d.ts +0 -6
  54. package/dist/commands/factory.js +0 -2
  55. package/dist/commands/feed-watch.js +0 -20
  56. package/dist/commands/feed.d.ts +0 -38
  57. package/dist/commands/feed.js +1 -151
  58. package/dist/commands/feedback.d.ts +0 -5
  59. package/dist/commands/feedback.js +0 -5
  60. package/dist/commands/fleet-capture.d.ts +0 -12
  61. package/dist/commands/fleet-capture.js +1 -39
  62. package/dist/commands/focus.d.ts +6 -94
  63. package/dist/commands/focus.js +13 -183
  64. package/dist/commands/fork.d.ts +0 -21
  65. package/dist/commands/fork.js +0 -45
  66. package/dist/commands/funnel.d.ts +0 -3
  67. package/dist/commands/go.d.ts +2 -71
  68. package/dist/commands/go.js +5 -99
  69. package/dist/commands/harness-hooks.d.ts +0 -41
  70. package/dist/commands/harness-hooks.js +0 -48
  71. package/dist/commands/harness-wizard.d.ts +0 -137
  72. package/dist/commands/harness-wizard.js +0 -109
  73. package/dist/commands/harness.d.ts +0 -63
  74. package/dist/commands/harness.js +0 -103
  75. package/dist/commands/hooks.d.ts +0 -9
  76. package/dist/commands/hooks.js +0 -26
  77. package/dist/commands/humans.d.ts +0 -8
  78. package/dist/commands/humans.js +0 -8
  79. package/dist/commands/import.d.ts +0 -22
  80. package/dist/commands/import.js +0 -79
  81. package/dist/commands/insights.d.ts +0 -37
  82. package/dist/commands/insights.js +3 -115
  83. package/dist/commands/inspect.d.ts +0 -117
  84. package/dist/commands/inspect.js +2 -448
  85. package/dist/commands/lease.d.ts +0 -28
  86. package/dist/commands/lease.js +0 -43
  87. package/dist/commands/logs.d.ts +0 -23
  88. package/dist/commands/logs.js +0 -30
  89. package/dist/commands/mailboxes.d.ts +0 -18
  90. package/dist/commands/mailboxes.js +0 -29
  91. package/dist/commands/mcp.d.ts +0 -9
  92. package/dist/commands/mcp.js +0 -53
  93. package/dist/commands/memory.d.ts +0 -7
  94. package/dist/commands/memory.js +0 -7
  95. package/dist/commands/menubar.d.ts +0 -8
  96. package/dist/commands/menubar.js +0 -24
  97. package/dist/commands/message.d.ts +0 -23
  98. package/dist/commands/message.js +0 -50
  99. package/dist/commands/mine.d.ts +0 -22
  100. package/dist/commands/mine.js +0 -21
  101. package/dist/commands/models.d.ts +0 -8
  102. package/dist/commands/models.js +0 -33
  103. package/dist/commands/modes.d.ts +0 -10
  104. package/dist/commands/modes.js +0 -13
  105. package/dist/commands/monitors.d.ts +0 -9
  106. package/dist/commands/monitors.js +3 -160
  107. package/dist/commands/open.d.ts +0 -26
  108. package/dist/commands/open.js +0 -10
  109. package/dist/commands/output.d.ts +0 -18
  110. package/dist/commands/output.js +1 -34
  111. package/dist/commands/packages-materialize.d.ts +0 -11
  112. package/dist/commands/packages-materialize.js +0 -3
  113. package/dist/commands/packages.d.ts +0 -10
  114. package/dist/commands/packages.js +0 -50
  115. package/dist/commands/perf.d.ts +0 -41
  116. package/dist/commands/perf.js +0 -55
  117. package/dist/commands/permissions.d.ts +0 -9
  118. package/dist/commands/permissions.js +0 -43
  119. package/dist/commands/plugins.d.ts +0 -14
  120. package/dist/commands/plugins.js +2 -55
  121. package/dist/commands/profiles.d.ts +0 -25
  122. package/dist/commands/profiles.js +0 -27
  123. package/dist/commands/projects-todo.d.ts +2 -0
  124. package/dist/commands/projects-todo.js +132 -0
  125. package/dist/commands/projects.d.ts +0 -85
  126. package/dist/commands/projects.js +344 -291
  127. package/dist/commands/prune.js +0 -30
  128. package/dist/commands/ps-roster.d.ts +92 -0
  129. package/dist/commands/ps-roster.js +744 -0
  130. package/dist/commands/ps.d.ts +6 -0
  131. package/dist/commands/ps.js +98 -0
  132. package/dist/commands/refresh-rules.d.ts +0 -13
  133. package/dist/commands/refresh-rules.js +0 -14
  134. package/dist/commands/reminders.d.ts +0 -7
  135. package/dist/commands/repo.d.ts +0 -89
  136. package/dist/commands/repo.js +7 -205
  137. package/dist/commands/resource-view.d.ts +0 -33
  138. package/dist/commands/resource-view.js +0 -49
  139. package/dist/commands/resume.d.ts +1 -19
  140. package/dist/commands/resume.js +0 -50
  141. package/dist/commands/route.d.ts +0 -10
  142. package/dist/commands/route.js +0 -19
  143. package/dist/commands/routines.d.ts +0 -42
  144. package/dist/commands/routines.js +5 -290
  145. package/dist/commands/routines.test-fixture.d.ts +0 -34
  146. package/dist/commands/routines.test-fixture.js +4 -100
  147. package/dist/commands/rules.d.ts +0 -9
  148. package/dist/commands/rules.js +1 -6
  149. package/dist/commands/run-account-picker.d.ts +0 -59
  150. package/dist/commands/run-account-picker.js +0 -71
  151. package/dist/commands/run-broadcast.d.ts +0 -9
  152. package/dist/commands/run-broadcast.js +0 -7
  153. package/dist/commands/run-cloud.d.ts +0 -15
  154. package/dist/commands/run-cloud.js +0 -37
  155. package/dist/commands/run-device-picker.d.ts +0 -25
  156. package/dist/commands/run-device-picker.js +1 -53
  157. package/dist/commands/secrets-passthrough.d.ts +0 -31
  158. package/dist/commands/secrets-passthrough.js +0 -10
  159. package/dist/commands/send.d.ts +0 -20
  160. package/dist/commands/send.js +14 -18
  161. package/dist/commands/sessions-backfill.d.ts +0 -7
  162. package/dist/commands/sessions-backfill.js +1 -16
  163. package/dist/commands/sessions-backup-setup.js +0 -11
  164. package/dist/commands/sessions-bookmark.d.ts +0 -8
  165. package/dist/commands/sessions-bookmark.js +0 -28
  166. package/dist/commands/sessions-browser.d.ts +2 -117
  167. package/dist/commands/sessions-browser.js +5 -243
  168. package/dist/commands/sessions-export.d.ts +1 -26
  169. package/dist/commands/sessions-export.js +3 -81
  170. package/dist/commands/sessions-import.d.ts +0 -14
  171. package/dist/commands/sessions-import.js +0 -59
  172. package/dist/commands/sessions-inject.d.ts +0 -60
  173. package/dist/commands/sessions-inject.js +3 -96
  174. package/dist/commands/sessions-migrate.d.ts +2 -37
  175. package/dist/commands/sessions-migrate.js +7 -159
  176. package/dist/commands/sessions-optimize.d.ts +0 -12
  177. package/dist/commands/sessions-picker-factory.d.ts +0 -7
  178. package/dist/commands/sessions-picker-factory.js +0 -8
  179. package/dist/commands/sessions-picker.d.ts +4 -103
  180. package/dist/commands/sessions-picker.js +13 -352
  181. package/dist/commands/sessions-render.d.ts +1 -2
  182. package/dist/commands/sessions-render.js +3 -7
  183. package/dist/commands/sessions-resume.d.ts +1 -24
  184. package/dist/commands/sessions-resume.js +2 -65
  185. package/dist/commands/sessions-share.d.ts +1 -9
  186. package/dist/commands/sessions-share.js +1 -45
  187. package/dist/commands/sessions-stats.d.ts +0 -24
  188. package/dist/commands/sessions-stats.js +0 -49
  189. package/dist/commands/sessions-stop.d.ts +1 -20
  190. package/dist/commands/sessions-stop.js +4 -9
  191. package/dist/commands/sessions-tail.d.ts +1 -19
  192. package/dist/commands/sessions-tail.js +3 -36
  193. package/dist/commands/sessions-trace.d.ts +5 -36
  194. package/dist/commands/sessions-trace.js +7 -82
  195. package/dist/commands/sessions.d.ts +1 -666
  196. package/dist/commands/sessions.js +30 -2279
  197. package/dist/commands/sessions.test-fixture.d.ts +0 -9
  198. package/dist/commands/sessions.test-fixture.js +8 -23
  199. package/dist/commands/setup-accounts.d.ts +0 -6
  200. package/dist/commands/setup-browser.d.ts +0 -23
  201. package/dist/commands/setup-browser.js +0 -28
  202. package/dist/commands/setup-computer.d.ts +0 -16
  203. package/dist/commands/setup-computer.js +0 -28
  204. package/dist/commands/setup-fleet.d.ts +0 -8
  205. package/dist/commands/setup-fleet.js +0 -11
  206. package/dist/commands/setup-mine.d.ts +0 -14
  207. package/dist/commands/setup-mine.js +0 -25
  208. package/dist/commands/setup-preferences.d.ts +0 -47
  209. package/dist/commands/setup-preferences.js +0 -53
  210. package/dist/commands/setup-secrets.d.ts +2 -24
  211. package/dist/commands/setup-secrets.js +0 -24
  212. package/dist/commands/setup-term.d.ts +0 -21
  213. package/dist/commands/setup-term.js +0 -21
  214. package/dist/commands/setup-terminal.d.ts +0 -1
  215. package/dist/commands/setup-terminal.js +0 -1
  216. package/dist/commands/setup-tools.d.ts +2 -0
  217. package/dist/commands/setup-tools.js +73 -0
  218. package/dist/commands/setup.d.ts +0 -20
  219. package/dist/commands/setup.js +4 -57
  220. package/dist/commands/skills.d.ts +0 -9
  221. package/dist/commands/skills.js +1 -22
  222. package/dist/commands/snapshot.d.ts +0 -9
  223. package/dist/commands/snapshot.js +0 -10
  224. package/dist/commands/ssh.d.ts +0 -64
  225. package/dist/commands/ssh.js +9 -420
  226. package/dist/commands/status.d.ts +0 -12
  227. package/dist/commands/status.js +0 -26
  228. package/dist/commands/subagents.d.ts +0 -8
  229. package/dist/commands/subagents.js +0 -31
  230. package/dist/commands/sync.d.ts +0 -37
  231. package/dist/commands/sync.js +0 -256
  232. package/dist/commands/teams-picker.d.ts +0 -3
  233. package/dist/commands/teams-picker.js +0 -34
  234. package/dist/commands/teams.d.ts +1 -76
  235. package/dist/commands/teams.js +9 -477
  236. package/dist/commands/tmux.d.ts +0 -25
  237. package/dist/commands/tmux.js +0 -46
  238. package/dist/commands/traces.js +0 -19
  239. package/dist/commands/trash.d.ts +0 -17
  240. package/dist/commands/trash.js +1 -11
  241. package/dist/commands/uninstall.d.ts +0 -9
  242. package/dist/commands/uninstall.js +0 -6
  243. package/dist/commands/update.d.ts +0 -22
  244. package/dist/commands/update.js +0 -44
  245. package/dist/commands/upgrade.d.ts +0 -1
  246. package/dist/commands/upgrade.js +0 -1
  247. package/dist/commands/utils.d.ts +0 -85
  248. package/dist/commands/utils.js +1 -95
  249. package/dist/commands/versions.d.ts +0 -16
  250. package/dist/commands/versions.js +0 -134
  251. package/dist/commands/view.d.ts +0 -90
  252. package/dist/commands/view.js +4 -343
  253. package/dist/commands/watchdog.d.ts +0 -19
  254. package/dist/commands/watchdog.js +3 -43
  255. package/dist/commands/webhook.d.ts +0 -8
  256. package/dist/commands/webhook.js +0 -14
  257. package/dist/commands/workflows.d.ts +0 -8
  258. package/dist/commands/workflows.js +0 -6
  259. package/dist/index.d.ts +0 -25
  260. package/dist/index.js +5 -119
  261. package/dist/lib/account-capabilities.d.ts +0 -34
  262. package/dist/lib/account-capabilities.js +0 -32
  263. package/dist/lib/account-catalog.d.ts +0 -128
  264. package/dist/lib/account-catalog.js +8 -154
  265. package/dist/lib/account-provider-registry.d.ts +0 -14
  266. package/dist/lib/account-provider-registry.js +0 -8
  267. package/dist/lib/account-registry.d.ts +0 -74
  268. package/dist/lib/account-registry.js +14 -189
  269. package/dist/lib/account-schema.d.ts +0 -19
  270. package/dist/lib/account-schema.js +0 -43
  271. package/dist/lib/accounting/account-launch.d.ts +0 -15
  272. package/dist/lib/accounting/account-launch.js +1 -3
  273. package/dist/lib/accounting/account-pool-collect.d.ts +0 -26
  274. package/dist/lib/accounting/account-pool-collect.js +0 -42
  275. package/dist/lib/accounting/account-pool.d.ts +0 -41
  276. package/dist/lib/accounting/account-pool.js +0 -17
  277. package/dist/lib/accounting/capacity.d.ts +0 -32
  278. package/dist/lib/accounting/capacity.js +0 -32
  279. package/dist/lib/accounting/rotate.d.ts +0 -518
  280. package/dist/lib/accounting/rotate.js +4 -598
  281. package/dist/lib/accounting/usage-ingest.d.ts +0 -1
  282. package/dist/lib/accounting/usage-ingest.js +0 -44
  283. package/dist/lib/accounting/usage-sync.d.ts +0 -60
  284. package/dist/lib/accounting/usage-sync.js +4 -51
  285. package/dist/lib/accounting/usage.d.ts +0 -632
  286. package/dist/lib/accounting/usage.js +14 -1055
  287. package/dist/lib/accounts/add.d.ts +0 -60
  288. package/dist/lib/accounts/add.js +0 -127
  289. package/dist/lib/accounts/auth-operation-lock.d.ts +0 -1
  290. package/dist/lib/accounts/auth-operation-lock.js +0 -4
  291. package/dist/lib/accounts/migrate.d.ts +0 -9
  292. package/dist/lib/accounts/migrate.js +3 -42
  293. package/dist/lib/accounts/slots.d.ts +0 -25
  294. package/dist/lib/accounts/slots.js +1 -49
  295. package/dist/lib/acp/client.d.ts +0 -16
  296. package/dist/lib/acp/client.js +0 -29
  297. package/dist/lib/acp/harnesses.d.ts +0 -15
  298. package/dist/lib/acp/harnesses.js +0 -16
  299. package/dist/lib/acp/run.d.ts +0 -8
  300. package/dist/lib/acp/run.js +0 -8
  301. package/dist/lib/actor.d.ts +1 -71
  302. package/dist/lib/actor.js +1 -99
  303. package/dist/lib/add-dir.d.ts +0 -46
  304. package/dist/lib/add-dir.js +1 -70
  305. package/dist/lib/address.d.ts +0 -17
  306. package/dist/lib/address.js +0 -15
  307. package/dist/lib/agent-cli-commands.d.ts +0 -10
  308. package/dist/lib/agent-cli-commands.js +0 -10
  309. package/dist/lib/agent-modes.d.ts +0 -29
  310. package/dist/lib/agent-modes.js +0 -31
  311. package/dist/lib/agent-spec/agents.d.ts +0 -426
  312. package/dist/lib/agent-spec/agents.js +37 -924
  313. package/dist/lib/agent-spec/index.d.ts +0 -5
  314. package/dist/lib/agent-spec/index.js +0 -14
  315. package/dist/lib/agent-spec/materialize.d.ts +0 -10
  316. package/dist/lib/agent-spec/materialize.js +2 -139
  317. package/dist/lib/agent-spec/package-resolve.d.ts +0 -8
  318. package/dist/lib/agent-spec/package-resolve.js +1 -44
  319. package/dist/lib/agent-spec/package-schema.d.ts +0 -2
  320. package/dist/lib/agent-spec/package-schema.js +0 -11
  321. package/dist/lib/agent-spec/package-types.d.ts +0 -27
  322. package/dist/lib/agent-spec/package-types.js +0 -1
  323. package/dist/lib/agent-spec/primitives.d.ts +0 -18
  324. package/dist/lib/agent-spec/primitives.js +0 -27
  325. package/dist/lib/agent-spec/provider.js +0 -2
  326. package/dist/lib/agent-spec/resolve.d.ts +0 -23
  327. package/dist/lib/agent-spec/resolve.js +0 -41
  328. package/dist/lib/agent-spec/types.d.ts +0 -34
  329. package/dist/lib/agent-spec/types.js +0 -6
  330. package/dist/lib/agents.d.ts +0 -1
  331. package/dist/lib/agents.js +0 -1
  332. package/dist/lib/analytics/mix-commands.d.ts +0 -23
  333. package/dist/lib/analytics/mix-commands.js +0 -26
  334. package/dist/lib/analytics/recipes.d.ts +0 -1
  335. package/dist/lib/analytics/recipes.js +5 -10
  336. package/dist/lib/analytics/usage-db.js +4 -6
  337. package/dist/lib/answer-router.d.ts +0 -61
  338. package/dist/lib/answer-router.js +0 -57
  339. package/dist/lib/app-bundle-install.d.ts +0 -13
  340. package/dist/lib/app-bundle-install.js +0 -50
  341. package/dist/lib/artifact-actions.d.ts +0 -15
  342. package/dist/lib/artifact-actions.js +0 -18
  343. package/dist/lib/artifacts-client.d.ts +0 -10
  344. package/dist/lib/artifacts-client.js +0 -17
  345. package/dist/lib/ask-classifier.d.ts +0 -38
  346. package/dist/lib/ask-classifier.js +0 -27
  347. package/dist/lib/audit/log.d.ts +0 -47
  348. package/dist/lib/audit/log.js +1 -59
  349. package/dist/lib/auth-health.d.ts +0 -213
  350. package/dist/lib/auth-health.js +16 -266
  351. package/dist/lib/auth-mint.d.ts +0 -83
  352. package/dist/lib/auth-mint.js +8 -85
  353. package/dist/lib/auto-pull-worker.d.ts +0 -10
  354. package/dist/lib/auto-pull-worker.js +3 -48
  355. package/dist/lib/auto-pull.d.ts +0 -64
  356. package/dist/lib/auto-pull.js +0 -79
  357. package/dist/lib/beta.d.ts +0 -9
  358. package/dist/lib/beta.js +0 -9
  359. package/dist/lib/binary-shadow.d.ts +0 -22
  360. package/dist/lib/binary-shadow.js +4 -34
  361. package/dist/lib/boot-profile.d.ts +0 -10
  362. package/dist/lib/boot-profile.js +1 -31
  363. package/dist/lib/brand.d.ts +0 -20
  364. package/dist/lib/brand.js +0 -50
  365. package/dist/lib/browser/context.d.ts +0 -54
  366. package/dist/lib/browser/context.js +0 -49
  367. package/dist/lib/browser/paths.d.ts +0 -21
  368. package/dist/lib/browser/paths.js +0 -26
  369. package/dist/lib/browser/record.d.ts +0 -34
  370. package/dist/lib/browser/record.js +0 -38
  371. package/dist/lib/browser/sessions-list.d.ts +1 -79
  372. package/dist/lib/browser/sessions-list.js +2 -98
  373. package/dist/lib/browser-client.d.ts +0 -112
  374. package/dist/lib/browser-client.js +1 -90
  375. package/dist/lib/budget/config.d.ts +0 -6
  376. package/dist/lib/budget/config.js +0 -29
  377. package/dist/lib/budget/enforce.d.ts +0 -50
  378. package/dist/lib/budget/enforce.js +0 -27
  379. package/dist/lib/budget/ledger.d.ts +0 -23
  380. package/dist/lib/budget/ledger.js +0 -28
  381. package/dist/lib/budget/live-cloud.d.ts +0 -26
  382. package/dist/lib/budget/live-cloud.js +0 -12
  383. package/dist/lib/budget/live-team.d.ts +0 -17
  384. package/dist/lib/budget/live-team.js +1 -35
  385. package/dist/lib/budget/preflight.d.ts +0 -51
  386. package/dist/lib/budget/preflight.js +0 -36
  387. package/dist/lib/byok-usage.d.ts +0 -20
  388. package/dist/lib/byok-usage.js +1 -24
  389. package/dist/lib/capabilities.d.ts +0 -24
  390. package/dist/lib/capabilities.js +0 -29
  391. package/dist/lib/catchup.d.ts +0 -87
  392. package/dist/lib/catchup.js +1 -81
  393. package/dist/lib/channels/owner-forward.d.ts +0 -70
  394. package/dist/lib/channels/owner-forward.js +1 -43
  395. package/dist/lib/channels/owner-sink.js +0 -21
  396. package/dist/lib/channels/providers/desktop.d.ts +0 -37
  397. package/dist/lib/channels/providers/desktop.js +0 -72
  398. package/dist/lib/channels/providers/index.d.ts +0 -1
  399. package/dist/lib/channels/providers/index.js +2 -6
  400. package/dist/lib/channels/providers/mailbox.js +0 -7
  401. package/dist/lib/channels/providers/openclaw-telegram.js +0 -8
  402. package/dist/lib/channels/providers/rush.d.ts +0 -2
  403. package/dist/lib/channels/providers/rush.js +0 -26
  404. package/dist/lib/channels/providers/session.d.ts +2 -0
  405. package/dist/lib/channels/providers/session.js +26 -0
  406. package/dist/lib/channels/registry.d.ts +0 -27
  407. package/dist/lib/channels/registry.js +0 -10
  408. package/dist/lib/channels/resolve.d.ts +0 -19
  409. package/dist/lib/channels/resolve.js +0 -2
  410. package/dist/lib/channels/send.d.ts +0 -50
  411. package/dist/lib/channels/send.js +0 -25
  412. package/dist/lib/checkpoint.d.ts +0 -36
  413. package/dist/lib/checkpoint.js +0 -28
  414. package/dist/lib/claude-account-token.d.ts +0 -98
  415. package/dist/lib/claude-account-token.js +7 -169
  416. package/dist/lib/claude-statusline.d.ts +0 -41
  417. package/dist/lib/claude-statusline.js +0 -68
  418. package/dist/lib/cli-entry.d.ts +0 -26
  419. package/dist/lib/cli-entry.js +1 -61
  420. package/dist/lib/cli-resources.d.ts +31 -89
  421. package/dist/lib/cli-resources.js +116 -152
  422. package/dist/lib/cloud/antigravity.d.ts +0 -29
  423. package/dist/lib/cloud/antigravity.js +0 -36
  424. package/dist/lib/cloud/codex.d.ts +0 -8
  425. package/dist/lib/cloud/codex.js +0 -41
  426. package/dist/lib/cloud/cursor.d.ts +0 -5
  427. package/dist/lib/cloud/cursor.js +2 -7
  428. package/dist/lib/cloud/dispatch.d.ts +0 -13
  429. package/dist/lib/cloud/dispatch.js +1 -48
  430. package/dist/lib/cloud/factory.d.ts +0 -52
  431. package/dist/lib/cloud/factory.js +3 -67
  432. package/dist/lib/cloud/host.d.ts +0 -39
  433. package/dist/lib/cloud/host.js +5 -48
  434. package/dist/lib/cloud/registry.d.ts +0 -25
  435. package/dist/lib/cloud/registry.js +0 -29
  436. package/dist/lib/cloud/rush.d.ts +0 -47
  437. package/dist/lib/cloud/rush.js +1 -82
  438. package/dist/lib/cloud/session-index.d.ts +0 -27
  439. package/dist/lib/cloud/session-index.js +1 -32
  440. package/dist/lib/cloud/store.d.ts +0 -18
  441. package/dist/lib/cloud/store.js +0 -28
  442. package/dist/lib/cloud/stream.d.ts +0 -14
  443. package/dist/lib/cloud/stream.js +0 -25
  444. package/dist/lib/cloud/types.d.ts +0 -168
  445. package/dist/lib/cloud/types.js +0 -46
  446. package/dist/lib/cloudflare/creds.d.ts +0 -2
  447. package/dist/lib/cloudflare/creds.js +0 -14
  448. package/dist/lib/cloudflare/provision.d.ts +0 -8
  449. package/dist/lib/cloudflare/provision.js +1 -19
  450. package/dist/lib/codex-home.d.ts +0 -60
  451. package/dist/lib/codex-home.js +2 -72
  452. package/dist/lib/codex-policy.d.ts +0 -10
  453. package/dist/lib/codex-policy.js +0 -13
  454. package/dist/lib/command-skills.d.ts +0 -10
  455. package/dist/lib/command-skills.js +0 -10
  456. package/dist/lib/commands.d.ts +0 -74
  457. package/dist/lib/commands.js +0 -112
  458. package/dist/lib/comms-render.d.ts +0 -5
  459. package/dist/lib/comms-render.js +0 -5
  460. package/dist/lib/computer/context.d.ts +0 -23
  461. package/dist/lib/computer/context.js +0 -14
  462. package/dist/lib/computer/policy.d.ts +0 -20
  463. package/dist/lib/computer/policy.js +0 -53
  464. package/dist/lib/computer/record.d.ts +0 -33
  465. package/dist/lib/computer/record.js +1 -48
  466. package/dist/lib/computer/sessions-list.d.ts +1 -128
  467. package/dist/lib/computer/sessions-list.js +6 -165
  468. package/dist/lib/computer-client.d.ts +0 -106
  469. package/dist/lib/computer-client.js +5 -86
  470. package/dist/lib/concurrency.d.ts +0 -14
  471. package/dist/lib/concurrency.js +0 -3
  472. package/dist/lib/config-drift.d.ts +0 -31
  473. package/dist/lib/config-drift.js +0 -32
  474. package/dist/lib/config-keys.d.ts +1 -65
  475. package/dist/lib/config-keys.js +6 -52
  476. package/dist/lib/config-transfer.d.ts +0 -14
  477. package/dist/lib/config-transfer.js +0 -26
  478. package/dist/lib/convert.d.ts +0 -17
  479. package/dist/lib/convert.js +0 -18
  480. package/dist/lib/crabbox/cli.d.ts +0 -156
  481. package/dist/lib/crabbox/cli.js +1 -188
  482. package/dist/lib/crabbox/config.d.ts +0 -18
  483. package/dist/lib/crabbox/config.js +1 -19
  484. package/dist/lib/crabbox/lease.d.ts +0 -93
  485. package/dist/lib/crabbox/lease.js +4 -148
  486. package/dist/lib/crabbox/progress.d.ts +0 -56
  487. package/dist/lib/crabbox/progress.js +2 -49
  488. package/dist/lib/crabbox/runtimes.d.ts +0 -94
  489. package/dist/lib/crabbox/runtimes.js +1 -111
  490. package/dist/lib/crabbox/setup-copy.d.ts +0 -64
  491. package/dist/lib/crabbox/setup-copy.js +1 -53
  492. package/dist/lib/daemon/account-state-daemon-service.d.ts +0 -48
  493. package/dist/lib/daemon/account-state-daemon-service.js +2 -63
  494. package/dist/lib/daemon/attention-notify-service.d.ts +0 -12
  495. package/dist/lib/daemon/attention-notify-service.js +1 -24
  496. package/dist/lib/daemon/auth-sync-service.d.ts +0 -28
  497. package/dist/lib/daemon/auth-sync-service.js +0 -56
  498. package/dist/lib/daemon/catchup-service.d.ts +0 -34
  499. package/dist/lib/daemon/catchup-service.js +0 -30
  500. package/dist/lib/daemon/daemon.d.ts +0 -374
  501. package/dist/lib/daemon/daemon.js +44 -1049
  502. package/dist/lib/daemon/daemon.test-fixture.d.ts +0 -19
  503. package/dist/lib/daemon/daemon.test-fixture.js +1 -24
  504. package/dist/lib/daemon/device-probe-service.d.ts +0 -16
  505. package/dist/lib/daemon/device-probe-service.js +0 -20
  506. package/dist/lib/daemon/feed-stream-service.d.ts +0 -15
  507. package/dist/lib/daemon/feed-stream-service.js +0 -20
  508. package/dist/lib/daemon/harness-update-service.d.ts +2 -61
  509. package/dist/lib/daemon/harness-update-service.js +6 -86
  510. package/dist/lib/daemon/heartbeat-service.d.ts +0 -1
  511. package/dist/lib/daemon/heartbeat-service.js +0 -1
  512. package/dist/lib/daemon/leaked-daemons.d.ts +0 -46
  513. package/dist/lib/daemon/leaked-daemons.js +2 -78
  514. package/dist/lib/daemon/monitor-engine-service.d.ts +0 -13
  515. package/dist/lib/daemon/monitor-engine-service.js +3 -15
  516. package/dist/lib/daemon/runner.d.ts +0 -194
  517. package/dist/lib/daemon/runner.js +39 -760
  518. package/dist/lib/daemon/self-heal-service.d.ts +18 -17
  519. package/dist/lib/daemon/self-heal-service.js +83 -37
  520. package/dist/lib/daemon/self-update-service.d.ts +1 -131
  521. package/dist/lib/daemon/self-update-service.js +26 -189
  522. package/dist/lib/daemon/service.d.ts +0 -73
  523. package/dist/lib/daemon/service.js +0 -34
  524. package/dist/lib/daemon/session-index-service.d.ts +0 -12
  525. package/dist/lib/daemon/session-index-service.js +0 -23
  526. package/dist/lib/daemon/session-state-service.d.ts +0 -8
  527. package/dist/lib/daemon/session-state-service.js +0 -8
  528. package/dist/lib/daemon/session-summarizer-service.d.ts +0 -14
  529. package/dist/lib/daemon/session-summarizer-service.js +1 -19
  530. package/dist/lib/daemon/session-title-service.d.ts +0 -25
  531. package/dist/lib/daemon/session-title-service.js +0 -32
  532. package/dist/lib/daemon/state-dir-check-service.d.ts +0 -24
  533. package/dist/lib/daemon/state-dir-check-service.js +0 -29
  534. package/dist/lib/daemon/supervisor.d.ts +0 -112
  535. package/dist/lib/daemon/supervisor.js +4 -147
  536. package/dist/lib/daemon/testdata/process-view-daemon.js +0 -2
  537. package/dist/lib/daemon/testdata/process-view-start.js +0 -5
  538. package/dist/lib/daemon/tmux-reap-service.d.ts +0 -1
  539. package/dist/lib/daemon/tmux-reap-service.js +0 -1
  540. package/dist/lib/daemon/usage-sync-service.d.ts +0 -23
  541. package/dist/lib/daemon/usage-sync-service.js +0 -26
  542. package/dist/lib/daemon/watchdog-service.d.ts +0 -9
  543. package/dist/lib/daemon/watchdog-service.js +0 -13
  544. package/dist/lib/daemon/webhook-receiver-service.d.ts +0 -1
  545. package/dist/lib/daemon/webhook-receiver-service.js +0 -1
  546. package/dist/lib/daemon-health.d.ts +0 -55
  547. package/dist/lib/daemon-health.js +4 -77
  548. package/dist/lib/daemon-services.d.ts +0 -36
  549. package/dist/lib/daemon-services.js +0 -45
  550. package/dist/lib/daemon-ticks.d.ts +0 -126
  551. package/dist/lib/daemon-ticks.js +1 -156
  552. package/dist/lib/daemon-webhooks.d.ts +0 -57
  553. package/dist/lib/daemon-webhooks.js +2 -54
  554. package/dist/lib/deeplink/register.d.ts +0 -15
  555. package/dist/lib/deeplink/register.js +0 -60
  556. package/dist/lib/deeplink/url.d.ts +0 -24
  557. package/dist/lib/deeplink/url.js +1 -33
  558. package/dist/lib/device-config.d.ts +1 -192
  559. package/dist/lib/device-config.js +86 -240
  560. package/dist/lib/devices/config-migration.d.ts +0 -43
  561. package/dist/lib/devices/config-migration.js +7 -127
  562. package/dist/lib/devices/connect.d.ts +0 -168
  563. package/dist/lib/devices/connect.js +6 -254
  564. package/dist/lib/devices/device-docs.d.ts +0 -24
  565. package/dist/lib/devices/device-docs.js +0 -46
  566. package/dist/lib/devices/discovery-policy.d.ts +0 -30
  567. package/dist/lib/devices/discovery-policy.js +3 -34
  568. package/dist/lib/devices/doctor-findings.d.ts +0 -109
  569. package/dist/lib/devices/doctor-findings.js +30 -326
  570. package/dist/lib/devices/doctor-overview-cache.d.ts +0 -33
  571. package/dist/lib/devices/doctor-overview-cache.js +0 -81
  572. package/dist/lib/devices/fleet-divergence.d.ts +0 -89
  573. package/dist/lib/devices/fleet-divergence.js +1 -60
  574. package/dist/lib/devices/fleet-inventory.d.ts +0 -27
  575. package/dist/lib/devices/fleet-inventory.js +0 -38
  576. package/dist/lib/devices/fleet.d.ts +0 -95
  577. package/dist/lib/devices/fleet.js +0 -79
  578. package/dist/lib/devices/harness-inventory.d.ts +0 -75
  579. package/dist/lib/devices/harness-inventory.js +0 -101
  580. package/dist/lib/devices/health-report.d.ts +0 -37
  581. package/dist/lib/devices/health-report.js +0 -73
  582. package/dist/lib/devices/health.d.ts +0 -71
  583. package/dist/lib/devices/health.js +2 -82
  584. package/dist/lib/devices/interactive-host.d.ts +0 -10
  585. package/dist/lib/devices/interactive-host.js +0 -34
  586. package/dist/lib/devices/known-hosts.d.ts +0 -45
  587. package/dist/lib/devices/known-hosts.js +0 -77
  588. package/dist/lib/devices/pending.d.ts +0 -31
  589. package/dist/lib/devices/pending.js +7 -67
  590. package/dist/lib/devices/pool.d.ts +0 -36
  591. package/dist/lib/devices/pool.js +0 -30
  592. package/dist/lib/devices/reachability.d.ts +0 -25
  593. package/dist/lib/devices/reachability.js +0 -14
  594. package/dist/lib/devices/registry.d.ts +0 -141
  595. package/dist/lib/devices/registry.js +4 -151
  596. package/dist/lib/devices/resolve-profile.d.ts +0 -18
  597. package/dist/lib/devices/resolve-profile.js +0 -18
  598. package/dist/lib/devices/resolve-target.d.ts +0 -20
  599. package/dist/lib/devices/resolve-target.js +1 -51
  600. package/dist/lib/devices/rollout-verify.d.ts +1 -81
  601. package/dist/lib/devices/rollout-verify.js +0 -77
  602. package/dist/lib/devices/self-host.d.ts +0 -7
  603. package/dist/lib/devices/self-host.js +1 -29
  604. package/dist/lib/devices/ssh-config.d.ts +0 -18
  605. package/dist/lib/devices/ssh-config.js +0 -9
  606. package/dist/lib/devices/stats-cache.d.ts +0 -48
  607. package/dist/lib/devices/stats-cache.js +0 -80
  608. package/dist/lib/devices/sync.d.ts +0 -97
  609. package/dist/lib/devices/sync.js +0 -88
  610. package/dist/lib/devices/tailscale.d.ts +0 -18
  611. package/dist/lib/devices/tailscale.js +1 -38
  612. package/dist/lib/devices/terminfo.d.ts +0 -27
  613. package/dist/lib/devices/terminfo.js +2 -64
  614. package/dist/lib/devices/worker-pick.d.ts +0 -15
  615. package/dist/lib/devices/worker-pick.js +0 -48
  616. package/dist/lib/diff-text.d.ts +0 -18
  617. package/dist/lib/diff-text.js +0 -15
  618. package/dist/lib/doctor-diff.d.ts +0 -79
  619. package/dist/lib/doctor-diff.js +2 -181
  620. package/dist/lib/drift-sync.d.ts +0 -29
  621. package/dist/lib/drift-sync.js +0 -40
  622. package/dist/lib/drift.d.ts +0 -43
  623. package/dist/lib/drift.js +0 -31
  624. package/dist/lib/event-families.d.ts +0 -17
  625. package/dist/lib/event-families.js +0 -33
  626. package/dist/lib/event-provenance.d.ts +0 -4
  627. package/dist/lib/event-provenance.js +0 -5
  628. package/dist/lib/event-stream.d.ts +0 -29
  629. package/dist/lib/event-stream.js +0 -36
  630. package/dist/lib/events-ingest.d.ts +0 -27
  631. package/dist/lib/events-ingest.js +0 -54
  632. package/dist/lib/exec-account-home.d.ts +0 -24
  633. package/dist/lib/exec-account-home.js +0 -41
  634. package/dist/lib/exec-bounded.d.ts +1 -37
  635. package/dist/lib/exec-bounded.js +10 -46
  636. package/dist/lib/exec.d.ts +3 -583
  637. package/dist/lib/exec.js +18 -1025
  638. package/dist/lib/factory/snapshot.js +1 -15
  639. package/dist/lib/feed/activity-stream.d.ts +0 -27
  640. package/dist/lib/feed/activity-stream.js +4 -80
  641. package/dist/lib/feed/activity.d.ts +1 -243
  642. package/dist/lib/feed/activity.js +8 -273
  643. package/dist/lib/feed/answer.d.ts +0 -103
  644. package/dist/lib/feed/answer.js +0 -267
  645. package/dist/lib/feed/attention.d.ts +0 -56
  646. package/dist/lib/feed/attention.js +0 -161
  647. package/dist/lib/feed/envelope.d.ts +2 -17
  648. package/dist/lib/feed/envelope.js +0 -14
  649. package/dist/lib/feed/events.d.ts +0 -118
  650. package/dist/lib/feed/events.js +13 -213
  651. package/dist/lib/feed/feed.d.ts +1 -250
  652. package/dist/lib/feed/feed.js +24 -334
  653. package/dist/lib/feed/hub-server.d.ts +0 -100
  654. package/dist/lib/feed/hub-server.js +1 -191
  655. package/dist/lib/feed/hub.d.ts +0 -53
  656. package/dist/lib/feed/hub.js +0 -89
  657. package/dist/lib/feed/pr-status.d.ts +1 -19
  658. package/dist/lib/feed/pr-status.js +0 -18
  659. package/dist/lib/feed/tool-activity.d.ts +0 -59
  660. package/dist/lib/feed/tool-activity.js +1 -119
  661. package/dist/lib/feed/tools.d.ts +0 -100
  662. package/dist/lib/feed/tools.js +0 -89
  663. package/dist/lib/feed/watch.d.ts +0 -33
  664. package/dist/lib/feed/watch.js +2 -94
  665. package/dist/lib/feed-broadcast.d.ts +0 -148
  666. package/dist/lib/feed-broadcast.js +1 -283
  667. package/dist/lib/feed-outcome.d.ts +0 -50
  668. package/dist/lib/feed-outcome.js +1 -67
  669. package/dist/lib/feed-policy.d.ts +0 -6
  670. package/dist/lib/feed-policy.js +1 -27
  671. package/dist/lib/feed-post.d.ts +0 -61
  672. package/dist/lib/feed-post.js +4 -61
  673. package/dist/lib/feed-ranking.d.ts +1 -1
  674. package/dist/lib/fleet/apply.d.ts +0 -64
  675. package/dist/lib/fleet/apply.js +0 -125
  676. package/dist/lib/fleet/auth-sync.d.ts +0 -48
  677. package/dist/lib/fleet/auth-sync.js +4 -49
  678. package/dist/lib/fleet/capture.d.ts +0 -26
  679. package/dist/lib/fleet/capture.js +1 -36
  680. package/dist/lib/fleet/manifest.d.ts +0 -38
  681. package/dist/lib/fleet/manifest.js +0 -40
  682. package/dist/lib/fleet/types.d.ts +1 -138
  683. package/dist/lib/fleet/types.js +0 -12
  684. package/dist/lib/fleet-cache.d.ts +0 -12
  685. package/dist/lib/fleet-cache.js +0 -24
  686. package/dist/lib/fleet-shared-state.d.ts +6 -59
  687. package/dist/lib/fleet-shared-state.js +5 -51
  688. package/dist/lib/fleet-status.d.ts +0 -27
  689. package/dist/lib/fleet-status.js +0 -48
  690. package/dist/lib/format.d.ts +0 -74
  691. package/dist/lib/format.js +3 -77
  692. package/dist/lib/friction-heuristics.d.ts +0 -20
  693. package/dist/lib/friction-heuristics.js +0 -8
  694. package/dist/lib/fs-atomic.d.ts +0 -51
  695. package/dist/lib/fs-atomic.js +8 -66
  696. package/dist/lib/fs-walk.d.ts +0 -13
  697. package/dist/lib/fs-walk.js +0 -22
  698. package/dist/lib/fuzzy.d.ts +0 -29
  699. package/dist/lib/fuzzy.js +0 -31
  700. package/dist/lib/gemini-settings.js +0 -12
  701. package/dist/lib/git.d.ts +0 -366
  702. package/dist/lib/git.js +7 -574
  703. package/dist/lib/github/ci-failure.d.ts +30 -0
  704. package/dist/lib/github/ci-failure.js +95 -0
  705. package/dist/lib/github/gh-overload.d.ts +0 -38
  706. package/dist/lib/github/gh-overload.js +3 -55
  707. package/dist/lib/github/pr-mergeable.d.ts +3 -34
  708. package/dist/lib/github/pr-mergeable.js +2 -42
  709. package/dist/lib/github/pr-verdict.d.ts +0 -44
  710. package/dist/lib/github/pr-verdict.js +0 -36
  711. package/dist/lib/github/project-prs.d.ts +135 -105
  712. package/dist/lib/github/project-prs.js +530 -170
  713. package/dist/lib/github/release-drift.d.ts +45 -0
  714. package/dist/lib/github/release-drift.js +91 -0
  715. package/dist/lib/github/rest.d.ts +0 -50
  716. package/dist/lib/github/rest.js +0 -49
  717. package/dist/lib/github/viewer.d.ts +27 -0
  718. package/dist/lib/github/viewer.js +101 -0
  719. package/dist/lib/goose-commands.d.ts +0 -29
  720. package/dist/lib/goose-commands.js +3 -48
  721. package/dist/lib/harness/adapter.d.ts +0 -151
  722. package/dist/lib/harness/adapter.js +0 -41
  723. package/dist/lib/harness/adapters/claude.d.ts +0 -8
  724. package/dist/lib/harness/adapters/claude.js +0 -89
  725. package/dist/lib/harness/adapters/codex.js +0 -18
  726. package/dist/lib/harness/adapters/copilot.js +0 -3
  727. package/dist/lib/harness/adapters/cursor.js +0 -16
  728. package/dist/lib/harness/adapters/droid.js +0 -3
  729. package/dist/lib/harness/adapters/kimi.js +0 -19
  730. package/dist/lib/harness/adapters/muse.js +0 -9
  731. package/dist/lib/harness/adapters/opencode.js +0 -2
  732. package/dist/lib/harness/exec-config-version.d.ts +0 -2
  733. package/dist/lib/harness/exec-config-version.js +0 -13
  734. package/dist/lib/harness/index.js +0 -10
  735. package/dist/lib/harness-auth-capabilities.d.ts +0 -26
  736. package/dist/lib/harness-auth-capabilities.js +0 -18
  737. package/dist/lib/harness-connection-test.d.ts +0 -27
  738. package/dist/lib/harness-connection-test.js +2 -20
  739. package/dist/lib/heal.d.ts +0 -45
  740. package/dist/lib/heal.js +2 -82
  741. package/dist/lib/help.d.ts +0 -32
  742. package/dist/lib/help.js +0 -41
  743. package/dist/lib/helper-download.d.ts +0 -85
  744. package/dist/lib/helper-download.js +0 -95
  745. package/dist/lib/helper-versions.d.ts +0 -51
  746. package/dist/lib/helper-versions.js +1 -45
  747. package/dist/lib/hooks/cache.d.ts +0 -40
  748. package/dist/lib/hooks/cache.js +8 -122
  749. package/dist/lib/hooks/install.d.ts +0 -253
  750. package/dist/lib/hooks/install.js +49 -822
  751. package/dist/lib/hooks/match.d.ts +0 -24
  752. package/dist/lib/hooks/match.js +0 -31
  753. package/dist/lib/hooks/profile.d.ts +0 -21
  754. package/dist/lib/hooks/profile.js +0 -28
  755. package/dist/lib/hosts/credential-transport.d.ts +0 -6
  756. package/dist/lib/hosts/credential-transport.js +0 -17
  757. package/dist/lib/hosts/credentials.d.ts +0 -35
  758. package/dist/lib/hosts/credentials.js +0 -38
  759. package/dist/lib/hosts/dispatch.d.ts +0 -140
  760. package/dist/lib/hosts/dispatch.js +0 -176
  761. package/dist/lib/hosts/logs.d.ts +0 -25
  762. package/dist/lib/hosts/logs.js +1 -51
  763. package/dist/lib/hosts/option.d.ts +0 -12
  764. package/dist/lib/hosts/option.js +0 -12
  765. package/dist/lib/hosts/passthrough.d.ts +0 -129
  766. package/dist/lib/hosts/passthrough.js +12 -249
  767. package/dist/lib/hosts/progress.d.ts +0 -90
  768. package/dist/lib/hosts/progress.js +5 -115
  769. package/dist/lib/hosts/providers/devices.d.ts +0 -19
  770. package/dist/lib/hosts/providers/devices.js +1 -34
  771. package/dist/lib/hosts/providers/local.d.ts +0 -14
  772. package/dist/lib/hosts/providers/local.js +0 -22
  773. package/dist/lib/hosts/ready.d.ts +0 -99
  774. package/dist/lib/hosts/ready.js +0 -101
  775. package/dist/lib/hosts/reconcile.d.ts +0 -38
  776. package/dist/lib/hosts/reconcile.js +1 -50
  777. package/dist/lib/hosts/reconnect.d.ts +0 -75
  778. package/dist/lib/hosts/reconnect.js +0 -98
  779. package/dist/lib/hosts/registry.d.ts +0 -74
  780. package/dist/lib/hosts/registry.js +0 -110
  781. package/dist/lib/hosts/remote-cmd.d.ts +1 -228
  782. package/dist/lib/hosts/remote-cmd.js +19 -294
  783. package/dist/lib/hosts/remote-cmd.test-fixture.d.ts +0 -1
  784. package/dist/lib/hosts/remote-cmd.test-fixture.js +0 -12
  785. package/dist/lib/hosts/remote-os.d.ts +0 -19
  786. package/dist/lib/hosts/remote-os.js +0 -22
  787. package/dist/lib/hosts/remote-session-id.d.ts +0 -22
  788. package/dist/lib/hosts/remote-session-id.js +0 -24
  789. package/dist/lib/hosts/routing-flag.d.ts +0 -21
  790. package/dist/lib/hosts/routing-flag.js +0 -21
  791. package/dist/lib/hosts/run-target.d.ts +0 -53
  792. package/dist/lib/hosts/run-target.js +0 -56
  793. package/dist/lib/hosts/session-index.d.ts +1 -53
  794. package/dist/lib/hosts/session-index.js +2 -59
  795. package/dist/lib/hosts/session-marker.d.ts +0 -31
  796. package/dist/lib/hosts/session-marker.js +0 -32
  797. package/dist/lib/hosts/ssh-config.d.ts +0 -25
  798. package/dist/lib/hosts/ssh-config.js +1 -32
  799. package/dist/lib/hosts/tasks.d.ts +0 -54
  800. package/dist/lib/hosts/tasks.js +0 -35
  801. package/dist/lib/hosts/types.d.ts +0 -39
  802. package/dist/lib/hosts/types.js +0 -22
  803. package/dist/lib/humans.d.ts +0 -21
  804. package/dist/lib/humans.js +0 -30
  805. package/dist/lib/identity/client.d.ts +1 -35
  806. package/dist/lib/identity/client.js +3 -29
  807. package/dist/lib/identity/index.d.ts +3 -27
  808. package/dist/lib/identity/index.js +8 -24
  809. package/dist/lib/import.d.ts +0 -104
  810. package/dist/lib/import.js +1 -137
  811. package/dist/lib/installations/active-check.d.ts +0 -53
  812. package/dist/lib/installations/active-check.js +0 -49
  813. package/dist/lib/installations/index.d.ts +0 -9
  814. package/dist/lib/installations/index.js +0 -9
  815. package/dist/lib/installations/installation-lock.js +0 -8
  816. package/dist/lib/installations/launch-gate.d.ts +0 -56
  817. package/dist/lib/installations/launch-gate.js +0 -83
  818. package/dist/lib/installations/migrate.d.ts +0 -100
  819. package/dist/lib/installations/migrate.js +105 -572
  820. package/dist/lib/installations/native-command.d.ts +0 -1
  821. package/dist/lib/installations/native-command.js +0 -6
  822. package/dist/lib/installations/resolve.d.ts +0 -24
  823. package/dist/lib/installations/resolve.js +0 -24
  824. package/dist/lib/installations/shims.d.ts +0 -395
  825. package/dist/lib/installations/shims.js +30 -957
  826. package/dist/lib/installations/store.d.ts +0 -199
  827. package/dist/lib/installations/store.js +1 -297
  828. package/dist/lib/installations/strategies.d.ts +0 -44
  829. package/dist/lib/installations/strategies.js +0 -87
  830. package/dist/lib/installations/types.d.ts +1 -67
  831. package/dist/lib/installations/types.js +0 -6
  832. package/dist/lib/installations/update-cancellation.d.ts +0 -74
  833. package/dist/lib/installations/update-cancellation.js +0 -74
  834. package/dist/lib/installations/update-policy.d.ts +0 -57
  835. package/dist/lib/installations/update-policy.js +0 -62
  836. package/dist/lib/installations/update-runtime.d.ts +0 -88
  837. package/dist/lib/installations/update-runtime.js +1 -127
  838. package/dist/lib/installations/update.d.ts +0 -53
  839. package/dist/lib/installations/update.js +0 -95
  840. package/dist/lib/installations/versions.d.ts +0 -310
  841. package/dist/lib/installations/versions.js +14 -837
  842. package/dist/lib/isolation-boundary-report.d.ts +0 -7
  843. package/dist/lib/isolation-boundary-report.js +0 -7
  844. package/dist/lib/launch-identity.d.ts +0 -8
  845. package/dist/lib/launch-identity.js +0 -8
  846. package/dist/lib/linear-autoclose.d.ts +0 -25
  847. package/dist/lib/linear-autoclose.js +0 -19
  848. package/dist/lib/linear-cache.d.ts +0 -57
  849. package/dist/lib/linear-cache.js +1 -81
  850. package/dist/lib/linear-project-counts.d.ts +0 -83
  851. package/dist/lib/linear-project-counts.js +2 -64
  852. package/dist/lib/linear-projects.d.ts +0 -62
  853. package/dist/lib/linear-projects.js +0 -85
  854. package/dist/lib/linear-rate-limit.d.ts +0 -21
  855. package/dist/lib/linear-rate-limit.js +1 -93
  856. package/dist/lib/linux-userns.d.ts +1 -42
  857. package/dist/lib/linux-userns.js +0 -47
  858. package/dist/lib/lock-compromise.d.ts +0 -7
  859. package/dist/lib/lock-compromise.js +0 -7
  860. package/dist/lib/log-follow.d.ts +0 -2
  861. package/dist/lib/log-follow.js +5 -15
  862. package/dist/lib/loop.d.ts +0 -106
  863. package/dist/lib/loop.js +0 -135
  864. package/dist/lib/machine-id.d.ts +0 -19
  865. package/dist/lib/machine-id.js +0 -19
  866. package/dist/lib/mailbox-gc.d.ts +0 -7
  867. package/dist/lib/mailbox-gc.js +0 -25
  868. package/dist/lib/mailbox-target.d.ts +0 -31
  869. package/dist/lib/mailbox-target.js +0 -27
  870. package/dist/lib/mailbox.d.ts +0 -77
  871. package/dist/lib/mailbox.js +5 -105
  872. package/dist/lib/manifest.d.ts +0 -4
  873. package/dist/lib/manifest.js +0 -36
  874. package/dist/lib/markdown.d.ts +0 -3
  875. package/dist/lib/markdown.js +0 -9
  876. package/dist/lib/mcp-registry.d.ts +1 -50
  877. package/dist/lib/mcp-registry.js +0 -64
  878. package/dist/lib/mcp.d.ts +0 -115
  879. package/dist/lib/mcp.js +3 -199
  880. package/dist/lib/memory-cache.d.ts +0 -11
  881. package/dist/lib/memory-cache.js +0 -9
  882. package/dist/lib/memory.d.ts +0 -52
  883. package/dist/lib/memory.js +12 -74
  884. package/dist/lib/menubar/download-menubar.d.ts +0 -35
  885. package/dist/lib/menubar/download-menubar.js +0 -38
  886. package/dist/lib/menubar/install-menubar.d.ts +0 -405
  887. package/dist/lib/menubar/install-menubar.js +25 -667
  888. package/dist/lib/menubar/migrate-prefs.d.ts +0 -47
  889. package/dist/lib/menubar/migrate-prefs.js +1 -70
  890. package/dist/lib/menubar/notify-desktop.d.ts +0 -82
  891. package/dist/lib/menubar/notify-desktop.js +0 -68
  892. package/dist/lib/menubar/resolve-version.d.ts +0 -41
  893. package/dist/lib/menubar/resolve-version.js +2 -44
  894. package/dist/lib/menubar/snapshot.d.ts +13 -66
  895. package/dist/lib/menubar/snapshot.js +45 -39
  896. package/dist/lib/merged-resources.d.ts +0 -10
  897. package/dist/lib/merged-resources.js +0 -10
  898. package/dist/lib/migrate-fold.d.ts +0 -31
  899. package/dist/lib/migrate-fold.js +6 -38
  900. package/dist/lib/model-tier-overrides.d.ts +0 -30
  901. package/dist/lib/model-tier-overrides.js +0 -14
  902. package/dist/lib/model-tiers.d.ts +0 -43
  903. package/dist/lib/model-tiers.js +5 -78
  904. package/dist/lib/models.d.ts +0 -145
  905. package/dist/lib/models.js +3 -333
  906. package/dist/lib/monitors/config.d.ts +0 -187
  907. package/dist/lib/monitors/config.js +4 -101
  908. package/dist/lib/monitors/dispatch.d.ts +0 -22
  909. package/dist/lib/monitors/dispatch.js +0 -35
  910. package/dist/lib/monitors/engine.d.ts +1 -53
  911. package/dist/lib/monitors/engine.js +17 -106
  912. package/dist/lib/monitors/fingerprint.d.ts +0 -43
  913. package/dist/lib/monitors/fingerprint.js +0 -57
  914. package/dist/lib/monitors/pid-watch.d.ts +0 -31
  915. package/dist/lib/monitors/pid-watch.js +0 -31
  916. package/dist/lib/monitors/remote.d.ts +0 -52
  917. package/dist/lib/monitors/remote.js +0 -42
  918. package/dist/lib/monitors/sources/command.d.ts +2 -9
  919. package/dist/lib/monitors/sources/command.js +13 -34
  920. package/dist/lib/monitors/sources/device.d.ts +0 -10
  921. package/dist/lib/monitors/sources/device.js +0 -14
  922. package/dist/lib/monitors/sources/failure.d.ts +0 -27
  923. package/dist/lib/monitors/sources/failure.js +0 -27
  924. package/dist/lib/monitors/sources/file.d.ts +0 -10
  925. package/dist/lib/monitors/sources/file.js +0 -11
  926. package/dist/lib/monitors/sources/http.d.ts +0 -7
  927. package/dist/lib/monitors/sources/http.js +0 -9
  928. package/dist/lib/monitors/sources/index.d.ts +0 -9
  929. package/dist/lib/monitors/sources/index.js +0 -9
  930. package/dist/lib/monitors/sources/poll.d.ts +0 -8
  931. package/dist/lib/monitors/sources/poll.js +0 -8
  932. package/dist/lib/monitors/sources/types.d.ts +0 -18
  933. package/dist/lib/monitors/sources/types.js +0 -8
  934. package/dist/lib/monitors/sources/webhook.d.ts +0 -7
  935. package/dist/lib/monitors/sources/webhook.js +0 -7
  936. package/dist/lib/monitors/sources/ws.d.ts +0 -10
  937. package/dist/lib/monitors/sources/ws.js +3 -13
  938. package/dist/lib/monitors/state.d.ts +0 -132
  939. package/dist/lib/monitors/state.js +2 -86
  940. package/dist/lib/native-accounts.d.ts +0 -32
  941. package/dist/lib/native-accounts.js +0 -17
  942. package/dist/lib/net-close.d.ts +0 -9
  943. package/dist/lib/net-close.js +0 -5
  944. package/dist/lib/notify.d.ts +0 -47
  945. package/dist/lib/notify.js +0 -30
  946. package/dist/lib/onepassword.d.ts +0 -14
  947. package/dist/lib/onepassword.js +0 -12
  948. package/dist/lib/open-url.d.ts +0 -38
  949. package/dist/lib/open-url.js +1 -69
  950. package/dist/lib/openclaw-keychain.js +2 -7
  951. package/dist/lib/operator.d.ts +0 -9
  952. package/dist/lib/operator.js +0 -34
  953. package/dist/lib/origin-machine.d.ts +0 -16
  954. package/dist/lib/origin-machine.js +0 -16
  955. package/dist/lib/output/git-output.d.ts +0 -31
  956. package/dist/lib/output/git-output.js +4 -43
  957. package/dist/lib/overdue.d.ts +0 -35
  958. package/dist/lib/overdue.js +0 -60
  959. package/dist/lib/owner-message.d.ts +0 -20
  960. package/dist/lib/owner-message.js +1 -40
  961. package/dist/lib/packages/output-home.d.ts +0 -28
  962. package/dist/lib/packages/output-home.js +0 -114
  963. package/dist/lib/paths.d.ts +0 -26
  964. package/dist/lib/paths.js +1 -27
  965. package/dist/lib/percentile.d.ts +0 -11
  966. package/dist/lib/percentile.js +0 -11
  967. package/dist/lib/perf/db.d.ts +0 -16
  968. package/dist/lib/perf/db.js +3 -32
  969. package/dist/lib/perf/spool.d.ts +0 -12
  970. package/dist/lib/perf/spool.js +0 -13
  971. package/dist/lib/perf/types.d.ts +0 -26
  972. package/dist/lib/perf/types.js +0 -1
  973. package/dist/lib/permissions-registry.d.ts +0 -48
  974. package/dist/lib/permissions-registry.js +0 -108
  975. package/dist/lib/permissions.d.ts +0 -215
  976. package/dist/lib/permissions.js +4 -407
  977. package/dist/lib/picker.d.ts +0 -124
  978. package/dist/lib/picker.js +0 -140
  979. package/dist/lib/placement.d.ts +0 -57
  980. package/dist/lib/placement.js +0 -47
  981. package/dist/lib/platform/exec.d.ts +0 -73
  982. package/dist/lib/platform/exec.js +0 -80
  983. package/dist/lib/platform/index.d.ts +0 -14
  984. package/dist/lib/platform/index.js +0 -14
  985. package/dist/lib/platform/ipc.d.ts +0 -10
  986. package/dist/lib/platform/ipc.js +0 -13
  987. package/dist/lib/platform/links.d.ts +0 -14
  988. package/dist/lib/platform/links.js +0 -25
  989. package/dist/lib/platform/paths.d.ts +0 -48
  990. package/dist/lib/platform/paths.js +0 -52
  991. package/dist/lib/platform/posixpath.d.ts +0 -18
  992. package/dist/lib/platform/posixpath.js +0 -62
  993. package/dist/lib/platform/process.d.ts +0 -67
  994. package/dist/lib/platform/process.js +5 -99
  995. package/dist/lib/platform/winpath.d.ts +0 -50
  996. package/dist/lib/platform/winpath.js +0 -81
  997. package/dist/lib/plugins/plugin-marketplace.d.ts +0 -165
  998. package/dist/lib/plugins/plugin-marketplace.js +10 -238
  999. package/dist/lib/plugins/plugins.d.ts +0 -238
  1000. package/dist/lib/plugins/plugins.js +20 -454
  1001. package/dist/lib/plugins/skills.d.ts +0 -86
  1002. package/dist/lib/plugins/skills.js +1 -139
  1003. package/dist/lib/pr-land-detach.d.ts +0 -17
  1004. package/dist/lib/pr-land-detach.js +0 -30
  1005. package/dist/lib/pricing/cost.d.ts +0 -29
  1006. package/dist/lib/pricing/cost.js +0 -38
  1007. package/dist/lib/pricing/index.d.ts +0 -6
  1008. package/dist/lib/pricing/index.js +0 -6
  1009. package/dist/lib/pricing/table.d.ts +0 -8
  1010. package/dist/lib/pricing/table.js +3 -56
  1011. package/dist/lib/probe.d.ts +0 -5
  1012. package/dist/lib/probe.js +0 -40
  1013. package/dist/lib/profiles-presets.d.ts +0 -20
  1014. package/dist/lib/profiles-presets.js +1 -36
  1015. package/dist/lib/profiles.d.ts +0 -185
  1016. package/dist/lib/profiles.js +1 -158
  1017. package/dist/lib/project-doctor.d.ts +0 -29
  1018. package/dist/lib/project-doctor.js +0 -26
  1019. package/dist/lib/project-focus.d.ts +0 -41
  1020. package/dist/lib/project-focus.js +0 -49
  1021. package/dist/lib/project-import.d.ts +0 -41
  1022. package/dist/lib/project-import.js +0 -36
  1023. package/dist/lib/project-key.d.ts +0 -65
  1024. package/dist/lib/project-key.js +0 -70
  1025. package/dist/lib/project-launch.d.ts +0 -49
  1026. package/dist/lib/project-launch.js +2 -91
  1027. package/dist/lib/project-probe.d.ts +0 -86
  1028. package/dist/lib/project-probe.js +1 -88
  1029. package/dist/lib/project-pull.d.ts +0 -96
  1030. package/dist/lib/project-pull.js +0 -122
  1031. package/dist/lib/project-resources.d.ts +0 -44
  1032. package/dist/lib/project-resources.js +7 -171
  1033. package/dist/lib/project-root.d.ts +0 -95
  1034. package/dist/lib/project-root.js +0 -101
  1035. package/dist/lib/project-schedule.d.ts +0 -43
  1036. package/dist/lib/project-schedule.js +0 -52
  1037. package/dist/lib/project-status.d.ts +0 -108
  1038. package/dist/lib/project-status.js +0 -117
  1039. package/dist/lib/projects.d.ts +0 -197
  1040. package/dist/lib/projects.js +1 -213
  1041. package/dist/lib/pwsh.d.ts +0 -41
  1042. package/dist/lib/pwsh.js +0 -51
  1043. package/dist/lib/quick-todo.d.ts +84 -0
  1044. package/dist/lib/quick-todo.js +243 -0
  1045. package/dist/lib/reconcile-and-repair.d.ts +0 -78
  1046. package/dist/lib/reconcile-and-repair.js +3 -66
  1047. package/dist/lib/redact.d.ts +0 -29
  1048. package/dist/lib/redact.js +0 -54
  1049. package/dist/lib/refresh-coordinator.d.ts +0 -15
  1050. package/dist/lib/refresh-coordinator.js +0 -10
  1051. package/dist/lib/refresh.d.ts +0 -39
  1052. package/dist/lib/refresh.js +0 -45
  1053. package/dist/lib/registry.d.ts +0 -65
  1054. package/dist/lib/registry.js +0 -127
  1055. package/dist/lib/reminders.d.ts +0 -21
  1056. package/dist/lib/reminders.js +0 -30
  1057. package/dist/lib/remote-agents-json.d.ts +0 -44
  1058. package/dist/lib/remote-agents-json.js +1 -44
  1059. package/dist/lib/reserved-stores.d.ts +0 -28
  1060. package/dist/lib/reserved-stores.js +2 -28
  1061. package/dist/lib/resource-aliases.d.ts +0 -12
  1062. package/dist/lib/resource-aliases.js +0 -12
  1063. package/dist/lib/resource-content-diff.d.ts +0 -28
  1064. package/dist/lib/resource-content-diff.js +7 -34
  1065. package/dist/lib/resource-inventory.d.ts +0 -51
  1066. package/dist/lib/resource-inventory.js +0 -45
  1067. package/dist/lib/resource-patterns.d.ts +0 -32
  1068. package/dist/lib/resource-patterns.js +0 -34
  1069. package/dist/lib/resource-profiles.d.ts +0 -7
  1070. package/dist/lib/resource-profiles.js +0 -11
  1071. package/dist/lib/resources/types.d.ts +0 -50
  1072. package/dist/lib/resources/types.js +0 -7
  1073. package/dist/lib/resources/workflows.d.ts +0 -7
  1074. package/dist/lib/resources/workflows.js +0 -13
  1075. package/dist/lib/resources.d.ts +0 -65
  1076. package/dist/lib/resources.js +0 -78
  1077. package/dist/lib/routers.d.ts +0 -67
  1078. package/dist/lib/routers.js +0 -60
  1079. package/dist/lib/routine-activation.d.ts +0 -23
  1080. package/dist/lib/routine-activation.js +0 -24
  1081. package/dist/lib/routine-context.d.ts +1 -91
  1082. package/dist/lib/routine-context.js +0 -107
  1083. package/dist/lib/routine-notify-owner.d.ts +0 -79
  1084. package/dist/lib/routine-notify-owner.js +1 -103
  1085. package/dist/lib/routine-notify.d.ts +0 -70
  1086. package/dist/lib/routine-notify.js +1 -75
  1087. package/dist/lib/routine-process-cleanup.d.ts +0 -1
  1088. package/dist/lib/routine-process-cleanup.js +1 -4
  1089. package/dist/lib/routine-readiness.d.ts +0 -63
  1090. package/dist/lib/routine-readiness.js +4 -86
  1091. package/dist/lib/routines-format.d.ts +0 -40
  1092. package/dist/lib/routines-format.js +0 -67
  1093. package/dist/lib/routines-placement.d.ts +0 -33
  1094. package/dist/lib/routines-placement.js +0 -40
  1095. package/dist/lib/routines-project.d.ts +0 -57
  1096. package/dist/lib/routines-project.js +6 -80
  1097. package/dist/lib/rules/compile.d.ts +0 -66
  1098. package/dist/lib/rules/compile.js +6 -118
  1099. package/dist/lib/rules/compose.d.ts +0 -56
  1100. package/dist/lib/rules/compose.js +2 -83
  1101. package/dist/lib/rules/rules.d.ts +0 -23
  1102. package/dist/lib/rules/rules.js +0 -35
  1103. package/dist/lib/rules/run-sync.d.ts +0 -16
  1104. package/dist/lib/rules/run-sync.js +1 -44
  1105. package/dist/lib/run-config.d.ts +0 -7
  1106. package/dist/lib/run-config.js +0 -8
  1107. package/dist/lib/run-defaults.d.ts +0 -14
  1108. package/dist/lib/run-defaults.js +0 -14
  1109. package/dist/lib/run-notify.d.ts +0 -18
  1110. package/dist/lib/run-notify.js +0 -36
  1111. package/dist/lib/run-trace-sync.d.ts +0 -21
  1112. package/dist/lib/run-trace-sync.js +2 -66
  1113. package/dist/lib/rush-session.d.ts +0 -26
  1114. package/dist/lib/rush-session.js +0 -28
  1115. package/dist/lib/sandbox.d.ts +0 -45
  1116. package/dist/lib/sandbox.js +5 -93
  1117. package/dist/lib/scheduler.d.ts +0 -28
  1118. package/dist/lib/scheduler.js +0 -45
  1119. package/dist/lib/scheduling/routines.d.ts +0 -652
  1120. package/dist/lib/scheduling/routines.js +8 -475
  1121. package/dist/lib/secrets-cli.d.ts +3 -8
  1122. package/dist/lib/secrets-cli.js +1 -19
  1123. package/dist/lib/secrets-client.d.ts +0 -117
  1124. package/dist/lib/secrets-client.js +4 -275
  1125. package/dist/lib/secrets-policy.d.ts +0 -142
  1126. package/dist/lib/secrets-policy.js +4 -237
  1127. package/dist/lib/secrets-types.d.ts +0 -87
  1128. package/dist/lib/secrets-types.js +0 -13
  1129. package/dist/lib/self-heal/checks/hook-manifest.js +0 -25
  1130. package/dist/lib/self-heal/checks/hook-runtime.js +0 -5
  1131. package/dist/lib/self-heal/checks/install-staging.d.ts +0 -1
  1132. package/dist/lib/self-heal/checks/install-staging.js +1 -28
  1133. package/dist/lib/self-heal/checks/menubar-helper.js +0 -5
  1134. package/dist/lib/self-heal/checks/path.js +0 -9
  1135. package/dist/lib/self-heal/checks/resources.js +0 -5
  1136. package/dist/lib/self-heal/checks/shadowing.js +2 -16
  1137. package/dist/lib/self-heal/checks/shims.js +0 -14
  1138. package/dist/lib/self-heal/child.d.ts +12 -0
  1139. package/dist/lib/self-heal/child.js +23 -0
  1140. package/dist/lib/self-heal/registry.d.ts +0 -9
  1141. package/dist/lib/self-heal/registry.js +0 -16
  1142. package/dist/lib/self-heal/types.d.ts +0 -12
  1143. package/dist/lib/self-heal/types.js +0 -15
  1144. package/dist/lib/self-update.d.ts +0 -312
  1145. package/dist/lib/self-update.js +9 -360
  1146. package/dist/lib/service-manifest.d.ts +0 -39
  1147. package/dist/lib/service-manifest.js +0 -72
  1148. package/dist/lib/session/active.d.ts +13 -869
  1149. package/dist/lib/session/active.js +20 -976
  1150. package/dist/lib/session/actor-sidecar.d.ts +1 -32
  1151. package/dist/lib/session/actor-sidecar.js +1 -41
  1152. package/dist/lib/session/bookmarks.d.ts +0 -33
  1153. package/dist/lib/session/bookmarks.js +0 -37
  1154. package/dist/lib/session/bundle.d.ts +0 -86
  1155. package/dist/lib/session/bundle.js +0 -54
  1156. package/dist/lib/session/claude-accounts.d.ts +0 -40
  1157. package/dist/lib/session/claude-accounts.js +0 -49
  1158. package/dist/lib/session/cloud.d.ts +1 -23
  1159. package/dist/lib/session/cloud.js +0 -26
  1160. package/dist/lib/session/db.d.ts +5 -658
  1161. package/dist/lib/session/db.js +22 -1443
  1162. package/dist/lib/session/detached.d.ts +0 -21
  1163. package/dist/lib/session/detached.js +0 -29
  1164. package/dist/lib/session/discover.d.ts +3 -420
  1165. package/dist/lib/session/discover.js +30 -1123
  1166. package/dist/lib/session/fork.d.ts +1 -41
  1167. package/dist/lib/session/fork.js +0 -19
  1168. package/dist/lib/session/ghostty-tabs.d.ts +0 -24
  1169. package/dist/lib/session/ghostty-tabs.js +0 -37
  1170. package/dist/lib/session/glance-files.d.ts +19 -0
  1171. package/dist/lib/session/glance-files.js +258 -0
  1172. package/dist/lib/session/hook-sessions.d.ts +0 -33
  1173. package/dist/lib/session/hook-sessions.js +4 -99
  1174. package/dist/lib/session/host-link.d.ts +1 -94
  1175. package/dist/lib/session/host-link.js +1 -81
  1176. package/dist/lib/session/inject-target.d.ts +8 -0
  1177. package/dist/lib/session/inject-target.js +32 -0
  1178. package/dist/lib/session/inject.d.ts +0 -15
  1179. package/dist/lib/session/inject.js +0 -15
  1180. package/dist/lib/session/live-metadata.d.ts +1 -34
  1181. package/dist/lib/session/live-metadata.js +1 -73
  1182. package/dist/lib/session/local-tmux-attach.d.ts +0 -37
  1183. package/dist/lib/session/local-tmux-attach.js +1 -76
  1184. package/dist/lib/session/migrate-targets.d.ts +0 -46
  1185. package/dist/lib/session/migrate-targets.js +0 -24
  1186. package/dist/lib/session/migrations.d.ts +0 -12
  1187. package/dist/lib/session/migrations.js +1 -20
  1188. package/dist/lib/session/mirror.d.ts +0 -32
  1189. package/dist/lib/session/mirror.js +0 -77
  1190. package/dist/lib/session/origin-machine.js +0 -3
  1191. package/dist/lib/session/pid-registry.d.ts +0 -80
  1192. package/dist/lib/session/pid-registry.js +2 -81
  1193. package/dist/lib/session/presence.d.ts +0 -39
  1194. package/dist/lib/session/presence.js +2 -52
  1195. package/dist/lib/session/process-view.d.ts +0 -11
  1196. package/dist/lib/session/process-view.js +0 -25
  1197. package/dist/lib/session/projection.d.ts +0 -3
  1198. package/dist/lib/session/projection.js +0 -10
  1199. package/dist/lib/session/provenance.d.ts +1 -37
  1200. package/dist/lib/session/provenance.js +0 -69
  1201. package/dist/lib/session/recovery.d.ts +1 -40
  1202. package/dist/lib/session/recovery.js +2 -80
  1203. package/dist/lib/session/relative-time.js +0 -3
  1204. package/dist/lib/session/remote/peer-stream.d.ts +0 -42
  1205. package/dist/lib/session/remote/peer-stream.js +0 -64
  1206. package/dist/lib/session/remote/remote-bundle.d.ts +0 -6
  1207. package/dist/lib/session/remote/remote-bundle.js +0 -21
  1208. package/dist/lib/session/remote/remote-list.d.ts +1 -110
  1209. package/dist/lib/session/remote/remote-list.js +5 -139
  1210. package/dist/lib/session/remote/remote.d.ts +0 -98
  1211. package/dist/lib/session/remote/remote.js +3 -119
  1212. package/dist/lib/session/remote/watch.d.ts +1 -34
  1213. package/dist/lib/session/remote/watch.js +12 -72
  1214. package/dist/lib/session/remote-active.d.ts +0 -35
  1215. package/dist/lib/session/remote-active.js +0 -48
  1216. package/dist/lib/session/remote-bundle.js +0 -2
  1217. package/dist/lib/session/remote-list.js +0 -2
  1218. package/dist/lib/session/remote-preview-cache.d.ts +0 -7
  1219. package/dist/lib/session/remote-preview-cache.js +1 -76
  1220. package/dist/lib/session/remote.js +0 -2
  1221. package/dist/lib/session/resume-command.d.ts +0 -6
  1222. package/dist/lib/session/resume-command.js +0 -6
  1223. package/dist/lib/session/resume-owner.d.ts +1 -52
  1224. package/dist/lib/session/resume-owner.js +0 -56
  1225. package/dist/lib/session/run-names.d.ts +0 -24
  1226. package/dist/lib/session/run-names.js +0 -26
  1227. package/dist/lib/session/session-cache.d.ts +2 -146
  1228. package/dist/lib/session/session-cache.js +26 -203
  1229. package/dist/lib/session/short-id.js +0 -3
  1230. package/dist/lib/session/sync/agents.d.ts +0 -68
  1231. package/dist/lib/session/sync/agents.js +0 -0
  1232. package/dist/lib/session/sync/backend.d.ts +0 -39
  1233. package/dist/lib/session/sync/backend.js +0 -45
  1234. package/dist/lib/session/sync/config.d.ts +0 -27
  1235. package/dist/lib/session/sync/config.js +0 -56
  1236. package/dist/lib/session/sync/managed-config.d.ts +0 -17
  1237. package/dist/lib/session/sync/managed-config.js +0 -17
  1238. package/dist/lib/session/sync/managed-key.d.ts +0 -38
  1239. package/dist/lib/session/sync/managed-key.js +1 -42
  1240. package/dist/lib/session/sync/net-client.d.ts +0 -36
  1241. package/dist/lib/session/sync/net-client.js +0 -30
  1242. package/dist/lib/session/sync/provision.d.ts +0 -2
  1243. package/dist/lib/session/sync/provision.js +0 -13
  1244. package/dist/lib/session/sync/r2.d.ts +0 -20
  1245. package/dist/lib/session/sync/r2.js +0 -20
  1246. package/dist/lib/session/sync/transcript-crypto.d.ts +0 -37
  1247. package/dist/lib/session/sync/transcript-crypto.js +5 -37
  1248. package/dist/lib/session/sync/worker-template.d.ts +0 -5
  1249. package/dist/lib/session/sync/worker-template.js +0 -40
  1250. package/dist/lib/session/testdata/pid-registry-namespace.js +0 -2
  1251. package/dist/lib/session/testdata/process-view-private.js +0 -1
  1252. package/dist/lib/session/throughput.d.ts +0 -24
  1253. package/dist/lib/session/throughput.js +1 -25
  1254. package/dist/lib/session/timeline-pass.d.ts +1 -63
  1255. package/dist/lib/session/timeline-pass.js +161 -148
  1256. package/dist/lib/session/title.d.ts +0 -182
  1257. package/dist/lib/session/title.js +0 -139
  1258. package/dist/lib/session/tool-index.d.ts +2 -21
  1259. package/dist/lib/session/tool-index.js +3 -75
  1260. package/dist/lib/session/tool-store.d.ts +2 -48
  1261. package/dist/lib/session/tool-store.js +1 -33
  1262. package/dist/lib/session/viewing-in.d.ts +0 -67
  1263. package/dist/lib/session/viewing-in.js +1 -71
  1264. package/dist/lib/session/watch.js +0 -2
  1265. package/dist/lib/session/width.js +0 -3
  1266. package/dist/lib/sessions-client.d.ts +0 -46
  1267. package/dist/lib/sessions-client.js +36 -113
  1268. package/dist/lib/settings-manifest.d.ts +1 -17
  1269. package/dist/lib/settings-manifest.js +4 -57
  1270. package/dist/lib/setup-tool-install.d.ts +0 -1
  1271. package/dist/lib/setup-tool-install.js +2 -7
  1272. package/dist/lib/setup-tool-status.d.ts +0 -3
  1273. package/dist/lib/setup-tool-status.js +4 -14
  1274. package/dist/lib/sha256-asset.d.ts +0 -20
  1275. package/dist/lib/sha256-asset.js +0 -20
  1276. package/dist/lib/share-runtime.d.ts +0 -10
  1277. package/dist/lib/share-runtime.js +1 -27
  1278. package/dist/lib/shim-heal.d.ts +0 -15
  1279. package/dist/lib/shim-heal.js +3 -29
  1280. package/dist/lib/signin-badge.d.ts +0 -72
  1281. package/dist/lib/signin-badge.js +0 -86
  1282. package/dist/lib/sink-format.d.ts +0 -32
  1283. package/dist/lib/sink-format.js +0 -14
  1284. package/dist/lib/smart-launch.d.ts +0 -75
  1285. package/dist/lib/smart-launch.js +1 -83
  1286. package/dist/lib/snapshot.d.ts +0 -46
  1287. package/dist/lib/snapshot.js +5 -31
  1288. package/dist/lib/spinner.d.ts +0 -37
  1289. package/dist/lib/spinner.js +0 -37
  1290. package/dist/lib/sqlite.d.ts +0 -13
  1291. package/dist/lib/sqlite.js +3 -71
  1292. package/dist/lib/ssh-exec.d.ts +0 -209
  1293. package/dist/lib/ssh-exec.js +11 -248
  1294. package/dist/lib/ssh-tunnel.d.ts +0 -43
  1295. package/dist/lib/ssh-tunnel.js +2 -48
  1296. package/dist/lib/staleness/checkers/commands.d.ts +0 -4
  1297. package/dist/lib/staleness/checkers/commands.js +0 -4
  1298. package/dist/lib/staleness/checkers/hooks.d.ts +0 -10
  1299. package/dist/lib/staleness/checkers/hooks.js +0 -15
  1300. package/dist/lib/staleness/checkers/mcp.d.ts +0 -9
  1301. package/dist/lib/staleness/checkers/mcp.js +0 -9
  1302. package/dist/lib/staleness/checkers/permissions.d.ts +0 -12
  1303. package/dist/lib/staleness/checkers/permissions.js +0 -13
  1304. package/dist/lib/staleness/checkers/plugins.d.ts +0 -8
  1305. package/dist/lib/staleness/checkers/plugins.js +0 -8
  1306. package/dist/lib/staleness/checkers/rules.d.ts +0 -15
  1307. package/dist/lib/staleness/checkers/rules.js +0 -26
  1308. package/dist/lib/staleness/checkers/skills.d.ts +0 -4
  1309. package/dist/lib/staleness/checkers/skills.js +0 -4
  1310. package/dist/lib/staleness/checkers/subagents.d.ts +0 -9
  1311. package/dist/lib/staleness/checkers/subagents.js +0 -9
  1312. package/dist/lib/staleness/checkers/types.d.ts +0 -34
  1313. package/dist/lib/staleness/checkers/types.js +0 -19
  1314. package/dist/lib/staleness/checkers/workflows.d.ts +0 -7
  1315. package/dist/lib/staleness/checkers/workflows.js +0 -7
  1316. package/dist/lib/staleness/detectors/commands.js +0 -17
  1317. package/dist/lib/staleness/detectors/hooks.js +1 -6
  1318. package/dist/lib/staleness/detectors/mcp.js +0 -4
  1319. package/dist/lib/staleness/detectors/permissions.js +10 -23
  1320. package/dist/lib/staleness/detectors/rules.js +0 -6
  1321. package/dist/lib/staleness/detectors/skills.d.ts +0 -1
  1322. package/dist/lib/staleness/detectors/skills.js +1 -12
  1323. package/dist/lib/staleness/detectors/types.d.ts +0 -10
  1324. package/dist/lib/staleness/fingerprint.d.ts +0 -19
  1325. package/dist/lib/staleness/fingerprint.js +0 -35
  1326. package/dist/lib/staleness/index.d.ts +0 -28
  1327. package/dist/lib/staleness/index.js +1 -45
  1328. package/dist/lib/staleness/layers.d.ts +0 -23
  1329. package/dist/lib/staleness/layers.js +0 -34
  1330. package/dist/lib/staleness/prune.d.ts +0 -71
  1331. package/dist/lib/staleness/prune.js +2 -27
  1332. package/dist/lib/staleness/registry.d.ts +0 -10
  1333. package/dist/lib/staleness/registry.js +3 -33
  1334. package/dist/lib/staleness/types.d.ts +0 -36
  1335. package/dist/lib/staleness/types.js +0 -5
  1336. package/dist/lib/staleness/writers/commands.js +1 -48
  1337. package/dist/lib/staleness/writers/hooks.js +1 -18
  1338. package/dist/lib/staleness/writers/kinds.d.ts +0 -12
  1339. package/dist/lib/staleness/writers/kinds.js +0 -1
  1340. package/dist/lib/staleness/writers/lazy-map.d.ts +0 -11
  1341. package/dist/lib/staleness/writers/mcp.js +0 -13
  1342. package/dist/lib/staleness/writers/plugins.js +0 -4
  1343. package/dist/lib/staleness/writers/rules.d.ts +0 -1
  1344. package/dist/lib/staleness/writers/rules.js +1 -19
  1345. package/dist/lib/staleness/writers/skills.js +3 -14
  1346. package/dist/lib/staleness/writers/sources.d.ts +0 -11
  1347. package/dist/lib/staleness/writers/sources.js +0 -32
  1348. package/dist/lib/staleness/writers/subagents.js +0 -16
  1349. package/dist/lib/staleness/writers/types.d.ts +0 -58
  1350. package/dist/lib/staleness/writers/workflows.js +1 -1
  1351. package/dist/lib/standalone-tools.d.ts +24 -0
  1352. package/dist/lib/standalone-tools.js +58 -0
  1353. package/dist/lib/star-nudge.d.ts +0 -32
  1354. package/dist/lib/star-nudge.js +2 -36
  1355. package/dist/lib/startup/command-registry.d.ts +0 -45
  1356. package/dist/lib/startup/command-registry.js +1 -46
  1357. package/dist/lib/startup/dev-build.d.ts +0 -9
  1358. package/dist/lib/startup/dev-build.js +1 -42
  1359. package/dist/lib/startup/root-command.d.ts +0 -19
  1360. package/dist/lib/startup/root-command.js +0 -19
  1361. package/dist/lib/startup/spellcheck.d.ts +0 -13
  1362. package/dist/lib/startup/spellcheck.js +0 -13
  1363. package/dist/lib/state.d.ts +0 -376
  1364. package/dist/lib/state.js +19 -737
  1365. package/dist/lib/storage/selection.d.ts +0 -40
  1366. package/dist/lib/storage/selection.js +0 -29
  1367. package/dist/lib/subagents-registry.d.ts +0 -56
  1368. package/dist/lib/subagents-registry.js +0 -99
  1369. package/dist/lib/subagents.d.ts +0 -128
  1370. package/dist/lib/subagents.js +1 -158
  1371. package/dist/lib/summarizer/config.d.ts +0 -37
  1372. package/dist/lib/summarizer/config.js +0 -37
  1373. package/dist/lib/summarizer/pass.d.ts +0 -20
  1374. package/dist/lib/summarizer/pass.js +1 -34
  1375. package/dist/lib/summarizer/summarize.d.ts +1 -49
  1376. package/dist/lib/summarizer/summarize.js +0 -35
  1377. package/dist/lib/sync-passphrase.d.ts +0 -16
  1378. package/dist/lib/sync-passphrase.js +1 -18
  1379. package/dist/lib/sync-status.d.ts +0 -72
  1380. package/dist/lib/sync-status.js +0 -55
  1381. package/dist/lib/sync-umbrella.d.ts +0 -54
  1382. package/dist/lib/sync-umbrella.js +0 -48
  1383. package/dist/lib/system-run-sync.d.ts +0 -5
  1384. package/dist/lib/system-run-sync.js +1 -31
  1385. package/dist/lib/teams/agents.d.ts +1 -444
  1386. package/dist/lib/teams/agents.js +11 -871
  1387. package/dist/lib/teams/api.d.ts +2 -52
  1388. package/dist/lib/teams/api.js +4 -63
  1389. package/dist/lib/teams/debug.d.ts +0 -6
  1390. package/dist/lib/teams/debug.js +0 -6
  1391. package/dist/lib/teams/delivery.d.ts +0 -41
  1392. package/dist/lib/teams/delivery.js +0 -32
  1393. package/dist/lib/teams/file_ops.d.ts +0 -11
  1394. package/dist/lib/teams/file_ops.js +0 -11
  1395. package/dist/lib/teams/forEach.d.ts +0 -76
  1396. package/dist/lib/teams/forEach.js +1 -77
  1397. package/dist/lib/teams/index.d.ts +1 -7
  1398. package/dist/lib/teams/index.js +1 -7
  1399. package/dist/lib/teams/parsers.d.ts +0 -4
  1400. package/dist/lib/teams/parsers.js +0 -81
  1401. package/dist/lib/teams/persistence.d.ts +0 -2
  1402. package/dist/lib/teams/persistence.js +0 -12
  1403. package/dist/lib/teams/placement-probe.d.ts +0 -12
  1404. package/dist/lib/teams/placement-probe.js +1 -51
  1405. package/dist/lib/teams/pr-watch.d.ts +0 -107
  1406. package/dist/lib/teams/pr-watch.js +1 -107
  1407. package/dist/lib/teams/registry.d.ts +0 -36
  1408. package/dist/lib/teams/registry.js +0 -47
  1409. package/dist/lib/teams/remoteWorktree.d.ts +0 -50
  1410. package/dist/lib/teams/remoteWorktree.js +1 -96
  1411. package/dist/lib/teams/scheduler.d.ts +0 -111
  1412. package/dist/lib/teams/scheduler.js +2 -125
  1413. package/dist/lib/teams/summarizer.d.ts +0 -22
  1414. package/dist/lib/teams/summarizer.js +6 -50
  1415. package/dist/lib/teams/supervisor.d.ts +0 -38
  1416. package/dist/lib/teams/supervisor.js +0 -21
  1417. package/dist/lib/teams/worktree.d.ts +0 -95
  1418. package/dist/lib/teams/worktree.js +3 -110
  1419. package/dist/lib/template.d.ts +0 -21
  1420. package/dist/lib/template.js +0 -23
  1421. package/dist/lib/term-client.d.ts +0 -26
  1422. package/dist/lib/term-client.js +0 -48
  1423. package/dist/lib/term-driver.d.ts +0 -5
  1424. package/dist/lib/term-driver.js +0 -8
  1425. package/dist/lib/terminal/backends/ghostty.d.ts +0 -2
  1426. package/dist/lib/terminal/backends/ghostty.js +0 -12
  1427. package/dist/lib/terminal/backends/index.d.ts +0 -17
  1428. package/dist/lib/terminal/backends/index.js +0 -15
  1429. package/dist/lib/terminal/backends/iterm.d.ts +0 -2
  1430. package/dist/lib/terminal/backends/iterm.js +0 -10
  1431. package/dist/lib/terminal/backends/terminal-app.d.ts +0 -10
  1432. package/dist/lib/terminal/backends/terminal-app.js +0 -30
  1433. package/dist/lib/terminal/backends/tmux.d.ts +0 -10
  1434. package/dist/lib/terminal/backends/tmux.js +0 -2
  1435. package/dist/lib/terminal/backends/vscodium-agent.d.ts +0 -25
  1436. package/dist/lib/terminal/backends/vscodium-agent.js +0 -36
  1437. package/dist/lib/terminal/engine.d.ts +0 -17
  1438. package/dist/lib/terminal/engine.js +0 -10
  1439. package/dist/lib/terminal/index.d.ts +0 -8
  1440. package/dist/lib/terminal/inject.d.ts +1 -173
  1441. package/dist/lib/terminal/inject.js +0 -146
  1442. package/dist/lib/terminal/policy.d.ts +0 -8
  1443. package/dist/lib/terminal/policy.js +0 -1
  1444. package/dist/lib/terminal/preferred.d.ts +0 -66
  1445. package/dist/lib/terminal/preferred.js +0 -30
  1446. package/dist/lib/terminal/quote.d.ts +0 -8
  1447. package/dist/lib/terminal/quote.js +0 -8
  1448. package/dist/lib/terminal/resolve.d.ts +0 -46
  1449. package/dist/lib/terminal/resolve.js +0 -30
  1450. package/dist/lib/terminal/run-surface.d.ts +0 -56
  1451. package/dist/lib/terminal/run-surface.js +0 -46
  1452. package/dist/lib/terminal/shell.d.ts +0 -3
  1453. package/dist/lib/terminal/shell.js +0 -13
  1454. package/dist/lib/terminal/transport.d.ts +0 -14
  1455. package/dist/lib/terminal/transport.js +1 -30
  1456. package/dist/lib/terminal/types.d.ts +0 -40
  1457. package/dist/lib/terminal/types.js +0 -10
  1458. package/dist/lib/text/relative-time.d.ts +0 -36
  1459. package/dist/lib/text/relative-time.js +0 -43
  1460. package/dist/lib/text/short-id.d.ts +0 -16
  1461. package/dist/lib/text/short-id.js +0 -16
  1462. package/dist/lib/text/width.d.ts +0 -24
  1463. package/dist/lib/text/width.js +10 -52
  1464. package/dist/lib/tmux/binary.d.ts +0 -36
  1465. package/dist/lib/tmux/binary.js +0 -28
  1466. package/dist/lib/tmux/index.d.ts +0 -5
  1467. package/dist/lib/tmux/index.js +0 -5
  1468. package/dist/lib/tmux/orphan-reap.d.ts +0 -253
  1469. package/dist/lib/tmux/orphan-reap.js +3 -299
  1470. package/dist/lib/tmux/paths.d.ts +0 -14
  1471. package/dist/lib/tmux/paths.js +0 -14
  1472. package/dist/lib/tmux/session.d.ts +0 -263
  1473. package/dist/lib/tmux/session.js +6 -344
  1474. package/dist/lib/traces/backend.d.ts +0 -20
  1475. package/dist/lib/traces/backend.js +0 -23
  1476. package/dist/lib/traces/classify.d.ts +0 -20
  1477. package/dist/lib/traces/classify.js +0 -7
  1478. package/dist/lib/traces/insights.d.ts +1 -84
  1479. package/dist/lib/traces/insights.js +0 -126
  1480. package/dist/lib/traces/phenotype.d.ts +0 -69
  1481. package/dist/lib/traces/phenotype.js +0 -150
  1482. package/dist/lib/traces/provision.d.ts +0 -1
  1483. package/dist/lib/traces/provision.js +0 -5
  1484. package/dist/lib/traces/schema2-build.d.ts +3 -60
  1485. package/dist/lib/traces/schema2-build.js +8 -149
  1486. package/dist/lib/traces/schema2-danger.d.ts +0 -30
  1487. package/dist/lib/traces/schema2-danger.js +1 -63
  1488. package/dist/lib/traces/schema2.d.ts +0 -11
  1489. package/dist/lib/traces/segments.d.ts +0 -44
  1490. package/dist/lib/traces/segments.js +0 -65
  1491. package/dist/lib/traces/sync.d.ts +2 -239
  1492. package/dist/lib/traces/sync.js +15 -237
  1493. package/dist/lib/traces/worker-template.d.ts +0 -3
  1494. package/dist/lib/traces/worker-template.js +0 -29
  1495. package/dist/lib/triggers/handlers.d.ts +0 -82
  1496. package/dist/lib/triggers/handlers.js +0 -75
  1497. package/dist/lib/triggers/webhook.d.ts +0 -158
  1498. package/dist/lib/triggers/webhook.js +0 -143
  1499. package/dist/lib/types.d.ts +0 -736
  1500. package/dist/lib/types.js +0 -50
  1501. package/dist/lib/uninstall.d.ts +0 -17
  1502. package/dist/lib/uninstall.js +0 -75
  1503. package/dist/lib/usage-backoff.d.ts +0 -20
  1504. package/dist/lib/usage-backoff.js +3 -60
  1505. package/dist/lib/usage-refresh.d.ts +0 -154
  1506. package/dist/lib/usage-refresh.js +8 -212
  1507. package/dist/lib/verbs.d.ts +0 -12
  1508. package/dist/lib/verbs.js +0 -12
  1509. package/dist/lib/version-duplicates.d.ts +0 -6
  1510. package/dist/lib/version-duplicates.js +0 -6
  1511. package/dist/lib/version.d.ts +0 -55
  1512. package/dist/lib/version.js +1 -58
  1513. package/dist/lib/view-types.d.ts +0 -48
  1514. package/dist/lib/warn-unpushed.d.ts +0 -27
  1515. package/dist/lib/warn-unpushed.js +1 -45
  1516. package/dist/lib/watchdog/history.d.ts +0 -1
  1517. package/dist/lib/watchdog/history.js +0 -3
  1518. package/dist/lib/watchdog/index.js +0 -2
  1519. package/dist/lib/watchdog/log.d.ts +0 -19
  1520. package/dist/lib/watchdog/log.js +0 -34
  1521. package/dist/lib/watchdog/read.d.ts +0 -27
  1522. package/dist/lib/watchdog/read.js +3 -58
  1523. package/dist/lib/watchdog/rotate.d.ts +0 -139
  1524. package/dist/lib/watchdog/rotate.js +2 -151
  1525. package/dist/lib/watchdog/runner.d.ts +0 -125
  1526. package/dist/lib/watchdog/runner.js +3 -223
  1527. package/dist/lib/watchdog/service.d.ts +0 -1
  1528. package/dist/lib/watchdog/service.js +0 -2
  1529. package/dist/lib/watchdog/watchdog-agent.d.ts +0 -31
  1530. package/dist/lib/watchdog/watchdog-agent.js +0 -27
  1531. package/dist/lib/watchdog/watchdog.d.ts +0 -7
  1532. package/dist/lib/watchdog/watchdog.js +0 -10
  1533. package/dist/lib/watchdog/watchdogTail.js +0 -7
  1534. package/dist/lib/whats-new.d.ts +0 -10
  1535. package/dist/lib/whats-new.js +0 -21
  1536. package/dist/lib/workflows-registry.d.ts +0 -45
  1537. package/dist/lib/workflows-registry.js +0 -60
  1538. package/dist/lib/workflows.d.ts +0 -282
  1539. package/dist/lib/workflows.js +3 -213
  1540. package/dist/lib/worktree/held.d.ts +0 -89
  1541. package/dist/lib/worktree/held.js +1 -103
  1542. package/dist/lib/wrap.d.ts +0 -32
  1543. package/dist/lib/wrap.js +0 -32
  1544. package/dist/lib/yaml-io.d.ts +0 -45
  1545. package/dist/lib/yaml-io.js +0 -47
  1546. package/dist/session-tracker/dist/adapters/claude.js +0 -2
  1547. package/dist/session-tracker/dist/hook.sh +4 -37
  1548. package/dist/session-tracker/dist/index.d.ts +0 -7
  1549. package/dist/session-tracker/dist/index.js +0 -5
  1550. package/dist/session-tracker/dist/install-hook.d.ts +0 -5
  1551. package/dist/session-tracker/dist/install-hook.js +1 -15
  1552. package/dist/session-tracker/dist/prune-state.js +0 -4
  1553. package/dist/session-tracker/dist/reader.js +0 -4
  1554. package/dist/session-tracker/dist/state-file.d.ts +0 -3
  1555. package/dist/session-tracker/dist/state-file.js +3 -8
  1556. package/package.json +3 -4
  1557. package/scripts/postinstall.js +8 -116
  1558. package/dist/lib/session/artifacts.d.ts +0 -14
  1559. package/dist/lib/session/artifacts.js +0 -101
  1560. package/dist/lib/session/bash-command.d.ts +0 -63
  1561. package/dist/lib/session/bash-command.js +0 -490
  1562. package/dist/lib/session/digest.d.ts +0 -66
  1563. package/dist/lib/session/digest.js +0 -328
  1564. package/dist/lib/session/highlights.d.ts +0 -151
  1565. package/dist/lib/session/highlights.js +0 -391
  1566. package/dist/lib/session/insights.d.ts +0 -165
  1567. package/dist/lib/session/insights.js +0 -563
  1568. package/dist/lib/session/linear.d.ts +0 -19
  1569. package/dist/lib/session/linear.js +0 -99
  1570. package/dist/lib/session/parse.d.ts +0 -224
  1571. package/dist/lib/session/parse.js +0 -2408
  1572. package/dist/lib/session/prompt.d.ts +0 -213
  1573. package/dist/lib/session/prompt.js +0 -601
  1574. package/dist/lib/session/render.d.ts +0 -133
  1575. package/dist/lib/session/render.js +0 -1047
  1576. package/dist/lib/session/share-html.d.ts +0 -35
  1577. package/dist/lib/session/share-html.js +0 -319
  1578. package/dist/lib/session/shell-programs.d.ts +0 -33
  1579. package/dist/lib/session/shell-programs.js +0 -380
  1580. package/dist/lib/session/state.d.ts +0 -269
  1581. package/dist/lib/session/state.js +0 -777
  1582. package/dist/lib/session/stream-render.d.ts +0 -4
  1583. package/dist/lib/session/stream-render.js +0 -131
  1584. package/dist/lib/session/tail.d.ts +0 -88
  1585. package/dist/lib/session/tail.js +0 -294
  1586. package/dist/lib/session/team-filter.d.ts +0 -129
  1587. package/dist/lib/session/team-filter.js +0 -269
  1588. package/dist/lib/session/timeline.d.ts +0 -172
  1589. package/dist/lib/session/timeline.js +0 -636
  1590. package/dist/lib/session/tool-calls.d.ts +0 -132
  1591. package/dist/lib/session/tool-calls.js +0 -674
  1592. package/dist/lib/session/trajectory-compare.d.ts +0 -48
  1593. package/dist/lib/session/trajectory-compare.js +0 -116
  1594. package/dist/lib/session/trajectory-html.d.ts +0 -19
  1595. package/dist/lib/session/trajectory-html.js +0 -771
  1596. package/dist/lib/session/trajectory-lineage.d.ts +0 -93
  1597. package/dist/lib/session/trajectory-lineage.js +0 -195
  1598. package/dist/lib/session/trajectory-text.d.ts +0 -38
  1599. package/dist/lib/session/trajectory-text.js +0 -284
  1600. package/dist/lib/session/trajectory.d.ts +0 -145
  1601. package/dist/lib/session/trajectory.js +0 -394
  1602. package/dist/lib/session/types.d.ts +0 -627
  1603. package/dist/lib/session/types.js +0 -43
@@ -1,10 +1,3 @@
1
- /**
2
- * Agent execution command.
3
- *
4
- * Registers the `agents run` command which spawns agent CLIs interactively
5
- * or headlessly. Supports profile resolution, version rotation, secrets
6
- * injection, and multi-agent fallback chains for rate-limit resilience.
7
- */
8
1
  import { InvalidArgumentError, Option } from 'commander';
9
2
  import chalk from 'chalk';
10
3
  import { isTierToken } from '../lib/model-tiers.js';
@@ -26,28 +19,17 @@ import * as path from 'path';
26
19
  import * as os from 'os';
27
20
  import { spawnSync } from 'child_process';
28
21
  import { randomUUID } from 'crypto';
29
- import { isSessionTrackedAgent } from '../lib/session/types.js';
22
+ import { isSessionTrackedAgent } from '@phnx-labs/sessions-cli/reader';
30
23
  import { applyActiveRulesPresetAtRun } from '../lib/rules/run-sync.js';
31
24
  import { applySystemResourcesAtRun } from '../lib/system-run-sync.js';
32
25
  import { handleBroadcast } from './run-broadcast.js';
33
26
  import { bootMark } from '../lib/boot-profile.js';
34
- /** Validate a caller-supplied session id before it reaches tmux, paths, indexes, or remote dispatch. */
35
27
  export function parseExplicitSessionId(value) {
36
28
  if (!/^[A-Za-z0-9._-]+$/.test(value)) {
37
29
  throw new InvalidArgumentError('must contain only ASCII letters, digits, dots, underscores, or hyphens');
38
30
  }
39
31
  return value;
40
32
  }
41
- /**
42
- * Parse the trailing picker markers on an `agents run` agent spec. A terminal
43
- * run of `#`/`@` characters requests the account picker (`#`) and/or the
44
- * device picker (`@`) — each at most once, in either order (`claude#@`,
45
- * `claude@#`). Stripping them yields the normalized spec (`claude#work@` →
46
- * `claude#work`, version pins and `#label` account pins intact). A picker
47
- * cannot combine with an explicit pin of what it picks: `claude@2.1.218#`
48
- * (the account picker already chooses the version — the old `claude@2.1.218@`
49
- * rule), `claude#work#`, `claude@@`.
50
- */
51
33
  export function parseRunPickerMarkers(agentSpec) {
52
34
  let rest = agentSpec;
53
35
  let accountPicker = false;
@@ -80,24 +62,9 @@ export function parseRunPickerMarkers(agentSpec) {
80
62
  }
81
63
  return { accountPicker, devicePicker, normalizedAgentSpec: rest, valid: reason === undefined, reason };
82
64
  }
83
- /**
84
- * The `--device` alias family — the flags that mean "dispatch this run to another
85
- * machine over SSH". `--device` is canonical; `--on`/`--computer` are hidden
86
- * aliases. Returns the values actually given (so callers can both test presence
87
- * and read the target). Kept in ONE place because a guard that listed only a
88
- * subset silently let `--terminal --device` open a local tab and drop the remote
89
- * target — the drift this predicate exists to prevent.
90
- */
91
65
  export function hostTargetGiven(options) {
92
66
  return [options.host, options.device, options.on, options.computer].filter((v) => !!v);
93
67
  }
94
- /**
95
- * Turn a host target that names THIS machine into an explicit local pin: the
96
- * host-family flags are cleared and `local` is set, so no dispatch path
97
- * self-SSHes and the bare-interactive default (`bareInteractiveRunDefaultsToDeviceAuto`)
98
- * sees a decided placement. Returns true when the pin was applied. Pure over
99
- * the `isSelf` predicate so the rule is testable without a device registry.
100
- */
101
68
  export function pinLocalWhenTargetIsSelf(options, isSelf) {
102
69
  const targets = hostTargetGiven(options);
103
70
  if (targets.length === 0 || !targets.every(isSelf))
@@ -109,11 +76,6 @@ export function pinLocalWhenTargetIsSelf(options, isSelf) {
109
76
  options.local = true;
110
77
  return true;
111
78
  }
112
- /**
113
- * Return every option whose selection semantics conflict with an account
114
- * choice (`agent#`). Device routing is deliberately absent: the marker rides
115
- * the hop and the peer picks from ITS slots.
116
- */
117
79
  export function runAccountPickerConflicts(options) {
118
80
  const conflicts = [];
119
81
  if (options.resume !== undefined)
@@ -130,11 +92,6 @@ export function runAccountPickerConflicts(options) {
130
92
  conflicts.push(`--account ${options.account}`);
131
93
  return conflicts;
132
94
  }
133
- /**
134
- * Return every option that already decides where the run lands, so a device
135
- * choice (`agent@`) would be silently ignored: any explicit host flag, and the
136
- * lease/box paths, which own placement outright.
137
- */
138
95
  export function runDevicePickerConflicts(options) {
139
96
  const conflicts = hostTargetGiven(options).map((h) => `--device ${h}`);
140
97
  if (options.local)
@@ -145,30 +102,11 @@ export function runDevicePickerConflicts(options) {
145
102
  conflicts.push('--box');
146
103
  return conflicts;
147
104
  }
148
- /** Type guard that narrows a string to a known AgentId. */
149
105
  function isValidAgent(agent) {
150
106
  return agent in AGENTS;
151
107
  }
152
- // Reserved `<agent>` keyword for `agents run auto` — canonical definition in
153
- // lib/types.ts (shared with the host dispatch layer); re-exported here.
154
108
  export { RUN_AUTO_KEYWORD };
155
- /**
156
- * Whether `run auto` should default its host layer to the affinity pick (the
157
- * same machinery as `--device auto`). False when the caller pinned any host
158
- * flag, and false when this process was itself dispatched by a host run —
159
- * the dispatcher exports AGENTS_RUN_AUTO_HOST_RESOLVED=1 into the remote SHELL
160
- * (hosts/dispatch.ts remoteRunShellPrelude) because it already resolved the
161
- * host layer, and re-picking here would chain-hop the run across the fleet.
162
- * An INTERACTIVE dispatch of a named harness also reaches the remote as a bare
163
- * `agents run <harness>` (its argv forwards without the routing flag), so the
164
- * interactive prelude's AGENTS_REMOTE_INTERACTIVE=1 counts as "already placed"
165
- * too — without it the remote would re-place the run and ping-pong across the
166
- * fleet. Pure so the pinning matrix is unit-testable.
167
- */
168
109
  export function runAutoDefaultsToAffinity(options, env = process.env) {
169
- // An explicit local pin (--local, --where local, --device <this machine>)
170
- // is a decided host layer with an empty host set; read it here so the
171
- // `run auto` and bare-interactive defaults share one rule.
172
110
  if (options.local)
173
111
  return false;
174
112
  if (hostTargetGiven(options).length > 0)
@@ -177,27 +115,6 @@ export function runAutoDefaultsToAffinity(options, env = process.env) {
177
115
  return false;
178
116
  return env.AGENTS_REMOTE_INTERACTIVE !== '1';
179
117
  }
180
- /**
181
- * Whether a bare human-facing `agents run <harness>` — no prompt, so an
182
- * interactive TUI run — defaults its placement to `--device auto` (PHNX-4083).
183
- * A marker left off is decided for you: no `#` means balanced rotation, and no
184
- * `@` (and no other placement flag) now means automatic device placement — the
185
- * same engine as `--device auto`, whose pool never contains a box marked
186
- * `personal`. ALL of these must hold:
187
- *
188
- * - no prompt (headless runs — teams, routines, hooks, `run <agent> "…"` —
189
- * keep running in place, unchanged);
190
- * - a human-facing surface: a real TTY and no `--json`. This is the same
191
- * two-condition gate `signInLaunchDecision` uses in run-account-picker.ts —
192
- * reused here through isHumanFacingRun, not re-derived;
193
- * - no device-picker marker (`agent@` already chose the device; picking this
194
- * machine there is a plain local run);
195
- * - no `--resume` / `--lease` / `--box` / `--cloud` (those own placement);
196
- * - the host layer is unpinned and this process is not itself a dispatched
197
- * hop — delegated to runAutoDefaultsToAffinity, which encodes both.
198
- *
199
- * Pure so the default-placement matrix is unit-testable.
200
- */
201
118
  export function bareInteractiveRunDefaultsToDeviceAuto(options, run, surface, env = process.env) {
202
119
  if (run.prompt !== undefined)
203
120
  return false;
@@ -209,15 +126,6 @@ export function bareInteractiveRunDefaultsToDeviceAuto(options, run, surface, en
209
126
  return false;
210
127
  return runAutoDefaultsToAffinity(options, env);
211
128
  }
212
- /**
213
- * Whether an interactive host dispatch must mint a correlation launch id and
214
- * resolve the remote session via the launch-id join (RUSH-2034), rather than
215
- * trusting a pre-known session id. `run auto` ALWAYS joins: the harness is
216
- * picked on the remote, so an explicit --session-id is only adopted when the
217
- * pick lands on claude — pre-registering it would strand a stale session-index
218
- * entry naming an id a non-claude pick never used (RUSH-2132). Pure so the
219
- * decision matrix is unit-testable.
220
- */
221
129
  export function hostInteractiveNeedsCorrelationId(runAgent, hostSessionId, resumeId) {
222
130
  if (resumeId)
223
131
  return false;
@@ -225,70 +133,39 @@ export function hostInteractiveNeedsCorrelationId(runAgent, hostSessionId, resum
225
133
  return true;
226
134
  return !hostSessionId && isSessionTrackedAgent(runAgent);
227
135
  }
228
- /** Build a one-line banner describing which version the strategy picked. */
229
136
  function formatRotationBanner(result, verb = 'balanced') {
230
137
  const { picked, healthy, excluded } = result;
231
138
  const label = picked.email ? `${picked.email} · ${picked.agent}@${picked.version}` : `${picked.agent}@${picked.version}`;
232
139
  const ratio = `${healthy.length} of ${healthy.length + excluded.length} healthy`;
233
- // Say it when the pick was a guess. A machine whose usage refresh is failing
234
- // reports old percentages with total confidence, so a silent banner reads
235
- // identical whether the router knew the account had headroom or merely hoped
236
- // so — and the operator only finds out when the agent answers "you've hit
237
- // your weekly limit".
238
140
  const caveat = result.usageUnverified ? ', usage unverified — no account could be refreshed' : '';
239
141
  return `[agents] ${verb} picked ${label} (${ratio}${caveat})`;
240
142
  }
241
- /**
242
- * Whether `cwd` is inside a git work tree.
243
- *
244
- * `--lease` / `--box` sync the working directory to the box through crabbox,
245
- * which enumerates the files to copy with `git ls-files`. Outside a git repo
246
- * that exits 128 (`fatal: not a git repository`) and the whole run dies at
247
- * "build sync file list: exit status 128" — AFTER the box is provisioned and
248
- * billed. Checking this up front lets the caller fail fast, before provisioning.
249
- */
250
143
  export function isInsideGitWorkTree(cwd) {
251
144
  const r = spawnSync('git', ['-C', cwd, 'rev-parse', '--is-inside-work-tree'], {
252
145
  encoding: 'utf-8',
253
146
  });
254
147
  return r.status === 0 && r.stdout.trim() === 'true';
255
148
  }
256
- /** Absolute git toplevel for `cwd`, or null when it is not a git repo. */
257
149
  export function gitToplevel(cwd) {
258
150
  const r = spawnSync('git', ['-C', cwd, 'rev-parse', '--show-toplevel'], { encoding: 'utf-8' });
259
151
  return r.status === 0 ? r.stdout.trim() : null;
260
152
  }
261
- /**
262
- * Network mode for a `--lease` run (F5, RUSH-1924). `--tailscale` forces the
263
- * tailnet, `--no-tailscale` forces public, and neither (undefined) defaults to
264
- * the tailnet ONLY in a reuse context (`--reuse`, `--box`, or a picked warm
265
- * box) — a one-shot solo `--lease` stays public. Pure so it is unit-testable;
266
- * the caller downgrades to `'public'` when no auth key is configured.
267
- */
268
153
  export function computeNetMode(opts) {
269
154
  if (opts.tailscale === false)
270
- return 'public'; // --no-tailscale wins
155
+ return 'public';
271
156
  if (opts.tailscale === true)
272
- return 'tailscale'; // explicit --tailscale
157
+ return 'tailscale';
273
158
  return opts.reuseContext ? 'tailscale' : 'public';
274
159
  }
275
- // ── "Always provision fresh" per-repo memory (F3, RUSH-1922) ─────────────────
276
- // The picker's "Always provision fresh (remember for this repo)" choice is
277
- // persisted as a list of git-toplevel paths in a small state file, so a repo
278
- // that opted out of the reuse picker is never prompted again.
279
- /** True when `repoRoot` is in the remembered always-fresh set. Pure. */
280
160
  export function isAlwaysFreshRepo(repos, repoRoot) {
281
161
  return repos.includes(repoRoot);
282
162
  }
283
- /** Add `repoRoot` to the always-fresh set (idempotent). Pure. */
284
163
  export function addAlwaysFreshRepo(repos, repoRoot) {
285
164
  return repos.includes(repoRoot) ? repos : [...repos, repoRoot];
286
165
  }
287
- /** Path to the always-fresh state file under the USER agents dir (CLI-written per-user preference, never the maintainer-owned `.system` repo). */
288
166
  export function leaseFreshReposPath() {
289
167
  return path.join(getUserAgentsDir(), 'lease-fresh-repos.json');
290
168
  }
291
- /** Read the remembered always-fresh repo roots (empty on any read/parse error). */
292
169
  export function readAlwaysFreshRepos() {
293
170
  try {
294
171
  const parsed = JSON.parse(fs.readFileSync(leaseFreshReposPath(), 'utf-8'));
@@ -298,7 +175,6 @@ export function readAlwaysFreshRepos() {
298
175
  return [];
299
176
  }
300
177
  }
301
- /** Persist the always-fresh repo roots. Best-effort — never throws. */
302
178
  export function writeAlwaysFreshRepos(repos) {
303
179
  try {
304
180
  const p = leaseFreshReposPath();
@@ -306,26 +182,13 @@ export function writeAlwaysFreshRepos(repos) {
306
182
  fs.writeFileSync(p, JSON.stringify(repos, null, 2));
307
183
  }
308
184
  catch {
309
- /* best-effort — losing the preference just means the picker shows next time */
310
185
  }
311
186
  }
312
- /**
313
- * Build the LoopConfig the driver consumes from CLI flags and/or a workflow's
314
- * `loop:` frontmatter block (issue #332). Returns undefined when neither source
315
- * activates a loop (the common single-shot run). CLI flags take precedence over
316
- * the workflow's declared values field-by-field, so `--max-iterations 5`
317
- * overrides a workflow's `max_iterations: 3`.
318
- *
319
- * `--loop` with no sub-options is a valid bare loop (driver applies its own
320
- * maxIterations safety cap). A workflow `loop:` block activates a loop even
321
- * without `--loop` so `agents run <workflow>` honors a declared loop.
322
- */
323
187
  export function buildLoopConfig(flags, workflowLoop) {
324
188
  const active = flags.loop === true || workflowLoop !== undefined;
325
189
  if (!active)
326
190
  return undefined;
327
191
  const cfg = {};
328
- // until: CLI > workflow. Only `signal` is supported.
329
192
  const until = flags.until ?? workflowLoop?.until;
330
193
  if (until !== undefined) {
331
194
  if (until !== 'signal') {
@@ -333,7 +196,6 @@ export function buildLoopConfig(flags, workflowLoop) {
333
196
  }
334
197
  cfg.until = 'signal';
335
198
  }
336
- // max_iterations: CLI > workflow.
337
199
  if (flags.maxIterations !== undefined) {
338
200
  const n = Number(flags.maxIterations);
339
201
  if (!Number.isInteger(n) || n <= 0) {
@@ -344,7 +206,6 @@ export function buildLoopConfig(flags, workflowLoop) {
344
206
  else if (workflowLoop?.max_iterations !== undefined) {
345
207
  cfg.maxIterations = workflowLoop.max_iterations;
346
208
  }
347
- // budget (tokens): CLI > workflow.
348
209
  if (flags.budget !== undefined) {
349
210
  const b = Number(flags.budget);
350
211
  if (!Number.isFinite(b) || b <= 0) {
@@ -355,9 +216,6 @@ export function buildLoopConfig(flags, workflowLoop) {
355
216
  else if (workflowLoop?.budget !== undefined) {
356
217
  cfg.budget = workflowLoop.budget;
357
218
  }
358
- // interval: CLI > workflow. Validate eagerly — an unparseable interval
359
- // (e.g. "30s", "5", "abc") must be rejected here, not silently coalesced to
360
- // 0ms (back-to-back) at run time. "0" is the one accepted non-duration value.
361
219
  const interval = flags.interval ?? workflowLoop?.interval;
362
220
  if (interval !== undefined) {
363
221
  try {
@@ -370,35 +228,21 @@ export function buildLoopConfig(flags, workflowLoop) {
370
228
  }
371
229
  return cfg;
372
230
  }
373
- /** Map a loop stop reason to a process exit code. condition-met/max are clean exits. */
374
231
  export function loopExitCode(stoppedBy) {
375
232
  switch (stoppedBy) {
376
233
  case 'condition-met':
377
234
  case 'max':
378
235
  return 0;
379
236
  case 'budget':
380
- return 7; // mirrors BUDGET_KILL_EXIT_CODE so CI can tell a budget stop apart
237
+ return 7;
381
238
  case 'signal':
382
- return 130; // 128 + SIGINT(2)
239
+ return 130;
383
240
  case 'stalled':
384
241
  case 'error':
385
242
  default:
386
243
  return 1;
387
244
  }
388
245
  }
389
- /**
390
- * Drive a workflow's declarative `for_each:` fan-out end-to-end (issue #343).
391
- *
392
- * Runs the producer, expands one stage teammate per produced item (respecting
393
- * `max_items` / `DEFAULT_FOR_EACH_CAP`, surfacing any truncation — never a
394
- * silent cap), stages them into a fresh team via the existing `runForEach`
395
- * bridge, then drives the teams supervisor until the DAG drains. When a verify
396
- * panel is declared, tallies each item's `keep_if` gate from the skeptics'
397
- * terminal status and logs which items survived.
398
- *
399
- * Reuses the teams substrate wholesale — no new orchestration engine. Returns
400
- * the process exit code (0 on drain, 1 on producer failure / non-drain).
401
- */
402
246
  export async function runWorkflowForEach(spec, opts) {
403
247
  const [{ produceItems, runForEach, tallyForEach }, { expandForEach, DEFAULT_FOR_EACH_CAP }, { AgentManager }, { createTeam }, { runSupervisor }, { ALL_AGENT_IDS }] = await Promise.all([
404
248
  import('../lib/teams/forEach.js'),
@@ -408,9 +252,6 @@ export async function runWorkflowForEach(spec, opts) {
408
252
  import('../lib/teams/supervisor.js'),
409
253
  import('../lib/agents.js'),
410
254
  ]);
411
- // The teams substrate spawns teammates as a real harness. When `agent:` names
412
- // a known harness id, honor it; otherwise fall back to claude (the workflow
413
- // harness) so a subagent-style name in `agent:` still runs.
414
255
  const isHarness = (a) => ALL_AGENT_IDS.includes(a);
415
256
  const runSpec = {
416
257
  ...spec,
@@ -422,7 +263,6 @@ export async function runWorkflowForEach(spec, opts) {
422
263
  if (runSpec.agent !== spec.agent) {
423
264
  process.stderr.write(chalk.gray(`[for_each] '${spec.agent}' is not a harness id — staging stage teammates as claude\n`));
424
265
  }
425
- // 1. Producer: run the shell command (or resolve itemsRef) into the item list.
426
266
  let items;
427
267
  try {
428
268
  items = await produceItems(runSpec, { cwd: opts.cwd });
@@ -435,14 +275,12 @@ export async function runWorkflowForEach(spec, opts) {
435
275
  process.stderr.write(chalk.yellow('[for_each] producer emitted no items — nothing to fan out.\n'));
436
276
  return 0;
437
277
  }
438
- // 2. Cap accounting (surfaced, never silent — acceptance criterion in #343).
439
278
  const cap = runSpec.max_items ?? DEFAULT_FOR_EACH_CAP;
440
279
  const { truncated } = expandForEach(runSpec, items);
441
280
  if (truncated > 0) {
442
281
  process.stderr.write(chalk.yellow(`[for_each] producer emitted ${items.length} items; capping at ${cap} (${truncated} dropped). Raise \`max_items\` to fan out more.\n`));
443
282
  }
444
283
  process.stderr.write(chalk.gray(`[for_each] ${Math.min(items.length, cap)} stage teammate(s) from ${items.length} produced item(s)\n`));
445
- // 3. Stage the expanded teammates into a fresh team via the existing bridge.
446
284
  const team = `foreach-${opts.workflowName.replace(/[^a-zA-Z0-9_-]/g, '-')}-${Date.now().toString(36)}`;
447
285
  await createTeam(team, { description: `for_each fan-out from workflow '${opts.workflowName}'` });
448
286
  const mgr = new AgentManager();
@@ -451,8 +289,6 @@ export async function runWorkflowForEach(spec, opts) {
451
289
  effort: opts.effort,
452
290
  concurrency: runSpec.concurrency,
453
291
  });
454
- // 4. Drive the supervisor until the DAG drains (the same loop `teams start
455
- // --watch` uses; it absorbs the staged teammates via rescanFromDisk).
456
292
  const result = await runSupervisor(mgr, {
457
293
  team,
458
294
  onWave: (s) => {
@@ -460,8 +296,6 @@ export async function runWorkflowForEach(spec, opts) {
460
296
  process.stderr.write(`[${ts}] [for_each] wave ${s.wave} launched=${s.launched.length} running=${s.running} pending=${s.pending} done=${s.completed} failed=${s.failed}\n`);
461
297
  },
462
298
  });
463
- // 5. keep_if tally: a skeptic that COMPLETED is a keep vote; a failed skeptic
464
- // votes to drop. Gate each item and report which survived.
465
299
  if (runSpec.verify) {
466
300
  const loaded = await mgr.listByTask(team);
467
301
  const statusByName = new Map(loaded.map((a) => [a.name, a.status]));
@@ -480,19 +314,6 @@ export async function runWorkflowForEach(spec, opts) {
480
314
  process.stderr.write(chalk.yellow(`[for_each] stopped by ${result.stoppedBy} after ${result.waves} waves. Team: ${team}\n`));
481
315
  return 1;
482
316
  }
483
- /**
484
- * The run's working directory from `--cwd` / `--project`. `--project <slug>` owns
485
- * the directory and is mutually exclusive with `--cwd`/`--remote-cwd`; both the
486
- * main dispatch and the `--terminal` handoff need the same answer, so the rule
487
- * and its error live here once instead of in two places that can drift.
488
- *
489
- * A project that binds several directories also contributes the ones it is not
490
- * landing in as `--add-dir` grants, so an agent on a multi-repo project can
491
- * actually reach the sibling checkouts. Claude / Cursor / Kimi take the native
492
- * flag; Codex folds them into workspace_roots; Grok widens its sandbox profile
493
- * (and always injects a rules note). Other harnesses have no multi-root surface
494
- * and ignore the grants (cwd only).
495
- */
496
317
  export async function resolveRunCwd(options, opts) {
497
318
  if (!options.project) {
498
319
  if (!options.cwd || opts.forRemote)
@@ -509,8 +330,6 @@ export async function resolveRunCwd(options, opts) {
509
330
  const { cwd, extraDirs } = await resolveProjectDirs(options.project, {
510
331
  forRemote: opts.forRemote,
511
332
  });
512
- // Explicit --add-dir values keep their position; a directory the project
513
- // already contributes is not passed twice.
514
333
  if (extraDirs.length > 0) {
515
334
  const seen = new Set(options.addDir ?? []);
516
335
  options.addDir = [...(options.addDir ?? []), ...extraDirs.filter((d) => !seen.has(d))];
@@ -522,15 +341,6 @@ export async function resolveRunCwd(options, opts) {
522
341
  process.exit(1);
523
342
  }
524
343
  }
525
- /**
526
- * `--terminal`: hand this run to a real terminal tab and exit.
527
- *
528
- * The terminal is detected from the user's live sessions, so a run started from
529
- * a surface that cannot host a TUI (the menu bar's "New Session", a script) lands
530
- * in the terminal they actually work in instead of a hardcoded Terminal.app.
531
- * Exits non-zero when no terminal could be opened — the caller must not believe
532
- * a session started when none did.
533
- */
534
344
  async function handleTerminalHandoff(agentSpec, options, prompt) {
535
345
  const { parseTerminalFlag, openRunInTerminal, toHostSamples, currentContext } = await import('../lib/terminal/index.js');
536
346
  const parsed = parseTerminalFlag(options.terminal);
@@ -538,14 +348,6 @@ async function handleTerminalHandoff(agentSpec, options, prompt) {
538
348
  console.error(chalk.red(parsed.error));
539
349
  process.exit(1);
540
350
  }
541
- // Reject an unrunnable target HERE, where the person can read it. The tab would
542
- // otherwise open, print the same error, and close — the failure lands in a
543
- // window that is gone before it can be read, which reads as "nothing happened".
544
- //
545
- // `agents run <thing>` takes an agent id, a PROFILE, or a WORKFLOW (see the
546
- // isValidAgent / profileExists / resolveWorkflowRef chain below), so this must
547
- // accept all three. Gating on the agent table alone rejected every profile —
548
- // the whole Kimi/DeepSeek/Qwen/GLM path — for `--terminal` runs only.
549
351
  const rawTarget = parseRunPickerMarkers(agentSpec).normalizedAgentSpec.split('#')[0].split('@')[0];
550
352
  const knownAgent = resolveAgentName(rawTarget);
551
353
  const [{ profileExists }, { resolveWorkflowRef }] = await Promise.all([
@@ -564,30 +366,16 @@ async function handleTerminalHandoff(agentSpec, options, prompt) {
564
366
  process.exit(1);
565
367
  }
566
368
  }
567
- // --device and its aliases (--on/--computer) all mean "dispatch this
568
- // run to another machine over SSH", which is incompatible with opening a
569
- // terminal tab on THIS machine — so reject the whole alias family, not just
570
- // the canonical flag. The rule and its wording live once, in the --device
571
- // forwarding table, so the classification a reviewer reads and the error a
572
- // user sees can't drift.
573
369
  if (hostTargetGiven(options).length) {
574
370
  const { RUN_OPTION_REJECT_MESSAGES } = await import('../lib/hosts/remote-cmd.js');
575
371
  console.error(chalk.red(RUN_OPTION_REJECT_MESSAGES.terminal));
576
372
  process.exit(1);
577
373
  }
578
- // Machine-readable output would land in the tab, where the caller that asked
579
- // for it can never read it. Same class of failure as --device: refuse, don't
580
- // hand back a stream that goes nowhere.
581
374
  const streamFlag = options.json ? '--json' : options.emitSessionId ? '--emit-session-id' : undefined;
582
375
  if (streamFlag) {
583
376
  console.error(chalk.red(`${streamFlag} streams to stdout, but --terminal moves the run into a tab where you cannot read it. Drop one.`));
584
377
  process.exit(1);
585
378
  }
586
- // `--project` owns the working directory, but the main action resolves it far
587
- // below this handoff — so without this the tab would open in THIS process's
588
- // cwd (launchd's `/` for a menu-bar click) while the run inside it moved to
589
- // the project. `forRemote: false` because --terminal is always local (--device
590
- // is rejected above).
591
379
  const cwd = await resolveRunCwd(options, { forRemote: false });
592
380
  const { getActiveSessions } = await import('../lib/session/active.js');
593
381
  let sessions = [];
@@ -595,8 +383,6 @@ async function handleTerminalHandoff(agentSpec, options, prompt) {
595
383
  sessions = await toHostSamples(await getActiveSessions());
596
384
  }
597
385
  catch {
598
- // Detection is best-effort — an unreadable session index must not block the
599
- // launch; resolution falls through to the available-backend floor.
600
386
  }
601
387
  const result = await openRunInTerminal({
602
388
  argv: process.argv.slice(2),
@@ -615,7 +401,6 @@ async function handleTerminalHandoff(agentSpec, options, prompt) {
615
401
  console.log(chalk.gray(`Opened the ${what} in ${result.description}.`));
616
402
  }
617
403
  }
618
- /** Register the `agents run <agent> [prompt]` command. */
619
404
  export function registerRunCommand(program) {
620
405
  const runCmd = program
621
406
  .command('run [agent] [prompt]')
@@ -684,19 +469,9 @@ export function registerRunCommand(program) {
684
469
  .option('--repo <owner/repo>', 'With --cloud: GitHub repository. Repeatable for multi-repo dispatch (Rush Cloud only).', (val, prev) => [...prev, val], [])
685
470
  .option('--branch <name>', 'With --cloud: target git branch.')
686
471
  .option('--cloud-env <id>', 'With --cloud: Codex Cloud environment ID (run\'s --env is the KEY=VAL passthrough, so the cloud env id gets its own flag).');
687
- // `--on` and `--computer` are hidden aliases of `--device` — same behavior.
688
472
  runCmd.addOption(new Option('--on <name>', 'Alias of --device.').hideHelp());
689
473
  runCmd.addOption(new Option('--computer <name>', 'Alias of --device.').hideHelp());
690
- // Internal: the `--device` dispatch forwards this so the REMOTE run prints its
691
- // resolved session id as a one-line stdout sentinel (hosts/session-marker.ts),
692
- // letting the launcher relate the remote-created session back to itself for
693
- // every agent — not just Claude, whose id it forces up front.
694
474
  runCmd.addOption(new Option('--emit-session-id', 'internal: print the resolved session id for a --device launcher to capture').hideHelp());
695
- // Required for the documented `agents run <agent> [prompt] -- <native flags>`
696
- // passthrough: commander >=13 rejects excess operands by default, so any
697
- // post-`--` token died with "too many arguments" before the action ran. The
698
- // action re-derives the `--` boundary from rawArgs and still errors on excess
699
- // operands that are NOT behind `--`.
700
475
  runCmd.allowExcessArguments(true);
701
476
  setHelpSections(runCmd, {
702
477
  examples: `
@@ -841,12 +616,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
841
616
  });
842
617
  runCmd.action(async (agentSpec, prompt, options, command) => {
843
618
  bootMark('run-action:enter');
844
- // Capture everything after -- as passthrough args forwarded verbatim to the
845
- // underlying CLI. Commander strips the literal `--` and folds what follows
846
- // into the positional operands (so `agents run codex -- --yolo` would parse
847
- // `--yolo` as the PROMPT) — recover the boundary from rawArgs instead of
848
- // operand counts. Excess operands not behind `--` are still an error (an
849
- // unquoted prompt must not silently become agent flags).
850
619
  const rawArgs = process.argv;
851
620
  const separatorIdx = rawArgs.indexOf('--');
852
621
  const passthroughArgs = separatorIdx === -1 ? [] : rawArgs.slice(separatorIdx + 1);
@@ -856,12 +625,8 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
856
625
  process.exit(1);
857
626
  }
858
627
  if (prompt !== undefined && operandsBeforeSeparator < 2) {
859
- // The token commander assigned to [prompt] came from behind `--` — it is
860
- // a native flag, not a prompt. Run interactively.
861
628
  prompt = undefined;
862
629
  }
863
- // Broadcast matrix (formerly `agents bench`): list/results/run cells, then exit.
864
- // --broadcast is local-only fan-out — it is mutually exclusive with --host/--device.
865
630
  if (options.broadcast || options.listTasks || options.results !== undefined) {
866
631
  const whereIsRemote = typeof options.where === 'string' && options.where.trim().toLowerCase() !== 'local';
867
632
  if (hostTargetGiven(options).length > 0 || whereIsRemote) {
@@ -891,9 +656,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
891
656
  console.error(chalk.red("Missing required argument 'agent'. Example: agents run claude \"hello\"."));
892
657
  process.exit(1);
893
658
  }
894
- // --cloud: vendor cloud placement. Validate BEFORE the terminal handoff
895
- // and every local dispatch path — flags like --terminal/--loop/--resume
896
- // belong to the local runner and must error, never ride along silently.
897
659
  if (options.cloud || (typeof options.where === 'string' && /^cloud(:|$)/i.test(options.where.trim()))) {
898
660
  const { runCloudConflicts } = await import('./run-cloud.js');
899
661
  const conflicts = runCloudConflicts(options);
@@ -902,25 +664,14 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
902
664
  process.exit(1);
903
665
  }
904
666
  }
905
- // --terminal: this process can't host the TUI (a menu-bar click, a script),
906
- // so hand the run to a real terminal and exit. Resolved from the user's own
907
- // live sessions, so it opens where they already work. Done before every
908
- // other dispatch path because the tab re-runs this same argv without the
909
- // flag — arming --notify or picking a version here would happen twice.
910
667
  if (options.terminal) {
911
668
  await handleTerminalHandoff(agentSpec, options, prompt);
912
669
  return;
913
670
  }
914
- // Placement: --where expands into --device / --lease / --cloud before any
915
- // dispatch. One door for "where does the body run?" — old flags remain
916
- // aliases. See lib/placement.ts and docs/concepts.md#placement.
917
671
  {
918
672
  const { placementFromRunFlags, expandPlacementToRunFlags, PlacementError } = await import('../lib/placement.js');
919
673
  try {
920
674
  const placement = placementFromRunFlags(options);
921
- // An explicit local placement (--local, --where local) must outlive
922
- // this block: expansion yields no host flag, and the bare-interactive
923
- // default below reads an empty host set as "decide for me".
924
675
  if (placement.kind === 'local' && placement.source !== 'default')
925
676
  options.local = true;
926
677
  if (options.where) {
@@ -937,8 +688,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
937
688
  options.cloud = expanded.cloud;
938
689
  if (expanded.provider !== undefined)
939
690
  options.provider = expanded.provider;
940
- // Clear the where flag so remote re-entry (host dispatch) does not
941
- // re-expand and conflict with the concrete host we just set.
942
691
  options.where = undefined;
943
692
  }
944
693
  }
@@ -950,17 +699,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
950
699
  throw err;
951
700
  }
952
701
  }
953
- // --device naming this machine (short id, MagicDNS name, loopback, or the
954
- // `interactive` sentinel pinned here) is a local run, not a self-SSH: the
955
- // hop probes its own login shell and times out under load. Pinned here,
956
- // ahead of every placement gate, so the bare-interactive default sees an
957
- // explicit local choice rather than an empty host set.
958
702
  {
959
703
  const { isSelfHost } = await import('../lib/devices/self-host.js');
960
704
  const { isDeviceInteractive, resolveInteractiveDevice } = await import('../lib/devices/interactive-host.js');
961
705
  pinLocalWhenTargetIsSelf(options, (name) => isSelfHost(isDeviceInteractive(name) ? resolveInteractiveDevice() ?? name : name));
962
706
  }
963
- // Cloud refinement flags without the placement are a typo, not a no-op.
964
707
  if (!options.cloud) {
965
708
  const { cloudFlagsWithoutCloud } = await import('./run-cloud.js');
966
709
  const stray = cloudFlagsWithoutCloud(options);
@@ -969,17 +712,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
969
712
  process.exit(1);
970
713
  }
971
714
  }
972
- // --cloud: dispatch through the cloud provider registry and return — the
973
- // run never touches the local/host/lease paths below.
974
715
  if (options.cloud) {
975
716
  const { handleRunCloud } = await import('./run-cloud.js');
976
717
  await handleRunCloud(agentSpec, prompt, options, command);
977
718
  return;
978
719
  }
979
- // --notify: post a desktop notification when this run finishes. Armed on
980
- // process exit so it covers EVERY dispatch path below (local, --device,
981
- // --lease, the error path) instead of one branch. Only for headless runs
982
- // — an interactive run ends in front of the person who started it.
983
720
  if (options.notify && prompt !== undefined) {
984
721
  const { armRunFinishNotification } = await import('../lib/run-notify.js');
985
722
  armRunFinishNotification({
@@ -990,11 +727,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
990
727
  host: options.host,
991
728
  });
992
729
  }
993
- // Trailing picker markers request an interactive choice: `#` picks the
994
- // account (and the version it signs in with), `@` picks the device, and
995
- // `#@`/`@#` ask both. Strip only those terminal markers; concrete
996
- // agent@version pins and `#label` account pins retain their meaning in
997
- // every dispatch path below.
998
730
  const pickerMarkers = parseRunPickerMarkers(agentSpec);
999
731
  const accountPickerRequested = pickerMarkers.accountPicker;
1000
732
  const devicePickerRequested = pickerMarkers.devicePicker;
@@ -1005,10 +737,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1005
737
  'Use agents run <agent># to pick an account, <agent>@ to pick a device, <agent>#@ for both.'));
1006
738
  process.exit(1);
1007
739
  }
1008
- // Peel `#name` off before --device dispatch so the selector rides the hop
1009
- // unchanged and the peer resolves ITS slot (PHNX-3940 T5). The later local
1010
- // parse is idempotent when the values match. A bare trailing `#` was the
1011
- // picker marker above, so it can never land here as an empty label.
1012
740
  {
1013
741
  const labelParts = normalizedAgentSpec.split('#');
1014
742
  if (labelParts.length > 2 || labelParts[1] === '') {
@@ -1023,8 +751,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1023
751
  if (specAccountLabel)
1024
752
  options.account = specAccountLabel;
1025
753
  }
1026
- // Bare resume is a session selection request, before fresh-run defaults or placement.
1027
- // Concrete IDs re-enter the executor below, so this cannot recurse.
1028
754
  if (options.resume === true || options.resume === '') {
1029
755
  if (options.sessionId || options.loop || options.fallback || options.resumeCheckpoint || options.lease) {
1030
756
  throw new Error('--resume cannot be combined with --session-id, --loop, --fallback, --resume-checkpoint, or --lease.');
@@ -1046,7 +772,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1046
772
  });
1047
773
  return;
1048
774
  }
1049
- // Hard-deprecated harnesses cannot be run — point the user at the successor.
1050
775
  const runBaseAgentName = normalizedAgentSpec.split('#')[0].split('@')[0];
1051
776
  const runBaseAgentId = resolveAgentName(runBaseAgentName);
1052
777
  const { profileExists: runProfileExists } = await import('../lib/profiles.js');
@@ -1054,9 +779,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1054
779
  console.error(chalk.red(hardDeprecationError(runBaseAgentId)));
1055
780
  process.exit(1);
1056
781
  }
1057
- // Picker conflict checks run BEFORE --resume/--device auto may place the
1058
- // run implicitly, so an implied placement never surfaces as a fake
1059
- // "cannot be combined with --device" when the user only typed a marker.
1060
782
  if (accountPickerRequested) {
1061
783
  const conflicts = runAccountPickerConflicts(options);
1062
784
  if (conflicts.length > 0) {
@@ -1073,8 +795,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1073
795
  process.exit(1);
1074
796
  }
1075
797
  }
1076
- // `agents run auto`: the reserved harness keyword — full-auto dispatch
1077
- // (host affinity → cross-harness balance → account balance, RUSH-2132).
1078
798
  if (normalizedAgentSpec.split('#')[0].split('@')[0] === RUN_AUTO_KEYWORD && normalizedAgentSpec !== RUN_AUTO_KEYWORD) {
1079
799
  console.error(chalk.red(`agents run auto picks the harness itself — a @version pin does not apply. ` +
1080
800
  `Pin a concrete harness instead: agents run <harness>@<version>.`));
@@ -1083,10 +803,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1083
803
  let autoHarnessRequested = normalizedAgentSpec === RUN_AUTO_KEYWORD;
1084
804
  let resolvedResumeSource;
1085
805
  let resolvedRecoveryTarget;
1086
- // Concrete resume ids resolve BEFORE placement. Full UUIDs take the local
1087
- // SQLite fast path; only a local miss fans out to the fleet. This lets a
1088
- // command entered on zion discover that the owning version-home is on a
1089
- // worker, while a command entered on that worker never pays for SSH.
1090
806
  if (typeof options.resume === 'string' && options.resume.trim()) {
1091
807
  const selector = options.resume.trim();
1092
808
  const injectedSource = (() => {
@@ -1103,10 +819,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1103
819
  ? { kind: 'resolved', session: injectedSource }
1104
820
  : await (await import('./sessions.js')).resolveSessionMetadataValue(selector, { agent: runBaseAgentId ?? undefined });
1105
821
  if (outcome.kind === 'partial') {
1106
- // RUSH-2492: an unreachable peer is a warning, not a hard failure. The
1107
- // resolver already resolves an id found on the reachable fleet (SES-9a),
1108
- // so reaching here means the session was not found on any device we
1109
- // COULD reach — it may live on an unreachable peer we could not check.
1110
822
  const offline = outcome.failedPeers;
1111
823
  console.error(chalk.yellow(`Warning: ${offline.length} device(s) unreachable, not checked: ${offline.join(', ')}`));
1112
824
  console.error(chalk.red(`No session matching "${selector}" on any reachable device (${offline.length} unreachable, not checked).`));
@@ -1128,9 +840,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1128
840
  `Use: agents sessions resume ${resolvedResumeSource.id}`));
1129
841
  process.exit(1);
1130
842
  }
1131
- // Omitted --mode inherits the effective source mode. Commander keeps
1132
- // the normal new-run default as a real value, so consult its provenance
1133
- // rather than mistaking the default for an explicit override.
1134
843
  if (command.getOptionValueSource('mode') === 'default') {
1135
844
  if (resolvedResumeSource.mode) {
1136
845
  options.mode = resolvedResumeSource.mode;
@@ -1152,10 +861,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1152
861
  `the requested device was ${hostTargetGiven(options).join(', ') || 'this machine'}.`));
1153
862
  process.exit(1);
1154
863
  }
1155
- // Recovery is resolved on the device that owns the transcript. A remote
1156
- // dispatch is pinned to the source HARNESS (not `run auto`'s cross-harness
1157
- // picker); the peer repeats this block with the injected SessionMeta and
1158
- // chooses its own healthy version. Locally, resolve it now.
1159
864
  const sourceAgent = resolvedResumeSource.agent;
1160
865
  if (!sourcePeer) {
1161
866
  try {
@@ -1177,8 +882,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1177
882
  }
1178
883
  }
1179
884
  if (autoHarnessRequested) {
1180
- // `auto` is reserved. If a future harness registers that id, the
1181
- // keyword collides — fail loud rather than silently shadow the harness.
1182
885
  if (RUN_AUTO_KEYWORD in AGENTS) {
1183
886
  console.error(chalk.red(`'${RUN_AUTO_KEYWORD}' is now a registered harness and collides with the reserved 'run auto' keyword. ` +
1184
887
  `Run the harness by name instead.`));
@@ -1192,21 +895,9 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1192
895
  console.error(chalk.red(`agents run auto picks the harness and its placement itself — the trailing-@ device picker needs a concrete harness (agents run <harness>@).`));
1193
896
  process.exit(1);
1194
897
  }
1195
- // Host layer: with no explicit --device, default to the
1196
- // affinity pick. Skipped on a device-dispatched run — its dispatcher
1197
- // already resolved this layer (see runAutoDefaultsToAffinity).
1198
898
  if (!resolvedResumeSource && runAutoDefaultsToAffinity(options))
1199
899
  options.device = 'auto';
1200
900
  }
1201
- // The picker menus run HERE — after every conflict check, before
1202
- // placement resolves — so the picked account labels the device rows and
1203
- // the picked device is concrete for every host branch below.
1204
- // `#@`/`@#`: account first, against THIS machine's slots; the picked
1205
- // account becomes options.account and the device menu shows its
1206
- // ✓/– per-device mark. A remote device pick dispatches with
1207
- // `<agent>#<label>` so the peer resolves its own slot.
1208
- // `@`: just the device menu; picking this machine is a plain local run.
1209
- // Either menu cancelled (Esc/Ctrl-C) launches nothing and exits 0.
1210
901
  let upFrontAccountPick = null;
1211
902
  if (accountPickerRequested && devicePickerRequested) {
1212
903
  const baseName = normalizedAgentSpec.split('#')[0].split('@')[0];
@@ -1227,7 +918,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1227
918
  const { pickRunAccountCandidate } = await import('./run-account-picker.js');
1228
919
  const selected = await pickRunAccountCandidate(baseAgentId);
1229
920
  if (!selected)
1230
- return; // Esc/Ctrl-C: launch nothing.
921
+ return;
1231
922
  if (selected.nativeAccount)
1232
923
  options.account = selected.nativeAccount;
1233
924
  upFrontAccountPick = selected;
@@ -1237,8 +928,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1237
928
  }
1238
929
  }
1239
930
  if (devicePickerRequested) {
1240
- // --resume above may have pinned the host implicitly (recovery to the
1241
- // source peer); a device menu against it would be a silent no-op.
1242
931
  const impliedHost = hostTargetGiven(options);
1243
932
  if (impliedHost.length > 0) {
1244
933
  console.error(chalk.red(`Device selection with ${agentSpec} cannot be combined with the placement --resume already chose (${impliedHost.join(', ')}). ` +
@@ -1252,39 +941,26 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1252
941
  accountLabel: options.account,
1253
942
  });
1254
943
  if (pickedDevice === null)
1255
- return; // Esc/Ctrl-C: launch nothing.
944
+ return;
1256
945
  const { isSelfHost } = await import('../lib/devices/self-host.js');
1257
- // Picking this machine is a plain local run — leave options.device unset.
1258
946
  if (!isSelfHost(pickedDevice))
1259
947
  options.device = pickedDevice;
1260
948
  }
1261
- // Default placement (PHNX-4083): a bare human-facing `agents run
1262
- // <harness>` (no prompt, real TTY, no placement flags, not a dispatched
1263
- // hop) places itself like `--device auto` — a marker left off is decided
1264
- // for you. Headless runs (a prompt, --json, teams/routines/hooks) keep
1265
- // running in place, unchanged.
1266
949
  const defaultPlacement = bareInteractiveRunDefaultsToDeviceAuto(options, { prompt, devicePickerRequested }, { tty: isInteractiveTerminal(), json: options.json });
1267
950
  if (defaultPlacement)
1268
951
  options.device = 'auto';
1269
- // --device auto: live fleet pick.
1270
- // Harness is always the agent the user typed — never auto-picked.
1271
- // Placement failure propagates; an automatic request never becomes local.
1272
952
  {
1273
953
  const { applyDeviceAutoToOptions } = await import('../lib/smart-launch.js');
1274
954
  let result;
1275
955
  try {
1276
956
  result = await applyDeviceAutoToOptions(options, {
1277
957
  accountPickerRequested,
1278
- // `run auto` selects its harness after placement, so do not filter
1279
- // candidates against an arbitrary proxy harness at this stage.
1280
958
  agent: normalizedAgentSpec.split('#')[0].split('@')[0] === RUN_AUTO_KEYWORD
1281
959
  ? undefined
1282
960
  : (resolveAgentName(normalizedAgentSpec.split('#')[0].split('@')[0]) ?? undefined),
1283
961
  });
1284
962
  }
1285
963
  catch (err) {
1286
- // Placement the DEFAULT chose must fail loud AND name the local
1287
- // escape hatch — never silently fall back to a local launch.
1288
964
  if (!defaultPlacement)
1289
965
  throw err;
1290
966
  console.error(chalk.red(err.message));
@@ -1298,9 +974,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1298
974
  ` · ${acctNote}\n`));
1299
975
  }
1300
976
  }
1301
- // --lease: invent a disposable cloud box for this run (via crabbox), run
1302
- // the agent there, then tear it down. --box: reuse a named warm crabbox
1303
- // box, run the same bootstrap there, and leave the box running.
1304
977
  if (options.lease || options.box) {
1305
978
  if (prompt === undefined) {
1306
979
  console.error(chalk.red(`A prompt is required for crabbox runs: agents run <agent> "<task>" ${options.box ? '--box <slug>' : '--lease'}`));
@@ -1319,17 +992,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1319
992
  process.exit(1);
1320
993
  }
1321
994
  const backend = typeof options.lease === 'string' ? options.lease : undefined;
1322
- // crabbox syncs this directory to the box via `git ls-files`; outside a
1323
- // git repo that fails with "build sync file list: exit status 128" — but
1324
- // only AFTER the box is provisioned and billed. Fail fast here instead.
1325
995
  const leaseCwd = options.cwd ?? process.cwd();
1326
996
  if (!isInsideGitWorkTree(leaseCwd)) {
1327
997
  console.error(chalk.red(`${options.box ? '--box' : '--lease'} syncs the working directory to the box, but ${leaseCwd} is not a git repository.`));
1328
998
  console.error(chalk.yellow(`Run from inside a git repo, or initialize one: (cd ${leaseCwd} && git init)`));
1329
999
  process.exit(1);
1330
1000
  }
1331
- // First-run: no provider credential resolves (no env var, no config, no
1332
- // detectable bundle) → guide the user through one-time setup, then continue.
1333
1001
  const { resolveLeaseBundle } = await import('../lib/crabbox/cli.js');
1334
1002
  if (options.lease && !resolveLeaseBundle()) {
1335
1003
  const { runLeaseSetup } = await import('./lease.js');
@@ -1339,19 +1007,9 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1339
1007
  process.exit(1);
1340
1008
  }
1341
1009
  }
1342
- // ── F3 reuse (RUSH-1922) + F5 net-mode (RUSH-1924) ───────────────────
1343
- // Resolve which box this run targets and how it is networked BEFORE any
1344
- // provisioning. `--box` is an explicit reuse; otherwise, on an
1345
- // interactive tty, offer the warm boxes as a reuse picker. Headless runs
1346
- // never block: leaseAndRun itself is reuse-first against the profile
1347
- // pool (a ready pool box is reused; none ready → warm a fresh one).
1348
- // `--fresh` opts out of every reuse path.
1349
1010
  const leaseSecretsBundle = process.env.AGENTS_LEASE_SECRETS_BUNDLE;
1350
1011
  const nowSecs = Math.floor(Date.now() / 1000);
1351
1012
  let reuseSlug = options.box;
1352
- // Lease runs share one default warm pool across repositories. The generic
1353
- // `.crabbox.yaml profile:` remains available to repo sandbox/CI scripts;
1354
- // `leaseProfile:` is the explicit opt-in for a dedicated lease hot box.
1355
1013
  const repoRoot = gitToplevel(leaseCwd);
1356
1014
  const { readCrabboxLeaseProfile } = await import('../lib/crabbox/config.js');
1357
1015
  const poolProfile = repoRoot ? readCrabboxLeaseProfile(repoRoot) : 'default';
@@ -1366,12 +1024,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1366
1024
  });
1367
1025
  }
1368
1026
  catch {
1369
- warm = []; // crabbox unavailable / no creds → the pool check in leaseAndRun decides
1027
+ warm = [];
1370
1028
  }
1371
1029
  const alwaysFresh = repoRoot ? isAlwaysFreshRepo(readAlwaysFreshRepos(), repoRoot) : false;
1372
1030
  if (warm.length > 0 && !alwaysFresh) {
1373
1031
  if (options.reuse) {
1374
- reuseSlug = warm[0].slug; // scriptable: most-recently-touched warm box
1032
+ reuseSlug = warm[0].slug;
1375
1033
  }
1376
1034
  else if (isInteractiveTerminal() && options.json !== true) {
1377
1035
  const { select } = await import('@inquirer/prompts');
@@ -1400,21 +1058,14 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1400
1058
  console.error(chalk.yellow('Selection cancelled — provisioning a fresh box.'));
1401
1059
  }
1402
1060
  }
1403
- // Headless with no --reuse falls through here → leaseAndRun's
1404
- // profile-pool check decides (reuse a ready pool box, else warm fresh).
1405
1061
  }
1406
1062
  else if (options.reuse && warm.length > 0) {
1407
- // --reuse still honors a warm box even when the picker is suppressed.
1408
1063
  reuseSlug = warm[0].slug;
1409
1064
  }
1410
1065
  }
1411
- // reuseContext: an existing box (picked, --box, or --reuse) defaults the
1412
- // network to the tailnet; a solo one-shot --lease stays public.
1413
1066
  const reuseContext = !!reuseSlug || !!options.reuse;
1414
1067
  let netMode = computeNetMode({ tailscale: options.tailscale, reuseContext });
1415
1068
  const copySetup = !options.bare;
1416
- // Tailscale requested but no auth key configured → downgrade to public
1417
- // with an actionable hint instead of hard-failing the run (F5).
1418
1069
  if (netMode === 'tailscale') {
1419
1070
  const { pickTailscaleBundleFromList } = await import('../lib/crabbox/cli.js');
1420
1071
  const { listBundles } = await import('../lib/secrets-client.js');
@@ -1443,10 +1094,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1443
1094
  let runtime = null;
1444
1095
  let credentialRuntimes = [];
1445
1096
  let dispatchProfile;
1446
- // `--lease` requires a prompt (guarded above), so it is headless by
1447
- // contract — never block on an interactive picker. Provision exactly the
1448
- // one runtime this run needs, inferred from the agent, not every
1449
- // signed-in CLI (which would ship unrelated tokens to a throwaway box).
1450
1097
  if (profileExists(agentName)) {
1451
1098
  try {
1452
1099
  const profile = readProfile(agentName);
@@ -1484,14 +1131,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1484
1131
  console.error(chalk.yellow(`Profile '${agentName}' needs ${runtime} credentials, but ${runtime} is not signed in locally. Sign in locally, then retry.`));
1485
1132
  process.exit(1);
1486
1133
  }
1487
- // Refuse before account selection, OAuth reads, box lookup, or lease
1488
- // provisioning. A provider-backed profile has no credentialRuntimes and
1489
- // proceeds with its portable provider environment instead.
1490
1134
  assertNoNativeOAuthTransfer(credentialRuntimes, detected);
1491
- // Headless-by-contract: don't prompt, but print exactly what ships and
1492
- // where — copying an auth token to a cloud box is a credential transfer.
1493
- // The box is destroyed after the run, so the credential's lifetime is
1494
- // bounded by the run.
1495
1135
  const whatShips = dispatchProfile
1496
1136
  ? `profile '${dispatchProfile.name}'`
1497
1137
  : `${runtime} runtime setup`;
@@ -1509,13 +1149,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1509
1149
  : 'the shared-pool box is kept after the run';
1510
1150
  console.error(chalk.gray(`${boxLifecycle} · shipping ${whatShips}; ${boxAfterRun}.`));
1511
1151
  const claudeCredentialsJson = null;
1512
- // Progress UI (F2, RUSH-1921). A self-throttled spinner (NOT ora — see
1513
- // progress.ts) covers provisioning; the box-side bootstrap then streams a
1514
- // structured step stream (sync → install → runtime → creds → …) via the
1515
- // router's `onStep`, and each step renders as a checklist line through the
1516
- // lib's `renderStepLine` (✔ <Step> — <detail> (<elapsed>)). The agent's own
1517
- // output prints verbatim after the box-side marker. Rule: only ONE spinner
1518
- // phase is active at a time, so it can never storm.
1519
1152
  const { createLeaseOutputRouter, createSpinner, renderStepLine } = await import('../lib/crabbox/progress.js');
1520
1153
  const spinner = createSpinner({ stream: process.stderr });
1521
1154
  let warmupTimer;
@@ -1525,10 +1158,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1525
1158
  } };
1526
1159
  const jsonMode = options.json === true;
1527
1160
  const stepsTty = Boolean(process.stderr.isTTY) && !jsonMode;
1528
- // The step currently in flight (its label spins on a TTY). It is persisted
1529
- // as a ✔ line when the NEXT step arrives (whose elapsedMs measures how long
1530
- // THIS step's block took) — or, for the last step, when agent output or
1531
- // teardown begins.
1532
1161
  let activeStep = null;
1533
1162
  const flushStep = (elapsedMs) => {
1534
1163
  if (!activeStep)
@@ -1544,18 +1173,15 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1544
1173
  };
1545
1174
  const router = createLeaseOutputRouter({
1546
1175
  now: () => Date.now(),
1547
- // Raw setup lines stay captured for a failure dump (router.setupLines());
1548
- // the structured step stream drives the visible checklist, so plain lines
1549
- // are not shown (they would fight the step spinner).
1550
1176
  onSetupLine: () => { },
1551
1177
  onStep: (step) => {
1552
- flushStep(step.elapsedMs); // persist the previous step, timed by this one
1178
+ flushStep(step.elapsedMs);
1553
1179
  activeStep = step;
1554
1180
  if (stepsTty)
1555
1181
  spinner.start(renderStepLine(step));
1556
1182
  },
1557
1183
  onAgentChunk: (chunk) => {
1558
- flushStep(); // last setup step done (no following sentinel to time it)
1184
+ flushStep();
1559
1185
  if (spinner.active)
1560
1186
  spinner.stop();
1561
1187
  process.stdout.write(chunk);
@@ -1595,7 +1221,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1595
1221
  else if (phase.kind === 'ready') {
1596
1222
  stopTimer();
1597
1223
  const addr = boxAddress(phase.box);
1598
- // Steps drive the spinner from here — no generic "Setting up box…".
1599
1224
  spinner.stopAndPersist('✔', `Box ${phase.box.slug} ready${addr ? ` (${addr})` : ''} · ${Math.round(phase.elapsedMs / 1000)}s`);
1600
1225
  }
1601
1226
  else if (phase.kind === 'teardown') {
@@ -1610,9 +1235,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1610
1235
  stopTimer();
1611
1236
  if (spinner.active)
1612
1237
  spinner.stop();
1613
- // Safety net: if setup failed before the agent ever ran, the setup log
1614
- // was only shown as transient spinner text — surface it so the error is
1615
- // diagnosable.
1616
1238
  if (exitCode !== 0 && !router.sawAgent()) {
1617
1239
  const log = router.setupLines();
1618
1240
  if (log.length)
@@ -1634,19 +1256,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1634
1256
  process.exit(1);
1635
1257
  }
1636
1258
  }
1637
- // --device/--on/--computer: offload this run onto a registered agent host
1638
- // over SSH instead of running locally. The three flags are aliases.
1639
1259
  const hostGiven = hostTargetGiven(options);
1640
- // Auto-sync this run's redacted trajectory when it exits, so the console is
1641
- // never stale and a session link/QR resolves the moment the run finishes
1642
- // (PHNX-3628). Armed HERE — after hostGiven is finalized — so every
1643
- // remote-placement signal is already reflected in options: --device/--on/
1644
- // --computer and --where device: (expanded to options.host above), AND the
1645
- // --resume-to-peer redirect that sets options.host during resume
1646
- // resolution. A run that will dispatch remotely (hostGiven non-empty, or
1647
- // --lease/--box) has its trajectory on that box and never arms a local
1648
- // sync; --cloud returned earlier. The module additionally gates on opt-in
1649
- // (signed in + already synced once) and is best-effort.
1650
1260
  if (prompt !== undefined &&
1651
1261
  hostGiven.length === 0 &&
1652
1262
  !options.lease &&
@@ -1654,8 +1264,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1654
1264
  const { armRunFinishTraceSync } = await import('../lib/run-trace-sync.js');
1655
1265
  armRunFinishTraceSync({ disabled: options.traceSync === false });
1656
1266
  }
1657
- // Home anchors belong to the executing host; preserve them until a remote
1658
- // invocation reaches its local execution path.
1659
1267
  options.cwd = await resolveRunCwd(options, { forRemote: hostGiven.length > 0 });
1660
1268
  if (hostGiven.length > 0) {
1661
1269
  if (new Set(hostGiven).size > 1) {
@@ -1663,18 +1271,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1663
1271
  process.exit(1);
1664
1272
  }
1665
1273
  const hostName = hostGiven[0];
1666
- // Note: a `run auto` dispatch needs no marker forwarded from here — the
1667
- // dispatch layer (hosts/dispatch.ts remoteRunShellPrelude) exports the
1668
- // chain-hop guard into the remote shell for BOTH interactive and
1669
- // headless paths, keyed off the agent name being `auto`.
1670
1274
  const { resolveHostRunTarget, resolveHostSessionId, dispatchPromptToHost, HostResolutionError } = await import('../lib/hosts/run-target.js');
1671
1275
  const { runInteractiveOnHost } = await import('../lib/hosts/dispatch.js');
1672
1276
  const { registerInteractiveHostSession } = await import('../lib/hosts/session-index.js');
1673
1277
  const { RUN_OPTION_REJECT_MESSAGES } = await import('../lib/hosts/remote-cmd.js');
1674
1278
  const { normalizeRunStrategy, RUN_STRATEGIES } = await import('../lib/accounting/rotate.js');
1675
- // The forwarding contract (RUN_OPTION_FORWARDING): options that cannot
1676
- // cross the SSH boundary fail loud BEFORE dispatch — never a silent
1677
- // drop. Value-aware: only reject what was actually passed.
1678
1279
  const hostRejects = [];
1679
1280
  if (options.secrets.length > 0)
1680
1281
  hostRejects.push(RUN_OPTION_REJECT_MESSAGES.secrets);
@@ -1695,10 +1296,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1695
1296
  process.exit(1);
1696
1297
  return;
1697
1298
  }
1698
- // Shared resolution (name → capability tag → error). A password-auth
1699
- // device throws DeviceOffloadUnsupportedError inside the helper and
1700
- // propagates untouched — it's printed cleanly by the top-level catch in
1701
- // index.ts (covers every resolveHost caller).
1702
1299
  let host;
1703
1300
  try {
1704
1301
  host = await resolveHostRunTarget(hostName, { any: options.any });
@@ -1712,13 +1309,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1712
1309
  }
1713
1310
  try {
1714
1311
  const [runAgent, rawRunVersion] = normalizedAgentSpec.split('#')[0].split('@');
1715
- // Forward the explicit @version pin verbatim. Resolving aliases like
1716
- // @latest locally would check local installs, but the remote host may
1717
- // have versions the laptop does not. The remote agents CLI resolves
1718
- // aliases against its own installed versions.
1719
1312
  const runVersion = rawRunVersion || undefined;
1720
- // Normalize the effective strategy exactly like the local path so we
1721
- // fail fast on invalid input and can forward --balanced/--strategy.
1722
1313
  const explicitStrategy = options.strategy ? normalizeRunStrategy(options.strategy) : null;
1723
1314
  if (options.strategy && !explicitStrategy) {
1724
1315
  console.error(chalk.red(`Invalid strategy: ${options.strategy}. Use ${RUN_STRATEGIES.join(', ')}.`));
@@ -1729,73 +1320,34 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1729
1320
  process.exit(1);
1730
1321
  }
1731
1322
  const runStrategy = options.balanced ? 'balanced' : explicitStrategy ?? undefined;
1732
- // Working directory on the host: an explicit --remote-cwd is used
1733
- // verbatim; --cwd/--project are made portable (a local-home absolute
1734
- // becomes `~/…` so the remote shell re-roots it at ITS home).
1735
- //
1736
- // With neither flag, mirror the LOCAL cwd's home-relative path onto
1737
- // the host (deriveMirroredCwd). Otherwise every host run starts in the
1738
- // remote `$HOME` — launch an agent from a repo and it opens with no
1739
- // project, and you `cd` by hand every time. The same checkout at the
1740
- // same home-relative path on both boxes is the normal fleet layout, so
1741
- // the mirror usually hits; when the host lacks that directory the run
1742
- // falls back to the remote home rather than failing.
1743
1323
  const { toRemotePortable } = await import('../lib/project-root.js');
1744
1324
  const { deriveMirroredCwd } = await import('../lib/hosts/dispatch.js');
1745
1325
  const explicitHostCwd = options.remoteCwd ?? (options.cwd ? toRemotePortable(options.cwd) : undefined);
1746
1326
  const hostCwd = explicitHostCwd ?? deriveMirroredCwd(process.cwd());
1747
1327
  const mirrorHostCwd = explicitHostCwd === undefined;
1748
1328
  const hostAddDirs = options.addDir.length > 0 ? options.addDir.map(toRemotePortable) : undefined;
1749
- // `--resume [id]`: commander yields the string id, or `true` when the
1750
- // flag is passed bare. A bare resume needs the interactive picker,
1751
- // which can't run over a detached remote dispatch — only forward a
1752
- // concrete id.
1753
1329
  const resumeId = typeof options.resume === 'string' ? options.resume : undefined;
1754
1330
  let hostCopyCreds;
1755
- // Decide whether this host run is interactive. No prompt always means
1756
- // interactive (matching local resolveInteractive); --interactive forces
1757
- // interactive even when a prompt is provided; --headless forces headless
1758
- // and therefore requires a prompt.
1759
1331
  if (options.interactive && options.headless) {
1760
1332
  console.error(chalk.red('--interactive and --headless are mutually exclusive. Pass one, or neither (mode is inferred from prompt presence).'));
1761
1333
  process.exit(1);
1762
1334
  }
1763
1335
  const interactiveHost = options.interactive === true || (prompt === undefined && options.headless !== true);
1764
- // When the account was already picked up front (`#@`), the dispatch
1765
- // forwards `#label` and the peer needs no interactive picker.
1766
1336
  if (accountPickerRequested && !upFrontAccountPick && !interactiveHost) {
1767
1337
  console.error(chalk.red(`Account selection with ${agentSpec} requires an interactive host run. ` +
1768
1338
  `Use agents run ${runAgent}# --device ${host.name} --interactive.`));
1769
1339
  process.exit(1);
1770
1340
  }
1771
1341
  if (interactiveHost) {
1772
- // Interactive host run: forward the local TTY over SSH and let the
1773
- // remote agent start its normal interactive UI (tmux on the host).
1774
1342
  if (options.follow === false) {
1775
1343
  console.error(chalk.red('--no-follow is not compatible with interactive host runs. Interactive runs are attached by definition.'));
1776
1344
  process.exit(1);
1777
1345
  }
1778
- // Mirror the local path (lib/exec.ts): only Claude accepts a forced
1779
- // `--session-id`. Adopt the caller's id when present; otherwise mint
1780
- // one here. Registering that same id keeps the local index aligned
1781
- // with the remote agent. On resume, don't mint a new one.
1782
1346
  const hostSessionId = resolveHostSessionId(runAgent, resumeId, options.sessionId);
1783
- // For every OTHER agent the remote coins its own id, which we can't
1784
- // know up front. Forward a launch id we control as AGENT_LAUNCH_ID:
1785
- // the remote `agents run` adopts it (exec.ts resolveLaunchId) and its
1786
- // SessionStart hook records the real id under that exact key, so after
1787
- // the stream we resolve the id by one ssh read of the remote hook
1788
- // record — the same launch-id join used locally (RUSH-2034). Not
1789
- // needed for Claude (id forced) or resume (id already known).
1790
- // `run auto` ALWAYS joins: the remote picks the harness, so an
1791
- // explicit --session-id is only adopted by a claude pick.
1792
1347
  const correlationLaunchId = hostInteractiveNeedsCorrelationId(runAgent, hostSessionId, resumeId) ? randomUUID() : undefined;
1793
1348
  const hostEnv = correlationLaunchId
1794
1349
  ? [...options.env, `AGENT_LAUNCH_ID=${correlationLaunchId}`]
1795
1350
  : options.env;
1796
- // `run auto` never pre-registers: the explicit id is only real when
1797
- // the remote pick lands on claude. The launch-id join below records
1798
- // the id the remote ACTUALLY used, whatever the pick.
1799
1351
  if (hostSessionId && runAgent !== RUN_AUTO_KEYWORD) {
1800
1352
  registerInteractiveHostSession({
1801
1353
  cwd: process.cwd(),
@@ -1852,13 +1404,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1852
1404
  forceInteractive: options.interactive,
1853
1405
  copyCreds: hostCopyCreds,
1854
1406
  });
1855
- // Resolve a non-Claude agent's REAL remote session id now the run has
1856
- // booted (its hook has fired on the peer): one ssh read of the remote
1857
- // hook record, keyed by the launch id we forwarded. Register it so the
1858
- // run shows in `agents sessions` and can be reconnected/focused —
1859
- // closing the non-Claude gap RUSH-2033 left. Best-effort: an
1860
- // unreachable host or a not-yet-landed record leaves the run un-mapped
1861
- // rather than mis-mapped.
1862
1407
  let resolvedRemoteId;
1863
1408
  if (correlationLaunchId) {
1864
1409
  const { resolveRemoteSessionId } = await import('../lib/hosts/remote-session-id.js');
@@ -1867,7 +1412,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1867
1412
  resolvedRemoteId = resolveRemoteSessionId(sshTargetFor(host), correlationLaunchId);
1868
1413
  }
1869
1414
  catch {
1870
- /* ssh read is best-effort — keep the run un-mapped, never guess */
1871
1415
  }
1872
1416
  if (resolvedRemoteId) {
1873
1417
  registerInteractiveHostSession({
@@ -1879,19 +1423,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1879
1423
  });
1880
1424
  }
1881
1425
  }
1882
- // A network drop kills the local ssh client (exit 255). What the
1883
- // remote agent does next depends on the peer's tmux.enabled
1884
- // (PHNX-3316): wrapped, it survives in its detached pane and the
1885
- // reconnect rejoins it; bare (the default), the drop SIGHUPs it and
1886
- // the reconnect resumes the session in place from disk. Either way,
1887
- // with a known session id (Claude's forced id, a resumed run, or a
1888
- // non-Claude id we just resolved from the remote hook record) we
1889
- // reconnect automatically instead of exiting — the user never has
1890
- // to notice the drop and `agents sessions focus` by hand.
1891
- // `raw` runs opted out of all of this, so there is nothing to
1892
- // reconnect to. For `run auto` prefer the join-resolved id (the
1893
- // harness the remote ACTUALLY picked) over the explicit
1894
- // --session-id only claude adopts.
1895
1426
  const { pickReconnectTarget, reconnectInteractiveSession, afterInteractiveRemoteExit, SSH_CONN_FAILURE } = await import('../lib/hosts/reconnect.js');
1896
1427
  const reconnectTarget = pickReconnectTarget({
1897
1428
  agent: runAgent,
@@ -1900,9 +1431,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1900
1431
  resumeId,
1901
1432
  launchId: correlationLaunchId,
1902
1433
  });
1903
- // Raw is not tmux-wrapped, so it never auto-reconnects — but it
1904
- // still prints the session id (EXEC-55). Bundling the notice
1905
- // behind `!isRaw` left a dropped `--raw` tab as a bare shell.
1906
1434
  const next = afterInteractiveRemoteExit({
1907
1435
  target: reconnectTarget,
1908
1436
  host: host.name,
@@ -1920,14 +1448,10 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1920
1448
  process.stderr.write(next.notice);
1921
1449
  process.exit(exitCode);
1922
1450
  }
1923
- // Headless host run: launch detached, tail the remote log, and follow
1924
- // until the remote process exits.
1925
1451
  if (prompt === undefined) {
1926
1452
  console.error(chalk.red('A prompt is required for headless host runs: agents run <agent> "<task>" --device <name>'));
1927
1453
  process.exit(1);
1928
1454
  }
1929
- // Session-id mint, detached dispatch, and local session-index
1930
- // registration all live in the shared helper (lib/hosts/run-target.ts).
1931
1455
  const { modeForRemoteDispatch } = await import('../lib/codex-policy.js');
1932
1456
  const forwardedMode = modeForRemoteDispatch(options.mode, command.getOptionValueSource('mode'));
1933
1457
  if (process.env.AGENTS_DISPATCH_DEBUG || options.verbose) {
@@ -1966,18 +1490,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1966
1490
  copyCreds: hostCopyCreds,
1967
1491
  });
1968
1492
  if (options.follow === false) {
1969
- // The handle the caller uses to check on the run: the name if given,
1970
- // else the real host-task id (never the old literal `<id>`). Steer
1971
- // to the compact `agents sessions` digest over the raw log first.
1972
1493
  const handle = task.name ?? task.id;
1973
1494
  console.log(chalk.green(`Dispatched to ${host.name}${task.name ? ` as "${task.name}"` : ''}.`) + '\n' +
1974
1495
  chalk.gray(` Status: agents sessions ${handle}`) + chalk.gray(' (compact digest — use this)') + '\n' +
1975
1496
  chalk.gray(` Raw log: agents logs ${handle} -f`) + chalk.gray(' (heavy, only if needed)'));
1976
1497
  process.exit(0);
1977
1498
  }
1978
- // -1 = the follow window closed but the run continues on the host (the
1979
- // reattach hint is already printed). That's a detach, not a failure —
1980
- // exit 0. Any real remote code passes through.
1981
1499
  if (exitCode === -1)
1982
1500
  process.exit(0);
1983
1501
  process.exit(exitCode ?? 1);
@@ -1987,11 +1505,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
1987
1505
  process.exit(1);
1988
1506
  }
1989
1507
  }
1990
- // --resume-checkpoint short-circuits normal dispatch entirely: the
1991
- // checkpoint already carries the agent, version, prompt, session id,
1992
- // iteration, and loop config of the killed run. Reconstruct ExecOptions
1993
- // straight from it and continue the loop from the last completed
1994
- // iteration, reusing the SAME runId/runDir (issue #332).
1995
1508
  if (options.resumeCheckpoint) {
1996
1509
  const { readCheckpoint } = await import('../lib/checkpoint.js');
1997
1510
  const { runLoop } = await import('../lib/loop.js');
@@ -2014,10 +1527,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2014
1527
  json: true,
2015
1528
  headless: true,
2016
1529
  };
2017
- // Resume honors the checkpoint's loop config, but lets the resume
2018
- // command RAISE the bounds field-by-field — `--max-iterations 4` on a
2019
- // checkpoint capped at 2 is the natural "continue, run more" gesture.
2020
- // Flags override; unspecified fields fall through from the checkpoint.
2021
1530
  const resumeLoop = { ...cp.loop };
2022
1531
  if (options.maxIterations !== undefined) {
2023
1532
  const n = Number(options.maxIterations);
@@ -2063,9 +1572,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2063
1572
  sessionId: cp.sessionId,
2064
1573
  });
2065
1574
  process.stderr.write(chalk.gray(`[loop] stopped: ${result.stoppedBy} after ${result.iterations} iteration(s), ${result.tokens} tokens\n`));
2066
- // Governance chokepoint (#347): --resume-checkpoint short-circuits normal
2067
- // dispatch and exits here — record its one audit entry with the agent,
2068
- // version, and cwd reconstructed from the checkpoint.
2069
1575
  const resumeExit = loopExitCode(result.stoppedBy);
2070
1576
  recordDispatchedRun({
2071
1577
  agent: cp.agent,
@@ -2074,8 +1580,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2074
1580
  cwd: resumeExec.cwd ?? process.cwd(),
2075
1581
  exitCode: resumeExit,
2076
1582
  });
2077
- // A resumed loop is always headless; surface any commits it left unpushed
2078
- // and any open PR it left unattended (RUSH-2394).
2079
1583
  if (shouldWarnUnpushed(resumeExec.mode ?? 'auto', false)) {
2080
1584
  const resumeCwd = resumeExec.cwd ?? process.cwd();
2081
1585
  await warnUnpushedWork(resumeCwd);
@@ -2083,10 +1587,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2083
1587
  }
2084
1588
  process.exit(resumeExit);
2085
1589
  }
2086
- const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, implicitModeFor, headlessPlanStallCommand, nativeResume, resolveInteractive, inferredInteractiveWithoutTty }, { ALL_AGENT_IDS, ACCOUNT_INSPECTION_AGENT_IDS, agentLabel, supportsAccountInspection }, { profileExists, readProfile, resolveProfileForRun },
2087
- // Engine DATA ops resolve through the standalone `secrets` process client
2088
- // (PHNX-3989); the agents-owned `bundle@host` policy helpers stay in agents-cli.
2089
- { readAndResolveBundleEnv, describeBundle, remoteResolveEnv }, { assertRemoteBundleFlagsUnsupported, splitBundleRef, resolveSecretsContextForRun }, { resolveHostSshTarget }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, DEFAULT_ROTATION_FAILOVER_LIMIT, shouldArmRotationFailover, preflightFallbackHandoff, preflightHandoffEligible, RUN_STRATEGIES, collectHarnessCandidates, pickHarnessWeighted, classifyHarnessCandidates, formatHarnessPickBanner, formatNoHealthyHarnessError, formatNoHealthyAccountError, formatNoVerifiedUsageError, signInRecoverableCandidates }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents, ensureSubagentDispatchTool }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports, capableAgents }, { shareRuntimeEnv },] = await Promise.all([
1590
+ 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, remoteResolveEnv }, { assertRemoteBundleFlagsUnsupported, splitBundleRef, resolveSecretsContextForRun }, { resolveHostSshTarget }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, DEFAULT_ROTATION_FAILOVER_LIMIT, shouldArmRotationFailover, preflightFallbackHandoff, preflightHandoffEligible, RUN_STRATEGIES, collectHarnessCandidates, pickHarnessWeighted, classifyHarnessCandidates, formatHarnessPickBanner, formatNoHealthyHarnessError, formatNoHealthyAccountError, formatNoVerifiedUsageError, signInRecoverableCandidates }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents, ensureSubagentDispatchTool }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports, capableAgents }, { shareRuntimeEnv },] = await Promise.all([
2090
1591
  import('../lib/exec.js'),
2091
1592
  import('../lib/agents.js'),
2092
1593
  import('../lib/profiles.js'),
@@ -2104,8 +1605,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2104
1605
  ]);
2105
1606
  bootMark('run-deps:imported');
2106
1607
  const isValidAgent = (agent) => ALL_AGENT_IDS.includes(agent);
2107
- // Parse agent@version#label. The label selects native auth without pinning
2108
- // the binary version; --account remains the equivalent flag form.
2109
1608
  const labelParts = normalizedAgentSpec.split('#');
2110
1609
  if (labelParts.length > 2 || labelParts[1] === '') {
2111
1610
  console.error(chalk.red(`Invalid account label in '${normalizedAgentSpec}'.`));
@@ -2137,25 +1636,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2137
1636
  let profileName;
2138
1637
  let profileFallbackModel;
2139
1638
  let workflowModel;
2140
- // WORKFLOW.md capability scoping, translated to Claude headless flags below.
2141
1639
  let workflowToolsRestrict;
2142
1640
  let workflowMcpConfigPath;
2143
- // Full paths of workflow subagent files THIS run copied into the shared
2144
- // per-agent agents dir. Torn down after the run to restore the shared dir
2145
- // (issue #401), mirroring cleanupWorkflowMcpConfig for the mcp-config.
2146
1641
  const workflowSubagentTargets = [];
2147
- // WORKFLOW.md `loop:` block (issue #332). When a workflow declares it,
2148
- // `agents run <workflow>` honors the loop without a --loop flag.
2149
1642
  let workflowLoop;
2150
- // WORKFLOW.md `for_each:` block (issue #343). When a workflow declares it,
2151
- // `agents run <workflow>` runs the producer, expands one stage teammate per
2152
- // produced item, and drives the teams supervisor to drain — no `teams`
2153
- // subcommands needed.
2154
1643
  let workflowForEach;
2155
- // True once this run copies ≥1 dispatchable subagent into the shared agents
2156
- // dir. Used below to keep the `Task` tool in a `tools:`-restricted workflow —
2157
- // an orchestrator handed subagents but denied `Task` cannot reach them and
2158
- // degenerates to a no-op ("I'll wait for the completion notification").
2159
1644
  let workflowHasSubagents = false;
2160
1645
  const cwd = options.cwd ?? process.cwd();
2161
1646
  if (accountPickerRequested && profileExists(rawAgent)) {
@@ -2169,15 +1654,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2169
1654
  }
2170
1655
  }
2171
1656
  if (autoHarnessRequested) {
2172
- // Harness layer (RUSH-2132): weighted pick across installed harnesses
2173
- // by best-account headroom. Zero healthy accounts anywhere fails loud
2174
- // — launching a default "because it's there" is how a rotate loop
2175
- // hammers an exhausted account.
2176
1657
  const byHarness = await collectHarnessCandidates();
2177
- // F1 (RUSH-2185 / EXEC-23a): a prompt-less run is interactive; only
2178
- // harnesses that can open a REPL with no argv are valid candidates.
2179
- // cursor-agent and similar exit immediately without a prompt, which
2180
- // leaves a silent [detached] pane and an orphan session.
2181
1658
  const interactive = prompt === undefined && options.headless !== true;
2182
1659
  const replCapable = interactive ? new Set(capableAgents('interactiveRepl')) : null;
2183
1660
  const candidateHarness = replCapable
@@ -2198,17 +1675,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2198
1675
  if (!options.quiet) {
2199
1676
  process.stderr.write(chalk.gray(formatHarnessPickBanner(harnessPick) + '\n'));
2200
1677
  }
2201
- // --session-id keeps its claude-only semantics: honored when auto
2202
- // picks claude, ignored (loudly) otherwise.
2203
1678
  if (options.sessionId && agent !== 'claude' && !options.quiet) {
2204
1679
  process.stderr.write(chalk.yellow(`[agents] --session-id ignored: auto picked ${agent} (only claude accepts a forced session id)\n`));
2205
1680
  }
2206
1681
  }
2207
1682
  else if (profileExists(rawAgent)) {
2208
- // A profile by this exact name exists. Profiles bind (host agent,
2209
- // version, env overrides, keychain-backed auth) so Chinese models
2210
- // (Kimi, DeepSeek, Qwen, GLM) can run inside Claude Code without a
2211
- // local proxy, including when the profile name matches a native id.
2212
1683
  try {
2213
1684
  const resolved = resolveProfileForRun(rawAgent, options.model);
2214
1685
  agent = resolved.agent;
@@ -2223,16 +1694,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2223
1694
  if (resolved.tierNote) {
2224
1695
  process.stderr.write(chalk.gray(`[agents] ${resolved.tierNote}\n`));
2225
1696
  }
2226
- // A tier token (cheap/default/best/ultra) already resolved against
2227
- // this PROFILE's own `models:` map above, when the profile opts in.
2228
- // Replace the raw --model value here so the tier never reaches the
2229
- // native, HOST-catalog tier block below. When the profile has no
2230
- // `models:` opt-in at all, resolvedModel stays undefined and
2231
- // options.model is left as the raw tier token on purpose — the
2232
- // "cost tiers don't apply to custom harness ..." discard guard further
2233
- // down this function is the canonical fallback for that case, and
2234
- // this block must not race it with a second, differently-worded
2235
- // message.
2236
1697
  if (resolved.resolvedModel !== undefined) {
2237
1698
  options.model = resolved.resolvedModel;
2238
1699
  }
@@ -2246,11 +1707,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2246
1707
  agent = rawAgent;
2247
1708
  }
2248
1709
  else if (resolveWorkflowRef(rawAgent, cwd)) {
2249
- // Workflow: explicit directory, project .agents/workflows/<name>, user, system, or extra repo.
2250
- // Resolution follows resource precedence: direct path, then project > user > system > extras.
2251
- // Structure:
2252
- // WORKFLOW.md ← orchestrator instructions fed to claude as system prompt
2253
- // subagents/*.md ← flat .md files copied to ~/.claude/agents/ for Agent tool discovery
2254
1710
  const workflowDir = resolveWorkflowRef(rawAgent, cwd);
2255
1711
  agent = 'claude';
2256
1712
  const workflowFrontmatter = parseWorkflowFrontmatter(workflowDir);
@@ -2262,29 +1718,14 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2262
1718
  const resolvedVersion = resolveVersionAlias('claude', version);
2263
1719
  const versionHome = getVersionHomePath('claude', resolvedVersion ?? getGlobalDefault('claude') ?? '');
2264
1720
  const claudeAgentsDir = path.join(versionHome, '.claude', 'agents');
2265
- // Copy subagents/*.md into ~/.claude/agents/ so Claude's Agent tool finds
2266
- // them. allowedAgents enforcement (issue #324): when the workflow declares
2267
- // `allowedAgents:`, copy ONLY those subagent files (matched by filename
2268
- // stem, e.g. security.md -> "security"). A subagent whose definition isn't
2269
- // on disk can't be dispatched — this is the actual, fail-closed mechanism.
2270
- // (Claude's `--agents` flag DEFINES custom agents; it does not restrict
2271
- // which subagents may be dispatched, so it is not used here.)
1721
+ // allowedAgents copies only named definitions; an explicit empty list means none, and pruning touches only managed copies.
2272
1722
  const subagentsDir = path.join(workflowDir, 'subagents');
2273
1723
  const allowedAgents = workflowFrontmatter?.allowedAgents;
2274
1724
  if (fs.existsSync(subagentsDir)) {
2275
1725
  fs.mkdirSync(claudeAgentsDir, { recursive: true });
2276
- // Fail-closed subagent scoping (issue #324). resolveAllowedSubagents
2277
- // distinguishes "allowedAgents absent" (undefined -> copy all) from
2278
- // "present but empty" (=> copy ZERO). An explicit `allowedAgents: []`
2279
- // must mean "allow none", never silently widen to "allow all".
2280
1726
  const allFiles = fs.readdirSync(subagentsDir).filter(f => f.endsWith('.md'));
2281
1727
  const { allowedStems, missing } = resolveAllowedSubagents(allFiles, allowedAgents);
2282
1728
  const allowStemSet = new Set(allowedStems);
2283
- // Fail-closed prune (issue #401, follow-up to #324). A prior
2284
- // unrestricted run may have left workflow subagent files that THIS
2285
- // scoped run does not permit; they linger in the shared dir and stay
2286
- // dispatchable. Remove those no-longer-permitted workflow-managed
2287
- // files BEFORE writing the allowed set — never a user's own subagent.
2288
1729
  const pruned = pruneStaleWorkflowSubagents(claudeAgentsDir, allFiles, allowedStems);
2289
1730
  if (pruned.length > 0) {
2290
1731
  process.stderr.write(chalk.gray(`[workflow] pruned ${pruned.length} stale workflow subagent(s) from shared dir: ${pruned.join(', ')}\n`));
@@ -2305,15 +1746,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2305
1746
  if (copied > 0)
2306
1747
  workflowHasSubagents = true;
2307
1748
  if (allowedAgents !== undefined) {
2308
- // Surface any allowedAgents entry with no matching subagent file, and
2309
- // report how many were filtered out, so the scope is auditable.
2310
1749
  if (missing.length > 0) {
2311
1750
  process.stderr.write(chalk.yellow(`[workflow] allowedAgents not found in subagents/: ${missing.join(', ')}\n`));
2312
1751
  }
2313
1752
  process.stderr.write(chalk.gray(`[workflow] subagents restricted to allowedAgents: copied ${copied}, withheld ${skipped}\n`));
2314
1753
  }
2315
1754
  }
2316
- // Feed WORKFLOW.md body (strip frontmatter) as orchestrator system context.
2317
1755
  const workflowMd = path.join(workflowDir, 'WORKFLOW.md');
2318
1756
  const orchestratorBody = fs.existsSync(workflowMd)
2319
1757
  ? fs.readFileSync(workflowMd, 'utf-8').replace(/^---[\s\S]*?---\n/, '').trim()
@@ -2321,7 +1759,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2321
1759
  if (orchestratorBody && prompt !== undefined) {
2322
1760
  prompt = `${orchestratorBody}\n\n---\n\n${prompt}`;
2323
1761
  }
2324
- // Sync workflow-scoped skills into the version home's skills dir.
2325
1762
  const workflowSkillsDir = path.join(workflowDir, 'skills');
2326
1763
  if (fs.existsSync(workflowSkillsDir)) {
2327
1764
  const skillsTarget = path.join(claudeAgentsDir, '..', 'skills');
@@ -2332,7 +1769,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2332
1769
  fs.cpSync(path.join(workflowSkillsDir, entry.name), path.join(skillsTarget, entry.name), { recursive: true });
2333
1770
  }
2334
1771
  }
2335
- // Sync workflow-scoped plugins into the version home.
2336
1772
  const workflowPluginsDir = path.join(workflowDir, 'plugins');
2337
1773
  if (fs.existsSync(workflowPluginsDir)) {
2338
1774
  for (const entry of fs.readdirSync(workflowPluginsDir, { withFileTypes: true })) {
@@ -2345,10 +1781,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2345
1781
  syncPluginToVersion(buildDiscoveredPlugin(pluginRoot, manifest), 'claude', versionHome);
2346
1782
  }
2347
1783
  }
2348
- // Auto-inject secrets bundles declared in the workflow's frontmatter `secrets:` field.
2349
- // Union with any --secrets flags the user passed; dedupe. Skip when --no-auto-secrets is set.
2350
- // (Commander stores the negated flag as `autoSecrets: false` — the old
2351
- // `noAutoSecrets` read was never populated, making the flag a no-op.)
2352
1784
  if (options.autoSecrets !== false) {
2353
1785
  const declared = workflowFrontmatter?.secrets ?? [];
2354
1786
  if (declared.length > 0) {
@@ -2366,14 +1798,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2366
1798
  }
2367
1799
  }
2368
1800
  }
2369
- // Capability scoping: translate WORKFLOW.md `tools:` / `mcpServers:` into
2370
- // the Claude headless flags that ACTUALLY restrict the run (verified
2371
- // against `claude --help`): tools -> `--tools` (restricts the available
2372
- // built-in tool set), mcpServers -> `--mcp-config` + `--strict-mcp-config`
2373
- // (loads ONLY the named servers). `allowedAgents:` is enforced separately,
2374
- // above, by copying only the allowed subagent definition files. Gated
2375
- // behind the `allowlist` capability — if the resolved agent lacks it, warn
2376
- // loudly rather than silently dropping the declaration (issue #324).
2377
1801
  const scopeVersion = resolveVersionAlias('claude', version) ?? getGlobalDefault('claude') ?? undefined;
2378
1802
  const allowlist = supports('claude', 'allowlist', scopeVersion);
2379
1803
  const tools = workflowFrontmatter?.tools;
@@ -2386,15 +1810,13 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2386
1810
  }
2387
1811
  else if (hasScoping) {
2388
1812
  if (tools && tools.length > 0) {
2389
- // An orchestrator with dispatchable subagents MUST retain the `Task`
2390
- // tool, or it can't reach the subagents this run just installed for it
2391
- // — the run silently no-ops ("I'll wait for the completion notification").
2392
1813
  workflowToolsRestrict = ensureSubagentDispatchTool(tools, workflowHasSubagents);
2393
1814
  process.stderr.write(chalk.gray(`[workflow] restricting available tools to: ${workflowToolsRestrict.join(', ')} (Write/Bash/Edit unavailable unless listed)\n`));
2394
1815
  if (workflowToolsRestrict.length !== tools.length) {
2395
1816
  process.stderr.write(chalk.gray(`[workflow] kept Task tool: workflow ships subagents to dispatch\n`));
2396
1817
  }
2397
1818
  }
1819
+ // Named MCP scope always writes strict config, even when no name resolves, so ambient servers cannot leak into the workflow.
2398
1820
  if (mcpServerNames && mcpServerNames.length > 0) {
2399
1821
  const servers = getMcpServersByName(mcpServerNames, { cwd });
2400
1822
  const found = new Set(servers.map(s => s.name));
@@ -2402,16 +1824,9 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2402
1824
  if (missing.length > 0) {
2403
1825
  process.stderr.write(chalk.yellow(`[workflow] mcpServers not found in registry, skipped: ${missing.join(', ')}\n`));
2404
1826
  }
2405
- // Fail-closed: `mcpServers:` was declared, so the run MUST be scoped to
2406
- // a config — never fall through to the user's ambient MCP set. When
2407
- // zero declared names resolve to installed servers, write a locked-down
2408
- // empty config (`{ "mcpServers": {} }`); with `--strict-mcp-config` the
2409
- // run gets NO MCP servers, which is LESS access than ambient (issue #324).
2410
1827
  const mcpConfig = buildWorkflowMcpConfig(servers);
2411
1828
  const configDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agents-workflow-mcp-'));
2412
1829
  workflowMcpConfigPath = path.join(configDir, 'mcp-config.json');
2413
- // 0o600: the config embeds server `env` which can carry tokens.
2414
- // Cleaned up after the run (finally block below).
2415
1830
  fs.writeFileSync(workflowMcpConfigPath, mcpConfig, { mode: 0o600 });
2416
1831
  if (servers.length > 0) {
2417
1832
  process.stderr.write(chalk.gray(`[workflow] scoping MCP servers to ONLY: ${servers.map(s => s.name).join(', ')}\n`));
@@ -2421,17 +1836,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2421
1836
  }
2422
1837
  }
2423
1838
  }
2424
- // Count the subagents THIS workflow made available (after allowedAgents
2425
- // filtering), not every file in the shared agents dir. Same fail-closed
2426
- // semantics as the copy above: `allowedAgents: []` -> 0.
2427
1839
  const subagentCount = fs.existsSync(subagentsDir)
2428
1840
  ? resolveAllowedSubagents(fs.readdirSync(subagentsDir).filter(f => f.endsWith('.md')), allowedAgents).allowedStems.length
2429
1841
  : 0;
2430
1842
  process.stderr.write(chalk.gray(`Workflow '${rawAgent}' → claude (${subagentCount} subagents)\n`));
2431
1843
  }
2432
1844
  else {
2433
- // Smart pick: auto-correct a single typo (insertion/deletion/substitution/transposition)
2434
- // against the known agent ids before giving up. Example: `cladue` -> `claude`, `grk` -> `grok`.
2435
1845
  const { fuzzyMatch, FUZZY_PRESETS } = await import('../lib/fuzzy.js');
2436
1846
  const suggested = fuzzyMatch(rawAgent, ALL_AGENT_IDS, FUZZY_PRESETS.agents);
2437
1847
  if (suggested && isValidAgent(suggested)) {
@@ -2445,9 +1855,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2445
1855
  process.exit(1);
2446
1856
  }
2447
1857
  }
2448
- // `#@` already asked the account up front (before the device menu) — a
2449
- // remote device pick never reaches here, so apply the local pick's
2450
- // version/home and skip the on-the-spot menu.
2451
1858
  if (accountPickerRequested && !upFrontAccountPick) {
2452
1859
  if (!supportsAccountInspection(agent)) {
2453
1860
  console.error(chalk.red(`${agentLabel(agent)} does not expose local account state, so agents-cli cannot safely select an account.`));
@@ -2496,8 +1903,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2496
1903
  accountEnv = { ...accountEnv, ...launchAccount.env };
2497
1904
  }
2498
1905
  else {
2499
- // Binding key: a custom harness keys on its own profile name; a native /
2500
- // global run keys on the exact `agent@version` (default when unpinned).
2501
1906
  const bindingTarget = fromProfile ? rawAgent : (version ? `${agent}@${version}` : `${agent}@${getGlobalDefault(agent) ?? ''}`);
2502
1907
  try {
2503
1908
  spawnAccount = resolveSpawnAccount(options.account, agent, version, readMeta(), { useDefault: !fromProfile, provider: profileProvider, target: bindingTarget });
@@ -2506,15 +1911,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2506
1911
  console.error(chalk.red(err.message));
2507
1912
  process.exit(1);
2508
1913
  }
2509
- // Downstream rotation gating asks only "was an account selected?".
2510
1914
  if (spawnAccount) {
2511
1915
  if (options.cloud || options.provider || options.lease) {
2512
1916
  console.error(chalk.red('--account selects a device-local credential and cannot be combined with cloud or lease placement.'));
2513
1917
  process.exit(1);
2514
1918
  }
2515
1919
  if (spawnAccount.kind === 'native') {
2516
- // `#name` / `--account` on a --device run is forwarded unchanged at
2517
- // dispatch time; the peer resolves ITS slot. This block is local-only.
2518
1920
  const remoteTarget = options.host || options.device;
2519
1921
  if (!remoteTarget) {
2520
1922
  const { adoptedConfigPointsAtHome, adoptedSymlinkMismatchError, durableSlotEnv, isSymlinkAdoptedHarness, resolveNativeSpawnHome, symlinkAdoptedAccountError, } = await import('../lib/exec-account-home.js');
@@ -2534,16 +1936,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2534
1936
  process.exit(1);
2535
1937
  }
2536
1938
  execHome = resolved.execHome;
2537
- // A worker's durable api-key slot holds no file: the pushed key
2538
- // rides the harness env var (CURSOR_API_KEY, …) on this launch.
2539
1939
  const durable = durableSlotEnv(agent, spawnAccount, resolved, meta);
2540
1940
  if (Object.keys(durable).length > 0)
2541
1941
  accountEnv = { ...accountEnv, ...durable };
2542
1942
  if (resolved.source === 'legacy-home') {
2543
1943
  accountConfigVersion = resolved.label;
2544
- // A leftover version-labeled home is both the spawn HOME and
2545
- // the account's installation — the pre-T5 `resolveAccountVersion`
2546
- // behavior. An explicit `@<label>` still controls the binary.
2547
1944
  if (!version && !fromProfile && resolved.label)
2548
1945
  version = resolved.label;
2549
1946
  }
@@ -2552,7 +1949,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2552
1949
  console.error(chalk.red(err.message));
2553
1950
  process.exit(1);
2554
1951
  }
2555
- // Slot / provisioned: binary comes from the one managed install unless `@<label>` pins it.
2556
1952
  if (!version && !fromProfile) {
2557
1953
  const { ensureHarnessInstallation } = await import('../lib/installations/store.js');
2558
1954
  const { installation } = await ensureHarnessInstallation(agent);
@@ -2568,7 +1964,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2568
1964
  }
2569
1965
  }
2570
1966
  const configuredAccount = launchAccount?.account?.name ?? spawnAccount?.name;
2571
- // The account and native context were resolved before launch defaults.
2572
1967
  let resumeNative = false;
2573
1968
  let resumeSessionId;
2574
1969
  let forceInteractive = false;
@@ -2600,10 +1995,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2600
1995
  if (resolvedRecoveryTarget.mode === 'native') {
2601
1996
  resumeNative = true;
2602
1997
  resumeSessionId = session.id;
2603
- // The centralized recovery decision proves the transcript belongs to
2604
- // this exact isolated home and resolves any harness-specific launch cwd.
2605
- // Claude's indexed `session.cwd` is the first user-turn cwd, which may
2606
- // differ from the earlier cwd that selected projects/<cwd-key>.
2607
1998
  if (!options.cwd && resolvedRecoveryTarget.cwd)
2608
1999
  options.cwd = resolvedRecoveryTarget.cwd;
2609
2000
  if (!options.quiet)
@@ -2627,39 +2018,10 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2627
2018
  }
2628
2019
  const configuredStrategy = getConfiguredRunStrategy(agent, cwd);
2629
2020
  const explicitStrategy = options.strategy ? normalizeRunStrategy(options.strategy) : null;
2630
- // Captured from resolveRunVersion below so mid-run rate-limit failover can
2631
- // synthesize a same-agent fallback chain from the other healthy accounts
2632
- // (issue #348). Stays null unless a non-pinned strategy actually rotated.
2633
2021
  let rotationResult = null;
2634
- /**
2635
- * The PRIMARY harness's configured run-default mode/effort, carried across a
2636
- * preflight alternate-harness handoff (PHNX-3999 F19).
2637
- *
2638
- * Run defaults are resolved after the harness is known, so without this a
2639
- * handoff would silently adopt the ALTERNATE's configured defaults — a
2640
- * primary configured `mode: plan` becoming the alternate's `mode: skip`
2641
- * escalates a read-only intent into an unattended writable run. The
2642
- * canonical mid-run cascade keeps the primary's resolved mode for the same
2643
- * reason (`runWithFallback` forwards `options.mode` and only re-derives the
2644
- * mode that was never configured at all). An IMPLICIT mode is deliberately
2645
- * not carried: it is the harness's own safe default, so the alternate's
2646
- * applies (identical to `modeWasImplicit ? implicitModeFor(agent)`).
2647
- */
2648
2022
  let handoffRunDefaults;
2649
- // Precomputed launchable-signed-in verdict for the ACTUAL launched
2650
- // candidate, fed to the pre-launch `run.launch` event so it need not
2651
- // re-probe. Sourced per resolution branch from the candidate that WON, not
2652
- // the original auto-pick: the interactive picker (RUSH-2334 / PHNX-2526)
2653
- // deliberately lets the user launch a LOGGED-OUT account, which is a
2654
- // different candidate than `rotationResult.picked` — reading the verdict off
2655
- // the auto-pick there would report `launchedLoggedOut:false` for a version
2656
- // that is actually logged out, the exact false-negative this event exists to
2657
- // prevent. Left undefined for pinned-default / explicit-pin so emitRunLaunch
2658
- // falls back to probing the version home itself.
2659
2023
  let launchSignedIn;
2660
2024
  let launchEmail;
2661
- // Set when the zero-healthy path already announced a deliberate
2662
- // launch-to-sign-in, so the login preflight below does not repeat it.
2663
2025
  let signInLaunch = false;
2664
2026
  if (options.strategy && !explicitStrategy) {
2665
2027
  console.error(chalk.red(`Invalid strategy: ${options.strategy}. Use ${RUN_STRATEGIES.join(', ')}.`));
@@ -2670,26 +2032,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2670
2032
  process.exit(1);
2671
2033
  }
2672
2034
  const strategy = options.balanced ? 'balanced' : explicitStrategy ?? configuredStrategy;
2673
- // Strategy applies to bare (unpinned) invocations. Explicit @version and
2674
- // profiles already name the target. A --fallback chain does NOT pin the
2675
- // primary: it only names where to cascade on a rate limit, so the bare
2676
- // primary still resolves through the strategy — otherwise every
2677
- // `agents run claude --fallback codex` run lands on the pinned default
2678
- // account and account rotation silently stops (the gh-monitor heal bug).
2679
- // `pinned` still resolves so a logged-out default can yield to a signed-in
2680
- // sibling on this device (PHNX-2685); an explicit @version pin is unchanged.
2681
- // Bounded handoff loop: each iteration resolves an account for `agent`, and
2682
- // the only `continue` is the preflight exhaustion handoff below, which
2683
- // consumes one entry of the `--fallback` spec before retrying as that
2684
- // alternate. The spec is finite, so this terminates (PHNX-3999 F19).
2685
- // A balanced pick or the no-fresh-usage picker returns a CANDIDATE. Since
2686
- // PHNX-3940 a native candidate is a registered account SLOT, not the
2687
- // version home the executable lives in, so the spawn must resolve that
2688
- // slot (home + durable env) through the canonical local launch resolver.
2689
- // Without this the run launched the version home and whichever login it
2690
- // held: on yosemite-m0 (2026-09-23) the picker chose trp and Claude
2691
- // started as a different account in its first-run wizard. A remote run
2692
- // re-resolves on the peer, which runs this same code locally.
2693
2035
  const applyPickedCandidate = async (candidate) => {
2694
2036
  if (!candidate.nativeAccount || options.host || options.device)
2695
2037
  return;
@@ -2723,11 +2065,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2723
2065
  }
2724
2066
  else {
2725
2067
  try {
2726
- // Account-centric candidate list: native version-home logins PLUS
2727
- // provider accounts (setup-token / API-key) that can auth this agent,
2728
- // so `--strategy balanced` spreads across ALL accounts, not just the
2729
- // ones sitting in a version home (RUSH-3182). Run-path only — the
2730
- // picker's other callers keep the native-only collector.
2731
2068
  const { collectRunCandidatesForRun } = await import('../lib/accounting/account-pool-collect.js');
2732
2069
  bootMark('resolve-version:start');
2733
2070
  const routingModel = options.model ?? resolvedResumeSource?.model ?? workflowModel
@@ -2735,20 +2072,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2735
2072
  const resolved = await resolveRunVersion(agent, strategy, cwd, collectRunCandidatesForRun, routingModel);
2736
2073
  bootMark('resolve-version:done');
2737
2074
  if (resolved.exhausted) {
2738
- // Zero healthy accounts splits two ways, and conflating them is what
2739
- // stranded a logged-out harness with no way in at all (RUSH-2334):
2740
- //
2741
- // - THROTTLED (rate_limited / out_of_credits) -> fail loud (RUSH-2132).
2742
- // The old behavior warned "found no usable version; falling back to
2743
- // defaults" and launched the pinned default anyway — the exact move
2744
- // that loops a rotate into an exhausted account. Only a window reset
2745
- // clears it. The message text is a contract the Factory watchdog
2746
- // tail-detects; do not reword it.
2747
- // - NEEDS A SIGN-IN (signed_out / revoked) -> launching IS the fix,
2748
- // because the harness's own TUI is the login surface. So on a TTY we
2749
- // carry the user into that login instead of erroring. Exiting here
2750
- // made `agents run <agent>`, `agents run <agent>#`, and `agents use`
2751
- // all dead-end with no reachable way to authenticate.
2752
2075
  const recoverable = signInRecoverableCandidates(resolved.exhausted);
2753
2076
  const { signInLaunchDecision } = await import('./run-account-picker.js');
2754
2077
  const decision = signInLaunchDecision({
@@ -2759,33 +2082,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2759
2082
  if (decision === 'launch') {
2760
2083
  const { pickSignInLaunchVersion } = await import('./run-account-picker.js');
2761
2084
  const signInVersion = await pickSignInLaunchVersion(agent, recoverable, !!options.quiet);
2762
- // A cancelled prompt launches nothing — same contract as the
2763
- // trailing-# account picker above.
2764
2085
  if (!signInVersion)
2765
2086
  return;
2766
2087
  version = signInVersion;
2767
- // We just told the user this account is logged out and why we're
2768
- // launching it, so suppress the downstream login preflight — it
2769
- // would print a second, near-identical "looks logged out" warning.
2770
2088
  signInLaunch = true;
2771
2089
  }
2772
2090
  else {
2773
- // Every account of this harness is throttled. A configured
2774
- // alternate exists for exactly this case, so hand off to it here
2775
- // rather than exiting — `runWithFallback` would only reach it
2776
- // after a run that can no longer start (PHNX-3999 F19). The
2777
- // alternate becomes the primary and is dropped from the spec, so
2778
- // the chain that remains never lists the agent now running.
2779
- //
2780
- // ONLY for a run shape `--fallback` is valid on. The handoff
2781
- // consumes the entry it uses, and the canonical --fallback
2782
- // validation runs later (it rejects interactive/--acp/--loop/
2783
- // --resume-checkpoint chains and requires a prompt) — so
2784
- // switching first on an ineligible shape would empty the spec,
2785
- // leave that guard nothing to reject, and start the alternate
2786
- // harness on a run the CLI refuses today. An ineligible shape
2787
- // never switches, so the spec survives and still fails there
2788
- // with its own message. See preflightHandoffEligible.
2789
2091
  const handoff = preflightHandoffEligible({
2790
2092
  hasPrompt: prompt !== undefined,
2791
2093
  interactive: options.interactive === true,
@@ -2799,12 +2101,8 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2799
2101
  : null;
2800
2102
  if (handoff) {
2801
2103
  process.stderr.write(chalk.yellow(`[agents] every ${agent} account is exhausted — handing off to ${handoff.agent}${handoff.version ? `@${handoff.version}` : ''}\n`));
2802
- // Snapshot the PRIMARY's configured defaults BEFORE the switch —
2803
- // this is the operator's intent for this run, not the alternate's.
2804
2104
  handoffRunDefaults ??= fromProfile ? undefined : resolveRunDefaults(agent, version ?? resolveVersion(agent, cwd), cwd);
2805
2105
  agent = handoff.agent;
2806
- // Alias-resolve against the NEW harness's installs, exactly as
2807
- // the canonical --fallback parse does for its own entries.
2808
2106
  version = resolveVersionAlias(agent, handoff.version);
2809
2107
  options.fallback = handoff.remainingSpec;
2810
2108
  rotationResult = null;
@@ -2812,9 +2110,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2812
2110
  }
2813
2111
  console.error(chalk.red(formatNoHealthyAccountError(agent, strategy, resolved.exhausted)));
2814
2112
  if (recoverable.length > 0) {
2815
- // Off a TTY nobody can complete a login, so we still exit — but
2816
- // name the actual fix rather than only offering --strategy pinned,
2817
- // which would just pin the same unauthenticated account.
2818
2113
  const { loginHint } = await import('../lib/signin-badge.js');
2819
2114
  console.error(chalk.gray(`To sign in: ${loginHint(agent)} — or run \`agents run ${agent}\` from a terminal.`));
2820
2115
  }
@@ -2822,13 +2117,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2822
2117
  }
2823
2118
  }
2824
2119
  else if (resolved.noVerifiedUsage) {
2825
- // Entirely stale usage (PHNX-2526): every eligible account carries
2826
- // a stale-but-present usage number and none is verified, so the
2827
- // route would be a guess. NEVER auto-pick it. Interactive: show the
2828
- // account picker so a human chooses with the (stale) numbers in
2829
- // view. Unattended: fail loud with NO_VERIFIED_USAGE. The stale
2830
- // pool survives ONLY as `resolved.rotation.healthy` for bounded
2831
- // post-rejection failover, never as the initial pick.
2832
2120
  const { noVerifiedUsageDecision, pickRunAccountCandidate } = await import('./run-account-picker.js');
2833
2121
  const decision = noVerifiedUsageDecision({
2834
2122
  tty: isInteractiveTerminal(),
@@ -2837,18 +2125,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2837
2125
  });
2838
2126
  if (decision === 'picker') {
2839
2127
  const selected = await pickRunAccountCandidate(agent);
2840
- // A cancelled picker launches nothing — same contract as the
2841
- // trailing-# account picker and the sign-in launch above.
2842
2128
  if (!selected)
2843
2129
  return;
2844
2130
  version = selected.version;
2845
- // Source the run.launch verdict from the account the user ACTUALLY
2846
- // picked — the picker may deliberately return a logged-out one
2847
- // (RUSH-2334), so it can differ from rotationResult.picked.
2848
2131
  launchSignedIn = selected.signedIn;
2849
2132
  launchEmail = selected.email;
2850
- // Keep the rotation so mid-run failover can still cascade across
2851
- // the other (stale) healthy accounts after a real rejection.
2852
2133
  rotationResult = resolved.rotation;
2853
2134
  await applyPickedCandidate(selected);
2854
2135
  if (!options.quiet) {
@@ -2864,18 +2145,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2864
2145
  else if (resolved.version) {
2865
2146
  version = resolved.version;
2866
2147
  rotationResult = resolved.rotation;
2867
- // The auto-pick already computed the launchable-signed-in verdict for
2868
- // this exact version via the same gate — reuse it for run.launch.
2869
2148
  if (resolved.rotation) {
2870
2149
  launchSignedIn = resolved.rotation.picked.signedIn;
2871
2150
  launchEmail = resolved.rotation.picked.email;
2872
2151
  await applyPickedCandidate(resolved.rotation.picked);
2873
2152
  }
2874
- // A balanced/available pick of a PROVIDER account (setup-token /
2875
- // API-key) carries `providerAccount`. Resolve its env through the
2876
- // same `resolveSpawnAccount` path an explicit `--account` uses, so
2877
- // exec injects the credential; a native pick has no providerAccount
2878
- // and resolved its slot home in applyPickedCandidate above.
2879
2153
  const pickedProviderAccount = resolved.rotation?.picked.providerAccount;
2880
2154
  if (pickedProviderAccount) {
2881
2155
  try {
@@ -2894,8 +2168,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2894
2168
  }
2895
2169
  }
2896
2170
  else if (!options.quiet) {
2897
- // No installed version at all (not "accounts exhausted" — that
2898
- // fails loud above): keep the pre-existing default resolution.
2899
2171
  process.stderr.write(chalk.yellow(`[agents] strategy ${strategy} found no usable ${agent} version; falling back to defaults\n`));
2900
2172
  }
2901
2173
  }
@@ -2908,21 +2180,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2908
2180
  }
2909
2181
  break;
2910
2182
  }
2911
- // Self-heal the launch target. A gutted install (JS wrapper present,
2912
- // native binary missing — a partial/raced npm extraction of the optional
2913
- // per-arch dependency) would otherwise spawn and die with a raw ENOENT
2914
- // inside the agent's own wrapper. Repair it in place (or fall back to a
2915
- // runnable version, re-pinning it) BEFORE we build the launch command.
2916
- // Skipped for headless resume-native/acp/loop paths only if it errored;
2917
- // here it runs for every normal dispatch. Best-effort log to stderr.
2918
2183
  {
2919
2184
  const launchTarget = version ?? resolveVersion(agent, cwd) ?? undefined;
2920
2185
  if (launchTarget) {
2921
2186
  const healed = await ensureAgentRunnable(agent, launchTarget, options.quiet ? undefined : (m) => process.stderr.write(chalk.yellow(`[agents] ${m}\n`)));
2922
2187
  if (healed === null) {
2923
- // An isolated copy is never repaired by adopting another version, so
2924
- // `add <agent>@latest` would build an unrelated NORMAL install rather
2925
- // than fix what the user asked to run. Point at the isolated re-add.
2926
2188
  const { isVersionIsolated } = await import('../lib/installations/versions.js');
2927
2189
  const hint = isVersionIsolated(agent, launchTarget)
2928
2190
  ? `agents add ${agent}@${launchTarget} --isolated`
@@ -2934,22 +2196,8 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2934
2196
  }
2935
2197
  }
2936
2198
  bootMark('ensure-runnable:done');
2937
- // The harness may simply not be on this machine. The self-heal above only
2938
- // runs when a managed version resolved, so with nothing installed we used
2939
- // to fall through and spawn the bare `cliCommand`, which dies as
2940
- // `exec: cursor-agent: not found` (exit 127) after a misleading
2941
- // "looks logged out" banner (RUSH-2339). Probe the executable
2942
- // buildExecCommand will actually spawn and fail loud instead.
2943
- //
2944
- // This is an EXISTENCE probe, not "does agents-cli manage a version". A
2945
- // harness the user installed themselves (Homebrew, a vendor `curl | sh`, a
2946
- // distro package) has no version home and MUST still launch — the PATH
2947
- // branch of resolveLaunchBinary is what keeps that working.
2948
2199
  {
2949
2200
  const { resolveLaunchBinary } = await import('../lib/exec.js');
2950
- // `version` already carries the self-heal's resolution above (it assigns
2951
- // `version = healed` whenever a version resolved at all), so re-deriving
2952
- // it with resolveVersion here would be dead.
2953
2201
  if (!resolveLaunchBinary(agent, version)) {
2954
2202
  const target = version ? `${agent}@${version}` : agent;
2955
2203
  console.error(chalk.red(`agents: ${target} is not installed on this machine.`));
@@ -2958,43 +2206,21 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
2958
2206
  }
2959
2207
  }
2960
2208
  const defaultVersion = version ?? resolveVersion(agent, cwd);
2961
- // Re-apply the active rules preset before every launch (issue: preset
2962
- // changes via `setActiveRulesPreset` only took effect after an explicit
2963
- // `agents rules switch` / `agents sync`). Version-scoped, skip-fast when
2964
- // nothing changed — see lib/rules/run-sync.ts. Placed here (immediately
2965
- // after the resolved version is known, before ACP/loop/fallback branch
2966
- // off) so every downstream dispatch path for this agent+version sees a
2967
- // fresh rules file, not just the plain execAgent path. `defaultVersion`
2968
- // is null when nothing is installed yet — execAgent handles that error
2969
- // path itself; there's no version home to sync into.
2970
2209
  if (defaultVersion) {
2971
2210
  applyActiveRulesPresetAtRun(agent, defaultVersion, getVersionHomePath(agent, defaultVersion));
2972
2211
  applySystemResourcesAtRun(agent, defaultVersion, getVersionHomePath(agent, defaultVersion));
2973
2212
  }
2974
2213
  bootMark('rules-sync:done');
2975
- // Login preflight (advisory, warn + continue). On a local INTERACTIVE
2976
- // launch, probe whether this agent's account has a credential and print a
2977
- // one-line warning if it looks logged out — so you find out BEFORE the TUI
2978
- // opens, not after typing a prompt and getting "/login" back. Inspect the
2979
- // selected account home, not an unrelated global login. This file-based
2980
- // read makes no Keychain ACL prompt. It can still false-negative for opaque
2981
- // credentials, so this NEVER blocks — it warns and launches anyway. Skipped
2982
- // for --json/--quiet, when a rotation already picked a signed-in account,
2983
- // and via --no-auth-check / AGENTS_NO_AUTH_CHECK=1. (--device/--lease return
2984
- // earlier.)
2985
2214
  {
2986
2215
  const { shouldCheckLoginBeforeLaunch, loginHint } = await import('../lib/signin-badge.js');
2987
2216
  const preflight = shouldCheckLoginBeforeLaunch({
2988
2217
  interactive: options.interactive,
2989
- forceInteractive, // a resumed interactive session (e.g. `run kimi --resume`) opens the TUI too
2218
+ forceInteractive,
2990
2219
  headless: options.headless,
2991
2220
  hasPrompt: prompt !== undefined,
2992
2221
  json: options.json,
2993
2222
  quiet: options.quiet,
2994
2223
  authCheckDisabled: options.authCheck === false || process.env.AGENTS_NO_AUTH_CHECK === '1',
2995
- // `signInLaunch` means the zero-healthy path already reported this exact
2996
- // account as logged out and named the login command, so re-probing here
2997
- // only prints a second, near-identical warning.
2998
2224
  rotated: !!rotationResult || accountPickerRequested || signInLaunch || (launchAccount?.account?.kind ?? spawnAccount?.kind) === 'provider',
2999
2225
  });
3000
2226
  if (preflight) {
@@ -3002,11 +2228,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3002
2228
  const { getAccountInfo } = await import('../lib/agents.js');
3003
2229
  const authVersion = accountConfigVersion ?? version;
3004
2230
  const info = await getAccountInfo(agent, execHome ?? (authVersion ? getVersionHomePath(agent, authVersion) : undefined));
3005
- // Claude authenticates interactively from a per-version setup-token on a
3006
- // keychain-less worker (the shim's .oauth_token fallback), which the
3007
- // native-credential probe above can't see — so don't warn "logged out" when
3008
- // a setup-token resolves for this version. No-op on macOS, where the
3009
- // credential lives in the keychain and resolveClaudeSetupToken returns null.
3010
2231
  let authedViaSetupToken = false;
3011
2232
  if (!info.signedIn && agent === 'claude' && version) {
3012
2233
  const { resolveClaudeSetupToken } = await import('../lib/claude-account-token.js');
@@ -3024,19 +2245,14 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3024
2245
  }
3025
2246
  }
3026
2247
  catch {
3027
- // Advisory only — a probe failure must never block a launch.
3028
2248
  }
3029
2249
  }
3030
2250
  }
3031
2251
  const runDefaults = fromProfile
3032
2252
  ? { sources: {} }
3033
2253
  : resolveRunDefaults(agent, defaultVersion, cwd);
3034
- // Accept the four canonical modes plus 'full' as a permanent silent
3035
- // alias for 'skip' (rewritten downstream by normalizeMode in exec.ts).
3036
2254
  let mode = options.mode;
3037
2255
  const modeSource = runCmd.getOptionValueSource('mode');
3038
- // A configured mode carried across a preflight handoff wins over the
3039
- // alternate harness's own configured default (see handoffRunDefaults).
3040
2256
  const configuredMode = handoffRunDefaults?.mode ?? runDefaults.mode;
3041
2257
  const modeFromRunDefault = modeSource === 'default' && !!configuredMode;
3042
2258
  if (modeFromRunDefault) {
@@ -3046,20 +2262,8 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3046
2262
  console.error(chalk.red(`Invalid mode: ${mode}. Use plan, edit, auto, or skip ('full' accepted as alias for skip).`));
3047
2263
  process.exit(1);
3048
2264
  }
3049
- // Default CLI mode is the generic 'plan'. Agents without a read-only
3050
- // mode (antigravity, …) degrade via resolveMode to their
3051
- // safest native mode (modes[0], typically edit). That covers both the
3052
- // implicit default and an explicit `--mode plan`, so multi-agent
3053
- // scripts can pass a uniform plan flag without per-agent branching.
3054
- // Mode degradation is never silent: buildExecCommand emits one stderr
3055
- // warning for the requested-to-resolved transition unless --quiet is set.
3056
- // `skip` still hard-fails when unsupported — pretending we bypassed
3057
- // permissions would be unsafe.
3058
2265
  const modeIsDefault = modeSource === 'default';
3059
2266
  let requestedMode = normalizeMode(mode);
3060
- // Codex's intrinsic omitted-mode default is safe writable: workspace plus
3061
- // common caches, network enabled, approvals on request. An explicit
3062
- // --mode plan and a configured run default remain read-only.
3063
2267
  const { modeWasImplicit } = await import('../lib/codex-policy.js');
3064
2268
  const wasModeImplicit = modeWasImplicit(modeSource, modeFromRunDefault);
3065
2269
  if (wasModeImplicit)
@@ -3073,11 +2277,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3073
2277
  process.exit(1);
3074
2278
  }
3075
2279
  mode = resolvedMode;
3076
- // Fail fast on the headless-plan stall footgun: a slash command run
3077
- // headless under the implicit default 'plan' mode hangs forever at
3078
- // ExitPlanMode (no TTY to approve the plan). Tell the user how to fix it
3079
- // instead of leaving them staring at a frozen process. Explicit
3080
- // `--mode plan` is respected for genuine read-only command runs.
3081
2280
  const stallCmd = headlessPlanStallCommand({
3082
2281
  prompt,
3083
2282
  interactive: resolveInteractive({ prompt, headless: options.headless, interactive: options.interactive || forceInteractive }),
@@ -3105,29 +2304,16 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3105
2304
  console.error(chalk.red(err.message));
3106
2305
  process.exit(1);
3107
2306
  }
3108
- // Resolve --secrets bundles in flag order. Later bundles override earlier
3109
- // ones. Any resolution failure (missing keychain item, blocked exec ref)
3110
- // aborts before spawn so the agent never sees a partial env.
3111
2307
  const secretsKeysSubset = options.secretsKeys
3112
2308
  ? options.secretsKeys.split(',').map((k) => k.trim()).filter(Boolean)
3113
2309
  : undefined;
3114
2310
  let secretsEnv = {};
3115
- // Resource-profile scoping (CTX-1): agents-cli computes which bundle
3116
- // names the active profile allows and forwards it as the client's
3117
- // `allowedBundles` on every local resolution — the standalone has no
3118
- // concept of a profile. undefined (no active profile) is full trust.
3119
2311
  const secretsContext = await resolveSecretsContextForRun(agent);
3120
2312
  for (const bundleRef of options.secrets) {
3121
2313
  try {
3122
2314
  const { bundle: bundleName, host } = splitBundleRef(bundleRef);
3123
2315
  if (host) {
3124
- // Least-privilege flags (--secrets-keys / --allow-expired) do not
3125
- // yet cross the SSH resolver — silently applying them would inject
3126
- // the full remote env or an expired key. Fail loud so the user
3127
- // can drop the flag or resolve locally instead.
3128
2316
  assertRemoteBundleFlagsUnsupported(bundleName, host, { keys: secretsKeysSubset, allowExpired: options.allowExpired }, { keysFlag: '--secrets-keys', allowExpiredFlag: '--allow-expired' });
3129
- // Remote bundle (`bundle@host`): resolve over SSH and inject
3130
- // ephemerally — values never touch this machine's keychain or disk.
3131
2317
  const target = await resolveHostSshTarget(host);
3132
2318
  const bundleEnv = await remoteResolveEnv(target, bundleName, { osLookupName: host });
3133
2319
  console.log(chalk.gray(`[secrets] Resolved ${bundleName}@${host}: ${Object.keys(bundleEnv).length} keys (remote, ephemeral)`));
@@ -3139,12 +2325,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3139
2325
  agent,
3140
2326
  keys: secretsKeysSubset,
3141
2327
  allowExpired: options.allowExpired,
3142
- // The harness identity scopes any cached grant. An agent launch
3143
- // resolves broker-only and fails fast naming
3144
- // `agents secrets unlock <bundle>` (bundles.ts:interactiveUnlock) — it
3145
- // MUST NOT raise a Touch ID sheet regardless of tty (SEC-13). Gating on
3146
- // isHeadlessSecretsContext() left `--interactive` launches (the watchdog's
3147
- // `agents run auto --interactive`) able to prompt, piling up helper sheets.
3148
2328
  agentOnly: true,
3149
2329
  }, secretsContext);
3150
2330
  const entries = await describeBundle(bundle, secretsContext);
@@ -3165,11 +2345,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3165
2345
  const autoShareEnv = options.autoSecrets !== false
3166
2346
  ? shareRuntimeEnv()
3167
2347
  : undefined;
3168
- // Merge order (later wins): profile env < selected account < auto share token < secrets bundles < --env K=V.
3169
- // Profile carries provider auth; secrets bundles carry user-defined
3170
- // values; --env is the per-invocation override. The share token is
3171
- // best-effort: if it is not already in env or an unlocked bundle, unrelated
3172
- // runs keep working, and `agents artifacts share` itself still fails loudly on use.
3173
2348
  const hasOverrides = profileEnv || accountEnv || autoShareEnv || options.secrets.length > 0 || userEnv;
3174
2349
  const env = hasOverrides
3175
2350
  ? { ...(profileEnv ?? {}), ...(accountEnv ?? {}), ...(autoShareEnv ?? {}), ...secretsEnv, ...(userEnv ?? {}) }
@@ -3180,10 +2355,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3180
2355
  ?? (!fromProfile && modelSource === undefined
3181
2356
  ? (workflowModel ?? (options.fallback ? undefined : runDefaults.model))
3182
2357
  : undefined);
3183
- // Cost tiers (cheap|default|best|ultra) resolve against a harness's own model
3184
- // catalog. A custom harness's model comes from its endpoint, not the host
3185
- // harness, so a tier here would forward an incompatible host-harness model to a
3186
- // different API. Discard it loudly and let the custom harness's own model stand.
3187
2358
  if (fromProfile && model && isTierToken(model)) {
3188
2359
  process.stderr.write(chalk.yellow(`[agents] --model ${model}: cost tiers don't apply to custom harness '${rawAgent}' ` +
3189
2360
  `(its model comes from the endpoint) — ignoring the tier, using the custom harness's configured model\n`));
@@ -3211,34 +2382,19 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3211
2382
  resume: resumeNative,
3212
2383
  verbose: options.verbose,
3213
2384
  modeWarningState: { quiet: options.quiet },
3214
- // --raw, --no-tmux (commander negation → options.tmux === false), and
3215
- // --disable-tmux all bypass the interactive tmux wrapper. AGENTS_NO_TMUX=1
3216
- // does the same via the env check in exec.ts.
3217
2385
  raw: options.raw || options.tmux === false || options.disableTmux === true,
3218
2386
  timeout: options.timeout,
3219
2387
  env,
3220
2388
  toolsRestrict: workflowToolsRestrict,
3221
2389
  mcpConfigPath: workflowMcpConfigPath,
3222
2390
  passthroughArgs,
3223
- // Set only on the REMOTE side of a `--device` dispatch (the launcher
3224
- // forwards `--emit-session-id`): print the resolved session id as a
3225
- // stdout sentinel so the launcher captures the id this run coined.
3226
2391
  emitSessionId: options.emitSessionId === true,
3227
- // Observability-only: carried onto the pre-launch `run.launch` event so
3228
- // the stream records HOW this version was chosen. Neither affects the
3229
- // spawn. `resolvedVia` attributes the version source cheaply — an
3230
- // explicit @version pin, a strategy rotation, or the pinned default.
3231
2392
  strategy,
3232
2393
  resolvedVia: rawVersion
3233
2394
  ? 'explicit-pin'
3234
2395
  : rotationResult
3235
2396
  ? 'rotated'
3236
2397
  : 'pinned-default',
3237
- // Launchable-signed-in verdict for the ACTUAL launched candidate, set per
3238
- // resolution branch above (auto-pick from rotation.picked; interactive
3239
- // picker from the user's `selected`, which may be logged out). Undefined
3240
- // for a pinned-default / explicit-pin launch, where spawnAgent probes the
3241
- // version home itself.
3242
2398
  launchSignedIn,
3243
2399
  launchEmail,
3244
2400
  };
@@ -3289,11 +2445,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3289
2445
  fallback.push({ agent: fbAgent, version: resolveVersionAlias(fbAgent, fbVersion || undefined) });
3290
2446
  }
3291
2447
  }
3292
- // Profile-declared same-host model swap (issue #325). Inserted BEFORE any
3293
- // user --fallback entries so a rate limit first tries the cheaper/backup
3294
- // model on the same provider (auth + base URL preserved via envOverride);
3295
- // only if THAT still rate-limits do we cascade to a different agent CLI.
3296
- // Requires a prompt for the same reason --fallback does — headless-only.
3297
2448
  if (fromProfile && profileFallbackModel && prompt !== undefined && !options.interactive) {
3298
2449
  fallback.unshift({
3299
2450
  agent,
@@ -3301,26 +2452,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3301
2452
  envOverride: { [profileFallbackModel.envKey]: profileFallbackModel.model },
3302
2453
  });
3303
2454
  }
3304
- // Mid-run rate-limit failover (issue #348). When a pre-flight rotation
3305
- // picked an account and there are OTHER healthy accounts for the same
3306
- // agent, synthesize a same-agent fallback chain from them so a 429 mid-run
3307
- // re-dispatches on the next healthy account via the SAME runWithFallback
3308
- // path (continuing the session via /continue). Because this injects into
3309
- // the same `fallback` array `--fallback` uses, it must only arm for run
3310
- // shapes that accept a fallback chain — shouldArmRotationFailover excludes
3311
- // acp/loop/resume-checkpoint (which reject a non-empty fallback below)
3312
- // and interactive/no-prompt runs. Pinned/single-account runs stay
3313
- // unchanged because rotationResult is null or rotationFailoverChain
3314
- // returns []. version is set here because rotationResult is only
3315
- // populated when resolveRunVersion picked one.
3316
- //
3317
- // Composes with an explicit --fallback chain: the same-agent accounts are
3318
- // UNSHIFTED ahead of the user's cross-agent entries, so a rate limit
3319
- // first tries the other accounts of the same agent (cheapest recovery —
3320
- // same CLI, session continues) and only then cascades to codex/gemini/etc.
3321
- // Profiles never compose: strategy is skipped for them, rotationResult
3322
- // stays null. (fromProfile's model-swap unshift above is therefore never
3323
- // displaced by this one.)
3324
2455
  if (shouldArmRotationFailover({
3325
2456
  hasRotation: !!rotationResult,
3326
2457
  hasVersion: !!version,
@@ -3330,11 +2461,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3330
2461
  loop: !!options.loop,
3331
2462
  resumeCheckpoint: !!options.resumeCheckpoint,
3332
2463
  })) {
3333
- // With an explicit alternate harness configured, "use the alternate once
3334
- // the primary's accounts are exhausted" is the policy — so EVERY healthy
3335
- // same-agent account has to be tried first, not the default cap of three
3336
- // (PHNX-3999 F19). Without one, the cap stands: it bounds how long a
3337
- // rate-limited run keeps retrying itself.
3338
2464
  const failover = rotationFailoverChain(rotationResult, version, fallback.length > 0 ? (rotationResult.healthy.length || DEFAULT_ROTATION_FAILOVER_LIMIT) : undefined);
3339
2465
  if (failover.length > 0) {
3340
2466
  fallback.unshift(...failover);
@@ -3367,11 +2493,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3367
2493
  mode,
3368
2494
  json: options.json ?? false,
3369
2495
  });
3370
- // Governance chokepoint (#347): the --acp path exits here, bypassing
3371
- // the normal finalize below — record its one audit entry.
3372
2496
  recordDispatchedRun({ agent, version: defaultVersion ?? 'unknown', mode, cwd, exitCode });
3373
- // ACP headless run always has a prompt; surface any unpushed commits
3374
- // and any open PR left unattended (RUSH-2394).
3375
2497
  if (shouldWarnUnpushed(mode, false)) {
3376
2498
  await warnUnpushedWork(cwd);
3377
2499
  await warnOrphanedOpenPr(cwd);
@@ -3383,21 +2505,9 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3383
2505
  process.exit(1);
3384
2506
  }
3385
2507
  }
3386
- // Budget pre-flight gate (issue #346). Estimate the run's cost and, when a
3387
- // cap is configured with on_exceed:block, refuse to launch if it would push
3388
- // a cap over the line — exiting non-zero so CI/headless inherit the block.
3389
- // --yes skips ONLY the interactive confirm threshold, never a hard block.
3390
2508
  {
3391
2509
  const { runPreflightGate } = await import('../lib/budget/preflight.js');
3392
2510
  const { resolveEffectiveModel } = await import('../lib/models.js');
3393
- // Estimate against the model that will ACTUALLY run, not an unpriced
3394
- // `${agent}-default` placeholder (which made estimateCost return $0 and
3395
- // silently neutered the per_run/per_day gate for the common no-`--model`
3396
- // case). When `model` is undefined the spawned CLI uses its built-in
3397
- // default, which we recover from the extracted catalog. If we still can't
3398
- // resolve a concrete model, pass the placeholder — the gate now treats an
3399
- // unpriced estimate under active caps as needing confirmation, so it is
3400
- // never a silent $0 wave-through.
3401
2511
  const effectiveModel = resolveEffectiveModel(agent, version ?? '', model) ?? `${agent}-default`;
3402
2512
  const gate = runPreflightGate({
3403
2513
  agent,
@@ -3412,14 +2522,12 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3412
2522
  process.stderr.write(chalk.gray(gate.banner + '\n'));
3413
2523
  }
3414
2524
  if (!gate.decision.allow) {
3415
- // Hard block. --yes does NOT override (acceptance criterion).
3416
2525
  console.error(chalk.red(`[budget] BLOCKED: ${gate.decision.reason}`));
3417
2526
  console.error(chalk.gray(`Raise the cap in agents.yaml budget: or set on_exceed: warn to proceed.`));
3418
2527
  process.exit(2);
3419
2528
  }
3420
2529
  if (gate.decision.needsConfirm && !options.yes) {
3421
2530
  if (!process.stdin.isTTY) {
3422
- // Non-interactive (CI/headless) and no --yes: cannot confirm — refuse.
3423
2531
  console.error(chalk.red(`[budget] ${gate.decision.reason}`));
3424
2532
  console.error(chalk.gray(`Re-run with --yes to confirm the spend, or lower require_confirm_over.`));
3425
2533
  process.exit(2);
@@ -3435,7 +2543,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3435
2543
  }
3436
2544
  }
3437
2545
  else if (gate.decision.blockedCap && gate.decision.allow && !options.quiet) {
3438
- // on_exceed:warn overrun notice (allowed but reported).
3439
2546
  process.stderr.write(chalk.yellow(`[budget] WARN: ${gate.decision.reason}\n`));
3440
2547
  }
3441
2548
  }
@@ -3444,9 +2551,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3444
2551
  if (!options.quiet) {
3445
2552
  process.stderr.write(chalk.gray(`Running: ${cmd.join(' ')}\n\n`));
3446
2553
  }
3447
- // Remove the ephemeral mcp-config (and its temp dir) after the run. It is
3448
- // written at mode 0o600 but still embeds server `env` (possibly tokens),
3449
- // so it must not linger in tmp. Synchronous so it completes before exit.
3450
2554
  const cleanupWorkflowMcpConfig = () => {
3451
2555
  if (!workflowMcpConfigPath)
3452
2556
  return;
@@ -3454,29 +2558,17 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3454
2558
  fs.rmSync(path.dirname(workflowMcpConfigPath), { recursive: true, force: true });
3455
2559
  }
3456
2560
  catch {
3457
- // best-effort: nothing actionable if the temp dir is already gone.
3458
2561
  }
3459
2562
  };
3460
- // Restore the shared per-agent agents dir after the run (issue #401):
3461
- // remove the workflow subagent files THIS run copied in, so a scoped
3462
- // workflow never leaves definitions behind for the next, unrelated run to
3463
- // inherit. Mirrors cleanupWorkflowMcpConfig — tear down only what we made.
3464
2563
  const cleanupWorkflowSubagents = () => {
3465
2564
  for (const target of workflowSubagentTargets) {
3466
2565
  try {
3467
2566
  fs.rmSync(target, { force: true });
3468
2567
  }
3469
2568
  catch {
3470
- // best-effort: nothing actionable if the file is already gone.
3471
2569
  }
3472
2570
  }
3473
2571
  };
3474
- // for_each dispatch (issue #343). A workflow that declares `for_each:` is a
3475
- // declarative dynamic fan-out, not a single-agent run: execute the producer,
3476
- // expand one stage teammate per produced item (+ optional verify panel),
3477
- // stage them into a team, then drive the supervisor until the DAG drains.
3478
- // This is mutually exclusive with the single-agent loop/fallback paths — the
3479
- // fan-out IS the run.
3480
2572
  if (workflowForEach) {
3481
2573
  cleanupWorkflowMcpConfig();
3482
2574
  cleanupWorkflowSubagents();
@@ -3487,10 +2579,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3487
2579
  });
3488
2580
  process.exit(exitCode);
3489
2581
  }
3490
- // Loop dispatch (issue #332). Active when --loop is passed OR a workflow
3491
- // declares a `loop:` block. The loop path runs AFTER the #346 pre-flight
3492
- // gate above (which fired once) — the loop's token budget is an ADDITIONAL
3493
- // guard, not a replacement. Composable, not bypassing.
3494
2582
  let loopConfig;
3495
2583
  try {
3496
2584
  loopConfig = buildLoopConfig(options, workflowLoop);
@@ -3528,12 +2616,8 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3528
2616
  cleanupWorkflowMcpConfig();
3529
2617
  cleanupWorkflowSubagents();
3530
2618
  process.stderr.write(chalk.gray(`[loop] stopped: ${result.stoppedBy} after ${result.iterations} iteration(s), ${result.tokens} tokens (checkpoint: ${path.join(runDir, 'checkpoint.json')})\n`));
3531
- // Governance chokepoint (#347): the --loop path exits here, bypassing
3532
- // the normal finalize below — record its one audit entry.
3533
2619
  const loopExit = loopExitCode(result.stoppedBy);
3534
2620
  recordDispatchedRun({ agent, version: defaultVersion ?? 'unknown', mode, cwd, exitCode: loopExit });
3535
- // A loop is always headless; surface any commits it left unpushed
3536
- // and any open PR left without a durable lander (RUSH-2394).
3537
2621
  if (shouldWarnUnpushed(mode, false)) {
3538
2622
  await warnUnpushedWork(cwd);
3539
2623
  await warnOrphanedOpenPr(cwd);
@@ -3547,15 +2631,7 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3547
2631
  process.exit(1);
3548
2632
  }
3549
2633
  }
3550
- // Agent footgun (RUSH-1829): a run with no prompt and no explicit
3551
- // --interactive resolves to interactive intent, but in a non-TTY shell
3552
- // (a headless agent, a pipe, CI) there is no terminal to host the REPL —
3553
- // the TUI attaches to dead stdin and hangs forever. Fail fast with the
3554
- // headless alternatives instead of launching a doomed interactive session.
3555
2634
  if (inferredInteractiveWithoutTty(execOptions, isInteractiveTerminal())) {
3556
- // Tear down the workflow MCP config + subagents staged above before we
3557
- // exit — same as every sibling exit path; requireInteractiveSelection
3558
- // process.exits, so cleanup must happen first or it leaks.
3559
2635
  cleanupWorkflowMcpConfig();
3560
2636
  cleanupWorkflowSubagents();
3561
2637
  requireInteractiveSelection(`Launching ${agent} interactively`, [
@@ -3568,10 +2644,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3568
2644
  let ranAgent = agent;
3569
2645
  let ranVersion = defaultVersion;
3570
2646
  if (fallback.length > 0 || (rotationResult !== null && prompt !== undefined && !options.interactive)) {
3571
- // Fallback and balanced runs need captured output so a clean-exit
3572
- // session-limit refusal can update account availability.
3573
- // The sink reports which chain entry actually executed (may differ from
3574
- // the primary after a rate-limit handoff) so the audit record is honest.
3575
2647
  const sink = {};
3576
2648
  exitCode = await runWithFallback({ ...execOptions, prompt: prompt, fallback, dispatchSink: sink });
3577
2649
  ranAgent = sink.agent ?? agent;
@@ -3582,28 +2654,11 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3582
2654
  }
3583
2655
  cleanupWorkflowMcpConfig();
3584
2656
  cleanupWorkflowSubagents();
3585
- // Surface committed-but-unpushed work a headless writable run left
3586
- // behind, so it isn't silently stranded in a worktree. Also warn when
3587
- // the branch still has an OPEN PR (RUSH-2394) — a background
3588
- // `gh pr checks --watch` dies with the agent. Advisory only,
3589
- // never throws; skipped for interactive runs (the human sees the shell)
3590
- // and read-only plan mode (can't commit).
3591
2657
  if (shouldWarnUnpushed(mode, resolveInteractive(execOptions))) {
3592
2658
  await warnUnpushedWork(cwd);
3593
2659
  await warnOrphanedOpenPr(cwd);
3594
2660
  }
3595
- // Governance chokepoint (#347): every dispatched run finalizes here.
3596
- // ONE tamper-evident audit record per run — non-fatal by contract.
3597
2661
  recordDispatchedRun({ agent: ranAgent, version: ranVersion ?? 'unknown', mode, cwd, exitCode });
3598
- // A clean headless exit is real auth evidence — the account authenticated
3599
- // and produced a result. Record it as the per-account FACT `agents view`
3600
- // renders (`last used ok`), keyed to the slot the run used so it lands on
3601
- // the right row and clears any stale failure fact (PHNX-4116). A non-zero
3602
- // exit is NOT recorded as an auth failure: the exit code alone does not
3603
- // prove the token was rejected (a task can fail for a hundred reasons), and
3604
- // a lying "auth failure" fact is worse than none. Real auth failures are
3605
- // recorded where they are actually detected (the routine runner's
3606
- // isAuthFailureFromLog sites) and by the daemon probe.
3607
2662
  if (exitCode === 0) {
3608
2663
  recordRunAuthOutcome({
3609
2664
  agent: ranAgent,
@@ -3613,8 +2668,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3613
2668
  outcome: { ok: true },
3614
2669
  });
3615
2670
  }
3616
- // First-successful-run star nudge (one-time, non-nagging). Only on a
3617
- // clean run, and never when output is machine-readable/quiet.
3618
2671
  if (exitCode === 0)
3619
2672
  maybeShowStarNudge({ quiet: options.json || options.quiet });
3620
2673
  process.exit(exitCode);
@@ -3622,8 +2675,6 @@ agents run auto --device yosemite-s0 "fix the flaky test" # pin the device
3622
2675
  catch (err) {
3623
2676
  cleanupWorkflowMcpConfig();
3624
2677
  cleanupWorkflowSubagents();
3625
- // An agent that committed then crashed is the case where stranded work
3626
- // matters most — warn before exiting the error path too.
3627
2678
  if (shouldWarnUnpushed(mode, resolveInteractive(execOptions))) {
3628
2679
  await warnUnpushedWork(cwd);
3629
2680
  await warnOrphanedOpenPr(cwd);