@phnx-labs/agents-cli 1.22.120 → 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 +227 -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 +17 -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
package/dist/lib/exec.js CHANGED
@@ -1,10 +1,4 @@
1
1
  import { captureLaunchBinding, recordCompletedLaunch } from './session/hook-sessions.js';
2
- /**
3
- * Agent execution -- command building, process spawning, and rate-limit fallback.
4
- *
5
- * Translates high-level ExecOptions into CLI invocations for each supported agent,
6
- * manages environment isolation per agent, and chains fallback agents on rate limits.
7
- */
8
2
  import { spawn } from 'child_process';
9
3
  import { randomUUID } from 'crypto';
10
4
  import * as fs from 'fs';
@@ -49,13 +43,6 @@ import { getAccountInfo } from './agents.js';
49
43
  import { getUsageLookupKey, noteClaudeSessionLimit, noteClaudeOutOfCredits, clearClaudeAccountRefusal, parseClaudeSessionLimitReset, noteClaudeModelRefusal, clearClaudeModelRefusal, parseClaudeModelRefusal, claudeModelRefusalKey, } from './accounting/usage.js';
50
44
  import { claudeProjectDirName } from './project-key.js';
51
45
  import { bootMark, flushBootProfile } from './boot-profile.js';
52
- /**
53
- * Map a raw mode string (CLI flag, YAML field, env var) to the canonical Mode.
54
- *
55
- * Accepts the historical `full` spelling and rewrites it to `skip`. Throws on
56
- * anything outside the four canonical values so bad input fails loud at the
57
- * boundary rather than silently picking a wrong code path.
58
- */
59
46
  export function normalizeMode(input) {
60
47
  if (!input) {
61
48
  throw new Error(`Mode is required. Use one of: ${ALL_MODES.join(', ')}.`);
@@ -67,23 +54,6 @@ export function normalizeMode(input) {
67
54
  return v;
68
55
  throw new Error(`Invalid mode '${input}'. Use one of: ${ALL_MODES.join(', ')} (or 'full' as a deprecated alias for 'skip').`);
69
56
  }
70
- /**
71
- * Detect the headless-plan stall footgun.
72
- *
73
- * A slash command (e.g. `/code:commit`) run headless under the IMPLICIT default
74
- * `plan` mode hangs forever: plan is read-only, so the agent calls ExitPlanMode
75
- * to start working, and in a headless run there is no TTY to approve it. The
76
- * process just sits there. Callers use this to fail fast with a fix instead.
77
- *
78
- * Returns the offending command token (e.g. `/code:commit`) when the run should
79
- * be blocked, else null. Guards are deliberately narrow:
80
- * - interactive runs / no prompt -> not headless, never blocks
81
- * - explicit --mode (modeIsDefault false) -> respected; `--mode plan` is a
82
- * legitimate read-only command run and must not be blocked
83
- * - resolved mode is not `plan` -> only plan stalls at ExitPlanMode
84
- * - prompt is not a slash command -> natural-language read-only prompts
85
- * ("summarize commits") are a valid default-plan use and must not be blocked
86
- */
87
57
  export function headlessPlanStallCommand(args) {
88
58
  const { prompt, interactive, mode, modeIsDefault } = args;
89
59
  if (interactive === true || prompt === undefined)
@@ -97,35 +67,14 @@ export function headlessPlanStallCommand(args) {
97
67
  return null;
98
68
  return trimmed.split(/\s+/)[0];
99
69
  }
100
- /**
101
- * Resolve a requested mode against an agent's capability table.
102
- *
103
- * - `auto` on an agent without auto support silently degrades to `edit`
104
- * (every agent supports edit-like behavior as its default).
105
- * - `plan` on an agent without a read-only mode degrades to the agent's
106
- * safest native mode (`capabilities.modes[0]`, typically `edit`). Agents
107
- * like antigravity have no plan flag; hard-failing made
108
- * multi-agent scripts (`--mode plan` for everyone) unusable and diverged
109
- * from `agents teams add`, which already defaults to `edit`. Callers that
110
- * care (the `agents run` CLI) must surface a warning when requested ≠
111
- * resolved so the elevation is not silent.
112
- * - `skip` on an agent without skip support throws with a clear message
113
- * naming the agent's supported modes. No silent fallback — the user
114
- * explicitly asked to bypass permissions; pretending we did is unsafe.
115
- */
116
70
  export function resolveMode(agent, requested) {
117
71
  const supported = AGENTS[agent].capabilities.modes;
118
72
  if (supported.includes(requested))
119
73
  return requested;
120
74
  if (requested === 'auto') {
121
- // Fall back to edit — guaranteed to exist on every agent (every agent has
122
- // at least 'edit' in its modes table, since that's the default behavior).
123
75
  return 'edit';
124
76
  }
125
77
  if (requested === 'plan') {
126
- // No read-only mode on this agent. modes[0] is the declared safest mode
127
- // (edit for antigravity/…). Prefer that over hard-fail so
128
- // uniform multi-agent `--mode plan` dispatches still run.
129
78
  return supported[0];
130
79
  }
131
80
  throw new Error(`${agent} does not support '${requested}' mode. Supported modes: ${supported.join(', ')}.`);
@@ -173,21 +122,9 @@ export function resolveHeadlessMode(agent, requested, interactive, warningContex
173
122
  }
174
123
  return mode;
175
124
  }
176
- /**
177
- * The mode an agent should run in when the caller has no preference.
178
- *
179
- * Returns the first entry in the agent's `capabilities.modes` table — the
180
- * declaration order is the source of truth for "the safest mode this agent
181
- * supports." Agents that include `plan` list it first; agents like
182
- * antigravity that have no read-only mode list `edit` first.
183
- *
184
- * Prefer this over a hard-coded `'plan'` when the agent is known. `resolveMode`
185
- * also maps an unsupported `'plan'` request onto this same value.
186
- */
187
125
  export function defaultModeFor(agent) {
188
126
  return AGENTS[agent].capabilities.modes[0];
189
127
  }
190
- /** Safe mode used when the user did not provide --mode or a configured default. */
191
128
  export function implicitModeFor(agent) {
192
129
  return agent === 'codex' ? 'edit' : 'plan';
193
130
  }
@@ -234,32 +171,16 @@ export function codexSandboxPreflight(args) {
234
171
  `\n` +
235
172
  `Or run codex WITHOUT a filesystem sandbox instead: add --mode skip.`);
236
173
  }
237
- /**
238
- * Identity a custom-harness run stamps on env / pid-registry / sidecars.
239
- * `agent` is the host CLI; `harnessName` is the profile the user launched.
240
- * Empty/whitespace harness names fall back to the host so a blank stamp
241
- * never hides a real agent.
242
- */
243
174
  export function stampedAgentName(options) {
244
175
  const harness = options.harnessName?.trim();
245
176
  return harness || options.agent;
246
177
  }
247
- /**
248
- * Profile name when it differs from the host agent. Undefined for a native
249
- * run, so pid-registry / sidecar records stay sparse.
250
- */
251
178
  export function customHarnessName(options) {
252
179
  const harness = options.harnessName?.trim();
253
180
  if (!harness || harness === options.agent)
254
181
  return undefined;
255
182
  return harness;
256
183
  }
257
- /**
258
- * Resolve interactive vs headless. Explicit flags are definitive and win over
259
- * inference: `--interactive` forces interactive, `--headless` forces headless.
260
- * With neither flag, prompt presence decides (prompt -> headless, none -> interactive).
261
- * `--interactive` takes precedence over `--headless`; the CLI layer rejects passing both.
262
- */
263
184
  export function resolveInteractive(options) {
264
185
  if (options.interactive === true)
265
186
  return true;
@@ -267,48 +188,17 @@ export function resolveInteractive(options) {
267
188
  return false;
268
189
  return options.prompt === undefined;
269
190
  }
270
- /**
271
- * True when a run resolved to *inferred* interactive intent — no prompt and no
272
- * explicit `--interactive` — but there is no terminal to host the REPL. Launching
273
- * would attach a TUI to a dead stdin and hang forever, so the caller should fail
274
- * fast with the headless alternatives instead (RUSH-1829).
275
- *
276
- * An explicit `--interactive` is the caller's deliberate choice and is never
277
- * blocked (they may be driving a PTY we can't detect). Pure — the TTY state is a
278
- * parameter so this is unit-testable without touching `process.std*`.
279
- */
280
191
  export function inferredInteractiveWithoutTty(options, isTty) {
281
192
  if (options.interactive === true)
282
193
  return false;
283
194
  return resolveInteractive(options) && !isTty;
284
195
  }
285
- /**
286
- * Decide whether spawnAgent must capture (PIPE + tee) the child's stdout so the
287
- * live budget watcher can parse it (issue #346, FIX 3).
288
- *
289
- * The bug this fixes: stdout used to be PIPED only when downstream output was
290
- * piped (`piped = !isTTY`). For a normal headless run AT A TERMINAL, stdout was
291
- * 'inherit', so `child.stdout` was null and the watcher — hence the mid-run
292
- * hard-cap kill — was silently skipped. We now tap stdout for ALL
293
- * non-interactive runs when caps are active, regardless of TTY, and tee it back
294
- * so the user still sees output. Interactive REPLs are never tapped (the human
295
- * owns the TTY; they rely on the pre-flight gate).
296
- *
297
- * @param interactive resolveInteractive() result for the run
298
- * @param piped true when the parent's stdout is NOT a TTY (output piped)
299
- * @param capsActive true when a budget watcher is attached (caps configured)
300
- */
301
196
  export function shouldTapStdout(interactive, piped, capsActive, captureTail = false) {
302
197
  if (interactive)
303
198
  return false;
304
- // Always pipe when the caller pipes us downstream (preserve composability),
305
- // when caps are active so the watcher can read the stream at a TTY, or when
306
- // a fallback chain needs a stdout tail for rate-limit detection.
307
199
  return piped || capsActive || captureTail;
308
200
  }
309
- /** Pattern for valid environment variable names (C identifier rules). */
310
201
  const EXEC_ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
311
- /** Parse a single KEY=VALUE string into a tuple, validating the key name. */
312
202
  function parseExecEnvEntry(entry) {
313
203
  const separatorIndex = entry.indexOf('=');
314
204
  if (separatorIndex <= 0) {
@@ -321,52 +211,21 @@ function parseExecEnvEntry(entry) {
321
211
  }
322
212
  return [key, value];
323
213
  }
324
- /** Parse an array of KEY=VALUE strings into an env record. Returns undefined for empty input. */
325
214
  export function parseExecEnv(entries) {
326
215
  if (entries.length === 0) {
327
216
  return undefined;
328
217
  }
329
218
  return Object.fromEntries(entries.map(parseExecEnvEntry));
330
219
  }
331
- /**
332
- * Resolve the launch id a run exports as `AGENT_LAUNCH_ID`.
333
- *
334
- * The launch id is the stable correlation key the SessionStart hook records
335
- * alongside the agent's real session id (terminals/sessions/<pid>.json), so it
336
- * is what maps a launch to its exact session even when the hook runs under a
337
- * different pid (tmux pane leaf / cmd.exe wrapper) — and, across an SSH hop, what
338
- * lets a `--device` launcher resolve the remote-coined id for agents that never
339
- * accept a forced `--session-id`.
340
- *
341
- * ADOPT a caller-supplied `AGENT_LAUNCH_ID` (a `--device` launcher forwards one via
342
- * `--env` so it controls the key end-to-end); MINT a fresh one otherwise (every
343
- * local run, which passes none). A malformed inbound value is ignored in favour
344
- * of a fresh mint — the key must be a real correlation id, never an empty string.
345
- */
346
220
  export function resolveLaunchId(envLaunchId) {
347
221
  const inbound = envLaunchId?.trim();
348
222
  return inbound ? inbound : randomUUID();
349
223
  }
350
- /**
351
- * Build the process environment for an agent invocation.
352
- * Pins CLAUDE_CONFIG_DIR for Claude, CODEX_HOME for Codex, and COPILOT_HOME
353
- * for GitHub Copilot; strips the other agents' env vars so they don't leak
354
- * into unrelated invocations.
355
- */
224
+ // Child runs shed parent session/mailbox/account/exec-home identity; lineage is reintroduced only through explicit parent fields.
356
225
  export function buildExecEnv(options) {
357
226
  const result = { ...sanitizeProcessEnv(process.env) };
358
- // Config-dir env vars are agent-specific. When the caller is running inside
359
- // an agent-managed shell, process.env already carries one; spreading into a
360
- // different agent's env would leak a config pointer the target CLI doesn't
361
- // understand. Each harness adapter pins its own config-dir var to the versioned
362
- // home and strips the foreign ones; a harness with no config-dir env (the old
363
- // `else`) has no adapter override, so all four are stripped here.
364
227
  const configAdapter = resolveHarnessAdapter(options.agent);
365
228
  if (configAdapter.applyExecConfigEnv) {
366
- // Resolve version/versionHome here (this module already imports
367
- // installations/versions); the adapters must not import it themselves or they
368
- // close a versions -> shims -> harness -> adapter import cycle. execHome is
369
- // the account slot (PHNX-3940 T5) and wins over a legacy configVersion label.
370
229
  const { version, versionHome } = resolveExecConfigHome(options);
371
230
  configAdapter.applyExecConfigEnv(result, {
372
231
  agent: options.agent,
@@ -380,108 +239,59 @@ export function buildExecEnv(options) {
380
239
  else {
381
240
  stripForeignConfigDir(result);
382
241
  }
383
- // A new harness must not inherit its spawner's own session/mailbox or editor
384
- // ownership. Keep those relationships as lineage, including across SSH.
385
242
  delete result.AGENT_SESSION_ID;
386
243
  delete result.AGENTS_SESSION_ID;
387
244
  delete result.AGENTS_MAILBOX_DIR;
388
245
  delete result.AGENT_TERMINAL_ID;
389
246
  const launchIdentity = launchIdentityEnv();
390
247
  Object.assign(result, launchIdentity);
391
- // Point the agent at its own mailbox so the PreToolUse `mailbox-inject` hook
392
- // knows which box to drain and inject mid-run. Keyed by the session id — the
393
- // same id the writer resolves via mailboxIdForActiveSession(). A loop run
394
- // overrides this to its run-level box via options.env (spread below), so all
395
- // iterations share one inbox.
396
248
  if (options.sessionId && isValidMailboxId(options.sessionId)) {
397
249
  result.AGENTS_MAILBOX_DIR = mailboxDir(options.sessionId);
398
- // Full session id for agent-callable tools (`agents feed post`, etc.).
399
250
  result.AGENT_SESSION_ID = options.sessionId;
400
251
  result.AGENTS_SESSION_ID = options.sessionId;
401
252
  }
402
- // Lineage edge: the child's parent is THIS process's session (the spawner), so a
403
- // sub-agent's events carry a walkable edge back to who spawned it. The event floor
404
- // (events.ts::resolveProvenance) reads AGENTS_PARENT_SESSION_ID and stamps it on
405
- // every event the child emits. `options.sessionId` is the CHILD's id, so read the
406
- // spawner from the live env; guard a same-session resume from naming itself parent.
407
- // An SSH continuation has no runtime marker; keep its forwarded parent edge.
408
253
  delete result.AGENTS_PARENT_SESSION_ID;
409
254
  const spawnerSessionId = launchIdentity.AGENTS_PARENT_SESSION_ID;
410
255
  if (spawnerSessionId && spawnerSessionId !== options.sessionId) {
411
256
  result.AGENTS_PARENT_SESSION_ID = spawnerSessionId;
412
257
  }
413
258
  result.AGENTS_RUNTIME = resolveInteractive(options) ? 'terminal' : 'headless';
414
- // The agent's own `secrets …` calls must hit the same store agents-cli reads
415
- // for it: the process client points the standalone at the user agents dir
416
- // (buildServeEnv, MIG-1), while a bare `secrets` defaults to ~/.secrets. Left
417
- // unset, an agent's `secrets exec` ran against a second broker and a second
418
- // event log, and an unlock in one was invisible in the other. An explicit
419
- // SECRETS_HOME in the launching environment wins, matching buildServeEnv.
259
+ // Bind the standalone secrets client to the same store agents-cli resolved.
420
260
  result.SECRETS_HOME = result.SECRETS_HOME ?? getUserAgentsDir();
421
- // Durable SessionStart metadata. The hook joins these launch facts to the
422
- // harness-provided real session id and writes them under the shared history
423
- // directory, so a later resume can restore the permission boundary without
424
- // re-parsing harness-specific transcripts.
425
261
  result.AGENTS_RUN_MODE = resolveHeadlessMode(options.agent, normalizeMode(options.mode), resolveInteractive(options), options.modeWarningContext, options.modeWarningState);
426
262
  result.AGENTS_HISTORY_DIR = getHistoryDir();
427
- // Durable origin version for a later native resume. The SessionStart hook joins
428
- // this to the harness's real session id (like AGENTS_RUN_MODE), so recovery can
429
- // pin the exact origin version even when the transcript carries no derivable one
430
- // (codex's `.codex-homes/<version>/` home) — the "version not recorded" fallback
431
- // to `/continue` this closes (PHNX-3626). Resolve the concrete version-home id
432
- // the same way the spawn path does; only stamp a real one.
433
263
  if (options.agent) {
434
264
  const runVersion = options.version ?? resolveVersion(options.agent, options.cwd || process.cwd());
435
265
  if (runVersion)
436
266
  result.AGENTS_RUN_VERSION = runVersion;
437
267
  }
438
- // So activity / feed posts stamp the right harness without re-detecting.
439
- // A custom-harness run (`agents run deepseek`) must stamp the PROFILE name,
440
- // not the host CLI (`claude`) — otherwise sessions and feed posts cannot
441
- // tell the two apart (PHNX-2935).
442
268
  if (options.agent) {
443
269
  result.AGENTS_AGENT_NAME = stampedAgentName(options);
444
270
  }
445
271
  if (options.cwd) {
446
272
  result.AGENTS_CWD = options.cwd;
447
273
  }
448
- // An account-slot launch (PHNX-3940 T5) tells the versioned alias which
449
- // HOME-shaped dir owns this run's config, so the alias's version-home pin
450
- // (claude: CLAUDE_CONFIG_DIR) yields to the slot instead of overriding the
451
- // adapter's pin above. Set only for a slot launch and cleared otherwise, so a
452
- // run spawned from inside a slot session never inherits its parent's slot.
453
274
  if (options.execHome) {
454
275
  result.AGENTS_EXEC_HOME = options.execHome;
455
276
  }
456
277
  else {
457
278
  delete result.AGENTS_EXEC_HOME;
458
279
  }
459
- // Durable account identity for this run (PHNX-3940 model-refusal tracking).
460
- // Cleared when absent so a run spawned from inside an account-scoped session
461
- // never inherits its parent's account id.
462
280
  if (options.accountId) {
463
281
  result.AGENTS_RUN_ACCOUNT_ID = options.accountId;
464
282
  }
465
283
  else {
466
284
  delete result.AGENTS_RUN_ACCOUNT_ID;
467
285
  }
468
- // Export the run's durable name (companion to AGENT_SESSION_ID) so a
469
- // SessionStart hook / the agent can associate its transcript with the handle
470
- // the user gave the run. Only set when --name was passed.
471
286
  if (options.name) {
472
287
  result.AGENT_SESSION_NAME = options.name;
473
288
  }
474
- // Actor provenance -- who initiated this run. Rides the env so the whole spawn
475
- // tree shares one actor, and (for a resolved human) so the agent's own git
476
- // commits are credited to the person instead of the shared account. options.env
477
- // (spread last) overrides any of these keys a caller sets explicitly.
478
289
  Object.assign(result, actorEnv(resolveActor()));
479
290
  return {
480
291
  ...result,
481
292
  ...options.env,
482
293
  };
483
294
  }
484
- /** Materialize config roots for vendor CLIs that do not create parents recursively. */
485
295
  export function ensureVendorHomeDir(agent, versionHome) {
486
296
  if (agent !== 'cursor' && agent !== 'grok' && agent !== 'copilot')
487
297
  return null;
@@ -502,12 +312,6 @@ function ensureVendorHomeForSpawn(options) {
502
312
  if (versionHome)
503
313
  ensureVendorHomeDir(options.agent, versionHome);
504
314
  }
505
- /**
506
- * CLI command templates for every supported agent.
507
- *
508
- * Each agent's `modeFlags` keys MUST match the modes listed in
509
- * AGENTS[agent].capabilities.modes. A test in exec.test.ts asserts this.
510
- */
511
315
  export const AGENT_COMMANDS = {
512
316
  claude: {
513
317
  base: ['claude'],
@@ -529,13 +333,9 @@ export const AGENT_COMMANDS = {
529
333
  promptFlag: 'positional',
530
334
  resume: { subcommand: 'resume' },
531
335
  modeFlags: {
532
- // Native Codex modes are assembled by codexPolicyArgs below. Named
533
- // permission profiles keep filesystem access and network access
534
- // independent; legacy --sandbox flags cannot express that combination.
535
336
  plan: [],
536
337
  edit: [],
537
338
  auto: [],
538
- // skip = codex --yolo: drops the sandbox entirely and approves anything.
539
339
  skip: ['--dangerously-bypass-approvals-and-sandbox'],
540
340
  },
541
341
  jsonFlags: ['--json'],
@@ -556,9 +356,6 @@ export const AGENT_COMMANDS = {
556
356
  opencode: {
557
357
  base: ['opencode', 'run'],
558
358
  promptFlag: 'positional',
559
- // opencode's native resume is `opencode --session <id>` (NOT under `run`), so
560
- // it does not compose with this headless `run` base. Until that's verified on
561
- // a box with opencode installed, opencode resumes via Tier-2 `/continue`.
562
359
  modeFlags: {
563
360
  plan: ['--agent', 'plan'],
564
361
  edit: ['--agent', 'build'],
@@ -577,17 +374,6 @@ export const AGENT_COMMANDS = {
577
374
  jsonFlags: ['--output-format', 'stream-json'],
578
375
  modelFlag: '--model',
579
376
  },
580
- // GitHub Copilot CLI (`@github/copilot`, GA 2026-02-25). Flags verified
581
- // against `copilot --help` from v0.0.413+:
582
- // -p, --prompt <text> non-interactive one-shot
583
- // --mode <interactive|plan|autopilot>
584
- // --autopilot start in autopilot (smart-classifier) mode
585
- // --allow-all-tools required for non-interactive tool exec
586
- // --allow-all (alias --yolo) tools + paths + URLs
587
- // --output-format <text|json> json => JSONL, one object per line
588
- // --model <model>
589
- // Plan mode is read-only so it does not need an allow-tools grant; edit
590
- // needs --allow-all-tools so headless runs don't stall on prompts.
591
377
  copilot: {
592
378
  base: ['copilot'],
593
379
  promptFlag: '-p',
@@ -613,20 +399,14 @@ export const AGENT_COMMANDS = {
613
399
  base: ['goose', 'run'],
614
400
  promptFlag: 'positional',
615
401
  modeFlags: {
616
- // goose has no permission flags — edit is the default behavior.
617
402
  edit: [],
618
403
  },
619
404
  },
620
405
  // TODO: --output-format json is documented but currently broken upstream
621
- // ("flags provided but not defined: -output-format"). Track resolution at
622
- // https://github.com/google-antigravity/antigravity-cli/issues/7 before
623
- // adding `jsonFlags` here.
624
406
  antigravity: {
625
407
  base: ['agy'],
626
408
  promptFlag: 'positional',
627
409
  modeFlags: {
628
- // agy --help shows no plan/edit flags; default behavior is edit-like
629
- // (prompts on tool use). Only skip has an explicit flag.
630
410
  edit: [],
631
411
  skip: ['--dangerously-skip-permissions'],
632
412
  },
@@ -637,7 +417,6 @@ export const AGENT_COMMANDS = {
637
417
  base: ['grok'],
638
418
  promptFlag: '-p',
639
419
  modeFlags: {
640
- // grok --help lists `--permission-mode plan`; the TUI defaults to ask.
641
420
  plan: ['--permission-mode', 'plan'],
642
421
  edit: [],
643
422
  skip: ['--always-approve'],
@@ -659,18 +438,13 @@ export const AGENT_COMMANDS = {
659
438
  modelFlag: '--model',
660
439
  resume: { flag: '--session', since: '0.19.2' },
661
440
  },
662
- // Factory AI Droid (`droid exec` for headless, `droid` for TUI). Flags from
663
- // docs.factory.ai CLI reference: prompt is positional; --auto low|medium|high
664
- // escalates autonomy (default is read-only); --skip-permissions-unsafe drops
665
- // all guardrails; -o stream-json streams JSONL events; -m selects the model.
666
- // The `exec` subcommand is dropped for interactive runs (see buildExecCommand).
667
441
  droid: {
668
442
  base: ['droid', 'exec'],
669
443
  promptFlag: 'positional',
670
444
  modeFlags: {
671
- plan: [], // droid's default exec mode is read-only
672
- edit: ['--auto', 'low'], // create/edit files, non-destructive
673
- auto: ['--auto', 'high'], // full autonomy
445
+ plan: [],
446
+ edit: ['--auto', 'low'],
447
+ auto: ['--auto', 'high'],
674
448
  skip: ['--skip-permissions-unsafe'],
675
449
  },
676
450
  jsonFlags: ['-o', 'stream-json'],
@@ -685,14 +459,6 @@ export const AGENT_COMMANDS = {
685
459
  },
686
460
  modelFlag: '--model',
687
461
  },
688
- // Meta Muse Code (`muse exec` headless, `muse` TUI). Flags from
689
- // `muse --help` / `muse exec --help` (v0.1.0): prompt is positional;
690
- // --model selects muse-spark-*; --reasoning-effort is the effort dial;
691
- // --disable-write approximates plan (no non-shell writes); --disable-approval
692
- // keeps the sandbox (auto); --yolo drops approval+sandbox and trusts the
693
- // workspace (skip). --json emits JSONL on stdout. Interactive resume is
694
- // `muse resume <id>`; headless resume is `muse exec --session-id <id>` —
695
- // see the muse resume branch in buildExecCommand.
696
462
  muse: {
697
463
  base: ['muse', 'exec'],
698
464
  promptFlag: 'positional',
@@ -704,20 +470,8 @@ export const AGENT_COMMANDS = {
704
470
  },
705
471
  jsonFlags: ['--json'],
706
472
  modelFlag: '--model',
707
- // Flag form covers headless (`--session-id`). Interactive uses the
708
- // `resume` subcommand — special-cased in buildExecCommand.
709
473
  resume: { flag: '--session-id' },
710
474
  },
711
- // Warp Agent CLI (`warp`) — the interactive TUI. It has NO headless one-shot
712
- // form: the documented flags are --api-key/--auto-approve/--resume <token>/
713
- // --set-provider-api-key/--clear-provider-api-key/--version/--help — no
714
- // -p/--prompt, no --model (model is the `/model` picker), no JSON output. So
715
- // bare `warp` opens the TUI and the single `edit` mode maps to no flags
716
- // (mirrors hermes); there are no jsonFlags/modelFlag to declare. No `resume`:
717
- // `warp --resume <token>` reopens a SERVER-SIDE conversation by token, but
718
- // warp is not session-tracked (absent from SESSION_AGENTS) so agents-cli has
719
- // no local id to feed — declaring it would make nativeResume(warp) true
720
- // against an unreachable path.
721
475
  warp: {
722
476
  base: ['warp'],
723
477
  promptFlag: 'positional',
@@ -726,11 +480,6 @@ export const AGENT_COMMANDS = {
726
480
  },
727
481
  },
728
482
  };
729
- /**
730
- * Whether `agent` has a native resume form (Tier 1). Derived solely from the
731
- * command template's `resume` field — the single source of truth. Agents that
732
- * return false resume via the universal Tier-2 `/continue` replay instead.
733
- */
734
483
  export function nativeResume(agent, version) {
735
484
  const resume = AGENT_COMMANDS[agent]?.resume;
736
485
  if (!resume)
@@ -739,41 +488,9 @@ export function nativeResume(agent, version) {
739
488
  return true;
740
489
  return !!version && compareVersions(installedReleaseFor(agent, version), resume.since) >= 0;
741
490
  }
742
- /**
743
- * Build the `-c` value that adds `dir` to codex's workspace-write writable
744
- * roots. Codex parses the value as TOML, so it's a single-element TOML array of
745
- * one quoted string. Used on codex resume forms, which reject `--add-dir` and
746
- * only accept `-c` config overrides.
747
- */
748
491
  export function codexWritableRootsConfig(dir) {
749
492
  return `sandbox_workspace_write.writable_roots=[${JSON.stringify(dir)}]`;
750
493
  }
751
- /**
752
- * Resolve the executable `buildExecCommand` will put in `cmd[0]`, or null when
753
- * that resolution finds nothing on disk.
754
- *
755
- * This is an EXISTENCE probe, not an "is it managed by us" check. A harness the
756
- * user installed themselves (Homebrew, a vendor `curl | sh`, a distro package)
757
- * has no version home at all, and running it is a supported state — so with no
758
- * version pinned we answer with a PATH lookup of the bare launch command, the
759
- * same thing `spawnAgent` would resolve.
760
- *
761
- * `findInPath` deliberately excludes our own shims dir, because a shim is a
762
- * dispatcher rather than an install. That exclusion alone is too strong here:
763
- * the shim DOES launch whenever agents-cli owns at least one version of the
764
- * agent — it resolves the version itself, and when no default is pinned it
765
- * prints its own accurate `no default set … agents use <agent> <version>`
766
- * guidance. Pre-empting that with "not installed" would name the wrong fix
767
- * (`agents add`) for a machine that already has the harness. So the shim counts
768
- * only when a managed version exists; with zero managed versions it is the dead
769
- * end this probe was written to catch (RUSH-2339).
770
- *
771
- * The version-pinned branch mirrors buildExecCommand exactly: versioned shim
772
- * first, then the version home's real binary. It deliberately does NOT fall back
773
- * to PATH — with a version pinned, buildExecCommand spawns the literal
774
- * `<cli>@<version>`, which is not on PATH, so a PATH hit here would be a lie
775
- * that still exits 127.
776
- */
777
494
  export function resolveLaunchBinary(agent, version) {
778
495
  const command = AGENT_COMMANDS[agent].base[0];
779
496
  if (version) {
@@ -791,19 +508,12 @@ export function resolveLaunchBinary(agent, version) {
791
508
  return native;
792
509
  if (listInstalledVersions(agent).length === 0)
793
510
  return null;
794
- // Re-scan PATH accepting the shim: point findInPath's exclusion at a path that
795
- // matches nothing, so the real shims dir participates like any other PATH entry.
796
511
  return findInPath(command, { shimsDir: path.join(getShimsDir(), '.no-such-dir') });
797
512
  }
798
- /** Assemble the full CLI argument array for an agent invocation. */
799
513
  export function buildExecCommand(options) {
800
514
  const template = AGENT_COMMANDS[options.agent];
801
515
  const cmd = [...template.base];
802
516
  const interactive = resolveInteractive(options);
803
- // For Codex, Droid, and Muse, 'exec' is the headless subcommand; for OpenCode,
804
- // 'run' is. Drop it for interactive mode so we launch the TUI (`codex` /
805
- // `droid` / `muse` / `opencode`) instead of the one-shot headless subcommand
806
- // ('codex exec' / 'droid exec' / 'muse exec' / 'opencode run').
807
517
  if (interactive) {
808
518
  if ((options.agent === 'codex' || options.agent === 'droid' || options.agent === 'muse') &&
809
519
  cmd[1] === 'exec') {
@@ -813,16 +523,6 @@ export function buildExecCommand(options) {
813
523
  cmd.splice(1, 1);
814
524
  }
815
525
  }
816
- // Native resume with a `{ subcommand }` shape (codex) appends the resume verb
817
- // to the base: `codex exec` -> `codex exec resume` (headless) and, after the
818
- // interactive drop above, `codex` -> `codex resume` (TUI). The session id is
819
- // pushed later as the first positional (before any prompt). `{ flag }` agents
820
- // (claude) need no base change — the flag is appended with the id below.
821
- //
822
- // Muse interactive resume is also a subcommand (`muse resume <id>`), but the
823
- // session id MUST sit immediately after the verb — mode/model flags come
824
- // after. So for interactive muse we push both `resume` and the id here, and
825
- // skip the later generic resume flag path.
826
526
  const resumeSpec = options.resume ? template.resume : undefined;
827
527
  let museInteractiveResumeDone = false;
828
528
  if (options.agent === 'muse' && options.resume && interactive && options.sessionId) {
@@ -832,17 +532,6 @@ export function buildExecCommand(options) {
832
532
  else if (resumeSpec && 'subcommand' in resumeSpec) {
833
533
  cmd.push(resumeSpec.subcommand);
834
534
  }
835
- // Use versioned alias if a specific version was requested (e.g., claude@2.1.98).
836
- // Resolve to the absolute path of the shim so spawn doesn't depend on PATH —
837
- // on Linux installs where the shims dir isn't on PATH, spawning the bare
838
- // versioned name fails with ENOENT even though `agents view` shows the agent.
839
- //
840
- // On Windows the alias is materialized as a `.cmd` only (see
841
- // createVersionedAlias — a bash alias next to it would shadow the `.cmd` in
842
- // cmd.exe/PowerShell name resolution); the extensionless existsSync branch
843
- // below still matches a legacy install's bash alias. When no shim exists on
844
- // disk we fall back to the bare versioned name, which spawnAgent() resolves
845
- // via PATH (+ PATHEXT/shell on Windows).
846
535
  if (options.version && cmd.length > 0) {
847
536
  const versionedName = `${cmd[0]}@${options.version}`;
848
537
  const absPath = path.join(getShimsDir(), versionedName);
@@ -853,23 +542,10 @@ export function buildExecCommand(options) {
853
542
  cmd[0] = absPath;
854
543
  }
855
544
  else {
856
- // No versioned shim on disk. Prefer the version's REAL launch binary
857
- // (node_modules/.bin/<cli>) over the bare `<cli>@<version>` name — that
858
- // literal is not on PATH and spawns as ENOENT (the `kimi@0.19.2` failure).
859
- // Fall back to the literal only if the binary is absent (the run path's
860
- // ensureAgentRunnable normally repairs/creates the alias before we reach here).
861
545
  const realBinary = options.agent ? getBinaryPath(options.agent, options.version) : undefined;
862
546
  cmd[0] = realBinary && fs.existsSync(realBinary) ? realBinary : versionedName;
863
547
  }
864
548
  }
865
- // Resolve the model up front so the reasoning-flag block can honor a cost tier
866
- // that maps to reasoning effort on a single-model harness (e.g. Grok, where the
867
- // tier IS the effort dial). `modelVersion` is null when no version resolves;
868
- // `tierModel` is the concrete model a tier resolved to (null => drop the flag).
869
- // Prefer the user's explicit --model. Codex falls back to ~/.codex/config.toml
870
- // (per-version CODEX_HOME may not carry that setting). OpenCode has no model
871
- // env var — a custom-harness pin lives in OPENCODE_MODEL and must become
872
- // `--model` here, or the host silently uses its configured default (PHNX-2577).
873
549
  const effectiveModel = options.model
874
550
  ?? (options.agent === 'codex' ? readCodexConfiguredModel() : undefined)
875
551
  ?? (options.agent === 'opencode' ? options.env?.OPENCODE_MODEL : undefined);
@@ -879,41 +555,23 @@ export function buildExecCommand(options) {
879
555
  const tierResolved = effectiveModel && modelVersion && isTierToken(effectiveModel)
880
556
  ? resolveTier(options.agent, modelVersion, effectiveModel)
881
557
  : null;
882
- // An explicit --effort wins; otherwise a single-model tier's effort applies.
883
558
  const effortLevel = options.effort !== 'auto' ? options.effort : (tierResolved?.effort ?? options.effort);
884
- // Add reasoning effort flags (before mode flags for codex -c positioning)
885
- // For codex, -c must come before 'exec' subcommand, so we insert at position 1
886
559
  if (effortLevel !== 'auto') {
887
560
  const reasoningFlags = buildReasoningFlags(options.agent, effortLevel);
888
561
  if (reasoningFlags.length > 0) {
889
562
  if (options.agent === 'codex') {
890
- // Insert after 'codex' (or 'codex@version') but before 'exec'
891
563
  cmd.splice(1, 0, ...reasoningFlags);
892
564
  }
893
565
  else {
894
- // For other agents, append after base
895
566
  cmd.push(...reasoningFlags);
896
567
  }
897
568
  }
898
569
  }
899
- // Resolve the requested mode against the agent's capability table.
900
- // - `auto` on an agent without auto support → silently degrades to `edit`
901
- // - `plan` on an agent without a read-only mode → degrades to modes[0]
902
- // - headless `plan` on an agent with headlessPlan:false (kimi, grok) →
903
- // degrades to `auto` with a stderr warning (see resolveHeadlessMode)
904
- // - `skip` on an unsupported agent → throws a clear error
905
- // After resolution, the chosen mode is guaranteed to be in template.modeFlags.
906
570
  const resolvedMode = resolveHeadlessMode(options.agent, normalizeMode(options.mode), interactive, options.modeWarningContext, options.modeWarningState);
907
571
  const modeFlags = template.modeFlags[resolvedMode];
908
572
  if (!modeFlags) {
909
- // Defense in depth: would only fire if AGENTS.capabilities.modes and
910
- // AGENT_COMMANDS.modeFlags drifted apart. Tests assert they agree.
911
573
  throw new Error(`Internal error: ${options.agent} declares '${resolvedMode}' in capabilities.modes but has no entry in AGENT_COMMANDS.modeFlags.${resolvedMode}.`);
912
574
  }
913
- // Launch-arg quirks (the harness axis of Move 3): cursor's additive `--trust`
914
- // and the codex/kimi mode-flag overrides move to the harness adapter, so the
915
- // per-agent name-chain collapses to one dispatch. The generic resume-subcommand
916
- // and modeFlags paths stay here — they are not per-harness.
917
575
  const launchAdapter = resolveHarnessAdapter(options.agent);
918
576
  const launchArgsCtx = {
919
577
  resolvedMode,
@@ -931,41 +589,21 @@ export function buildExecCommand(options) {
931
589
  }
932
590
  else if (resumeSpec && 'subcommand' in resumeSpec) {
933
591
  if (resolvedMode === 'skip') {
934
- // skip = yolo on resume too; both `codex resume` (TUI) and
935
- // `codex exec resume` accept the bypass flag.
936
592
  cmd.push('--dangerously-bypass-approvals-and-sandbox');
937
593
  }
938
594
  else if (interactive) {
939
595
  cmd.push(...modeFlags);
940
596
  }
941
597
  else {
942
- // `codex exec resume` rejects `--sandbox <mode>` (verified against
943
- // `codex exec resume --help` on 0.142.5), but takes -c config overrides —
944
- // map the mode through sandbox_mode so a non-skip resume never gets the
945
- // approval/sandbox bypass.
946
598
  cmd.push(...modeFlags);
947
599
  }
948
600
  }
949
601
  else {
950
602
  cmd.push(...modeFlags);
951
603
  }
952
- // Add print/headless flags whenever the run RESOLVED headless -- gate on the
953
- // resolved state (`!interactive`), not the raw `--headless` flag. Headless is
954
- // inferred from prompt presence (resolveInteractive), and `--headless` defaults
955
- // to `false` at the CLI layer, so gating on `options.headless` skipped these
956
- // flags for a bare `agents run <agent> "prompt"`. For antigravity that meant
957
- // `agy <prompt>` with no `--print`, launching the TUI and dying on `/dev/tty`
958
- // in any non-terminal shell. `!interactive` is true for both an explicit
959
- // `--headless` and a prompt-inferred headless run; an interactive run (no
960
- // prompt, or `--interactive`) still skips them so the CLI opens its REPL.
961
604
  if (!interactive && template.printFlags) {
962
605
  cmd.push(...template.printFlags);
963
606
  }
964
- // Resume vs. create. With `resume`, emit the agent's NATIVE resume reference:
965
- // `{ flag }` agents append `<flag> <id>` (claude `--resume <id>`); `{ subcommand }`
966
- // agents (codex) already pushed the verb above, so the id is the first
967
- // positional here — placed before the prompt positional appended later. Without
968
- // `resume`, the legacy claude-only `--session-id` CREATES a session with that id.
969
607
  if (options.resume && options.sessionId && resumeSpec && !museInteractiveResumeDone) {
970
608
  if ('flag' in resumeSpec) {
971
609
  const flag = interactive
@@ -980,14 +618,8 @@ export function buildExecCommand(options) {
980
618
  else if (options.sessionId && options.agent === 'claude') {
981
619
  cmd.push('--session-id', options.sessionId);
982
620
  }
983
- // Add model. `effectiveModel` already preferred --model, then Codex's
984
- // configured default, then an OpenCode custom-harness pin (OPENCODE_MODEL).
985
621
  if (effectiveModel && template.modelFlag) {
986
622
  if (tierResolved) {
987
- // Cost tier (cheap|default|best|ultra) -> a concrete model this harness+
988
- // version actually ships. Covers `agents run` and `agents teams` (both
989
- // funnel here). A null model means nothing resolved -> drop the flag and
990
- // let the harness pick its default.
991
623
  if (tierResolved.model) {
992
624
  cmd.push(template.modelFlag, tierResolved.model);
993
625
  if (tierResolved.note)
@@ -1008,35 +640,22 @@ export function buildExecCommand(options) {
1008
640
  cmd.push(template.modelFlag, effectiveModel);
1009
641
  }
1010
642
  else {
1011
- // Tier token but no version resolved -> forwarding the literal "best"/etc.
1012
- // would be rejected by the CLI, so drop the flag (harness default).
1013
643
  process.stderr.write(`[agents] cannot resolve tier "${effectiveModel}" without a version; using harness default\n`);
1014
644
  }
1015
645
  }
1016
- // Add JSON output flags if requested
1017
646
  if (options.json && template.jsonFlags) {
1018
647
  cmd.push(...template.jsonFlags);
1019
648
  }
1020
- // Add verbose flag independently of JSON
1021
649
  if (options.verbose && template.verboseFlag) {
1022
- // Avoid duplicate if jsonFlags already included --verbose
1023
650
  if (!(options.json && template.jsonFlags?.includes(template.verboseFlag))) {
1024
651
  cmd.push(template.verboseFlag);
1025
652
  }
1026
653
  }
1027
- // Add prompt when provided. In pure interactive mode (no prompt) we skip this
1028
- // so the CLI launches its TUI. When --interactive is passed alongside a prompt
1029
- // we still forward the prompt so the agent receives it as the first message.
1030
654
  if (options.prompt !== undefined) {
1031
655
  if (interactive && options.agent === 'opencode') {
1032
- // The OpenCode TUI takes an initial prompt via --prompt; a bare positional
1033
- // on the default command is parsed as a project path, not a message.
1034
656
  cmd.push('--prompt', options.prompt);
1035
657
  }
1036
658
  else if (interactive && options.agent === 'claude') {
1037
- // Claude's -p is --print, not a prompt-value flag. In an interactive run
1038
- // the initial prompt is positional; emitting `-p /continue <id>` turns a
1039
- // focus recovery into a one-shot print process that immediately exits.
1040
659
  cmd.push(options.prompt);
1041
660
  }
1042
661
  else if (template.promptFlag === 'positional') {
@@ -1046,45 +665,9 @@ export function buildExecCommand(options) {
1046
665
  cmd.push(template.promptFlag, options.prompt);
1047
666
  }
1048
667
  }
1049
- // Project / --add-dir grants. Codex folds them into the named edit profile
1050
- // above (workspace_roots); resume rejects the native --add-dir flag.
1051
- // Everything else is strategy-driven in applyAddDirs:
1052
- // native-flag — claude, kimi, cursor (`--add-dir`)
1053
- // grok-sandbox — rules + project sandbox profile when sandboxed
1054
- // none — ignored (no multi-root surface)
1055
- //
1056
- // `~` is expanded in normalizeAddDirs (via expandLocalHome), because no shell
1057
- // does it for us: a forwarded grant crosses the SSH boundary single-quoted
1058
- // (`shellQuote` in ssh-exec.ts), so the remote login shell leaves `~/…`
1059
- // literal and the harness resolves it as a directory actually named `~`.
1060
- // Expanding on the side that runs the harness is what lets one home-relative
1061
- // grant re-root per machine.
1062
668
  applyAddDirs(options.agent, cmd, options.addDirs, {
1063
669
  cwd: options.cwd ?? process.cwd(),
1064
670
  });
1065
- // Claude-specific: workflow capability scoping. WORKFLOW.md frontmatter
1066
- // `tools:` / `mcpServers:` is translated to the headless flags that ACTUALLY
1067
- // restrict the run (verified against `claude --help` on the installed CLI):
1068
- //
1069
- // tools: -> `--tools <names...>` — restricts the AVAILABLE built-in
1070
- // tool set. This is the security boundary: tools NOT named
1071
- // here (e.g. Write, Bash, Edit) are unavailable for the whole
1072
- // run. `--allowedTools` would only auto-approve without
1073
- // restricting, so it is the WRONG flag for sandboxing.
1074
- // We also emit `--allowedTools <names...>` for the same set so
1075
- // the permitted tools don't prompt in headless `-p` mode.
1076
- // mcpServers: -> `--mcp-config <path>` PLUS `--strict-mcp-config`. The
1077
- // config flag alone ADDS servers to the existing set; only
1078
- // `--strict-mcp-config` makes the run use *only* the named
1079
- // servers, which is what scoping means.
1080
- //
1081
- // The command layer gates this behind the `allowlist` capability and assembles
1082
- // the mcp-config file; buildExecCommand stays a pure string-builder.
1083
- //
1084
- // `<tools...>` is variadic. Emit the names as separate argv tokens. The flags
1085
- // here are appended AFTER the positional prompt (added above), so the variadic
1086
- // never swallows the prompt; the trailing `--allowedTools` / `--strict-mcp-config`
1087
- // tokens also terminate the `--tools` variadic cleanly.
1088
671
  if (options.agent === 'claude') {
1089
672
  if (options.toolsRestrict && options.toolsRestrict.length > 0) {
1090
673
  cmd.push('--tools', ...options.toolsRestrict);
@@ -1095,52 +678,25 @@ export function buildExecCommand(options) {
1095
678
  cmd.push('--strict-mcp-config');
1096
679
  }
1097
680
  }
1098
- // Forward arbitrary native flags supplied after `--` verbatim. Appended last
1099
- // so they cannot be misinterpreted as values for earlier flags or as the prompt.
1100
681
  if (options.passthroughArgs && options.passthroughArgs.length > 0) {
1101
682
  cmd.push(...options.passthroughArgs);
1102
683
  }
1103
684
  return cmd;
1104
685
  }
1105
- /** Spawn an agent and return its exit code. Convenience wrapper over spawnAgent. */
1106
686
  export async function execAgent(options) {
1107
687
  const { exitCode } = await spawnAgent(options);
1108
688
  return exitCode;
1109
689
  }
1110
- /**
1111
- * Resolve how to spawn a shim target for a platform. Pure — testable on any host.
1112
- *
1113
- * POSIX always execs the binary directly (no shell). On Windows a bare
1114
- * (non-absolute) name or a `.cmd` companion goes through the shell so cmd.exe
1115
- * resolves it via PATHEXT — the common, `.cmd`-present path; an absolute `.cmd`
1116
- * or extensionless path is exec'd through the shell / directly. npm always ships
1117
- * a `<cmd>.cmd` companion on Windows, so the runnable target `execShimPassthrough`
1118
- * hands us is the `.cmd` (never a bare `.ps1`).
1119
- */
1120
690
  export function resolveShimSpawn(platform, binary, extraArgs) {
1121
691
  if (platform === 'win32') {
1122
- // Use win32 path semantics regardless of the host running this (the platform
1123
- // is the parameter, not process.platform) so `C:\...` reads as absolute.
1124
692
  const useShell = !path.win32.isAbsolute(binary) || binary.endsWith('.cmd');
1125
693
  if (useShell) {
1126
- // DEP0190-safe: hand cmd.exe ONE fully-quoted command line with an EMPTY
1127
- // args array, so Node never concatenates `extraArgs` (which carry the
1128
- // user's raw prompt/flags) into the shell line unescaped — that concat is
1129
- // both the deprecation and a command-injection surface.
1130
694
  return { command: composeWin32CommandLine(binary, extraArgs), args: [], shell: true };
1131
695
  }
1132
696
  return { command: binary, args: extraArgs, shell: false };
1133
697
  }
1134
698
  return { command: binary, args: extraArgs, shell: false };
1135
699
  }
1136
- /**
1137
- * Transparent passthrough exec for generated shims — the node-side delegate that
1138
- * Windows `.cmd` shims call. Resolves the active version (explicit pin, else
1139
- * project/default) and execs the real binary with the user's RAW args and the
1140
- * per-version env isolation, WITHOUT injecting mode/model/reasoning flags. This
1141
- * mirrors what the POSIX bash shim does inline (`exec $BINARY $launchArgs "$@"`),
1142
- * keeping version resolution in one place instead of reimplementing it in batch.
1143
- */
1144
700
  export async function execShimPassthrough(agent, rawArgs, cwd, pinnedVersion) {
1145
701
  const version = pinnedVersion ?? resolveVersion(agent, cwd) ?? undefined;
1146
702
  if (!version || !isVersionInstalled(agent, version))
@@ -1155,50 +711,20 @@ async function execShimPassthroughLeased(agent, rawArgs, cwd, pinnedVersion) {
1155
711
  }
1156
712
  let binary = getBinaryPath(agent, version);
1157
713
  if (process.platform === 'win32') {
1158
- // npm ships <cmd>.cmd alongside the bare script on Windows; that's the runnable form.
1159
714
  const cmdPath = binary + '.cmd';
1160
715
  if (fs.existsSync(cmdPath))
1161
716
  binary = cmdPath;
1162
717
  }
1163
- // Match the POSIX shim: direct Codex launches default to the safe writable
1164
- // profile, while later user arguments can still override native settings.
1165
718
  const launchArgs = agent === 'codex'
1166
719
  ? ['-c', 'check_for_update_on_startup=false', ...codexPolicyArgs('edit', codexEditWritableRoots(cwd))]
1167
720
  : [];
1168
- // Mint a launch id and export it as AGENT_LAUNCH_ID so the agent's SessionStart
1169
- // hook records the same id — the join key that maps this launch to its exact
1170
- // session even though the recorded pid here is the cmd.exe wrapper (Windows) or
1171
- // a shell, while the hook runs under the agent descendant. This is the primary
1172
- // attribution path on Windows (no lsof), so the launchId join matters most here.
1173
721
  const launchId = randomUUID();
1174
- // mode/effort are required by ExecOptions but do not affect the env buildExecEnv
1175
- // derives; pass the agent's default to satisfy the type. Passing no prompt makes
1176
- // this resolve INTERACTIVE, so the launch authenticates from the per-version
1177
- // login rather than the headless `auth` setup-token (EXEC-2a) — right for the
1178
- // common case, someone invoking the harness binary directly. Known limit: we do
1179
- // not parse `rawArgs`, so a `-p "task"` passthrough is headless in fact and
1180
- // interactive by this classification, and loses the token. Windows-only in
1181
- // practice (POSIX uses the bash shim, which execs the binary and never reaches
1182
- // buildExecEnv — `installations/shims.ts` generateShimScript).
1183
722
  const env = buildExecEnv({ agent, version, cwd, mode: defaultModeFor(agent), effort: 'auto', env: { AGENT_LAUNCH_ID: launchId } });
1184
723
  ensureVendorHomeDir(agent, getVersionHomePath(agent, version));
1185
724
  const { command, args, shell } = resolveShimSpawn(process.platform, binary, [...launchArgs, ...rawArgs]);
1186
- // Pre-launch marker for the SECOND live launch path: the Windows generated
1187
- // `.cmd` shim delegates here and spawns the harness directly, so without this
1188
- // a pinned, logged-out version launched via the shim would be invisible —
1189
- // exactly the blind spot this event closes. Best-effort; re-derives the
1190
- // signed-in verdict from the pinned version home (no rotated pick here).
1191
725
  await emitRunLaunch({ agent, version, resolvedVia: 'shim' });
1192
726
  return new Promise((resolve) => {
1193
- // Register listeners in the same synchronous turn as spawn: awaiting a lock
1194
- // release after spawn can miss a fast child's exit/error event.
1195
727
  const child = spawn(command, args, { cwd, stdio: 'inherit', env, shell });
1196
- // Record the launch so `ag sessions --active` can attribute the agent
1197
- // process to its cwd (and exact session when the caller passed
1198
- // --session-id). Vital on Windows, where there is no lsof to recover a
1199
- // foreign process's cwd. On the shell path this pid is the cmd.exe
1200
- // wrapper, not the agent binary — the active scan resolves that by
1201
- // walking the candidate's ancestors (readAncestorSessionEntry).
1202
728
  if (child.pid) {
1203
729
  const passthroughSessionId = extractSessionIdArg(rawArgs);
1204
730
  writePidSessionEntry({
@@ -1212,8 +738,6 @@ async function execShimPassthroughLeased(agent, rawArgs, cwd, pinnedVersion) {
1212
738
  terminalId: launchIdentityEnv().AGENT_TERMINAL_ID,
1213
739
  startedAtMs: Date.now(),
1214
740
  });
1215
- // Durable sessionId -> actor record (RUSH-2019) so the scanner can attribute
1216
- // this session to a person after the pid dies. Best-effort; no-ops without id.
1217
741
  if (passthroughSessionId) {
1218
742
  writeSessionActorRecord({
1219
743
  sessionId: passthroughSessionId,
@@ -1231,37 +755,9 @@ async function execShimPassthroughLeased(agent, rawArgs, cwd, pinnedVersion) {
1231
755
  });
1232
756
  });
1233
757
  }
1234
- /**
1235
- * Whether a dead pane's failure should be recapped to stderr (RUSH-2185 / EXEC-23a).
1236
- *
1237
- * For headless runs only a nonzero exit is a failure worth surfacing — a
1238
- * clean 0 means the agent finished the task before we could attach.
1239
- * For interactive runs ANY exit (including 0) is a failure: an instant clean
1240
- * exit means the harness has no bare REPL and the user would see only a mute
1241
- * `[detached]` with no explanation.
1242
- */
1243
758
  export function shouldRecapDeadPane(status, interactive) {
1244
759
  return (status ?? 0) !== 0 || interactive;
1245
760
  }
1246
- /**
1247
- * The exit code a tmux-wrapped run resolves with (RUSH-2185 / EXEC-23b).
1248
- *
1249
- * Three inputs, one rule: report success ONLY for an outcome tmux actually told
1250
- * us about. A clean user detach (`knownAlive`) is 0; a dead pane reports the
1251
- * status tmux read off it; everything else — pane unreadable because the server
1252
- * or session went away, or dead with no status — is UNKNOWN and resolves to
1253
- * {@link UNKNOWN_OUTCOME_EXIT_CODE}, never 0.
1254
- *
1255
- * Why this is not `status ?? 0`: an interactive run whose tmux server died mid-
1256
- * work landed on exactly those unknown branches and returned 0, so `agents run`
1257
- * printed a failure banner while handing its caller a success code. The same
1258
- * "1 if unknown" rule already governs the `--device` follow path
1259
- * (`docs/specifications.md` §Agent execution, exit-code table).
1260
- *
1261
- * @param pane What `paneExitStatus` read back for the agent pane.
1262
- * @param knownAlive Positive proof the pane is still alive (see
1263
- * {@link isPaneKnownAliveFromQueryResult}) — a clean detach.
1264
- */
1265
761
  export function tmuxRunExitCode(pane, knownAlive) {
1266
762
  if (knownAlive)
1267
763
  return 0;
@@ -1269,70 +765,28 @@ export function tmuxRunExitCode(pane, knownAlive) {
1269
765
  return pane.status;
1270
766
  return UNKNOWN_OUTCOME_EXIT_CODE;
1271
767
  }
1272
- /**
1273
- * True only when a `display-message #{pane_dead}` tmux query explicitly returned
1274
- * "0" (pane alive). Used to distinguish "pane alive" from "query failed" in
1275
- * situations where `paneExitStatus` conservatively returns `{dead: false}` for
1276
- * both (RUSH-2185 / EXEC-23a / F3).
1277
- *
1278
- * @param code The exit code of the `tmux display-message` command.
1279
- * @param stdout Its stdout (expected to be "0" when the pane is alive).
1280
- */
1281
768
  export function isPaneKnownAliveFromQueryResult(code, stdout) {
1282
769
  return code === 0 && stdout.trim() === '0';
1283
770
  }
1284
- /**
1285
- * Tmux is opt-in except when a TTY-less remote launch would otherwise have no
1286
- * interface. Explicit per-run opt-outs always win.
1287
- */
1288
771
  export function resolveTmuxWrap(ctx) {
1289
- // A headless `-p` run has no TTY to attach, Windows has no tmux path, and
1290
- // nesting tmux-in-tmux is pointless.
1291
772
  if (!ctx.interactive)
1292
773
  return { kind: 'bare' };
1293
774
  if (ctx.platform === 'win32')
1294
775
  return { kind: 'bare' };
1295
776
  if (ctx.inTmux)
1296
777
  return { kind: 'bare' };
1297
- // Explicit opt-outs win over every other rule: `--raw` exists precisely to
1298
- // get the unwrapped process.
1299
778
  if (ctx.raw)
1300
779
  return { kind: 'bare' };
1301
780
  if (ctx.noTmuxEnv)
1302
781
  return { kind: 'bare' };
1303
- // Local interactive with no TTY cannot attach. Wrapping anyway creates a
1304
- // detached pane, attach returns immediately, and resolveAfterAttach treats
1305
- // the still-alive pane as Ctrl-b d — the session-tracker test leak.
1306
782
  if (!ctx.hasTty && !ctx.remoteDispatch)
1307
783
  return { kind: 'bare' };
1308
- // tmux.enabled gates the wrap for local AND followed remote runs. The one
1309
- // exception: a followed remote run whose launcher has no TTY (CI, scripts)
1310
- // gives the peer nothing to attach to — the detached pane is its only
1311
- // interface, infrastructure rather than ergonomics.
1312
784
  if (!ctx.configEnabled && !(ctx.remoteDispatch && !ctx.hasTty))
1313
785
  return { kind: 'bare' };
1314
- // Fail loud rather than launch a remote agent that a blink would kill: the
1315
- // caller refuses the run instead of starting work that cannot be recovered.
1316
786
  if (!ctx.tmuxAvailable)
1317
787
  return ctx.remoteDispatch ? { kind: 'undurable' } : { kind: 'bare' };
1318
788
  return { kind: 'wrap' };
1319
789
  }
1320
- /**
1321
- * True when `options.sessionId` is an id the HARNESS actually received, and so a
1322
- * real, resumable handle — rather than one the launcher generated for its own
1323
- * bookkeeping and the agent never saw.
1324
- *
1325
- * Mirrors exactly the two branches in buildExecCommand that put the id on the
1326
- * command line: a native resume (any harness with a `resume` spec) and claude's
1327
- * create-with-`--session-id`. Everything else — `agents run codex --session-id X`
1328
- * without `--resume`, or a fresh non-claude launch whose real id only shows up
1329
- * later via the SessionStart hook — leaves the agent with an id of its own
1330
- * choosing, so `options.sessionId` must not be published as if it were that id.
1331
- *
1332
- * Keep in lockstep with buildExecCommand's resume/create branches: a harness
1333
- * that gains a forced-session-id flag must be reflected here in the SAME change,
1334
- * or this reports a genuine id as fabricated.
1335
- */
1336
790
  export function isHarnessKnownSessionId(agent, sessionId, resume) {
1337
791
  if (!sessionId)
1338
792
  return false;
@@ -1340,27 +794,12 @@ export function isHarnessKnownSessionId(agent, sessionId, resume) {
1340
794
  return true;
1341
795
  return agent === 'claude';
1342
796
  }
1343
- /**
1344
- * Build the pane command without inheriting stale tmux-server env. Redacted
1345
- * copies keep secret values out of persisted SessionMeta commands.
1346
- */
797
+ // Resolved env values never enter tmux argv/metadata; source an exclusive 0600 file, unlink it, and abort if sourcing fails.
1347
798
  export function buildTmuxAgentCommand(executable, args, env, opts = {}) {
1348
799
  const agentCmd = [executable, ...args].map(shellQuote).join(' ');
1349
800
  const absentIdentity = LAUNCH_IDENTITY_KEYS.filter(key => env[key] === undefined);
1350
- // envFile: source the values instead of inlining them, so no VALUE ever lands
1351
- // in the pane's argv. `exec env K=V …` put every resolved secret into the
1352
- // process table, readable by any process of this user — on one fleet box six
1353
- // live processes carried the secrets-store master passphrase, which decrypts
1354
- // every file-backed bundle including the Claude OAuth tokens (RUSH-2100).
1355
- // `set -a` exports what the file assigns; the file is unlinked before `exec`,
1356
- // so it exists only for the sourcing itself. A missing file aborts the pane
1357
- // rather than silently launching with a half-built env.
1358
801
  if (opts.envFile) {
1359
802
  const f = shellQuote(opts.envFile);
1360
- // Remove the file whether or not sourcing succeeds — a bare `. f || exit 1`
1361
- // strands the plaintext env (incl. the secrets-store master passphrase) on
1362
- // disk on any source failure, worse than the argv leak this replaces
1363
- // (RUSH-2100). Capture the source rc, unlink, then honor it.
1364
803
  return `${absentIdentity.length ? `unset ${absentIdentity.join(' ')}; ` : ''}set -a; . ${f}; __agents_rc=$?; set +a; rm -f ${f}; [ "$__agents_rc" -eq 0 ] || exit 1; exec ${agentCmd}`;
1365
804
  }
1366
805
  const envPrefix = Object.entries(env)
@@ -1369,16 +808,6 @@ export function buildTmuxAgentCommand(executable, args, env, opts = {}) {
1369
808
  .join(' ');
1370
809
  return `exec env ${absentIdentity.map(key => `-u ${key}`).join(' ')} ${envPrefix} ${agentCmd}`;
1371
810
  }
1372
- /**
1373
- * Serialize the pane env to a shell-sourceable file, created 0600 and exclusively
1374
- * (`wx`) so it can never adopt a pre-existing file's mode or content.
1375
- *
1376
- * EVERY key goes in the file, not a curated "secret-bearing" subset: a denylist
1377
- * has to be updated for each new credential and is wrong the moment someone
1378
- * forgets, whereas routing all of it through the file makes the guarantee hold by
1379
- * construction. Keys are filtered to valid shell identifiers for the same reason
1380
- * `env` needed it — an exported function (`BASH_FUNC_x%%`) is not assignable.
1381
- */
1382
811
  export function writeTmuxEnvFile(env, filePath) {
1383
812
  const body = Object.entries(env)
1384
813
  .filter(([k, v]) => v !== undefined && EXEC_ENV_KEY_PATTERN.test(k))
@@ -1393,13 +822,6 @@ export function writeTmuxEnvFile(env, filePath) {
1393
822
  fs.closeSync(fd);
1394
823
  }
1395
824
  }
1396
- /**
1397
- * Trim a raw `tmux capture-pane` dump to its last `maxLines` non-empty lines
1398
- * (right-stripping each). Used by runInTmux to recap a fast-failed agent's
1399
- * output into the caller's shell so a launch crash (e.g. a gutted install that
1400
- * dies with ENOENT the instant it spawns) isn't swallowed by the bare
1401
- * `[detached]` the pane-died hook otherwise leaves behind.
1402
- */
1403
825
  export function formatPaneTail(raw, maxLines = 30) {
1404
826
  return raw
1405
827
  .split('\n')
@@ -1408,28 +830,6 @@ export function formatPaneTail(raw, maxLines = 30) {
1408
830
  .slice(-maxLines)
1409
831
  .join('\n');
1410
832
  }
1411
- /**
1412
- * Run an interactive agent inside a detached tmux session on the shared socket,
1413
- * attach the current TTY, and propagate the wrapped agent's exit code.
1414
- *
1415
- * Lifecycle:
1416
- * 1. createSession() launches `sh -c 'exec env … agent'` detached, remain-on-exit
1417
- * on (global), and returns the pane id.
1418
- * 2. A per-session `pane-died` hook tears the session down the instant the AGENT
1419
- * pane exits: with a client attached it `detach-client`s so attach returns
1420
- * instead of parking on a dead pane (then resolveAfterAttach reads the status
1421
- * and kills); with no client attached it `kill-session`s outright, so a
1422
- * wrapped agent that exits unattended can't leave a dead husk lingering on the
1423
- * socket. The hook is guarded on `#{hook_pane}` so it fires ONLY for the agent
1424
- * pane — user-created splits (Ctrl-b " / %) that the user exits are closed in
1425
- * place (`kill-pane`) instead of tearing down the whole client, so exiting one
1426
- * split leaves the agent running full-window rather than kicking you out.
1427
- * 3. We record the agent pane's pid → session mapping (WITH the tmux pane) so the
1428
- * headless active-scan attributes it, then attach the TTY (blocking).
1429
- * 4. On return: if the pane is dead the agent exited — read its status, tear the
1430
- * session down, return that code. If the pane is still alive the user detached
1431
- * (Ctrl-b d) — return 0 and LEAVE the session for `agents focus` to re-attach.
1432
- */
1433
833
  async function runInTmux(options, executable, args) {
1434
834
  const { createSession, killSession, paneExitStatus, prepareSessionForResume, setSessionHook, slugifyName, agentPaneDiedHook, markSessionHookSchema } = await import('./tmux/session.js');
1435
835
  const { getDefaultSocketPath } = await import('./tmux/paths.js');
@@ -1440,13 +840,6 @@ async function runInTmux(options, executable, args) {
1440
840
  const name = slugifyName(`ag-${options.agent}-${idSeed}`);
1441
841
  const RED = '\x1b[31m', GRAY = '\x1b[90m', OFF = '\x1b[0m';
1442
842
  const NO_TMUX_TIP = `${GRAY} This run used the opt-in tmux wrap. Re-run with --no-tmux for a direct launch, or turn the wrap off: agents config set devices.${machineId()}.tmux off${OFF}\n\n`;
1443
- // Read a dead pane's scrollback. Must run BEFORE killSession — capture-pane
1444
- // needs the session still alive (remain-on-exit keeps the dead pane readable
1445
- // until we tear it down). Best-effort: a missing/gone pane just yields ''.
1446
- // Callers thread this into SpawnResult.stdout for a GENUINELY dead pane only
1447
- // (positive proof from paneExitStatus) — never for the "still alive, user
1448
- // detached" or "outcome unknown" paths below, so an interactive detach or an
1449
- // unresolved tmux race can never masquerade as refusal evidence.
1450
843
  const capturePaneTail = async (pane) => {
1451
844
  if (!pane)
1452
845
  return '';
@@ -1458,10 +851,6 @@ async function runInTmux(options, executable, args) {
1458
851
  return '';
1459
852
  }
1460
853
  };
1461
- // Recap a dead pane's tail into THIS shell's stderr. The pane-died hook
1462
- // detaches the client the instant the agent exits, so a fast failure (a
1463
- // gutted install that dies with ENOENT, a bad flag, a crash on startup) would
1464
- // otherwise leave only a bare `[detached]` with no clue why.
1465
854
  const surfacePaneFailure = async (pane, status, headline, tail) => {
1466
855
  if (!pane)
1467
856
  return;
@@ -1473,10 +862,6 @@ async function runInTmux(options, executable, args) {
1473
862
  }
1474
863
  process.stderr.write(NO_TMUX_TIP);
1475
864
  };
1476
- // F3 (RUSH-2185 / EXEC-23a): paneExitStatus returns {dead:false} for BOTH
1477
- // "pane is alive" and "tmux query failed (race / pane already gone)". Require
1478
- // POSITIVE proof before taking the keep-session path — a separate direct query
1479
- // that only returns true when tmux explicitly confirms pane_dead=0.
1480
865
  const checkPaneKnownAlive = async (p) => {
1481
866
  try {
1482
867
  const r = await runTmux({ socket, args: ['display-message', '-pt', p, '-p', '#{pane_dead}'], throwOnError: false });
@@ -1486,13 +871,6 @@ async function runInTmux(options, executable, args) {
1486
871
  return false;
1487
872
  }
1488
873
  };
1489
- /**
1490
- * Resolve what an attach client's return actually means, for EVERY path that
1491
- * attaches (the fresh wrapper below AND the resume-attach above). Asking tmux
1492
- * is the only way to tell "the user detached" from "the agent exited" from
1493
- * "the session went away underneath us", so an attach that skips this cannot
1494
- * do better than assume success — which is exactly the defect EXEC-23b fixes.
1495
- */
1496
874
  let paneLaunchBinding;
1497
875
  const bindCompletedPane = () => {
1498
876
  recordCompletedLaunch(paneLaunchBinding);
@@ -1501,44 +879,18 @@ async function runInTmux(options, executable, args) {
1501
879
  const after = pane ? await paneExitStatus(pane, socket) : { found: false, dead: false, status: undefined };
1502
880
  if (after.dead) {
1503
881
  bindCompletedPane();
1504
- // Positive proof of a genuinely completed pane (paneExitStatus confirmed
1505
- // dead) — capture its scrollback as refusal evidence for the caller
1506
- // (classifyClaudeRunRefusal etc.) BEFORE tearing the session down.
1507
- // Deliberately not done for the "alive" (detach) or "unknown" branches
1508
- // below: neither is a demonstrated completion, so neither may carry
1509
- // evidence a caller could mistake for a real refusal or success.
1510
882
  const tail = await capturePaneTail(pane);
1511
- // Nonzero exit after attach → the agent crashed rather than the user
1512
- // detaching cleanly (a clean detach leaves the pane ALIVE, handled below).
1513
- // F2: for interactive runs, also recap a clean exit-0 — the harness exited
1514
- // without error but without starting a REPL, which is still a failure.
1515
883
  if (shouldRecapDeadPane(after.status, resolveInteractive(options))) {
1516
884
  await surfacePaneFailure(pane, after.status, `${options.agent} exited`, tail);
1517
885
  }
1518
886
  await killSession(name, socket).catch(() => { });
1519
- // A dead pane whose status tmux never reported is UNKNOWN, not success —
1520
- // and surfacePaneFailure already printed `exit 1` for it, so the old
1521
- // `?? 0` made the message and the returned code disagree (EXEC-23b).
1522
887
  return { exitCode: tmuxRunExitCode(after, false), stderr: '', stdout: tail };
1523
888
  }
1524
- // after.dead===false, but that could be a stale/unreadable-pane result.
1525
- // Require positive proof before keeping the session as "user detached".
1526
889
  if (pane && await checkPaneKnownAlive(pane)) {
1527
- // Confirmed alive: the user pressed Ctrl-b d; keep the session for `agents focus`.
1528
890
  return { exitCode: tmuxRunExitCode(after, true), stderr: '', stdout: '' };
1529
891
  }
1530
- // F4 (EXEC-23b): the outcome is UNKNOWN — tmux could not tell us whether the
1531
- // agent finished or was killed. MUST NOT be reported as success: a caller
1532
- // scripting `agents run` would count a run killed mid-work as a clean
1533
- // finish. Tear down so no orphan session is left, say so, and exit non-zero
1534
- // — the same "1 if unknown" rule the `--device` follow path already uses.
1535
892
  await killSession(name, socket).catch(() => { });
1536
- // One computation feeds both the banner and the return value — printing a
1537
- // code the caller does not receive is the same defect in miniature.
1538
893
  const exitCode = tmuxRunExitCode(after, false);
1539
- // Two distinct causes reach here, and the banner must not assert the wrong
1540
- // one: a pane we HAD (the session went away under it) versus a run whose
1541
- // pane id tmux never reported at creation, which had nothing to read from.
1542
894
  const cause = pane
1543
895
  ? 'The tmux session went away before its exit status could be read, so this run may have been killed mid-work.'
1544
896
  : 'This run had no readable tmux pane, so its exit status could never be read.';
@@ -1546,49 +898,27 @@ async function runInTmux(options, executable, args) {
1546
898
  `${GRAY} ${cause}${OFF}\n` + NO_TMUX_TIP);
1547
899
  return { exitCode, stderr: '', stdout: '' };
1548
900
  };
1549
- // A native resume must not create a competing wrapper for a live session.
1550
- // A retained dead pane is reaped before the harness resumes normally.
1551
901
  const resumePrep = options.resume ? await prepareSessionForResume(name, socket) : { decision: 'create' };
1552
902
  if (resumePrep.decision === 'attach') {
1553
903
  if (options.sessionId)
1554
904
  writeSessionAliasRecord(options.sessionId, name);
1555
905
  await attachTmux({ socket, args: ['attach-session', '-t', name] });
1556
- // EXEC-23b: a resume-attach is an attach like any other — it must ask tmux
1557
- // what happened rather than assume 0. Before this it returned a hardcoded
1558
- // success, so a resumed run whose server died under it reported a clean
1559
- // finish, the identical defect on the identical shape.
1560
906
  return resolveAfterAttach(resumePrep.pane);
1561
907
  }
1562
- // SessionStart learns some harness IDs only after launch. Carry the wrapper
1563
- // name into that hook so it can bind both identities durably.
1564
908
  const execEnv = { ...buildExecEnv(options), AGENT_TMUX_SESSION_NAME: name };
1565
- // The pane sources its env from a 0600 file it unlinks before exec, so no
1566
- // resolved secret VALUE reaches the process table (RUSH-2100). SessionMeta.cmd
1567
- // keeps the value-redacted inline form — the human-readable record of what ran,
1568
- // which never carried real values anyway (RUSH-1758).
1569
909
  const envFile = path.join(getRuntimeStateDir(), 'tmux-env', `${name}-${randomUUID().slice(0, 8)}.env`);
1570
910
  writeTmuxEnvFile(execEnv, envFile);
1571
911
  let cmd = buildTmuxAgentCommand(executable, args, execEnv, { envFile });
1572
912
  const leaseVersion = options.version ?? resolveVersion(options.agent, cwd);
1573
913
  if (leaseVersion && isVersionInstalled(options.agent, leaseVersion)) {
1574
914
  const leaseCli = getCliLaunch(['__launch-lease', options.agent, leaseVersion], getAgentsBinPath());
1575
- // The pane outlives a detached launcher. Lease its own exec-replaced shell
1576
- // before launching, so detaching cannot open an unprotected launch gap.
1577
915
  cmd = `${[leaseCli.command, ...leaseCli.args].map(shellQuote).join(' ')} "$$" || exit 1; ${cmd}`;
1578
916
  }
1579
917
  const metaCmd = buildTmuxAgentCommand(executable, args, execEnv, { redactEnvValues: true });
1580
918
  const labels = { agent: options.agent };
1581
- // Only publish an id the harness actually received. createSession turns this
1582
- // label into the `@ag_session_id` tmux option that status bars read, and a
1583
- // launcher-internal id displayed there looks exactly like a resumable one
1584
- // while `ag focus <id>` rejects it.
1585
919
  if (isHarnessKnownSessionId(options.agent, options.sessionId, options.resume)) {
1586
920
  labels.sessionId = options.sessionId;
1587
921
  }
1588
- // Only a launched pane sources-and-unlinks the env file. If createSession
1589
- // throws, the pane never runs, so the resolved secrets (incl. the master
1590
- // passphrase) would linger on disk — remove it on that failure path
1591
- // (RUSH-2100). On success the detached pane owns the unlink.
1592
922
  let meta;
1593
923
  try {
1594
924
  meta = await createSession({ name, cmd, metaCmd, cwd, socket, source: 'cli', labels });
@@ -1597,34 +927,22 @@ async function runInTmux(options, executable, args) {
1597
927
  try {
1598
928
  fs.rmSync(envFile, { force: true });
1599
929
  }
1600
- catch { /* best-effort */ }
930
+ catch { }
1601
931
  throw err;
1602
932
  }
1603
933
  const pane = meta.pane;
1604
934
  if (options.sessionId)
1605
935
  writeSessionAliasRecord(options.sessionId, name);
1606
936
  if (pane) {
1607
- // When the AGENT pane dies, detach the client (don't kill) so the session
1608
- // survives just long enough to read the dead pane's exit status below. The
1609
- // `#{hook_pane}` guard scopes this to the agent pane only: if the user splits
1610
- // the window and exits one of THEIR panes, the else-branch closes that split
1611
- // in place instead of detaching everyone (`run-shell -C` executes the
1612
- // targeted kill inside tmux's server command queue, avoiding a second
1613
- // client racing the same socket under load, #965). Without the guard,
1614
- // exiting any split kicked the user clean out of tmux.
1615
937
  const hookInstalled = await setSessionHook(name, 'pane-died', agentPaneDiedHook(name, pane), socket);
1616
- // Stamp the schema marker only after tmux accepted the hook. A failed
1617
- // install stays unmarked so daemon reconciliation retries it later.
1618
938
  if (hookInstalled)
1619
939
  await markSessionHookSchema(name, socket);
1620
- // Record the agent's OS pid (the pane leaf, thanks to `exec`) WITH its tmux
1621
- // pane so the active-scan attributes it exactly and shows the %pane.
1622
940
  let panePid = 0;
1623
941
  try {
1624
942
  const r = await runTmux({ socket, args: ['display-message', '-pt', pane, '-p', '#{pane_pid}'], throwOnError: false });
1625
943
  panePid = parseInt(r.stdout.trim(), 10) || 0;
1626
944
  }
1627
- catch { /* best-effort */ }
945
+ catch { }
1628
946
  writePidSessionEntry({
1629
947
  pid: panePid,
1630
948
  agent: options.agent,
@@ -1633,10 +951,6 @@ async function runInTmux(options, executable, args) {
1633
951
  cwd,
1634
952
  actor: resolveActor().id,
1635
953
  initiatedBy: resolveActor().kind,
1636
- // spawnAgent injected AGENT_LAUNCH_ID into options.env before delegating
1637
- // here; record the same id so the hook (running under the pane-leaf agent
1638
- // pid) reconciles by launchId. This pane's pid usually IS the agent pid,
1639
- // but the launchId join is robust even when it isn't.
1640
954
  launchId: options.env?.AGENT_LAUNCH_ID,
1641
955
  terminalId: launchIdentityEnv().AGENT_TERMINAL_ID,
1642
956
  tmuxPane: pane,
@@ -1655,44 +969,20 @@ async function runInTmux(options, executable, args) {
1655
969
  });
1656
970
  }
1657
971
  }
1658
- // The agent could exit before we attach (fast failure). Don't attach to an
1659
- // already-dead pane — surface its output + status directly and tear down.
1660
972
  const before = pane ? await paneExitStatus(pane, socket) : { found: false, dead: false, status: undefined };
1661
973
  if (before.dead) {
1662
974
  bindCompletedPane();
1663
- // Positive proof of a genuinely completed pane — capture scrollback as
1664
- // refusal evidence before tearing the session down (see the matching
1665
- // comment in resolveAfterAttach).
1666
975
  const tail = await capturePaneTail(pane);
1667
- // F2 (RUSH-2185 / EXEC-23a): for interactive runs, ALWAYS recap — a clean
1668
- // exit-0 before attach means the harness has no interactive REPL and the
1669
- // user would see only a bare `[detached]` with no clue why. For headless
1670
- // runs the old quiet behaviour stands: exit-0 is a successful quick run.
1671
976
  if (shouldRecapDeadPane(before.status, resolveInteractive(options))) {
1672
977
  await surfacePaneFailure(pane, before.status, `${options.agent} exited before it could start`, tail);
1673
978
  }
1674
979
  await killSession(name, socket).catch(() => { });
1675
- // A dead pane whose status tmux never reported is an UNKNOWN outcome, not a
1676
- // success — and the banner one line up already printed `exit 1` for it, so
1677
- // the old `?? 0` also made the message and the returned code disagree.
1678
980
  return { exitCode: tmuxRunExitCode(before, false), stderr: '', stdout: tail };
1679
981
  }
1680
982
  await attachTmux({ socket, args: ['attach-session', '-t', name] });
1681
983
  return resolveAfterAttach(pane);
1682
984
  }
1683
- /**
1684
- * Print the run's resolved session id as a one-line stdout sentinel so a `--device`
1685
- * launcher can relate the remote-created session back to itself (see the
1686
- * `emitSessionId` option and hosts/session-marker.ts).
1687
- *
1688
- * For Claude the id was forced up front (`options.sessionId`, wired as
1689
- * `--session-id`), so it's authoritative with no lookup. Every other agent coined
1690
- * its OWN id, which its SessionStart hook recorded under this run's launchId — the
1691
- * exact join key `agents sessions --active` uses — so we read it back from the hook
1692
- * index by launchId (falling back to the child pid the hook may have recorded
1693
- * under). Nothing to emit when the hook hasn't landed an id (hookless harness):
1694
- * the launcher simply keeps the un-mapped task, never a fabricated id.
1695
- */
985
+ // Publish only a session id supplied by the harness or joined through the shared launch id.
1696
986
  function emitResolvedSessionId(options, launchId, childPid) {
1697
987
  let sessionId = options.sessionId;
1698
988
  if (!sessionId) {
@@ -1704,29 +994,16 @@ function emitResolvedSessionId(options, launchId, childPid) {
1704
994
  });
1705
995
  }
1706
996
  catch {
1707
- /* hook index unreadable — emit nothing rather than a guess */
1708
997
  }
1709
998
  }
1710
999
  if (sessionId)
1711
1000
  process.stdout.write(sessionIdMarkerLine(sessionId));
1712
1001
  }
1713
- /**
1714
- * Build the `run.launch` event payload. Pure and exported so the signedIn ->
1715
- * launchedLoggedOut mapping is unit-testable without spawning. Mirrors the
1716
- * buildRotationDecisionEvent / emitRotationDecision split in rotate.ts.
1717
- *
1718
- * `launchedLoggedOut` is the headline flag — true ONLY when `signedIn` was
1719
- * resolved to false (a launch into a logged-out version, the yosemite-m3 2.1.219
1720
- * incident). An UNKNOWN verdict (`signedIn === null`) is never treated as
1721
- * logged out.
1722
- */
1723
1002
  export function buildRunLaunchPayload(input) {
1724
1003
  return {
1725
1004
  module: 'run',
1726
1005
  agent: input.agent,
1727
1006
  ...(input.harnessName ? { harnessName: input.harnessName } : {}),
1728
- // Omitted only when no version could be resolved at all — the typed `version`
1729
- // field can't carry null, and an absent version is honest.
1730
1007
  version: input.version,
1731
1008
  strategy: input.strategy ?? null,
1732
1009
  signedIn: input.signedIn,
@@ -1735,36 +1012,15 @@ export function buildRunLaunchPayload(input) {
1735
1012
  ...(input.resolvedVia ? { resolvedVia: input.resolvedVia } : {}),
1736
1013
  };
1737
1014
  }
1738
- /**
1739
- * Emit the pre-launch `run.launch` observability event just before the harness
1740
- * child is spawned. Best-effort by construction — the whole point is that it can
1741
- * NEVER break a launch, so every step (the signed-in probe, the emit itself) is
1742
- * wrapped and a failure is swallowed. Mirrors the non-fatal pattern of
1743
- * recordDispatchedRun and emitRotationDecision.
1744
- *
1745
- * The `signedIn` verdict is for the SPECIFIC launched version on THIS device, so
1746
- * `launchedLoggedOut` catches a launch into a logged-out version that
1747
- * `--device auto` readiness let through (the yosemite-m3 2.1.219 incident). It is
1748
- * REUSED from `ctx.launchSignedIn` when the caller already computed it via the
1749
- * identical gate (the rotated pick — no double fs read, no disagreement window),
1750
- * and only otherwise re-derived via {@link isVersionLaunchableHere} (dynamically
1751
- * imported so the spawn path takes on no static dependency on the accounting
1752
- * layer).
1753
- */
1754
1015
  async function emitRunLaunch(ctx) {
1755
1016
  try {
1756
1017
  let signedIn;
1757
1018
  let email;
1758
1019
  if (ctx.launchSignedIn !== undefined) {
1759
- // Caller already computed the verdict for this exact version via the same
1760
- // gate — reuse it verbatim.
1761
1020
  signedIn = ctx.launchSignedIn;
1762
1021
  email = ctx.launchEmail ?? null;
1763
1022
  }
1764
1023
  else {
1765
- // Pinned-default / shim paths: probe the version home now. Without a
1766
- // concrete version we cannot probe, so leave the verdict unknown (null)
1767
- // rather than guess.
1768
1024
  signedIn = null;
1769
1025
  email = null;
1770
1026
  if (ctx.version) {
@@ -1775,7 +1031,6 @@ async function emitRunLaunch(ctx) {
1775
1031
  email = state.email;
1776
1032
  }
1777
1033
  catch {
1778
- /* probe unavailable — record the launch without the signed-in verdict */
1779
1034
  }
1780
1035
  }
1781
1036
  }
@@ -1790,7 +1045,6 @@ async function emitRunLaunch(ctx) {
1790
1045
  }));
1791
1046
  }
1792
1047
  catch {
1793
- /* observability must never break a launch */
1794
1048
  }
1795
1049
  }
1796
1050
  async function spawnAgent(options) {
@@ -1836,10 +1090,10 @@ async function spawnAgent(options) {
1836
1090
  else if (!row.isApiErrorMessage && row.message?.model && content.trim())
1837
1091
  clearClaudeModelRefusal(modelKey, row.message.model);
1838
1092
  }
1839
- catch { /* Partial or non-message transcript rows provide no evidence. */ }
1093
+ catch { }
1840
1094
  }
1841
1095
  }
1842
- catch { /* Transcript observation must not interrupt the harness. */ }
1096
+ catch { }
1843
1097
  };
1844
1098
  const observer = transcript ? setInterval(observeTranscript, 2_000) : undefined;
1845
1099
  observer?.unref();
@@ -1865,19 +1119,10 @@ async function spawnAgent(options) {
1865
1119
  }
1866
1120
  async function spawnAgentLeased(options) {
1867
1121
  bootMark('spawn-agent:enter');
1868
- // Assign a known session id up front for agents that accept one, so the
1869
- // launcher can record an EXACT pid -> session mapping (see pid-registry) —
1870
- // otherwise the headless `ag sessions --active` path can only guess
1871
- // "newest .jsonl in the cwd" and collapses co-located agents onto one row.
1872
- // Claude: `--session-id <uuid>` CREATES the session with that id (wired in
1873
- // buildExecCommand). Skip on resume — the id is the one being resumed.
1874
1122
  if (options.agent === 'claude' && !options.resume && !options.sessionId) {
1875
1123
  options = { ...options, sessionId: randomUUID() };
1876
1124
  }
1877
1125
  ensureVendorHomeForSpawn(options);
1878
- // Record the run's --name against its session id (when both are known at
1879
- // launch) so `agents sessions <name>` resolves it. Best-effort; unnamed runs
1880
- // and agents whose id isn't known up front simply skip this.
1881
1126
  if (options.name && options.sessionId) {
1882
1127
  recordRunName({ sessionId: options.sessionId, name: options.name, agent: options.agent, cwd: options.cwd });
1883
1128
  }
@@ -1886,10 +1131,6 @@ async function spawnAgentLeased(options) {
1886
1131
  const timeoutMs = options.timeout ? parseTimeout(options.timeout) : undefined;
1887
1132
  const piped = !process.stdout.isTTY;
1888
1133
  const interactive = resolveInteractive(options);
1889
- // Fail loud before spawning a headless codex whose Linux sandbox can't start —
1890
- // otherwise it burns a turn and lands zero tools (PHNX-3285). Cheap gate first
1891
- // so the userns probe (one `unshare`) runs only for the exact case it applies to
1892
- // (codex + Linux + headless + a sandboxed mode), never for every spawn.
1893
1134
  if (options.agent === 'codex' && process.platform === 'linux' && !interactive) {
1894
1135
  const codexMode = options.mode ? normalizeMode(options.mode) : defaultModeFor(options.agent);
1895
1136
  if (codexMode !== 'skip') {
@@ -1907,18 +1148,9 @@ async function spawnAgentLeased(options) {
1907
1148
  }
1908
1149
  }
1909
1150
  }
1910
- // Fail loud before an INTERACTIVE claude run on a worker with no synced
1911
- // credential falls through to Claude Code's "Select login method" screen — an
1912
- // interactive OAuth on a headless box that never persists, the 10-minute
1913
- // re-login loop (PHNX-3502 sibling). A worker authenticates from the
1914
- // setup-token; when none resolves for the selected account, refuse with the
1915
- // real fix instead of the useless login prompt. Headless already fails loud
1916
- // (401), so the gate is interactive-only (the preflight enforces that).
1151
+ // Headed Claude uses native OAuth only; workers require the selected slot's durable setup token and never open interactive login.
1917
1152
  if (options.agent === 'claude') {
1918
1153
  const { versionHome } = resolveExecConfigHome(options);
1919
- // A credential reaches the child if the worker setup-token resolves for the
1920
- // selected account OR the caller passed an explicit --env override
1921
- // (buildExecEnv merges options.env last, so it wins even the worker strip).
1922
1154
  const hasWorkerCredential = Boolean(options.env?.CLAUDE_CODE_OAUTH_TOKEN) ||
1923
1155
  (versionHome ? resolveClaudeSetupToken(versionHome) !== null : false);
1924
1156
  const loginTrap = claudeWorkerLoginTrapPreflight({
@@ -1932,34 +1164,12 @@ async function spawnAgentLeased(options) {
1932
1164
  process.stderr.write(`\x1b[31m${loginTrap}\x1b[0m\n`);
1933
1165
  return { exitCode: 1, stdout: '', stderr: loginTrap };
1934
1166
  }
1935
- // A credentialed run on a worker never needs Claude Code's first-run
1936
- // onboarding, and in a provider (setup-token) launch's shared version home
1937
- // nothing else completes it: the tab opened on the theme picker instead of
1938
- // the agent (yosemite-m1, 2026-09-28). A headed device keeps its own
1939
- // onboarding; the person at it answers it.
1940
1167
  if (hasWorkerCredential && versionHome && !isHeadedDeviceRole(selfConfiguredDeviceRole())) {
1941
1168
  seedClaudeWorkerHomeIdentity(versionHome);
1942
1169
  }
1943
1170
  }
1944
- // Budget live kill-switch (issue #346). For headless runs we incrementally
1945
- // parse stream-json usage off stdout, accumulate cost, and kill the child the
1946
- // moment a configured cap is crossed — exactly like the --timeout path, but
1947
- // resolving with a DISTINCT exit code so CI/headless can tell budget-kill from
1948
- // timeout. Spend is recorded to the shared ledger in the close handler. The
1949
- // watcher is dormant (and zero-cost) when no caps are configured.
1950
1171
  const cwd = options.cwd || process.cwd();
1951
- // Resolve the launch id once. It doubles as the budget watcher's run id AND is
1952
- // exported to the child as AGENT_LAUNCH_ID, so the agent's SessionStart hook
1953
- // records the SAME id in its own state file (terminals/sessions/<pid>.json).
1954
- // That id is the join key that reconciles this launch's pid-registry entry
1955
- // with the hook's authoritative session id even when the hook runs under a
1956
- // different pid (tmux pane leaf / cmd.exe wrapper) — see pid-registry.ts and
1957
- // session/hook-sessions.ts. ADOPT a launch id a `--device` launcher already
1958
- // forwarded (via `--env AGENT_LAUNCH_ID=…`) so ONE correlation key spans the
1959
- // SSH hop and the launcher can resolve this run's real session id for every
1960
- // agent, not just Claude (RUSH-2034); mint a fresh one for every local run.
1961
- // Injected into options.env so every downstream env build (the bare spawn
1962
- // below AND the tmux env prefix in runInTmux) carries it.
1172
+ // One launch id joins SSH, tmux, hook, and tracker observations into the same run.
1963
1173
  const launchId = resolveLaunchId(options.env?.AGENT_LAUNCH_ID);
1964
1174
  const runId = launchId;
1965
1175
  options = { ...options, env: { ...options.env, AGENT_LAUNCH_ID: launchId } };
@@ -1968,9 +1178,6 @@ async function spawnAgentLeased(options) {
1968
1178
  agent: options.agent,
1969
1179
  version: options.version,
1970
1180
  cwd: options.cwd || process.cwd(),
1971
- // The mode that ran, not the one requested — `agents run` passes the
1972
- // requested mode so the resolver can warn, but telemetry must agree with
1973
- // the audit log. See RUSH-2106 for removing that ambiguity at the source.
1974
1181
  mode: resolveMode(options.agent, normalizeMode(options.mode)),
1975
1182
  model: options.model,
1976
1183
  interactive,
@@ -1979,11 +1186,6 @@ async function spawnAgentLeased(options) {
1979
1186
  command: executable,
1980
1187
  args: redactArgs(args.slice(0, 10)),
1981
1188
  });
1982
- // Interactive spawn-wrap: run the agent INSIDE a shared-socket tmux session
1983
- // (then attach this TTY) so it gets a unique, addressable %pane. Opt-in via
1984
- // this device's tmux.enabled, local and remote alike (PHNX-3316); a followed
1985
- // remote run left bare relies on reconnect-and-resume, not a pane. Every
1986
- // failed guard keeps the bare spawn below.
1987
1189
  const tmuxWrap = resolveTmuxWrap({
1988
1190
  interactive,
1989
1191
  platform: process.platform,
@@ -1996,17 +1198,6 @@ async function spawnAgentLeased(options) {
1996
1198
  hasTty: !!process.stdout.isTTY,
1997
1199
  });
1998
1200
  if (tmuxWrap.kind === 'undurable') {
1999
- // Refuse rather than start work a blink would destroy. This is the ONLY
2000
- // check — `ensureHostReady` gates a `--device` dispatch on the peer being
2001
- // reachable and able to run the pinned agent, not on it having tmux, so
2002
- // there is no launcher-side probe ahead of this one. Failing here still
2003
- // fails before the agent starts, which is what matters; a pre-dispatch
2004
- // probe would only move the message earlier, at the cost of a round trip on
2005
- // every launch. Reached only when the wrap was wanted: the device opted in
2006
- // via tmux.enabled, or a followed run whose launcher had no TTY (CI,
2007
- // scripts) left the peer nothing to attach to, so the pane is its stdout.
2008
- // The config tip uses the ssh form because tmux.enabled is machine-local:
2009
- // setting it from the launcher throws (assertLocalTarget).
2010
1201
  const msg = `agents: ${machineId()} has no tmux, so this --device run cannot get the pane it needs.\n`
2011
1202
  + ` install it: (apt|dnf|brew) install tmux\n`
2012
1203
  + ` or turn the wrap off: agents ssh ${machineId()} 'agents devices config ${machineId()} tmux.enabled off'\n`
@@ -2015,14 +1206,6 @@ async function spawnAgentLeased(options) {
2015
1206
  timer.end({ exitCode: 1, status: 'failed', error: 'remote interactive run has no tmux for durability' });
2016
1207
  return { exitCode: 1, stdout: '', stderr: msg };
2017
1208
  }
2018
- // Pre-launch marker (`run.launch`), fired on THIS device right before the
2019
- // harness child is spawned — for BOTH the tmux-wrapped and bare paths below,
2020
- // and only once the undurable refusal above has passed (a refused run never
2021
- // spawns). Unlike `run.dispatched` (recordDispatchedRun, at FINALIZE), this
2022
- // records a launch that then sits stuck at a login screen and never finalizes,
2023
- // so a launch into a logged-out version is visible instead of silent. The
2024
- // signed-in verdict is REUSED from the rotated pick when the command threaded
2025
- // it (options.launchSignedIn), else re-derived from the version home.
2026
1209
  await emitRunLaunch({
2027
1210
  agent: options.agent,
2028
1211
  harnessName: options.harnessName,
@@ -2046,23 +1229,10 @@ async function spawnAgentLeased(options) {
2046
1229
  }
2047
1230
  }
2048
1231
  return new Promise((resolve, reject) => {
2049
- // Interactive mode inherits all stdio so the CLI owns the TTY (TUI
2050
- // rendering, raw-mode keystrokes, colored output). Headless mode pipes
2051
- // stderr so we can scan for rate limits and feed fallback. stdout stays
2052
- // inherited for TTY, piped when the caller pipes us downstream.
2053
- // PIPE (and later tee) stdout whenever the live budget watcher must read it
2054
- // — for ALL non-interactive runs when caps are active, regardless of TTY.
2055
- // See shouldTapStdout() for the rationale (FIX 3, issue #346).
2056
1232
  const tapStdout = shouldTapStdout(interactive, piped, watcherState !== null, options.captureStdoutTail);
2057
1233
  const stdio = interactive
2058
1234
  ? ['inherit', 'inherit', 'inherit']
2059
1235
  : ['inherit', tapStdout ? 'pipe' : 'inherit', 'pipe'];
2060
- // On Windows, .cmd batch wrappers (npm-installed CLIs) require shell:true
2061
- // whether addressed by name or absolute path. On that shell path, compose a
2062
- // single fully-quoted command line and pass an EMPTY args array (see
2063
- // composeWin32CommandLine) so Node never concatenates the args array — which
2064
- // carries the user's prompt — into the cmd.exe line unescaped (DEP0190 +
2065
- // command injection).
2066
1236
  const useShell = process.platform === 'win32' && (!path.isAbsolute(executable) || executable.endsWith('.cmd'));
2067
1237
  const spawnCommand = useShell ? composeWin32CommandLine(executable, args) : executable;
2068
1238
  const spawnArgs = useShell ? [] : args;
@@ -2073,10 +1243,6 @@ async function spawnAgentLeased(options) {
2073
1243
  env: buildExecEnv(options),
2074
1244
  shell: useShell,
2075
1245
  });
2076
- // Record this launch so `ag sessions --active` can map the pid to its exact
2077
- // session (sessionId is set for Claude above) instead of guessing the newest
2078
- // .jsonl in the cwd — the collapse that made co-located agents indistinguishable.
2079
- // Best-effort: pruned when the pid dies; a failed write just degrades to the heuristic.
2080
1246
  writePidSessionEntry({
2081
1247
  pid: child.pid ?? 0,
2082
1248
  agent: options.agent,
@@ -2102,23 +1268,16 @@ async function spawnAgentLeased(options) {
2102
1268
  startedAtMs: Date.now(),
2103
1269
  });
2104
1270
  }
2105
- // Mark startup time (time from function call to process spawn)
2106
1271
  timer.mark('startup');
2107
1272
  let budgetKilled = false;
2108
1273
  let budgetKillTimer;
2109
1274
  let stdoutTail = '';
2110
1275
  const STDOUT_TAIL_CAP = 16 * 1024;
2111
1276
  if (!interactive && tapStdout && child.stdout) {
2112
- // TEE the child's stdout back to the parent's so the user still sees
2113
- // output (mirrors stdio:'inherit') while we tap the same stream for usage.
2114
1277
  child.stdout.pipe(process.stdout);
2115
- // Keep a rolling TAIL (billing refusals arrive at the very end of a run)
2116
- // for the fallback chain's rate-limit scan.
2117
1278
  child.stdout.on('data', (chunk) => {
2118
1279
  stdoutTail = (stdoutTail + chunk.toString('utf-8')).slice(-STDOUT_TAIL_CAP);
2119
1280
  });
2120
- // Tap the same stream for budget usage events without consuming the pipe
2121
- // (a 'data' listener and .pipe() both receive every chunk). Kill on breach.
2122
1281
  if (watcherState) {
2123
1282
  let pendingLine = '';
2124
1283
  child.stdout.on('data', (chunk) => {
@@ -2165,31 +1324,19 @@ async function spawnAgentLeased(options) {
2165
1324
  recordCompletedLaunch(launchBinding);
2166
1325
  if (timeoutTimer)
2167
1326
  clearTimeout(timeoutTimer);
2168
- // Clear the budget-kill SIGKILL escalation timer (mirror the --timeout
2169
- // timer cleanup) so a programmatic caller reusing execAgent (the #332 loop
2170
- // driver) never sees a stray 5s kill event fire after the child has exited.
2171
1327
  if (budgetKillTimer)
2172
1328
  clearTimeout(budgetKillTimer);
2173
- // Record final spend to the shared ledger (issue #346). Best-effort: a
2174
- // ledger write must never mask the run's own outcome.
2175
1329
  if (watcherState) {
2176
1330
  try {
2177
1331
  watcherState.finalize();
2178
1332
  }
2179
- catch { /* ledger write is non-critical */ }
2180
- // Release the watcher's references / stop accepting events (symmetry).
1333
+ catch { }
2181
1334
  try {
2182
1335
  watcherState.watcher.dispose();
2183
1336
  }
2184
- catch { /* dispose is best-effort */ }
1337
+ catch { }
2185
1338
  }
2186
- // Budget kill resolves with a DISTINCT non-zero exit so CI/headless and
2187
- // teams/cloud can tell a budget termination apart from a normal failure.
2188
1339
  const exitCode = budgetKilled ? BUDGET_KILL_EXIT_CODE : (code ?? 0);
2189
- // Relate the session id back to a `--device` launcher (see the emitSessionId
2190
- // doc). Claude's id is the one we forced; every other agent coined its own,
2191
- // which the SessionStart hook recorded under this run's launchId — resolve
2192
- // and print it as a one-line sentinel that rides the followed log home.
2193
1340
  if (options.emitSessionId)
2194
1341
  emitResolvedSessionId(options, launchId, child.pid);
2195
1342
  timer.end({ exitCode, status: budgetKilled ? 'budget_killed' : code === 0 ? 'success' : 'failed' });
@@ -2197,21 +1344,8 @@ async function spawnAgentLeased(options) {
2197
1344
  });
2198
1345
  });
2199
1346
  }
2200
- /** Exit code spawnAgent resolves with when a run is killed for crossing a budget cap. */
2201
1347
  export const BUDGET_KILL_EXIT_CODE = 7;
2202
- /**
2203
- * Exit code a tmux-wrapped run resolves with when tmux cannot tell us how the
2204
- * agent finished — the pane is unreadable, or it is dead with no reported status
2205
- * (EXEC-23b). Never 0: an unknown outcome reported as success is how a run killed
2206
- * mid-work gets counted as a clean finish by whatever scripted it.
2207
- */
2208
1348
  export const UNKNOWN_OUTCOME_EXIT_CODE = 1;
2209
- /**
2210
- * Resolve the budget watcher for a run. Returns null (watcher dormant) when no
2211
- * caps are configured, so non-budget users pay nothing. When caps exist, builds
2212
- * a live watcher seeded with the day/project spend already on the ledger, plus
2213
- * a finalize() that appends this run's accumulated spend.
2214
- */
2215
1349
  async function setupBudgetWatcher(options, cwd, runId) {
2216
1350
  const interactive = resolveInteractive(options);
2217
1351
  if (interactive)
@@ -2232,7 +1366,6 @@ async function setupBudgetWatcher(options, cwd, runId) {
2232
1366
  agentDaySpend: { [options.agent]: ledger.spendForAgentDay(options.agent, today, entries) },
2233
1367
  });
2234
1368
  const watcher = makeLiveSpendWatcher({ caps, onBreach: () => { } });
2235
- // Accumulate per-(model) usage for a clean final ledger record.
2236
1369
  const seen = [];
2237
1370
  const model = options.model ?? `${options.agent}-default`;
2238
1371
  return {
@@ -2266,13 +1399,6 @@ async function setupBudgetWatcher(options, cwd, runId) {
2266
1399
  },
2267
1400
  };
2268
1401
  }
2269
- /**
2270
- * Patterns that indicate a rate/usage limit. Matching is intentionally broad
2271
- * because providers phrase these differently -- Anthropic uses "5-hour limit"
2272
- * and "rate limit", OpenAI surfaces 429s, Google says "quota exceeded".
2273
- * False positives here just trigger a fallback attempt; false negatives leave
2274
- * the original error unhandled, which is worse.
2275
- */
2276
1402
  export const RATE_LIMIT_PATTERNS = [
2277
1403
  /rate[\s-]?limit/i,
2278
1404
  /usage[\s-]?limit/i,
@@ -2282,23 +1408,12 @@ export const RATE_LIMIT_PATTERNS = [
2282
1408
  /too many requests/i,
2283
1409
  /api[\s_-]?overloaded/i,
2284
1410
  /\boverloaded\b/i,
2285
- // Claude billing refusals — "You've hit your org's monthly spend limit" and
2286
- // "You're out of usage credits". Both end the run with exit 1 and are exactly
2287
- // the condition a fallback chain exists to recover from. Printed to STDOUT,
2288
- // hence the stdout tail in SpawnResult.
2289
1411
  /spend[\s-]?limit/i,
2290
1412
  /out of (?:usage )?credits/i,
2291
1413
  ];
2292
- /** Return true if the text contains any known rate-limit or overload indicator. */
2293
1414
  export function detectRateLimit(text) {
2294
1415
  return RATE_LIMIT_PATTERNS.some(pattern => pattern.test(text));
2295
1416
  }
2296
- /**
2297
- * Narrow detector for a BILLING exhaustion — tokens/credits run out or the
2298
- * monthly spend cap is hit — as opposed to a time-window rate limit. This class
2299
- * does NOT recover on a clock, so rotation must remember it per-account
2300
- * (noteClaudeOutOfCredits) until a later successful run clears it.
2301
- */
2302
1417
  const OUT_OF_CREDITS_PATTERNS = [
2303
1418
  /out of (?:usage )?credits/i,
2304
1419
  /spend[\s-]?limit/i,
@@ -2306,17 +1421,6 @@ const OUT_OF_CREDITS_PATTERNS = [
2306
1421
  export function detectOutOfCredits(text) {
2307
1422
  return OUT_OF_CREDITS_PATTERNS.some(pattern => pattern.test(text));
2308
1423
  }
2309
- /**
2310
- * Classify a Claude run's output + exit code, model-limit refusal included.
2311
- * Precedence: a session-limit reset first (it carries a clock), then a
2312
- * clock-less billing exhaustion, then a MODEL-specific refusal ("You've
2313
- * reached your Fable limit…") — checked BEFORE the exit-0 clear so a model
2314
- * refusal that ends the run with exit 0 is never misread as a clean success
2315
- * that clears every other stale marker on the account. A model refusal never
2316
- * maps to `note_out_of_credits`/`note_session`: those are account-wide, this
2317
- * names one model. Only a clean run with NO refusal text clears stale
2318
- * markers; anything else leaves them untouched.
2319
- */
2320
1424
  export function classifyClaudeRunRefusal(output, exitCode, model) {
2321
1425
  const sessionLimitReset = parseClaudeSessionLimitReset(output);
2322
1426
  if (sessionLimitReset)
@@ -2331,22 +1435,7 @@ export function classifyClaudeRunRefusal(output, exitCode, model) {
2331
1435
  return { action: 'clear' };
2332
1436
  return { action: 'none' };
2333
1437
  }
2334
- /**
2335
- * Parse Codex's usage-limit refusal reset. Codex prints
2336
- * `ERROR: You've hit your usage limit. … try again at Sep 12th, 2026 8:32 AM.`
2337
- * (or `…try again at 8:32 AM.` for the 5-hour window). The reset is what makes
2338
- * this a session-style limit that auto-clears on its clock rather than a
2339
- * clock-less billing exhaustion. Ordinal suffixes (`12th`) are stripped so
2340
- * `Date.parse` accepts the date; a time-only reset resolves against today/tomorrow.
2341
- * Returns null when there is no future reset to parse (caller then leaves the
2342
- * marker untouched rather than persisting a sticky one it cannot expire).
2343
- */
2344
1438
  export function parseCodexUsageLimitReset(text, nowMs = Date.now()) {
2345
- // Gate on the CLI's own refusal phrasing, NOT a bare "usage limit" substring:
2346
- // this runs against a 16KB stdout tail of `codex exec`, which streams the whole
2347
- // agent transcript, so a session that merely *discusses* usage-limit code would
2348
- // otherwise false-positive and wrongly mark a HEALTHY account excluded. Mirrors
2349
- // the narrow Claude convention (`hit your session limit`).
2350
1439
  if (!/hit your usage limit/i.test(text))
2351
1440
  return null;
2352
1441
  const match = /try again (?:at|on)\s+([^.\n]+)/i.exec(text);
@@ -2355,14 +1444,8 @@ export function parseCodexUsageLimitReset(text, nowMs = Date.now()) {
2355
1444
  const segment = match[1].trim().replace(/(\d{1,2})(st|nd|rd|th)\b/gi, '$1');
2356
1445
  const absolute = Date.parse(segment);
2357
1446
  if (!Number.isNaN(absolute)) {
2358
- // A full date parsed — honor it only while still in the future; a past reset
2359
- // means the window already recovered, so there is nothing to note. Do NOT
2360
- // fall through to the clock path, which would understate the real date as
2361
- // today/tomorrow.
2362
1447
  return absolute > nowMs ? new Date(absolute) : null;
2363
1448
  }
2364
- // No date parsed — the 5-hour "try again at 8:32 AM" (time-only) form. Resolve
2365
- // it against today, rolling to tomorrow when the clock has already passed.
2366
1449
  const clock = /(\d{1,2})(?::(\d{2}))?\s*(am|pm)/i.exec(segment);
2367
1450
  if (!clock)
2368
1451
  return null;
@@ -2376,18 +1459,6 @@ export function parseCodexUsageLimitReset(text, nowMs = Date.now()) {
2376
1459
  result.setDate(result.getDate() + 1);
2377
1460
  return result;
2378
1461
  }
2379
- /**
2380
- * Classify what a Codex run's output + exit code means for the account's
2381
- * persisted refusal marker — the Codex sibling of {@link classifyClaudeRunRefusal}
2382
- * (the `ClaudeRefusalAction` shape is harness-generic; the usage cache it drives
2383
- * is identity-keyed and shared across harnesses). Codex's usage limit is
2384
- * time-windowed and carries a reset ("try again at <date>"), so it is noted as a
2385
- * clock-bearing session limit that auto-clears — NOT a clock-less out_of_credits,
2386
- * which would stay sticky until a successful run the excluded account can never
2387
- * get. A genuine credit/quota exhaustion IS clock-less. A clean run clears any
2388
- * stale marker; a limit with no parseable reset is left untouched (the run still
2389
- * cascades via detectRateLimit) rather than persisting an unexpirable marker.
2390
- */
2391
1462
  export function classifyCodexRunRefusal(output, exitCode, nowMs = Date.now()) {
2392
1463
  const reset = parseCodexUsageLimitReset(output, nowMs);
2393
1464
  if (reset)
@@ -2420,11 +1491,6 @@ const AUTH_FAILURE_PATTERNS = [
2420
1491
  /organization has (?:disabled|revoked) .*(?:subscription|access)/i,
2421
1492
  /401\b[^\n]*(?:OAuth|authenticat|credential|Unauthorized)/i,
2422
1493
  ];
2423
- /**
2424
- * Return true if the text contains any known authentication-failure indicator.
2425
- * Agent-agnostic: matches the user-visible error string wherever it surfaces
2426
- * (stdout tail, a captured error message, a plain-text agent's output).
2427
- */
2428
1494
  export function detectAuthFailure(text) {
2429
1495
  return AUTH_FAILURE_PATTERNS.some(pattern => pattern.test(text));
2430
1496
  }
@@ -2467,12 +1533,6 @@ export function detectAuthFailureEvent(logText, agent) {
2467
1533
  }
2468
1534
  return false;
2469
1535
  }
2470
- /**
2471
- * Return the first human-readable auth-failure phrase found in the text, for use
2472
- * as a stable, short run `errorMessage` reason. Falls back to null when the only
2473
- * signal was the structural `error:"authentication_failed"` marker with no
2474
- * user-visible string.
2475
- */
2476
1536
  export function authFailureReason(text) {
2477
1537
  for (const pattern of AUTH_FAILURE_PATTERNS) {
2478
1538
  const m = text.match(pattern);
@@ -2481,20 +1541,6 @@ export function authFailureReason(text) {
2481
1541
  }
2482
1542
  return null;
2483
1543
  }
2484
- /**
2485
- * Decide whether a run's stream-json log is an authentication failure. The
2486
- * single source of truth for both the foreground and detached run paths.
2487
- *
2488
- * The structural marker (`detectAuthFailureEvent`, gated on `is_error:true`) is
2489
- * authoritative and safe on ANY exit — it catches a logged-out Claude that exits
2490
- * 0 (its `result` event carries `is_error:true` while `terminal_reason` is
2491
- * "completed"). The raw user-visible string (`detectAuthFailure`) is only
2492
- * consulted when the process actually FAILED, as a fallback for a run that died
2493
- * mid-stream before emitting a `result` event. That gate is what prevents a
2494
- * genuinely-completed run whose output merely *mentions* an auth phrase (e.g. a
2495
- * routine documenting a login flow) from being misclassified and having its
2496
- * legitimate report suppressed.
2497
- */
2498
1544
  export function isAuthFailureFromLog(logText, agent, opts) {
2499
1545
  if (detectAuthFailureEvent(logText, agent))
2500
1546
  return true;
@@ -2502,16 +1548,6 @@ export function isAuthFailureFromLog(logText, agent, opts) {
2502
1548
  return true;
2503
1549
  return false;
2504
1550
  }
2505
- /**
2506
- * Build the prompt handed to the fallback agent when the primary was stopped
2507
- * mid-task by a rate limit.
2508
- *
2509
- * When the prior agent was Claude we pin its session ID via `--session-id` so
2510
- * `prevSessionId` is always defined; for other primaries we pass undefined and
2511
- * get a simpler retry-with-context prompt. Claude understands `/continue <id>`
2512
- * via its shipped skill -- other agents fall through to an explicit instruction
2513
- * that points at the version-agnostic `agents sessions <id>` reader.
2514
- */
2515
1551
  export function buildFallbackPrompt(prevAgent, prevSessionId, nextAgent, originalPrompt) {
2516
1552
  if (nextAgent === 'claude' && prevSessionId) {
2517
1553
  return `/continue ${prevSessionId}`;
@@ -2525,20 +1561,7 @@ export function buildFallbackPrompt(prevAgent, prevSessionId, nextAgent, origina
2525
1561
  lines.push(``, `Original request: ${originalPrompt}`, ``, `Continue from where the prior agent left off.`);
2526
1562
  return lines.join('\n');
2527
1563
  }
2528
- /**
2529
- * Run an agent and, on rate-limit failure, cascade through the fallback chain.
2530
- *
2531
- * The primary agent gets the original prompt. Subsequent agents get a
2532
- * `/continue <id>`-style handoff (see buildFallbackPrompt) when we can pin a
2533
- * session ID -- which today means Claude as primary (supports `--session-id`).
2534
- * For other primaries, fallbacks run with the original prompt plus a
2535
- * retry-with-context note, since we can't deterministically resolve their
2536
- * auto-generated session IDs.
2537
- *
2538
- * Only rate-limit failures cascade. Other errors (missing flag, auth failure,
2539
- * compile error) bubble up from the primary so the caller sees the real cause
2540
- * instead of an opaque "all agents failed" message.
2541
- */
1564
+ // Fallback preserves an explicit mode; only an implicit mode is re-resolved for the next harness.
2542
1565
  export async function runWithFallback(options) {
2543
1566
  const chain = [
2544
1567
  { agent: options.agent, version: options.version },
@@ -2546,11 +1569,6 @@ export async function runWithFallback(options) {
2546
1569
  ];
2547
1570
  let prevAgent;
2548
1571
  let prevSessionId;
2549
- // Workflow capability scoping only takes effect on claude (buildExecCommand
2550
- // guards `--tools` / `--mcp-config` / `--strict-mcp-config` on agent==='claude').
2551
- // A fallback to any non-claude agent would run with NONE of that scoping — the
2552
- // declared sandbox silently evaporates. Warn loudly so a rate-limit handoff to
2553
- // an unscoped agent is never silent (issue #324 fail-open).
2554
1572
  const scopingActive = (options.toolsRestrict && options.toolsRestrict.length > 0)
2555
1573
  || !!options.mcpConfigPath;
2556
1574
  if (scopingActive) {
@@ -2563,25 +1581,18 @@ export async function runWithFallback(options) {
2563
1581
  }
2564
1582
  for (let i = 0; i < chain.length; i++) {
2565
1583
  const { agent, version, envOverride } = chain[i];
2566
- // Every fallback entry can target a different harness/version home. Sync
2567
- // its active preset immediately before dispatch so entries 2..N cannot
2568
- // inherit the stale rules file left by the primary entry.
2569
1584
  const rulesVersion = version ?? resolveVersion(agent);
2570
1585
  if (rulesVersion) {
2571
1586
  applyActiveRulesPresetAtRun(agent, rulesVersion, getVersionHomePath(agent, rulesVersion));
2572
1587
  applySystemResourcesAtRun(agent, rulesVersion, getVersionHomePath(agent, rulesVersion));
2573
1588
  }
2574
- // Record the entry we're about to attempt so the caller (audit log) sees the
2575
- // agent+version that actually ran, even after a rate-limit handoff.
2576
1589
  if (options.dispatchSink) {
2577
1590
  options.dispatchSink.agent = agent;
2578
1591
  options.dispatchSink.version = version;
2579
1592
  }
2580
1593
  const pinnedSessionId = agent === 'claude' ? randomUUID() : undefined;
2581
- // Same-host retry (same agent+version as previous entry — used by profile
2582
- // `fallback_model` swaps) keeps the original prompt: the model changed,
2583
- // not the CLI, so a `/continue` handoff prompt would be misleading.
2584
1594
  const prev = i > 0 ? chain[i - 1] : undefined;
1595
+ // Same-agent entries are account/model retries, not cross-harness transcript handoff.
2585
1596
  const sameHostRetry = !!prev && prev.agent === agent && prev.version === version;
2586
1597
  const prompt = prevAgent && !sameHostRetry
2587
1598
  ? buildFallbackPrompt(prevAgent, prevSessionId, agent, options.prompt)
@@ -2594,8 +1605,6 @@ export async function runWithFallback(options) {
2594
1605
  prompt,
2595
1606
  env: envOverride ? { ...(options.env ?? {}), ...envOverride } : options.env,
2596
1607
  sessionId: pinnedSessionId ?? (i === 0 ? options.sessionId : undefined),
2597
- // Claude prints billing refusals (spend limit / out of credits) to
2598
- // stdout; tail it so the cascade check below can see them.
2599
1608
  captureStdoutTail: true,
2600
1609
  };
2601
1610
  const label = version ? `${agent}@${version}` : agent;
@@ -2620,13 +1629,6 @@ export async function runWithFallback(options) {
2620
1629
  throw err;
2621
1630
  }
2622
1631
  const output = `${result.stderr}\n${result.stdout}`;
2623
- // Persist a per-account refusal marker so rotation stops re-picking a
2624
- // known-dead account: a session/usage limit recovers on its clock, a billing
2625
- // exhaustion (tokens/credits) recovers only on a later successful run, and a
2626
- // clean run clears any stale marker. Claude and Codex both surface these as
2627
- // run-ending text, and the usage cache is identity-keyed (shared across
2628
- // harnesses), so one path notes either. Decisions extracted + unit-tested in
2629
- // classify{Claude,Codex}RunRefusal.
2630
1632
  const refusal = agent === 'claude'
2631
1633
  ? classifyClaudeRunRefusal(output, result.exitCode ?? 1, execOpts.model)
2632
1634
  : agent === 'codex'
@@ -2634,12 +1636,6 @@ export async function runWithFallback(options) {
2634
1636
  : null;
2635
1637
  const sessionLimitReset = refusal?.action === 'note_session' ? refusal.resetsAt : null;
2636
1638
  if (refusal && version && refusal.action !== 'none') {
2637
- // Resolve the account from the HOME this attempt actually authenticated
2638
- // from — execHome (a slot dir, PHNX-3940 T5) or configVersion wins over
2639
- // the bare managed-binary version home. Reading `getVersionHomePath(agent,
2640
- // version)` unconditionally attributed a refusal to the wrong account for
2641
- // every account-slot / configVersion launch, since `version` there is the
2642
- // BINARY, not the credential's home.
2643
1639
  const { versionHome: refusalHome } = resolveExecConfigHome(execOpts);
2644
1640
  const account = await getAccountInfo(agent, refusalHome ?? getVersionHomePath(agent, version));
2645
1641
  const usageKey = getUsageLookupKey(account);
@@ -2652,16 +1648,13 @@ export async function runWithFallback(options) {
2652
1648
  clearClaudeAccountRefusal(usageKey);
2653
1649
  }
2654
1650
  }
2655
- // A model-limit refusal commonly ends the CLI turn with exit 0 (Claude
2656
- // just refuses to keep going on that model rather than crashing) — so,
2657
- // like a session-limit reset, it must not be read as a clean success that
2658
- // short-circuits the cascade before the fallback chain ever runs.
2659
1651
  const modelLimited = refusal?.action === 'note_model_limit';
2660
1652
  if (result.exitCode === 0 && !sessionLimitReset && !modelLimited)
2661
1653
  return 0;
2662
1654
  const isLast = i === chain.length - 1;
2663
1655
  if (isLast)
2664
1656
  return result.exitCode || 1;
1657
+ // Authentication and ordinary failures never trigger provider fallback; only explicit capacity signals do.
2665
1658
  if (!sessionLimitReset && !modelLimited && !detectRateLimit(result.stderr) && !detectRateLimit(result.stdout)) {
2666
1659
  return result.exitCode;
2667
1660
  }