@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
@@ -1,12 +1,4 @@
1
1
  import { daemonProcessViewAllowed, recordDaemonProcessView } from '../session/process-view.js';
2
- /**
3
- * Daemon lifecycle management for the routines scheduler.
4
- *
5
- * The daemon is a long-running process that holds a JobScheduler and
6
- * triggers jobs on their cron schedules. It can be managed via launchd
7
- * (macOS), systemd (Linux), or as a plain detached process. PID tracking,
8
- * log output, reload (SIGHUP), and graceful shutdown are handled here.
9
- */
10
2
  import { spawn, execFileSync } from 'child_process';
11
3
  import * as fs from 'fs';
12
4
  import * as path from 'path';
@@ -17,7 +9,6 @@ import { isAlive, killTree, backgroundSpawnOptions, waitForExit } from '../platf
17
9
  import { listJobs as listAllJobs } from '../scheduling/routines.js';
18
10
  import { syncAllProjectRoutines } from '../routines-project.js';
19
11
  import { JobScheduler } from '../scheduler.js';
20
- // MonitorEngine is now owned by MonitorEngineService (daemon/monitor-engine-service.ts).
21
12
  import { executeJobDetached, listLiveRoutineChildren } from './runner.js';
22
13
  import { detectOverdueJobs, notifyOverdue } from '../overdue.js';
23
14
  import { runCatchup } from '../catchup.js';
@@ -32,18 +23,7 @@ import { ServiceSupervisor } from './supervisor.js';
32
23
  import { emit, emitAsync, emitRoutineEnd } from '../feed/events.js';
33
24
  import { readDaemonServicesConfig, drainDaemonServiceRestartQueue } from '../daemon-services.js';
34
25
  import { sleepSync } from '../fs-atomic.js';
35
- /**
36
- * The live `ServiceSupervisor` for the current `runDaemon()` invocation, or
37
- * `null` before boot / after shutdown. In-process only — a separate `agents
38
- * daemon status` process cannot see this; per-service health that must
39
- * survive across processes goes through `daemon-health.ts` instead (which
40
- * `ServiceSupervisor` already writes on every tick). This getter exists so a
41
- * FUTURE same-process consumer (e.g. a `daemon services` live-status IPC
42
- * handler) can read the supervisor's live state (`running`/`stopped`, plus the
43
- * failure streak) without needing its own reference to `runDaemon()`'s locals.
44
- */
45
26
  let activeServiceSupervisor = null;
46
- /** Health for every service currently registered on the live supervisor, or `null` if the daemon isn't running in this process. */
47
27
  export function getServiceSupervisorHealth() {
48
28
  return activeServiceSupervisor?.health() ?? null;
49
29
  }
@@ -52,133 +32,32 @@ const LIFETIME_FILE = 'daemon.lifetime';
52
32
  const LOCK_FILE = 'daemon.lock';
53
33
  const LOG_FILE = 'logs.jsonl';
54
34
  const HEARTBEAT_FILE = 'heartbeat.json';
55
- const LOG_MAX_SIZE = 5 * 1024 * 1024; // 5 MB
35
+ const LOG_MAX_SIZE = 5 * 1024 * 1024;
56
36
  const LOG_ROTATE_COUNT = 3;
57
37
  const PLIST_NAME = 'com.phnx-labs.agents-daemon';
58
38
  const SYSTEMD_UNIT = 'agents-daemon.service';
59
- /**
60
- * The service-manager identifiers of the REAL install's daemon — never
61
- * namespaced. A caller under a redirected HOME (a test/e2e harness) uses these
62
- * to recognize the box's production daemon as owned, where
63
- * `daemonSystemdUnitName()`/`daemonServiceLabel()` would name only its own
64
- * sandbox job (W4, PHNX-3736).
65
- */
39
+ // Redirected HOME instances namespace manager ids because launchd/systemd key by label/unit, not manifest path; tests must never unload production.
66
40
  export function productionDaemonServiceNames() {
67
41
  return { systemdUnit: SYSTEMD_UNIT, launchdLabel: PLIST_NAME };
68
42
  }
69
- /**
70
- * RUSH-2639 (residual): launchd/systemd route `unload`/`load`/`list` by the
71
- * service identifier ALONE, never by the plist/unit file's path. Baking the
72
- * caller's HOME into the plist content (the earlier RUSH-2639 fix, above)
73
- * keeps the STARTED daemon inside its sandbox, but every hermetic-test
74
- * instance and every real interactive install still share the one literal
75
- * `PLIST_NAME`/`SYSTEMD_UNIT` string. `startDaemonLocked`'s own `unload`
76
- * before `load` is written to be a no-op ("not loaded, expected") for a
77
- * plist that has never been loaded — but confirmed on darwin: when a
78
- * DIFFERENT plist is already loaded under that same label, `unload
79
- * <this-instance's-own-never-loaded-path>` still tears down the OTHER job
80
- * (verified directly against real launchctl with two throwaway plists
81
- * sharing one label — the second job's own `unload` silently kills the
82
- * first, still alive under a different path). On a machine running several
83
- * hermetic test forks at once (CI) — or a developer's own suite next to
84
- * their real always-on daemon — that "other job" is a live daemon with
85
- * DIFFERENT baked-in state.
86
- *
87
- * Namespace the identifier itself whenever HOME has been redirected away
88
- * from the account's real home. `os.userInfo().homedir` reads the OS/passwd
89
- * record directly and ignores `$HOME` (unlike `os.homedir()`, which honors
90
- * it), so comparing the two detects exactly this redirection — true for
91
- * every hermetic test process, false for every real interactive/production
92
- * invocation, so a real user's daemon keeps registering under the unchanged
93
- * production identifier.
94
- *
95
- * The rule itself now lives in `service-manifest.ts` — the daemon was the first
96
- * manifest to need it, not the only one — and is re-exported here because it is
97
- * part of this module's published surface.
98
- */
99
43
  export { isolatedHomeSuffix };
100
- /** launchd Label for this process's daemon — namespaced under a redirected HOME. */
101
44
  export function daemonServiceLabel() {
102
45
  return namespacedServiceLabel(PLIST_NAME);
103
46
  }
104
- /** systemd --user unit name for this process's daemon — namespaced under a redirected HOME. */
105
47
  export function daemonSystemdUnitName() {
106
48
  const suffix = isolatedHomeSuffix();
107
49
  return suffix ? `agents-daemon-sandbox-${suffix}.service` : SYSTEMD_UNIT;
108
50
  }
109
- // Catch-up cadence + the supervised CatchupService live in catchup-service.ts
110
- // (PHNX-3608): the pass now runs under the ServiceSupervisor with a deadline +
111
- // AbortSignal + circuit breaker instead of a bare setInterval.
112
- /**
113
- * Cadences for the in-process background ticks, named here beside the other
114
- * tick constants rather than left as inline literals at their `setInterval`
115
- * (RUSH-2423). Self-heal, state-dir-check, watchdog, and device-probe
116
- * cadences moved to their own `*-service.ts` files (RUSH-3193 P3, alongside
117
- * session-index/account-state/etc.) — see those files for the per-service
118
- * trade-offs (self-heal's 6h/cheap-to-be-late repair cadence, state-dir-check's
119
- * env override for tests, watchdog/device-probe's shared 3min in-process
120
- * housekeeping cadence, NOT a routine — RUSH-2495). The secrets broker and its
121
- * self-heal/reap ticks moved out of this daemon entirely with the standalone
122
- * `secrets` engine (PHNX-3989 OWN-1) — this daemon no longer hosts that broker.
123
- */
124
- // Session-index warm interval/deadline live in session-index-service.ts now
125
- // (RUSH-3193 — migrated onto ServiceSupervisor).
126
51
  const WEDGE_THRESHOLD_TICKS = 3;
127
52
  const DAEMON_HEARTBEAT_TICK_MS = 60_000;
128
- /**
129
- * Crash-loop pacing and auto-start bounding (RUSH-2418, PHNX-4116). Two layers,
130
- * because a daemon that dies during startup must be paced but must NEVER be
131
- * abandoned:
132
- *
133
- * 1. **The OS supervisor paces AND always retries the respawn.** launchd's
134
- * `KeepAlive` with `ThrottleInterval=30` (and systemd's `Restart=always`
135
- * `RestartSec=30`) relaunch a dead daemon every ~30s. Crucially systemd's
136
- * `StartLimitIntervalSec=0` REMOVES the burst cap (PHNX-4116): a repeatedly
137
- * deadline-breaching daemon is restarted every ~30s indefinitely rather than
138
- * parked in `failed` and left dark until a human runs `systemctl restart`.
139
- * The owner requirement is that a wedged daemon always recovers on its own —
140
- * "just work like systemd/launchd". A supervised deadline breach is precisely
141
- * what forces the exit (see `ServiceSupervisor.exitForRestart`), so the exit
142
- * is the recovery, not a failure to give up on.
143
- * 2. **The application-level circuit breaker** below still stops *auto*-starts
144
- * from re-entering the loop from the other direction — a foreground command
145
- * that calls `ensureDaemonStarted()` on every invocation. This bounds the
146
- * IMPLICIT starts a busy operator would otherwise trigger; the OS-level
147
- * unit-restart above is deliberately unbounded.
148
- */
149
53
  const DAEMON_THROTTLE_SECONDS = 30;
150
- /**
151
- * How many consecutive failed daemon starts disable the *implicit* auto-start
152
- * (`ensureDaemonStarted`). This bounds foreground-command auto-starts only; the
153
- * OS-level unit restart is deliberately unbounded (`StartLimitIntervalSec=0`) so
154
- * a wedged daemon always recovers (PHNX-4116). `agents daemon start` is the
155
- * deliberate override and is never gated by this.
156
- */
157
54
  export const DAEMON_AUTOSTART_FAILURE_LIMIT = 5;
158
55
  export function schedulerGateTransition(running, enabled) {
159
56
  if (running)
160
57
  return enabled ? 'reload' : 'stop';
161
58
  return enabled ? 'boot' : 'none';
162
59
  }
163
- /**
164
- * Wrap an async routine so it runs AT MOST ONCE, however many callers fire it.
165
- *
166
- * Extracted rather than left as a `let shuttingDown = false` inside runDaemon so
167
- * the property can actually be tested (RUSH-2423). The daemon's shutdown is
168
- * reachable from SIGTERM, SIGINT, and the state-dir self-check, but a real
169
- * shutdown completes in ~26ms, so the re-entrant window is not reachable from
170
- * outside the process — an end-to-end "send three signals" test passes with the
171
- * guard removed and proves nothing. The mechanism is what is testable, so the
172
- * mechanism is what is separated out.
173
- *
174
- * The flag is set synchronously before the first `await`, which is what makes
175
- * this safe: two callers in the same tick cannot both get past it.
176
- *
177
- * A rejected `fn` leaves the guard SET — one attempt is all there is, and the
178
- * rejection propagates to the caller that made it. That is right for shutdown
179
- * (a failed shutdown must not be silently retried by the next signal) but is
180
- * the thing to re-examine before giving this a second consumer.
181
- */
60
+ // Latch before the first await and never retry after rejection: daemon shutdown is single-shot.
182
61
  export function singleShot(fn) {
183
62
  let ran = false;
184
63
  return async () => {
@@ -199,11 +78,7 @@ function getPidPath() {
199
78
  function getLockPath() {
200
79
  return path.join(ensureDaemonDir(), LOCK_FILE);
201
80
  }
202
- /**
203
- * Acquire an exclusive start lock. Returns a release function on success,
204
- * or null if another process already holds the lock. Uses O_EXCL to
205
- * atomically create the file — no TOCTOU window.
206
- */
81
+ // Start, claim, and stop share this O_EXCL lifecycle lock; unreadable live identity is unverified, never stale.
207
82
  function acquireStartLock() {
208
83
  const lockPath = getLockPath();
209
84
  try {
@@ -214,38 +89,30 @@ function acquireStartLock() {
214
89
  try {
215
90
  fs.unlinkSync(lockPath);
216
91
  }
217
- catch { /* already removed */ }
92
+ catch { }
218
93
  };
219
94
  }
220
95
  catch (err) {
221
96
  if (err.code === 'EEXIST') {
222
- // Lock file exists — check if the holder is still alive (stale lock recovery)
223
97
  try {
224
98
  const holderPid = parseInt(fs.readFileSync(lockPath, 'utf-8').trim(), 10);
225
99
  if (!isNaN(holderPid)) {
226
100
  try {
227
101
  process.kill(holderPid, 0);
228
- return null; // holder is alive, lock is valid
102
+ return null;
229
103
  }
230
104
  catch {
231
- // holder is dead, remove stale lock and retry once
232
105
  fs.unlinkSync(lockPath);
233
106
  return acquireStartLock();
234
107
  }
235
108
  }
236
109
  }
237
- catch { /* can't read lock file — treat as held */ }
110
+ catch { }
238
111
  return null;
239
112
  }
240
113
  throw err;
241
114
  }
242
115
  }
243
- /**
244
- * Stop is a lifecycle mutation just like start/claim, so it must cross the same
245
- * lock. A claim can legitimately hold the lock through the incumbent's 5s
246
- * graceful window plus the 2s hard-kill backstop; wait beyond that complete
247
- * takeover window before failing loud instead of running teardown unlocked.
248
- */
249
116
  const STOP_LOCK_WAIT_MS = 10_000;
250
117
  const STOP_LOCK_POLL_MS = 50;
251
118
  function acquireLifecycleLock() {
@@ -259,14 +126,6 @@ function acquireLifecycleLock() {
259
126
  sleepSync(Math.min(STOP_LOCK_POLL_MS, deadline - Date.now()));
260
127
  }
261
128
  }
262
- /**
263
- * Absolute path to the daemon's structured log.
264
- *
265
- * Exported because two commands rebuilt the same path from a hardcoded
266
- * `'logs.jsonl'` literal (`commands/daemon.ts`, `commands/routines.ts`), so
267
- * renaming the file would have silently pointed them at nothing (RUSH-2423).
268
- * One definition, three callers.
269
- */
270
129
  export function getDaemonLogPath() {
271
130
  return path.join(ensureDaemonDir(), LOG_FILE);
272
131
  }
@@ -276,7 +135,6 @@ function getLaunchdPlistPath() {
276
135
  function getSystemdUnitPath() {
277
136
  return path.join(os.homedir(), '.config', 'systemd', 'user', daemonSystemdUnitName());
278
137
  }
279
- /** Read the stored daemon PID from disk. Returns null if not present or invalid. */
280
138
  export function readDaemonPid(daemonDir) {
281
139
  const pidPath = daemonDir ? path.join(daemonDir, PID_FILE) : getPidPath();
282
140
  if (!fs.existsSync(pidPath))
@@ -289,25 +147,23 @@ export function readDaemonPid(daemonDir) {
289
147
  return null;
290
148
  }
291
149
  }
292
- /** Write the daemon PID to the pid file. */
293
150
  export function writeDaemonPid(pid) {
294
151
  fs.writeFileSync(getPidPath(), String(pid), 'utf-8');
295
152
  }
296
- /** Remove the daemon PID file. */
297
153
  export function removeDaemonPid() {
298
154
  const pidPath = getPidPath();
299
155
  if (fs.existsSync(pidPath)) {
300
156
  fs.unlinkSync(pidPath);
301
157
  }
302
158
  }
303
- /** Remove the pid registration only while it still names the owner we observed. */
159
+ // Remove registration only while it still names the owner observed by this cleanup.
304
160
  function removeDaemonPidIfOwned(pid) {
305
161
  if (readDaemonPid() !== pid)
306
162
  return false;
307
163
  try {
308
164
  fs.unlinkSync(getPidPath());
309
165
  }
310
- catch { /* already removed */ }
166
+ catch { }
311
167
  return readDaemonPid() !== pid;
312
168
  }
313
169
  function getHeartbeatPath() {
@@ -318,7 +174,7 @@ export function writeHeartbeat(pid = process.pid) {
318
174
  try {
319
175
  fs.writeFileSync(getHeartbeatPath(), JSON.stringify(hb), 'utf-8');
320
176
  }
321
- catch { /* best effort */ }
177
+ catch { }
322
178
  }
323
179
  export function readHeartbeat() {
324
180
  try {
@@ -336,43 +192,15 @@ export function removeHeartbeat() {
336
192
  try {
337
193
  fs.unlinkSync(getHeartbeatPath());
338
194
  }
339
- catch { /* already removed */ }
340
- }
341
- /**
342
- * A heartbeat is "fresh" when its last tick falls inside the freshness window. A
343
- * fresh heartbeat whose pid is alive is proof of a live, ticking daemon even
344
- * when the pid file has been lost, which is why `resolveLiveDaemonPid` trusts it.
345
- *
346
- * There is no separate "wedged" verdict any more (PHNX-4116): a daemon whose
347
- * event loop stalls no longer sits `wedged` waiting for a human — a supervised
348
- * service that breaches its deadline exits the process, and systemd/launchd
349
- * restart it. So the daemon is simply `running` or `stopped`.
350
- */
195
+ catch { }
196
+ }
351
197
  function isHeartbeatFresh(hb) {
352
198
  const elapsed = Date.now() - Date.parse(hb.lastTick);
353
199
  return elapsed <= WEDGE_THRESHOLD_TICKS * DAEMON_HEARTBEAT_TICK_MS;
354
200
  }
355
- /** How long stopDaemon waits for a SIGTERMed daemon to exit before escalating. */
356
201
  const STOP_GRACE_MS = 5000;
357
- /** How long it waits after the hard tree-kill before giving up. */
358
202
  const STOP_KILL_GRACE_MS = 2000;
359
- /**
360
- * Resolve the PID of the live daemon, tolerant of a pid-file/heartbeat desync.
361
- *
362
- * The daemon writes the pid file once (on claim/start) but rewrites the
363
- * heartbeat every tick. If the pid file is lost while the daemon keeps ticking
364
- * — e.g. an earlier isDaemonRunning() found a stale/reused/dead pid and cleared
365
- * the file, or it was removed out from under a live daemon — the pid file reads
366
- * empty even though a daemon is genuinely alive and firing jobs. Reading only
367
- * the pid file then reports "stopped" for a running scheduler, and (worse) lets
368
- * claimDaemonInstance() start a SECOND daemon that double-fires every routine.
369
- *
370
- * So: trust the pid file only when its pid is a live `__daemon-run`; otherwise
371
- * trust a FRESH heartbeat whose pid passes the same identity check. Callers that
372
- * already own daemon.lock may request repair, re-adopting the heartbeat pid or
373
- * removing the exact stale pid they observed. Read-only liveness probes never
374
- * mutate shared state outside that lock.
375
- */
203
+ // A fresh heartbeat may repair a lost pid record; unknown identity is preserved so inspection failure cannot create a second daemon.
376
204
  function resolveLiveDaemonPid(repair = false) {
377
205
  const pid = readDaemonPid();
378
206
  const pidIdentity = pid !== null ? daemonProcessIdentity(pid) : 'dead';
@@ -381,17 +209,13 @@ function resolveLiveDaemonPid(repair = false) {
381
209
  const hb = readHeartbeat();
382
210
  if (hb && isHeartbeatFresh(hb) && daemonProcessIdentity(hb.pid) === 'daemon') {
383
211
  if (repair && pid !== hb.pid)
384
- writeDaemonPid(hb.pid); // lock owner heals the desync
212
+ writeDaemonPid(hb.pid);
385
213
  return hb.pid;
386
214
  }
387
- // A failed command-line inspection is not proof the pid is stale. Leave the
388
- // registration intact so a sandbox/permission failure cannot erase the only
389
- // owner record and trigger a duplicate daemon.
390
215
  if (repair && pid !== null && pidIdentity !== 'unknown')
391
216
  removeDaemonPidIfOwned(pid);
392
217
  return null;
393
218
  }
394
- /** A live recorded pid whose command identity could not be inspected. */
395
219
  function unverifiedLiveDaemonPid() {
396
220
  const pid = readDaemonPid();
397
221
  if (pid !== null && daemonProcessIdentity(pid) === 'unknown')
@@ -401,17 +225,7 @@ function unverifiedLiveDaemonPid() {
401
225
  return hb.pid;
402
226
  return null;
403
227
  }
404
- /**
405
- * Check whether a daemon is alive — via the pid file, or a fresh heartbeat when
406
- * the pid file has been lost (see resolveLiveDaemonPid). The observation itself
407
- * is read-only; when it finds desync it opportunistically acquires daemon.lock
408
- * and repeats the observation there before repairing. A contended probe still
409
- * returns the observed liveness without mutating another lifecycle operation's
410
- * state.
411
- */
412
228
  export function isDaemonRunning() {
413
- // Fail safe for reporting/start suppression: inability to inspect a live pid
414
- // is never permission to declare it dead and launch a duplicate.
415
229
  if (unverifiedLiveDaemonPid() !== null)
416
230
  return true;
417
231
  const recordedPid = readDaemonPid();
@@ -428,63 +242,22 @@ export function isDaemonRunning() {
428
242
  release();
429
243
  }
430
244
  }
431
- /**
432
- * Single-instance claim for the daemon foreground entrypoint.
433
- *
434
- * `agents __daemon-run` is reachable directly — a manual invocation, or a
435
- * service-manager restart that races a still-alive predecessor — bypassing the
436
- * start lock in startDaemon(). Without this guard runDaemon() would call
437
- * writeDaemonPid() unconditionally, clobber a live daemon's recorded PID, and
438
- * run a second JobScheduler concurrently, so every cron routine fires twice.
439
- *
440
- * LAST-WINS takeover (SING-11, RUSH-2352): when a live daemon already owns the
441
- * pid file, this does NOT defer to it — it evicts the incumbent and becomes the
442
- * survivor, so a second install can never leave two daemons running. Returns true
443
- * and records our PID once the incumbent is provably dead (its resources
444
- * released). Returns false when another `__daemon-run` currently holds the
445
- * O_EXCL start lock, or when the incumbent cannot be safely identified/evicted,
446
- * in which case the caller must exit without touching further state.
447
- * The read-evict-write is serialized behind the same start lock startDaemon()
448
- * uses, so two `_run` processes can't both claim in the window between the
449
- * liveness check and the write.
450
- */
451
245
  export function claimDaemonInstance() {
452
- // A nested caller cannot interpret legacy numeric lock/PID files. Authenticate
453
- // before acquiring the lock (whose stale-PID cleanup itself mutates state).
454
246
  if (!daemonProcessViewAllowed()) {
455
247
  console.error('Daemon startup requires the owning process namespace. Automatic reuse of a private-container HOME across namespaces is unsupported; run in its owning namespace or use a fresh HOME.');
456
248
  return false;
457
249
  }
458
- // A stop owns this same lock through teardown. Waiting here is load-bearing:
459
- // returning false while stopDaemon() holds it lets this replacement exit 0,
460
- // then the stop completes with no singleton left alive. The bounded lifecycle
461
- // acquisition also preserves concurrent-start serialization: after the first
462
- // claimer publishes its pid, the waiter takes the lock and performs the normal
463
- // last-wins takeover rather than ever running the read-evict-write unlocked.
464
250
  const release = acquireLifecycleLock();
465
251
  if (!release)
466
252
  return false;
467
253
  try {
468
- // Recheck under lifecycle serialization; invocation is not provenance.
469
254
  if (!daemonProcessViewAllowed())
470
255
  return false;
471
256
  recordDaemonProcessView();
472
- // Do not overwrite a live-but-uninspectable owner. This is the non-
473
- // destructive side of the same fail-closed rule stopDaemon applies.
474
257
  if (unverifiedLiveDaemonPid() !== null)
475
258
  return false;
476
- // resolveLiveDaemonPid() also consults a fresh heartbeat, so a live daemon
477
- // whose pid file was lost is still found and evicted — otherwise a missing
478
- // pid file would let both this instance AND the orphaned incumbent run a
479
- // JobScheduler at once and double-fire every routine.
480
259
  const existing = resolveLiveDaemonPid(true);
481
260
  if (existing !== null && existing !== process.pid) {
482
- // Evict, and WAIT for the incumbent to be provably dead — its graceful
483
- // handleShutdown releasing its socket bindings (feed-stream hub, monitor)
484
- // — before we write our pid and (later, in runDaemon) bind our own.
485
- // Binding before the release recreates the two-owners-on-one-socket orphan
486
- // documented at stopDaemon below, so the pid file is not written until the
487
- // prior owner is gone.
488
261
  if (!evictIncumbentDaemon(existing))
489
262
  return false;
490
263
  }
@@ -495,21 +268,6 @@ export function claimDaemonInstance() {
495
268
  release();
496
269
  }
497
270
  }
498
- /**
499
- * SIGTERM a live incumbent daemon and block until it is provably dead, so its
500
- * graceful handleShutdown has released its socket bindings (the feed-stream hub,
501
- * the monitor socket) BEFORE the newcomer binds anything of its own (SING-11) —
502
- * the daemon no longer hosts a secrets broker socket (the standalone `secrets`
503
- * CLI owns it, PHNX-3989 OWN-1) nor a browser IPC socket (the standalone
504
- * `browser` CLI owns it, PHNX-4101). Escalates
505
- * to killTree after the grace window. Passes the POSITIVE pid so the kill reaches
506
- * only the incumbent daemon — never its detached routine children, which run in
507
- * their own process groups and must survive takeover (SING-11a); the new daemon
508
- * re-adopts them via monitorRunningJobs. Synchronous to match claimDaemonInstance's
509
- * read-evict-write, which runs under the O_EXCL start lock; mirrors stopDaemon's
510
- * grace-then-escalate shape and constants exactly, because the same
511
- * proof-of-release requirement applies.
512
- */
513
271
  function evictIncumbentDaemon(pid) {
514
272
  const beforeSignal = daemonProcessIdentity(pid);
515
273
  if (beforeSignal === 'dead' || beforeSignal === 'other')
@@ -517,9 +275,6 @@ function evictIncumbentDaemon(pid) {
517
275
  if (beforeSignal === 'unknown')
518
276
  return false;
519
277
  if (process.platform === 'win32') {
520
- // No graceful termination signal on Windows — take the incumbent down and
521
- // still wait for the kill to land before the caller binds anything (mirrors
522
- // stopDaemon's win32 branch).
523
278
  killTree(pid);
524
279
  if (waitForExit(pid, STOP_KILL_GRACE_MS))
525
280
  return true;
@@ -534,67 +289,39 @@ function evictIncumbentDaemon(pid) {
534
289
  return afterSignal === 'dead' || afterSignal === 'other';
535
290
  }
536
291
  if (waitForExit(pid, STOP_GRACE_MS))
537
- return true; // graceful release complete
292
+ return true;
538
293
  const beforeKill = daemonProcessIdentity(pid);
539
294
  if (beforeKill === 'dead' || beforeKill === 'other')
540
295
  return true;
541
296
  if (beforeKill === 'unknown')
542
297
  return false;
543
- killTree(pid); // positive pid: SIGKILL reaches the daemon, not its job children
298
+ killTree(pid);
544
299
  if (waitForExit(pid, STOP_KILL_GRACE_MS))
545
300
  return true;
546
301
  const afterKill = daemonProcessIdentity(pid);
547
302
  return afterKill === 'dead' || afterKill === 'other';
548
303
  }
549
- /** Directory that registers every live daemon of THIS device (one per state dir). */
550
304
  function getDaemonInstancesDir() {
551
305
  return path.join(getDaemonDir(), 'instances');
552
306
  }
553
- /**
554
- * Record this daemon in the device's instance registry — a marker file named by
555
- * pid under `<daemonDir>/instances/`. The registry, not a process scan, is how
556
- * the reaper enumerates the device singleton: because the dir lives INSIDE the
557
- * state dir (`AGENTS_DAEMON_DIR` ?? `<HOME>/.agents/.cache/helpers/daemon`), every
558
- * daemon of one device — however it was launched — registers in the same place,
559
- * while a genuinely separate install/home or a test fixture registers under its
560
- * own state dir and is invisible here. This is what fixes the two-entry pile-up:
561
- * the compiled `dist/bin/agents` binary and the `node <shim>` JS entry have
562
- * different `process.argv[1]`, so the old launch-entry-scoped `ps` match never
563
- * reaped across them and duplicates accumulated (78 observed on one box), every
564
- * routine double-firing. Best-effort — the reaper self-heals a missing/stale
565
- * marker, and reading another process's ENV to key on the state dir directly is
566
- * not portable (hardened macOS hides it from `ps`), so identity rides the shared
567
- * on-disk registry instead. No-op on Windows (POSIX-only reaper).
568
- */
569
307
  export function registerDaemonInstance(pid = process.pid) {
570
308
  if (process.platform === 'win32')
571
309
  return;
572
310
  try {
573
311
  const dir = getDaemonInstancesDir();
574
312
  fs.mkdirSync(dir, { recursive: true });
575
- // The command line is stored for diagnostics; the filename (pid) is identity.
576
313
  fs.writeFileSync(path.join(dir, String(pid)), process.argv.slice(1).join(' '), 'utf-8');
577
314
  }
578
- catch { /* best effort — the reaper self-heals a missing marker */ }
315
+ catch { }
579
316
  }
580
- /** Remove this daemon's registry marker on graceful shutdown. */
581
317
  export function unregisterDaemonInstance(pid = process.pid) {
582
318
  if (process.platform === 'win32')
583
319
  return;
584
320
  try {
585
321
  fs.rmSync(path.join(getDaemonInstancesDir(), String(pid)), { force: true });
586
322
  }
587
- catch { /* ignore */ }
588
- }
589
- /**
590
- * Reap stray duplicate daemons of THIS device — every registrant in the instance
591
- * registry that is a live `agents __daemon-run` and is neither this process nor
592
- * the current pid-file owner. A predecessor SIGKILLed/OOM-ed without cleanup, or a
593
- * duplicate that lost the pid-file write race, would otherwise keep a second
594
- * scheduler alive and double-fire jobs even after claimDaemonInstance() hands the
595
- * pid file to the survivor. Also garbage-collects markers whose pid is dead or was
596
- * reused by an unrelated process. No-op on Windows (POSIX-only).
597
- */
323
+ catch { }
324
+ }
598
325
  export function reapStrayDaemons(keepPid = process.pid) {
599
326
  const details = [];
600
327
  let reaped = 0;
@@ -606,28 +333,25 @@ export function reapStrayDaemons(keepPid = process.pid) {
606
333
  entries = fs.readdirSync(dir);
607
334
  }
608
335
  catch {
609
- return { reaped, details }; // no registry yet — nothing to reap
336
+ return { reaped, details };
610
337
  }
611
338
  const ownerPid = resolveLiveDaemonPid();
612
339
  const dropMarker = (name) => {
613
340
  try {
614
341
  fs.rmSync(path.join(dir, name), { force: true });
615
342
  }
616
- catch { /* ignore */ }
343
+ catch { }
617
344
  };
618
345
  for (const name of entries) {
619
346
  const pid = parseInt(name, 10);
620
347
  if (isNaN(pid) || String(pid) !== name)
621
- continue; // not a pid marker
348
+ continue;
622
349
  if (pid === keepPid || pid === process.pid || pid === ownerPid)
623
350
  continue;
624
- // Dead registrant → stale marker.
625
351
  if (!isAlive(pid)) {
626
352
  dropMarker(name);
627
353
  continue;
628
354
  }
629
- // Live pid, but guard against pid reuse: only a real `__daemon-run` is ours.
630
- // Process ARGS are readable cross-platform (unlike ENV on hardened macOS).
631
355
  const identity = daemonProcessIdentity(pid);
632
356
  if (identity === 'unknown') {
633
357
  details.push(`could not verify stray daemon pid ${pid}; marker retained`);
@@ -640,16 +364,13 @@ export function reapStrayDaemons(keepPid = process.pid) {
640
364
  try {
641
365
  process.kill(pid, 'SIGTERM');
642
366
  }
643
- catch { /* already gone between the alive check and the signal */ }
367
+ catch { }
644
368
  if (waitForExit(pid, STOP_GRACE_MS)) {
645
369
  reaped++;
646
370
  details.push(`reaped stray daemon pid ${pid}`);
647
371
  dropMarker(name);
648
372
  continue;
649
373
  }
650
- // The pid may have been recycled during the grace window. Never hard-kill
651
- // it unless it still identifies as a daemon; a stale registry marker is all
652
- // we own when the command identity changed.
653
374
  const beforeKill = daemonProcessIdentity(pid);
654
375
  if (beforeKill === 'unknown') {
655
376
  details.push(`could not reverify stray daemon pid ${pid}; marker retained`);
@@ -666,8 +387,6 @@ export function reapStrayDaemons(keepPid = process.pid) {
666
387
  dropMarker(name);
667
388
  }
668
389
  else {
669
- // Keep the only marker for a process that survived both signals so the
670
- // next reaper/doctor can still see it.
671
390
  details.push(`stray daemon pid ${pid} survived SIGKILL`);
672
391
  }
673
392
  }
@@ -683,9 +402,6 @@ function daemonProcessIdentity(pid) {
683
402
  encoding: 'utf-8',
684
403
  stdio: ['ignore', 'pipe', 'ignore'],
685
404
  });
686
- // getDaemonLaunch always places __daemon-run last. Matching it anywhere in
687
- // the command line mistakes an agent prompt or shell script that merely
688
- // mentions the token for the shared daemon.
689
405
  return /(?:^|\s)["']?__daemon-run["']?\s*$/.test(out.trim()) ? 'daemon' : 'other';
690
406
  }
691
407
  catch {
@@ -711,7 +427,6 @@ function rotateLogsIfNeeded(logPath) {
711
427
  }
712
428
  catch { }
713
429
  }
714
- /** Append a JSONL log entry to the daemon log file (owner-only permissions). */
715
430
  export function log(level, message) {
716
431
  const logPath = getDaemonLogPath();
717
432
  rotateLogsIfNeeded(logPath);
@@ -720,30 +435,21 @@ export function log(level, message) {
720
435
  try {
721
436
  fs.chmodSync(logPath, 0o600);
722
437
  }
723
- catch { /* best effort */ }
724
- // Mirror into the unified event stream so `agents events --module daemon` sees
725
- // always-on process lifecycle the same way secrets/browser/computer do.
726
- // Fail soft — the daemon log file remains the primary sink for `daemon logs`.
438
+ catch { }
727
439
  try {
728
440
  const lvl = level.toUpperCase();
729
441
  const event = lvl === 'ERROR' || lvl === 'FATAL' ? 'daemon.error'
730
442
  : lvl === 'START' || /starting|started/i.test(message) ? 'daemon.start'
731
443
  : lvl === 'STOP' || /stopping|stopped|shutting down/i.test(message) ? 'daemon.stop'
732
444
  : 'daemon.info';
733
- // Fire-and-forget the event mirror: `log()` is a synchronous primitive on
734
- // every daemon tick's `ctx.log`, and the mirror's event-log lock would
735
- // otherwise block the shared event loop for up to 30s under contention
736
- // (PHNX-3695). The daemon-log append above is the primary, synchronous sink;
737
- // the mirror is best-effort, so a fire-and-forget async write is correct.
738
445
  void emitAsync(event, {
739
446
  module: 'daemon',
740
447
  detail: redactSecrets(message).slice(0, 500),
741
448
  status: lvl,
742
449
  }).catch(() => { });
743
450
  }
744
- catch { /* never crash the daemon on event-log failure */ }
451
+ catch { }
745
452
  }
746
- /** Keep synchronous signal-handler failures inside the daemon's crash barrier. */
747
453
  export function guardSignalHandler(handler, onError) {
748
454
  return () => {
749
455
  try {
@@ -754,24 +460,6 @@ export function guardSignalHandler(handler, onError) {
754
460
  }
755
461
  };
756
462
  }
757
- /** Main daemon loop: load jobs, schedule crons, monitor runs, and handle signals. */
758
- /**
759
- * Anchor the daemon's working directory to a stable, always-present path.
760
- *
761
- * The daemon is long-lived and inherits whatever cwd it was launched from — often
762
- * a git worktree (e.g. a `.agents/worktrees/<slug>/` a session happened to be in).
763
- * When that directory is later removed (`git worktree remove`, `rm -rf`), the
764
- * daemon keeps the deleted inode as its cwd — a process cannot chdir out of a
765
- * deleted directory on its own — and every job it spawns inherits the dead cwd
766
- * (`spawnJobAttempt` and command runs pass no explicit `cwd`, so the child uses
767
- * the parent's). Bun then fails `getcwd()` during startup and every routine crashes
768
- * at 0 seconds with `ENOENT: Bun could not find a file` before the agent even runs.
769
- *
770
- * Re-anchoring to the home directory once, at daemon startup, makes the daemon
771
- * immune regardless of how it was launched (systemd unit, launchd, or a manual
772
- * `agents __daemon-run` from any directory). Returns the resolved cwd, or null if
773
- * anchoring failed (logged, non-fatal).
774
- */
775
463
  export function anchorDaemonCwd() {
776
464
  const home = os.homedir();
777
465
  try {
@@ -783,22 +471,6 @@ export function anchorDaemonCwd() {
783
471
  return null;
784
472
  }
785
473
  }
786
- /**
787
- * Surface, at the daemon's OWN startup, that it was launched from an ephemeral
788
- * root that will wedge it if the directory is removed. This is the runtime
789
- * companion to the launch-time check in validateDaemonBinary (which only runs
790
- * when the daemon is *spawned* via getDaemonLaunch): a direct
791
- * `agents __daemon-run` from a temp or worktree build — e.g. a review/verify
792
- * checkout under /tmp — never passes through that path, so without this the
793
- * wedge risk stays invisible until jobs start ENOENT-ing on their dynamic
794
- * imports. Best-effort and non-fatal; the cwd is already handled by
795
- * anchorDaemonCwd, but a deleted module root can only be flagged, not repaired.
796
- *
797
- * `resolveBin` is injectable (defaults to getAgentsBinPath) so the wiring — the
798
- * predicate call, the WARN, and the non-fatal guard around a throwing resolver —
799
- * is testable. Returns the warning message it logged, or null when the launch
800
- * root is stable (or could not be resolved).
801
- */
802
474
  export function warnEphemeralDaemonRoot(resolveBin = getAgentsBinPath) {
803
475
  try {
804
476
  const bin = resolveBin();
@@ -816,27 +488,6 @@ export function warnEphemeralDaemonRoot(resolveBin = getAgentsBinPath) {
816
488
  return null;
817
489
  }
818
490
  }
819
- /**
820
- * Test-home tripwire (PHNX-2545). The routines/daemon test suite spawns real
821
- * `agents __daemon-run` processes against an isolated /tmp HOME. If that HOME
822
- * override fails to reach the child — an `env: {...process.env}` spawn that
823
- * forgot to set it, a login shell that reset HOME — the daemon resolves its
824
- * state dir under the operator's REAL home and its scheduler/watchdog then tick
825
- * against shared production state. That is the exact leak the ticket reports:
826
- * real test daemons found alive on a fleet box, each a second live scheduler
827
- * racing the legitimate one, in violation of the execution-singularity spec.
828
- *
829
- * A test that spawns a daemon sets AGENTS_DAEMON_TEST_HOME to the isolated home
830
- * it provisioned. When that marker is present, this daemon's resolved state dir
831
- * MUST sit under it; otherwise the daemon refuses to boot — failing loud before
832
- * it claims an instance, writes a pid, or fires a single tick (the throw is
833
- * caught in index.ts's `__daemon-run` handler, logged, and exits non-zero) —
834
- * rather than running in the wrong directory against the real host. In
835
- * production the marker is never set, so this is a no-op there.
836
- *
837
- * `daemonDir`/`testHome` are injectable so the pure guard is unit-testable
838
- * without spawning a process; the defaults read the live daemon dir and env.
839
- */
840
491
  export function assertTestDaemonHome(daemonDir = getDaemonDir(), testHome = process.env.AGENTS_DAEMON_TEST_HOME) {
841
492
  if (!testHome)
842
493
  return;
@@ -850,28 +501,8 @@ export function assertTestDaemonHome(daemonDir = getDaemonDir(), testHome = proc
850
501
  throw new Error(msg);
851
502
  }
852
503
  }
853
- // ---------------------------------------------------------------------------
854
- // Module-level periodic maintenance helpers (RUSH-2422)
855
- //
856
- // These were inline closures inside runDaemon(). Moved here so they are
857
- // named in stack traces, readable without scrolling through runDaemon's
858
- // 500-line body, and not recreated on every function invocation.
859
- //
860
- // self-heal moved to SelfHealService on the ServiceSupervisor (RUSH-3193 P3)
861
- // — the supervisor's own per-tick deadline + inFlight guard replaces its local
862
- // `healing` flag. state-dir-check moved to StateDirCheckService (RUSH-3193
863
- // P3), registered after `handleShutdown` is declared — see its registration
864
- // site below. The secrets broker (self-heal, reap, and hosting) moved out of
865
- // this daemon entirely with the standalone `secrets` engine (PHNX-3989 OWN-1).
866
- // ---------------------------------------------------------------------------
867
504
  export async function runDaemon() {
868
- // PHNX-2545 test-home tripwire — FIRST, before this daemon claims an instance,
869
- // writes a pid, or fires any tick. A test-spawned daemon that lost its isolated
870
- // HOME override must refuse to run against the operator's real state rather than
871
- // schedule against the real host. No-op in production (the marker is never set).
872
505
  assertTestDaemonHome();
873
- // Lifecycle readers and launchers do not run services. Load their code only
874
- // in the daemon process, before it claims or publishes lifecycle state.
875
506
  const [{ SessionIndexService }, { SessionSummarizerService }, { SessionTitleService }, { MonitorEngineService }, { AccountUsageService, AccountAuthService }, { CatchupService }, { WatchdogService }, { DeviceProbeService }, { SelfHealService }, { SelfUpdateService }, { HarnessUpdateService }, { AuthSyncService }, { UsageSyncService }, { StateDirCheckService }, { SessionStateService }, { FeedStreamService }, { AttentionNotifyService }, { WebhookReceiverService }, { HeartbeatService }, { TmuxReapService },] = await Promise.all([
876
507
  import('./session-index-service.js'),
877
508
  import('./session-summarizer-service.js'),
@@ -894,13 +525,6 @@ export async function runDaemon() {
894
525
  import('./heartbeat-service.js'),
895
526
  import('./tmux-reap-service.js'),
896
527
  ]);
897
- // Install the shared-daemon reload signal boundary BEFORE publishing our PID
898
- // in claimDaemonInstance(). Browser/routines clients use that PID to decide a
899
- // daemon exists and may request a service reload immediately. POSIX otherwise
900
- // applies its default SIGHUP action during the rest of startup and terminates
901
- // the whole process — exactly the client-caused eviction PHNX-3605 forbids.
902
- // Requests received before services are ready coalesce into one reload and are
903
- // applied through the normal guarded handler once startup completes.
904
528
  let reloadRequestedDuringStartup = false;
905
529
  let liveReloadHandler = null;
906
530
  const dispatchReloadSignal = () => {
@@ -911,22 +535,12 @@ export async function runDaemon() {
911
535
  };
912
536
  if (process.platform !== 'win32')
913
537
  process.on('SIGHUP', dispatchReloadSignal);
914
- // Single-instance guard (last-wins, SING-11): a direct `agents __daemon-run`
915
- // (manual, or a service-manager restart racing a live predecessor) EVICTS the
916
- // incumbent and becomes the survivor. claimDaemonInstance returns false only
917
- // when a concurrent `__daemon-run` currently holds the start lock — that peer
918
- // is mid-takeover and will be the singleton, so this instance stands down.
919
538
  if (!claimDaemonInstance()) {
920
539
  if (process.platform !== 'win32')
921
540
  process.removeListener('SIGHUP', dispatchReloadSignal);
922
541
  log('WARN', `Another daemon owns lifecycle state or is mid-takeover; this instance (PID ${process.pid}) is exiting`);
923
- // Exit cleanly (0) so a service manager treats it as an orderly no-op
924
- // rather than a failure to restart-flap on.
925
542
  process.exit(0);
926
543
  }
927
- // Deterministic integration-test seam for the PID-published/startup-complete
928
- // signal window above. It is honored only inside an explicitly isolated test
929
- // HOME; production daemons never pause here.
930
544
  const startupDelayRaw = process.env.AGENTS_DAEMON_TEST_STARTUP_DELAY_MS;
931
545
  if (process.env.AGENTS_DAEMON_TEST_HOME && startupDelayRaw) {
932
546
  const startupDelayMs = Number(startupDelayRaw);
@@ -935,21 +549,12 @@ export async function runDaemon() {
935
549
  }
936
550
  await new Promise((resolve) => setTimeout(resolve, startupDelayMs));
937
551
  }
938
- // Unlike the pid and heartbeat files, this marker is written exactly once
939
- // for this daemon lifetime. Status probes deliberately repair those other
940
- // files, so they cannot prove that the original state dir still exists.
941
552
  const lifetimePath = path.join(getDaemonDir(), LIFETIME_FILE);
942
553
  const lifetimeToken = `${process.pid}:${Date.now()}`;
943
554
  fs.writeFileSync(lifetimePath, lifetimeToken, 'utf-8');
944
555
  log('INFO', `Daemon started (PID: ${process.pid})`);
945
556
  anchorDaemonCwd();
946
557
  warnEphemeralDaemonRoot();
947
- // Converge the device-config/pins stores (legacy central block /
948
- // auto-launch.json / tracked-doc pins → per-device docs + pins file).
949
- // Idempotent, cheap no-op once folded. The daemon boots via
950
- // `agents __daemon-run`, which bypasses bootstrap's migration sentinel — so
951
- // the daemon runs this itself so its scheduler/watchdog gates read the
952
- // converged store.
953
558
  try {
954
559
  const { migrateDeviceConfigStores } = await import('../devices/config-migration.js');
955
560
  migrateDeviceConfigStores();
@@ -957,12 +562,6 @@ export async function runDaemon() {
957
562
  catch (err) {
958
563
  log('WARN', `device config migration failed: ${err.message}`);
959
564
  }
960
- // Version-skew one-shot (RUSH-2435): retrofit the current pane-died hook onto
961
- // any managed tmux session a pre-fix binary left with a stale one. The 5-min
962
- // `tmux-reconcile` routine that used to run this on a poll was deleted
963
- // (RUSH-2495) — startup + `ensureSessionHookRepaired` at attach time
964
- // (tmux/session.ts) now cover what that poll used to. Idempotent and
965
- // non-destructive: a session already at the current schema is a no-op.
966
565
  try {
967
566
  const { reconcileSessionHooks } = await import('../tmux/session.js');
968
567
  const { isTmuxInstalled } = await import('../tmux/binary.js');
@@ -975,21 +574,8 @@ export async function runDaemon() {
975
574
  catch (err) {
976
575
  log('WARN', `tmux hook reconcile failed: ${err.message}`);
977
576
  }
978
- // Per-service toggles live outside device-config so they can be checked by
979
- // service clients (e.g. secrets) without loading the whole config stack.
980
577
  let servicesConfig = readDaemonServicesConfig();
981
578
  const isEnabled = (id) => servicesConfig.services[id] !== false;
982
- // The daemon holds NO Claude credential of its own. Routine runs authenticate
983
- // exactly like an interactive `agents run`: through the per-account
984
- // CLAUDE_CONFIG_DIR login on this device (its own auto-refreshing
985
- // .credentials.json). Claude Code's interactive access token is short-lived but
986
- // refreshes itself per-device; a routine whose account login has gone dead is
987
- // skipped up front by the auth-health preflight (runner.ts) with a re-login
988
- // hint, rather than papered over by an injected fallback token.
989
- // Register this daemon in the device instance registry, then reap any stray
990
- // duplicate that slipped past the start lock or was orphaned by a hard-crash —
991
- // before it can double-fire jobs. Registration comes first so a racing peer's
992
- // reaper can see this pid, and so this reaper never mistakes itself for a stray.
993
579
  registerDaemonInstance();
994
580
  try {
995
581
  const strays = reapStrayDaemons();
@@ -1002,19 +588,12 @@ export async function runDaemon() {
1002
588
  catch (err) {
1003
589
  log('ERROR', `Stray daemon reaper failed: ${err.message}`);
1004
590
  }
1005
- // Socket services: monitor engine, account-state, and the feed-stream hub are
1006
- // all managed by the ServiceSupervisor (RUSH-3193 P2). The secrets broker moved
1007
- // with the standalone `secrets` engine (PHNX-3989 OWN-1) and the browser IPC
1008
- // service with the standalone `browser` CLI (PHNX-4101) — this daemon no longer
1009
- // hosts either; each standalone owns its own lifecycle exclusively.
1010
591
  const supervisor = new ServiceSupervisor();
1011
592
  if (isEnabled('session-state')) {
1012
593
  supervisor.register(new SessionStateService(() => supervisor.runNow('session-state')));
1013
594
  }
1014
595
  else
1015
596
  log('INFO', 'Live session-state service disabled');
1016
- // The shared feed fan-out. Registered even when disabled at boot so a later
1017
- // `agents daemon services enable feed-stream` brings it up over SIGHUP.
1018
597
  supervisor.register(new FeedStreamService(), { enabled: isEnabled('feed-stream') });
1019
598
  if (!isEnabled('feed-stream'))
1020
599
  log('INFO', 'Shared feed stream service disabled');
@@ -1023,9 +602,6 @@ export async function runDaemon() {
1023
602
  supervisor.register(monitorEngineSvc);
1024
603
  else
1025
604
  log('INFO', 'Monitor engine disabled');
1026
- // Usage and auth refresh are two INDEPENDENT supervised services (PHNX-3608)
1027
- // so a run of usage-refresh throws is recorded against usage alone and never
1028
- // starves the slower auth refresh — each keeps ticking on its own interval.
1029
605
  if (isEnabled('account-state'))
1030
606
  supervisor.register(new AccountUsageService());
1031
607
  else
@@ -1034,19 +610,7 @@ export async function runDaemon() {
1034
610
  supervisor.register(new AccountAuthService());
1035
611
  else
1036
612
  log('INFO', 'Account-auth service disabled');
1037
- // The routine scheduler handle. Declared HERE — before the CatchupService
1038
- // registration — because `supervisor.startAll()` below fires each service's
1039
- // first tick synchronously, so the `catchup` tick reads `scheduler` during
1040
- // startAll, BEFORE this `let` would initialise if it lived at its old textual
1041
- // position further down. That was a real TDZ `ReferenceError` on every boot
1042
- // ("Cannot access 'scheduler' before initialization"), not a race (PHNX-3608).
1043
- // `bootScheduler`/`stopScheduler` (hoisted below) assign this same binding.
1044
613
  let scheduler = null;
1045
- // Catch-up recovery under the supervisor (PHNX-3608). The closures reference
1046
- // `scheduler` (declared just above) and `catchupPass` (a hoisted function
1047
- // declaration). The tick self-gates on the scheduler being booted, so it is a
1048
- // cheap no-op — including on its immediate first tick during startAll, when
1049
- // `scheduler` is still null — on a device whose scheduler.enabled gate is off.
1050
614
  if (isEnabled('catchup')) {
1051
615
  supervisor.register(new CatchupService({
1052
616
  isSchedulerBooted: () => scheduler !== null,
@@ -1056,40 +620,22 @@ export async function runDaemon() {
1056
620
  else {
1057
621
  log('INFO', 'Catch-up recovery service disabled');
1058
622
  }
1059
- // The browser IPC service and its task reaper are the standalone `browser`
1060
- // CLI's now (@phnx-labs/browser-cli, PHNX-4101): it hosts its own IPC service
1061
- // and runs its own `prune` reaper. agents-cli no longer constructs a
1062
- // BrowserService, binds a browser socket, or reaps browser tasks — see
1063
- // `commands/browser.ts` and `docs/browser.md`.
1064
623
  if (isEnabled('session-index'))
1065
624
  supervisor.register(new SessionIndexService());
1066
625
  else
1067
626
  log('INFO', 'Session-index warm service disabled');
1068
- // Session summarizer (PHNX-3939) — registered when the service toggle is on,
1069
- // but each tick is a no-op unless the operator also set summarizer.enabled and
1070
- // a model endpoint, so registering it costs nothing while unconfigured.
1071
627
  if (isEnabled('session-summarizer'))
1072
628
  supervisor.register(new SessionSummarizerService());
1073
629
  else
1074
630
  log('INFO', 'Session summarizer service disabled');
1075
- // Attention desktop banners (PHNX-4004) — posts one actionable native banner
1076
- // per new attention key. Reader-independent: it fires whether or not a
1077
- // `sessions watch` reader is present, and the notified-ledger is its
1078
- // idempotency truth across daemon restarts.
1079
631
  if (isEnabled('attention-notify'))
1080
632
  supervisor.register(new AttentionNotifyService());
1081
633
  else
1082
634
  log('INFO', 'Attention-notify service disabled');
1083
- // Session titles (PHNX-3797) — generates each session row's headline once,
1084
- // with a cheap model, off the request path.
1085
635
  if (isEnabled('session-title'))
1086
636
  supervisor.register(new SessionTitleService());
1087
637
  else
1088
638
  log('INFO', 'Session-title service disabled');
1089
- // Watchdog, device-probe, and self-heal are all periodic services managed
1090
- // by the ServiceSupervisor (RUSH-3193 P3). Each is gated the same way as
1091
- // the socket services above; state-dir-check is registered separately,
1092
- // later, after `handleShutdown` exists (see below).
1093
639
  if (isEnabled('watchdog'))
1094
640
  supervisor.register(new WatchdogService());
1095
641
  else
@@ -1132,15 +678,6 @@ export async function runDaemon() {
1132
678
  log('INFO', 'Tmux reap service disabled');
1133
679
  await supervisor.startAll({ log });
1134
680
  activeServiceSupervisor = supervisor;
1135
- // scheduler.enabled=false in this machine's device doc means NO routines fire
1136
- // here — the scheduler and its catchup recovery simply never start, while the
1137
- // daemon keeps its other duties (feed stream, session sync).
1138
- // The refusal message is the same one the start surfaces
1139
- // (`routines add` auto-start, manual `routines start`) raise. The gate is
1140
- // re-evaluated on every SIGHUP reload (handleReload below) via
1141
- // schedulerGateTransition, so flipping the key never needs a daemon restart.
1142
- // Also honour the daemon-services toggle so `agents daemon services disable scheduler`
1143
- // has a single, obvious effect.
1144
681
  const schedulerEnabledAtBoot = isSchedulerEnabled() && isEnabled('scheduler');
1145
682
  if (!schedulerEnabledAtBoot) {
1146
683
  try {
@@ -1166,15 +703,10 @@ export async function runDaemon() {
1166
703
  ...(config.agent ? { agent: config.agent } : {}),
1167
704
  ...(config.workflow ? { workflow: config.workflow } : {}),
1168
705
  });
1169
- // RUSH-2030: branded desktop notification on start (agent/workflow routines;
1170
- // suppressed for command housekeeping). Finish/output is fired from the
1171
- // onFinish hook below — executeJobDetached finalizes the run in-process, so
1172
- // the monitor tick never sees the live transition. Never let a notification
1173
- // failure break the trigger.
1174
706
  try {
1175
707
  notifyRoutineStart(config);
1176
708
  }
1177
- catch { /* best-effort */ }
709
+ catch { }
1178
710
  try {
1179
711
  const meta = await executeJobDetached(config, {
1180
712
  onFinish: (final) => {
@@ -1182,11 +714,7 @@ export async function runDaemon() {
1182
714
  try {
1183
715
  notifyRoutineFinish(final);
1184
716
  }
1185
- catch { /* best-effort */ }
1186
- // RUSH-2288: a failed/timed-out routine also reaches the OWNER's phone
1187
- // (in-process owner channel stack), not just the local desktop. Green
1188
- // runs are silent — the builder returns early. Async + swallowed so a
1189
- // delivery hiccup never blocks the finish path.
717
+ catch { }
1190
718
  void notifyOwnerRoutineFinish(final)
1191
719
  .then((r) => {
1192
720
  if (r.attempts.length && !r.delivered)
@@ -1205,17 +733,10 @@ export async function runDaemon() {
1205
733
  status: 'failed',
1206
734
  detail: redactSecrets(message).slice(0, 500),
1207
735
  });
1208
- // RUSH-2030: the START ping already fired unconditionally above. A pre-spawn
1209
- // failure produces no run record and thus no onFinish, so send a synthetic
1210
- // "failed to start" finish here — otherwise the user is left with an orphaned
1211
- // "Routine started" and never told it failed.
1212
736
  try {
1213
737
  notifyRoutineStartFailed(config, message);
1214
738
  }
1215
- catch { /* best-effort */ }
1216
- // RUSH-2288: the pre-spawn failure (e.g. auth_failed) is exactly the one the
1217
- // per-routine `agents send --to owner` prompt can never send — its agent never ran —
1218
- // so the daemon reaches the owner directly.
739
+ catch { }
1219
740
  void notifyOwnerRoutineStartFailed(config, message)
1220
741
  .then((r) => {
1221
742
  if (r.attempts.length && !r.delivered)
@@ -1224,13 +745,6 @@ export async function runDaemon() {
1224
745
  .catch(() => { });
1225
746
  }
1226
747
  };
1227
- // `scheduler` is declared earlier (before the CatchupService registration) to
1228
- // avoid a TDZ read during supervisor.startAll — see the comment there.
1229
- // Boot the scheduler. Called at daemon start when the gate allows, and again
1230
- // from handleReload when the gate flips on. Catch-up recovery is a separate
1231
- // supervised service (CatchupService, registered above) that self-gates on
1232
- // `scheduler !== null`; here we just kick an immediate supervised pass so a
1233
- // fresh boot catches up missed fires without waiting a full CATCHUP_TICK_MS.
1234
748
  function bootScheduler() {
1235
749
  scheduler = new JobScheduler(triggerJob);
1236
750
  scheduler.loadAll();
@@ -1242,14 +756,10 @@ export async function runDaemon() {
1242
756
  if (supervisor.isRegistered('catchup'))
1243
757
  supervisor.runNow('catchup');
1244
758
  }
1245
- // Stop the scheduler (gate flipped off on reload). The CatchupService keeps its
1246
- // supervised timer but its tick no-ops once `scheduler` is null.
1247
759
  function stopScheduler() {
1248
760
  scheduler?.stopAll();
1249
761
  scheduler = null;
1250
762
  }
1251
- // Materialise opted-in project routines into the user layer on every start
1252
- // so a fresh daemon picks up project YAML without a separate sync step.
1253
763
  try {
1254
764
  const result = syncAllProjectRoutines();
1255
765
  const n = result.projects.reduce((acc, p) => acc + p.synced.length, 0);
@@ -1261,36 +771,6 @@ export async function runDaemon() {
1261
771
  }
1262
772
  if (schedulerEnabledAtBoot)
1263
773
  bootScheduler();
1264
- // Live-session metadata publishing is owned by SessionStateService. Its
1265
- // presence watcher requests an immediate supervised tick when a reader
1266
- // connects; callers consume the journal instead of duplicating the gather.
1267
- // Session-index warm (RUSH-2682) is registered on the supervisor above
1268
- // (RUSH-3193 P2) alongside the socket services.
1269
- // Watchdog and device-probe are now managed by WatchdogService /
1270
- // DeviceProbeService on the supervisor (RUSH-3193 P3), registered above
1271
- // alongside the socket services. The supervisor fires an immediate first
1272
- // tick on start, which replaces device-probe's old `void
1273
- // runDeviceProbeTick()` kick-off (the 3-minute lag that used to leave the
1274
- // menubar showing 20 phantom NEW DEVICES after a hermetic leak).
1275
- // Monitor engine is now managed by MonitorEngineService on the supervisor
1276
- // (RUSH-3193 P2). Access it via monitorEngineSvc.getEngine() in handleReload.
1277
- // Backlog recovery: any enabled recurring job whose most-recent expected fire
1278
- // is older than its most-recent recorded run was missed — the laptop slept,
1279
- // the machine was off, or the daemon crashed through the fire. croner only
1280
- // schedules forward from "now", so nothing replays it on its own.
1281
- //
1282
- // Every miss is RECORDED as a `missed` run and, unless the routine sets
1283
- // `catchup: false`, RUN late. Runs on a timer as well as at startup: a startup
1284
- // pass alone misses a fire lost while the daemon stayed up but its event loop
1285
- // was wedged, or one lost across an OS suspend that the process survived.
1286
- // A pass awaits executeJobDetached per job and an off-box (host/cloud)
1287
- // dispatch can block for a while. Overlap is now guarded by the supervisor's
1288
- // per-service inFlight guard (CatchupService) — a slow pass never overlaps the
1289
- // next supervised tick — rather than a local `catchingUp` flag; and the
1290
- // idempotency of the `missed` record still guards across passes and daemon
1291
- // restarts. `signal` aborts at the CatchupService deadline, so a wedged pass is
1292
- // abandoned + restarted instead of latching (PHNX-3608). Function declaration
1293
- // (hoisted) so the CatchupService registration above can reference it.
1294
774
  async function catchupPass(signal) {
1295
775
  try {
1296
776
  const overdue = detectOverdueJobs();
@@ -1306,9 +786,6 @@ export async function runDaemon() {
1306
786
  notifyOverdue(overdue);
1307
787
  const outcomes = await runCatchup({ overdue });
1308
788
  for (const o of outcomes) {
1309
- // Every variant handled explicitly: a catch-all else would log the
1310
- // benign 'claimed-elsewhere' (another process legitimately won the
1311
- // claim) as an ERROR with an undefined reason.
1312
789
  switch (o.result) {
1313
790
  case 'ran':
1314
791
  log('INFO', `Caught up '${o.name}' (run: ${o.runId})`);
@@ -1323,9 +800,6 @@ export async function runDaemon() {
1323
800
  log('ERROR', `Catchup for '${o.name}' failed: ${o.error}`);
1324
801
  break;
1325
802
  default: {
1326
- // Compile-time exhaustiveness: a new CatchupOutcome variant fails
1327
- // typecheck here rather than silently landing in the wrong log level,
1328
- // which is exactly how 'claimed-elsewhere' was first missed.
1329
803
  const unhandled = o.result;
1330
804
  log('ERROR', `Catchup for '${o.name}' returned an unhandled result: ${String(unhandled)}`);
1331
805
  }
@@ -1333,76 +807,23 @@ export async function runDaemon() {
1333
807
  }
1334
808
  }
1335
809
  catch (err) {
1336
- // Ordinary pass errors are logged, not re-thrown: a transient catchup
1337
- // failure should not be counted as a service failure. A HANG is still
1338
- // caught — the CatchupService deadline aborts the tick and the supervisor
1339
- // exits the daemon for an OS restart regardless of this swallow (PHNX-4116).
1340
810
  log('ERROR', `Catchup pass failed: ${err.message}`);
1341
811
  }
1342
812
  }
1343
- // The browser IPC server and its orphan reap left this daemon with the
1344
- // standalone `browser` CLI (PHNX-4101) — it hosts its own IPC service now.
1345
- // Webhook receivers: signed webhook receiver(s) + their funnel (RUSH-2548).
1346
- // Resolves each receiver's signing secret headlessly through the standalone
1347
- // `secrets` CLI (an agentOnly secrets-client read) — no AGENTS_SECRETS_PASSPHRASE,
1348
- // no nohup. Binds nothing unless daemon/webhooks.yaml declares a receiver, so an
1349
- // unconfigured box no-ops.
1350
- // Signed webhook ingress is owned by WebhookReceiverService, including
1351
- // per-service failure isolation, measured health, and shutdown cleanup.
1352
- // Resource self-heal is now managed by SelfHealService on the supervisor
1353
- // (RUSH-3193 P3), registered above alongside the socket services. The
1354
- // supervisor's immediate first tick on start replaces the old
1355
- // SELF_HEAL_KICKOFF_MS (30s) delayed kickoff timer — see self-heal-service.ts.
1356
- // The secrets broker's self-heal and keychain-reap ticks (formerly
1357
- // SecretsBrokerService / KeychainReapService, RUSH-1817 / RUSH-2232) moved
1358
- // out of this daemon entirely with the standalone `secrets` engine
1359
- // (PHNX-3989 OWN-1) — the standalone owns its own broker lifecycle.
1360
- // RUSH-2501: reap tmux sessions whose panes are all dead. Daemon-only
1361
- // (single executor). Dead managed panes and their orphan helpers are
1362
- // reaped by TmuxReapService.
1363
- // Abandoned browser-task reaping (RUSH-2622) left this daemon with the
1364
- // standalone `browser` CLI (PHNX-4101) — its own `prune` reaper owns it now.
1365
- // RUSH-2367 / RUSH-3193 P3: state-dir-check (self-terminate guard) is
1366
- // registered on the supervisor further below, once `handleShutdown` exists
1367
- // — see the registration site after its declaration for why.
1368
- // RUSH-2418: startup is over — the scheduler, feed stream, monitor engine and
1369
- // every background tick are up. Only NOW does this daemon
1370
- // clear the auto-start failure streak `ensureDaemonStarted` reads. Clearing it
1371
- // at claim time instead would reset the breaker for a process that dies while
1372
- // initializing a subsystem, which is exactly the crash loop it exists to stop.
813
+ // Clear the start-failure streak only after every startup subsystem is live.
1373
814
  recordSubsystemOk(SUBSYSTEM_DAEMON_START);
1374
815
  const handleReload = () => {
1375
816
  log('INFO', 'Reloading jobs (SIGHUP)');
1376
- // Re-read per-service toggles so `agents daemon services enable|disable`
1377
- // followed by `agents daemon reload` is truthful. Most services require a
1378
- // restart to start/stop safely; log those instead of pretending they applied.
1379
817
  const reloadedConfig = readDaemonServicesConfig();
1380
818
  const reloadedEnabled = (id) => reloadedConfig.services[id] !== false;
1381
819
  for (const id of Object.keys(servicesConfig.services)) {
1382
820
  const was = servicesConfig.services[id] !== false;
1383
821
  const now = reloadedEnabled(id);
1384
822
  if (was !== now) {
1385
- // The scheduler is not a supervised service — its gate is re-evaluated
1386
- // live later in this handler, so don't tell the user to restart for it.
1387
823
  if (id === 'scheduler') {
1388
824
  continue;
1389
825
  }
1390
- // RUSH-3193 P4: a service the supervisor already owns takes the toggle
1391
- // live via supervisor.start/stop — no restart needed. monitors is a
1392
- // supervised service (PHNX-3608): its enable/disable takes effect through
1393
- // that generic supervisor.start/stop path, so a disabled monitors service
1394
- // actually stops dispatching (its supervised tick is torn down) instead of
1395
- // being ticked with the last-loaded set. browser-ipc is deliberately
1396
- // registered in a stopped state too (PHNX-3605), so a later browser client
1397
- // can enable that service without restarting the shared daemon. Most other
1398
- // services are only registered when enabled at boot; one disabled at boot
1399
- // was never registered, so it falls through to the same "restart to apply"
1400
- // advice as before.
1401
826
  if (supervisor.isRegistered(id)) {
1402
- // A periodic service may be inside a real tick when SIGHUP arrives.
1403
- // Queue the desired transition behind that exact promise: deadlines
1404
- // detect a wedge but cannot cancel arbitrary work, and polling here
1405
- // would create another lifecycle timer outside the supervisor.
1406
827
  const action = supervisor.awaitIdle(id).then(() => now ? supervisor.start(id) : supervisor.stop(id));
1407
828
  void action
1408
829
  .then(() => log('INFO', `Service '${id}' ${now ? 'started' : 'stopped'} live (SIGHUP reload)`))
@@ -1413,9 +834,7 @@ export async function runDaemon() {
1413
834
  }
1414
835
  }
1415
836
  }
1416
- // Remember the reloaded state so subsequent reloads log transitions truthfully.
1417
837
  servicesConfig = reloadedConfig;
1418
- // Drain queued `agents daemon services restart <id>` requests (RUSH-3193 P4).
1419
838
  for (const id of drainDaemonServiceRestartQueue()) {
1420
839
  if (supervisor.isRegistered(id)) {
1421
840
  void supervisor.awaitIdle(id).then(() => supervisor.restartOne(id))
@@ -1426,9 +845,6 @@ export async function runDaemon() {
1426
845
  log('WARN', `Restart requested for '${id}' but it is not supervisor-managed on this daemon — restart the daemon instead`);
1427
846
  }
1428
847
  }
1429
- // Refresh user-layer copies of opted-in project routines BEFORE the
1430
- // scheduler reloads, so YAML edits under `<project>/.agents/routines/`
1431
- // take effect on the next fire without a manual `routines sync`.
1432
848
  try {
1433
849
  const result = syncAllProjectRoutines();
1434
850
  const n = result.projects.reduce((acc, p) => acc + p.synced.length, 0);
@@ -1439,11 +855,6 @@ export async function runDaemon() {
1439
855
  catch (err) {
1440
856
  log('WARN', `Project routines sync failed: ${err.message}`);
1441
857
  }
1442
- // Re-evaluate the scheduler.enabled gate: flipping the key takes effect on
1443
- // this reload, no daemon restart needed. A `routines add` on a re-enabled
1444
- // box signals exactly this reload, which boots the scheduler — the
1445
- // "Scheduler reloaded" it prints is then truthful, not a dead-end.
1446
- // Also honour the daemon-services toggle.
1447
858
  const schedulerEnabledNow = isSchedulerEnabled() && reloadedEnabled('scheduler');
1448
859
  const transition = schedulerGateTransition(scheduler !== null, schedulerEnabledNow);
1449
860
  if (transition === 'boot') {
@@ -1459,12 +870,6 @@ export async function runDaemon() {
1459
870
  const reloaded = scheduler.listScheduled();
1460
871
  log('INFO', `Reloaded ${reloaded.length} jobs`);
1461
872
  }
1462
- // Refresh monitor CONFIGS when the engine is live and monitors stays enabled
1463
- // (the common `monitors add/edit` + SIGHUP case). The enable/disable
1464
- // TRANSITION itself is handled by the generic supervisor.start/stop loop
1465
- // above (PHNX-3608) — a disabled monitors service is supervisor.stop()'d
1466
- // there, which tears down its supervised tick so nothing dispatches; an
1467
- // off-transition leaves getEngine() null, so this reload is correctly skipped.
1468
873
  const liveMonitorEngine = monitorEngineSvc.getEngine();
1469
874
  if (liveMonitorEngine && reloadedEnabled('monitors')) {
1470
875
  try {
@@ -1475,18 +880,9 @@ export async function runDaemon() {
1475
880
  }
1476
881
  }
1477
882
  };
1478
- // Structurally single-shot (RUSH-2423). Shutdown is reachable from SIGTERM,
1479
- // SIGINT, and StateDirCheckService's independent `onMissing` callback (which
1480
- // calls this same handler), and two of those can arrive together — a
1481
- // service manager that SIGTERMs a daemon whose state dir was just removed.
1482
- // It was only INCIDENTALLY safe before (every step inside happens to be
1483
- // idempotent); the guard makes single-shot a property of the function
1484
- // rather than one that every step added later has to re-earn.
883
+ // Cleanup removes lifetime, pid, heartbeat, and registry state only when each still belongs to this instance.
1485
884
  const handleShutdown = singleShot(async () => {
1486
885
  log('INFO', 'Daemon shutting down');
1487
- // supervisor.stopAll() stops every registered service, including socket
1488
- // hosts, session publishers/indexers, monitor/account work, and every
1489
- // maintenance timer; state-dir-check joins the registry just below.
1490
886
  await supervisor.stopAll();
1491
887
  activeServiceSupervisor = null;
1492
888
  stopScheduler();
@@ -1495,7 +891,6 @@ export async function runDaemon() {
1495
891
  fs.unlinkSync(lifetimePath);
1496
892
  }
1497
893
  catch {
1498
- // Already removed with the state dir, or replaced by a newer owner.
1499
894
  }
1500
895
  removeDaemonPidIfOwned(process.pid);
1501
896
  if (readHeartbeat()?.pid === process.pid)
@@ -1503,14 +898,6 @@ export async function runDaemon() {
1503
898
  unregisterDaemonInstance();
1504
899
  process.exit(0);
1505
900
  });
1506
- // State-dir self-check (RUSH-2367 self-terminate guard) is registered on
1507
- // the supervisor here — AFTER `handleShutdown` above — rather than
1508
- // alongside watchdog/device-probe/self-heal earlier. The
1509
- // supervisor fires an immediate first tick on `register()`+`start()`; doing
1510
- // that before `handleShutdown` exists would reference the const in its
1511
- // temporal dead zone the moment a mismatch is ever detected. Registering it
1512
- // here, once `handleShutdown` is a real function, removes that risk
1513
- // entirely rather than relying on the marker always matching on tick one.
1514
901
  if (isEnabled('state-dir-check')) {
1515
902
  supervisor.register(new StateDirCheckService({
1516
903
  lifetimePath,
@@ -1523,13 +910,10 @@ export async function runDaemon() {
1523
910
  log('INFO', 'State-dir self-check disabled');
1524
911
  }
1525
912
  liveReloadHandler = guardSignalHandler(handleReload, (err) => {
1526
- // Signal callbacks sit outside the supervisor's service barriers. A
1527
- // reload failure must be observable without reaching the process-wide
1528
- // uncaughtException handler and taking down every daemon service.
1529
913
  try {
1530
914
  log('ERROR', `SIGHUP reload failed: ${err.message}`);
1531
915
  }
1532
- catch { /* logging must not crash the daemon */ }
916
+ catch { }
1533
917
  });
1534
918
  if (reloadRequestedDuringStartup) {
1535
919
  reloadRequestedDuringStartup = false;
@@ -1540,22 +924,13 @@ export async function runDaemon() {
1540
924
  process.on('SIGINT', () => handleShutdown());
1541
925
  await new Promise(() => { });
1542
926
  }
1543
- /** Escape a string for safe inclusion in an XML <string> node. */
1544
927
  function xmlEscape(s) {
1545
928
  return s
1546
929
  .replace(/&/g, '&amp;')
1547
930
  .replace(/</g, '&lt;')
1548
931
  .replace(/>/g, '&gt;');
1549
932
  }
1550
- /**
1551
- * Write a launchd plist or systemd unit with owner-only permissions atomically.
1552
- *
1553
- * `writeFileSync`'s `mode` is honored only when the file is *created*, so we
1554
- * unlink any pre-existing manifest first. That guarantees every write is a
1555
- * fresh 0600 create — closing the TOCTOU window on new files AND re-locking a
1556
- * stale world-readable manifest left by an older install — since these files
1557
- * embed long-lived credentials.
1558
- */
933
+ // Manifests are owner-only and carry only the canonical HOME/AGENTS_REAL_HOME/PATH surface.
1559
934
  export function writeOwnerOnlyServiceManifest(filePath, content) {
1560
935
  const dir = path.dirname(filePath);
1561
936
  if (!fs.existsSync(dir)) {
@@ -1564,29 +939,6 @@ export function writeOwnerOnlyServiceManifest(filePath, content) {
1564
939
  fs.rmSync(filePath, { force: true });
1565
940
  fs.writeFileSync(filePath, content, { encoding: 'utf-8', mode: 0o600 });
1566
941
  }
1567
- /**
1568
- * Generate a macOS launchd plist for auto-starting the daemon.
1569
- *
1570
- * The plist never embeds a Claude OAuth token: the daemon holds no Claude
1571
- * credential at all. Routine runs authenticate through the per-account
1572
- * CLAUDE_CONFIG_DIR login on this device, exactly like an interactive
1573
- * `agents run`, so no credential ever touches the service manifest.
1574
- *
1575
- * RUSH-2639: launchd does NOT inherit `launchctl load`'s caller's process
1576
- * environment — a spawned daemon only ever sees the login session's default
1577
- * env plus whatever this dict adds/overrides. Before this fix the dict carried
1578
- * only PATH, so HOME resolved to the launchd session's own value regardless of
1579
- * what HOME the process that generated (and loaded) the plist was running
1580
- * under. In production that's a no-op (the login session's HOME already is the
1581
- * real HOME), but under a hermetic test harness that redirects HOME to a
1582
- * fork-private sandbox, a launchd-started daemon silently escaped the sandbox
1583
- * and bootstrapped `~/.agents` (.cache/.history/.system/routines) in the
1584
- * developer's/runner's REAL home. Baking HOME (and the AGENTS_REAL_HOME seam
1585
- * every version-home consumer honors, see tests/setup.ts) into the plist at
1586
- * generation time makes the launchd child inherit the SAME home the caller
1587
- * resolved, exactly like the plain detached-spawn path already does via
1588
- * `env: {...process.env}`.
1589
- */
1590
942
  export function generateLaunchdPlist(agentsBin = getAgentsBinPath()) {
1591
943
  const launch = getDaemonLaunch(agentsBin);
1592
944
  const logPath = getDaemonLogPath();
@@ -1623,25 +975,9 @@ ${[launch.command, ...launch.args].map((arg) => ` <string>${xmlEscape(arg)}</
1623
975
  </dict>
1624
976
  </plist>`;
1625
977
  }
1626
- /** Quote one systemd ExecStart argument without delegating parsing to a shell. */
1627
978
  function systemdExecArg(value) {
1628
979
  return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
1629
980
  }
1630
- /**
1631
- * Generate a Linux systemd user unit for auto-starting the daemon.
1632
- *
1633
- * The unit never embeds a Claude OAuth token: the daemon holds no Claude
1634
- * credential at all. Routine runs authenticate through the per-account
1635
- * CLAUDE_CONFIG_DIR login on this device, exactly like an interactive
1636
- * `agents run`, so no credential ever touches the unit file.
1637
- *
1638
- * RUSH-2639: same seam as `generateLaunchdPlist` — a systemd --user unit is
1639
- * started by the user's systemd instance, not the process that generated the
1640
- * unit, so HOME is whatever that session provides unless this file pins it.
1641
- * Baking HOME (and AGENTS_REAL_HOME) in at generation time keeps a
1642
- * hermetic-test-started unit inside its sandbox instead of resolving against
1643
- * the real account home.
1644
- */
1645
981
  export function generateSystemdUnit(agentsBin = getAgentsBinPath()) {
1646
982
  const launch = getDaemonLaunch(agentsBin);
1647
983
  const execStart = [launch.command, ...launch.args].map(systemdExecArg).join(' ');
@@ -1664,26 +1000,9 @@ Environment=AGENTS_REAL_HOME=${realHome}
1664
1000
  [Install]
1665
1001
  WantedBy=default.target`;
1666
1002
  }
1667
- // Binary-resolution helpers (getAgentsBinPath / isNodeScriptEntry / getCliLaunch)
1668
- // live in ./cli-entry.js — a leaf module. Re-exported so existing
1669
- // `from './daemon.js'` importers of getAgentsBinPath keep resolving.
1670
1003
  export { getAgentsBinPath };
1671
- /**
1672
- * Ask the service manager for the daemon's live PID. Used as a fallback when
1673
- * the daemon hasn't yet written its pid file but launchd/systemd already report
1674
- * it running — so a start never has to surface a null PID for a daemon that is
1675
- * in fact up. Returns null when the service isn't running or the query fails.
1676
- *
1677
- * `names` defaults to THIS process's (possibly sandbox-namespaced) job; a
1678
- * caller under a redirected HOME passes `productionDaemonServiceNames()` to
1679
- * ask after the real install's unit instead. Read-only either way.
1680
- */
1681
1004
  export function readServiceManagerPid(platform = os.platform(), names) {
1682
1005
  const resolved = names ?? { systemdUnit: daemonSystemdUnitName(), launchdLabel: daemonServiceLabel() };
1683
- // The registration gate exists because a sandboxed process must not REGISTER
1684
- // or tear down jobs in the real per-user service manager. Asking after an
1685
- // explicitly named job is read-only — in particular the production unit from
1686
- // a redirected-HOME caller (W4) — and mutates nothing, so it is let through.
1687
1006
  if (names === undefined && !serviceManagerRegistrationAllowed().allowed)
1688
1007
  return null;
1689
1008
  try {
@@ -1701,32 +1020,13 @@ export function readServiceManagerPid(platform = os.platform(), names) {
1701
1020
  }
1702
1021
  }
1703
1022
  }
1704
- catch { /* not running / manager unavailable */ }
1023
+ catch { }
1705
1024
  return null;
1706
1025
  }
1707
- /**
1708
- * Thrown when a daemon LAUNCH is attempted under a redirected HOME without the
1709
- * explicit test opt-in (W4, PHNX-3736). `bootstrap.ts` prints the message
1710
- * without a stack — this is user-actionable, not an engineering bug.
1711
- */
1712
1026
  export class RedirectedHomeDaemonError extends Error {
1713
1027
  name = 'RedirectedHomeDaemonError';
1714
1028
  }
1715
- /**
1716
- * W4 (PHNX-3736): never LAUNCH a daemon under a redirected (sandbox/test) HOME
1717
- * without an explicit opt-in. A daemon started there keeps its own pid file
1718
- * under the temp home, so the real install's pid-file takeover can never see
1719
- * it — the leaked `HOME=/tmp/pin-e2e-<pid>` daemon that ran 4+ days on
1720
- * yosemite-s1 was launched exactly this way by a headless e2e session that
1721
- * never cleaned up. RUSH-3021 closed this for `ensureDaemonStarted`'s
1722
- * AUTO-start path but left the explicit `startDaemon()` open, which is the
1723
- * path the e2e harness took.
1724
- *
1725
- * Placed after the `already-running` early-return: reporting a live daemon (so
1726
- * `daemon stop` can still kill a leaked one) must stay possible under any
1727
- * HOME. `AGENTS_ALLOW_TEST_DAEMON=1` is the deliberate test/e2e seam — a
1728
- * harness that sets it owns stopping what it starts.
1729
- */
1029
+ // A redirected HOME daemon is invisible to production takeover and can outlive its sandbox, so explicit test opt-in is required.
1730
1030
  function assertDaemonLaunchHomeAllowed() {
1731
1031
  const suffix = isolatedHomeSuffix();
1732
1032
  if (!suffix)
@@ -1738,10 +1038,7 @@ function assertDaemonLaunchHomeAllowed() {
1738
1038
  `install's pid-file takeover, and outlives whatever launched it (PHNX-3736). ` +
1739
1039
  `For a deliberate test/e2e launch set AGENTS_ALLOW_TEST_DAEMON=1 — and stop the daemon when done.`);
1740
1040
  }
1741
- /** Start the daemon via launchd, systemd, or as a detached process. */
1742
1041
  export function startDaemon(agentsBin) {
1743
- // The public launcher must obey the same namespace boundary as its child:
1744
- // even probing/repairing legacy PID state or pruning a lock can mutate it.
1745
1042
  if (!daemonProcessViewAllowed())
1746
1043
  throw new Error('Daemon startup requires the owning process namespace. Automatic reuse of a private-container HOME across namespaces is unsupported; run in its owning namespace or use a fresh HOME.');
1747
1044
  if (isDaemonRunning()) {
@@ -1751,14 +1048,9 @@ export function startDaemon(agentsBin) {
1751
1048
  assertDaemonLaunchHomeAllowed();
1752
1049
  const releaseLock = acquireStartLock();
1753
1050
  if (!releaseLock) {
1754
- // Another process is already starting the daemon
1755
1051
  const pid = waitForPid(3000);
1756
1052
  return { pid, method: 'already-starting' };
1757
1053
  }
1758
- // Released by startDaemonLocked the moment the launch has been ISSUED, and
1759
- // again here as the backstop for every path that returned before reaching
1760
- // that point (a throw, or the platform default branch). Idempotent so the
1761
- // double call is a no-op rather than unlinking a lock a later claimer owns.
1762
1054
  let released = false;
1763
1055
  const releaseOnce = () => {
1764
1056
  if (released)
@@ -1766,26 +1058,11 @@ export function startDaemon(agentsBin) {
1766
1058
  released = true;
1767
1059
  releaseLock();
1768
1060
  };
1769
- // RUSH-2418: count starts PESSIMISTICALLY, and let a daemon that reaches
1770
- // steady state clear the streak itself (`recordSubsystemOk` at the end of
1771
- // runDaemon's startup). Recording a failure only on an observable error would
1772
- // miss the crash loop entirely: a daemon that spawns and then dies returns a
1773
- // perfectly real `child.pid`, so the launcher has no error to see. Every path
1774
- // out of startDaemonLocked is either pid-truthy or a throw, so an
1775
- // outcome-shaped check here can only ever catch an unspawnable binary — not
1776
- // the failure this breaker exists for. Marking the attempt up front and
1777
- // clearing on proven health inverts that: the streak grows exactly when
1778
- // starts stop producing a daemon that lives.
1779
- //
1780
- // The no-launch returns above (`already-running`, `already-starting`) return
1781
- // before this point on purpose — they attempted nothing, so they count nothing.
1782
1061
  recordSubsystemError(SUBSYSTEM_DAEMON_START, 'start issued; no daemon has reported healthy since');
1783
1062
  try {
1784
1063
  return startDaemonLocked(agentsBin ?? getAgentsBinPath(), releaseOnce);
1785
1064
  }
1786
1065
  catch (err) {
1787
- // Replace the provisional reason with the real one — the streak is already
1788
- // counted, this just makes `agents daemon doctor` name the actual cause.
1789
1066
  recordSubsystemErrorReason(SUBSYSTEM_DAEMON_START, `start failed: ${err?.message ?? String(err)}`);
1790
1067
  throw err;
1791
1068
  }
@@ -1793,60 +1070,17 @@ export function startDaemon(agentsBin) {
1793
1070
  releaseOnce();
1794
1071
  }
1795
1072
  }
1796
- /**
1797
- * Is the auto-start circuit breaker open (RUSH-2418)? True once
1798
- * {@link DAEMON_AUTOSTART_FAILURE_LIMIT} consecutive starts have failed to
1799
- * produce a daemon that reported healthy. Pure read of the persisted health
1800
- * record, and `agents daemon doctor` reports the same record — the message the
1801
- * breaker prints has to lead somewhere that can explain it.
1802
- */
1803
1073
  export function isDaemonAutostartCircuitOpen() {
1804
1074
  const health = readSubsystemHealth(SUBSYSTEM_DAEMON_START);
1805
1075
  return (health?.consecutiveFailures ?? 0) >= DAEMON_AUTOSTART_FAILURE_LIMIT;
1806
1076
  }
1807
- /**
1808
- * Bring the always-on daemon up as a side effect of a background-adjacent
1809
- * command (secrets unlock, browser start, ...), not only from `routines add`.
1810
- *
1811
- * Delegates to the single `startDaemon` entrypoint, so it honors the
1812
- * single-instance start lock and is a no-op when a daemon is already running
1813
- * (returns `already-running`). Best-effort: any failure is swallowed and null
1814
- * returned, so ensuring the daemon can never break the foreground command that
1815
- * happened to bring it up. See issue #415.
1816
- */
1817
1077
  export function ensureDaemonStarted() {
1818
- // RUSH-2354: honor daemon.enabled — a background-adjacent caller (secrets
1819
- // unlock, browser start, ...) must not resurrect a daemon the owner
1820
- // explicitly turned off. `agents daemon start` is the deliberate override
1821
- // and calls startDaemon() directly instead of going through this helper.
1822
1078
  if (!isDaemonEnabled())
1823
1079
  return null;
1824
- // A live daemon is the answer whatever the failure history says — the breaker
1825
- // gates LAUNCHING one, never reporting one that is already up. Checked first
1826
- // so a stale failure streak can't make a healthy daemon read as absent to
1827
- // callers that branch on this return (e.g. secrets/agent.ts).
1828
1080
  if (isDaemonRunning())
1829
1081
  return startDaemon();
1830
- // RUSH-3021: never LAUNCH a daemon from a redirected (sandbox/test) HOME.
1831
- // #2860 gated service-manager registration on this signal but left the
1832
- // detached spawn itself ungated, so a test-spawned CLI could fork a daemon
1833
- // into the test's temp HOME; the child outlives the test and races its
1834
- // recursive teardown rm (ENOTEMPTY). Placed after the already-running branch
1835
- // — reporting a live daemon stays allowed, same as the circuit breaker.
1836
- // AGENTS_SERVICE_MANAGER_ALLOW_REDIRECTED_HOME=1 is the test seam for suites
1837
- // that exercise daemon startup deliberately. The explicit `agents daemon
1838
- // start` path is gated separately by startDaemon's own redirected-HOME
1839
- // refusal (AGENTS_ALLOW_TEST_DAEMON=1, W4/PHNX-3736).
1840
1082
  if (!serviceManagerRegistrationAllowed().allowed)
1841
1083
  return null;
1842
- // RUSH-2418: the auto-start circuit breaker. A daemon that dies during
1843
- // startup would otherwise be relaunched by EVERY foreground command that
1844
- // wants one (secrets unlock, browser start, watchdog, ...) — an
1845
- // application-level crash loop the OS supervisor's throttle cannot see,
1846
- // because each attempt is a fresh service start rather than a respawn. After
1847
- // DAEMON_AUTOSTART_FAILURE_LIMIT consecutive failures, refuse and say why.
1848
- // Deliberately NOT applied in startDaemon(): `agents daemon start` is the
1849
- // operator's override and must always be able to retry.
1850
1084
  if (isDaemonAutostartCircuitOpen()) {
1851
1085
  process.stderr.write(`[agents] daemon auto-start disabled after ${DAEMON_AUTOSTART_FAILURE_LIMIT} consecutive failed starts. ` +
1852
1086
  `Run 'agents daemon doctor' to diagnose, or 'agents daemon start' to retry anyway.\n`);
@@ -1859,29 +1093,9 @@ export function ensureDaemonStarted() {
1859
1093
  return null;
1860
1094
  }
1861
1095
  }
1862
- /**
1863
- * Issue the launch, then wait for the child to record its pid.
1864
- *
1865
- * RUSH-2417: the wait phase MUST NOT hold the start lock. `acquireStartLock`
1866
- * and `claimDaemonInstance` resolve the same `<daemonDir>/daemon.lock`, so a
1867
- * parent that busy-waits on `waitForPid` while still holding it deterministically
1868
- * defeats the child it just launched: the child's `claimDaemonInstance` hits
1869
- * EEXIST, reads a holder pid that IS alive (this process), and exits with the
1870
- * false "another daemon is mid-takeover" warning — every launchd/systemd start
1871
- * on a fresh install. The lock's job is to keep two concurrent `startDaemon()`
1872
- * calls from both launching, and that is done once `launchctl load` /
1873
- * `systemctl start` / the detached spawn has been issued, so `releaseLock()` is
1874
- * called there rather than in the caller's `finally`.
1875
- *
1876
- * Releasing early cannot produce two daemons: launchd (one plist label) and
1877
- * systemd (one unit) are singletons that no-op a second start, and the detached
1878
- * path is covered by `claimDaemonInstance`'s last-wins takeover (SING-11) —
1879
- * a second claimer evicts the incumbent rather than running beside it.
1880
- */
1096
+ // Release the start lock before the child claims it; manager success is not health until pid/heartbeat proof appears.
1881
1097
  function startDaemonLocked(agentsBin, releaseLock) {
1882
1098
  const platform = os.platform();
1883
- // Same contract on the fallback path: the spawn IS the launch, so the lock is
1884
- // dropped before the child exists rather than in a `finally` the child races.
1885
1099
  const detachedFallback = () => {
1886
1100
  releaseLock();
1887
1101
  return startDetached({ agentsBin });
@@ -1895,28 +1109,18 @@ function startDaemonLocked(agentsBin, releaseLock) {
1895
1109
  if (!fs.existsSync(plistDir)) {
1896
1110
  fs.mkdirSync(plistDir, { recursive: true });
1897
1111
  }
1898
- // The plist carries no credential (RUSH-1759 — the daemon reads the OAuth
1899
- // token itself at startup); still create owner-only atomically to match the
1900
- // detached path and keep the log/PATH surface owner-private.
1901
1112
  writeOwnerOnlyServiceManifest(plistPath, generateLaunchdPlist(agentsBin));
1902
1113
  try {
1903
1114
  execFileSync('launchctl', ['unload', plistPath], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
1904
1115
  }
1905
- catch { /* not loaded, expected */ }
1906
- // launchctl prints `Load failed:` and exits 0 when the label is in a
1907
- // stuck state from a prior session — so a zero exit code isn't proof
1908
- // of success. If no pid materializes within the window, give up on
1909
- // launchd and fall through to a plain detached spawn.
1116
+ catch { }
1910
1117
  execFileSync('launchctl', ['load', plistPath], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
1911
- // Launch issued — the child needs this lock to claim (RUSH-2417).
1912
1118
  releaseLock();
1913
1119
  const pid = waitForPid(3000) ?? readServiceManagerPid();
1914
1120
  if (pid)
1915
1121
  return { pid, method: 'launchd' };
1916
- // launchctl claimed success but nothing ran. Fall through.
1917
1122
  }
1918
1123
  catch {
1919
- // load threw — fall through to detached spawn
1920
1124
  }
1921
1125
  }
1922
1126
  else {
@@ -1932,22 +1136,16 @@ function startDaemonLocked(agentsBin, releaseLock) {
1932
1136
  if (!fs.existsSync(unitDir)) {
1933
1137
  fs.mkdirSync(unitDir, { recursive: true });
1934
1138
  }
1935
- // Carries no credential (RUSH-1759 — the daemon reads the OAuth token
1936
- // itself at startup); owner-only to keep the PATH/log surface private.
1937
1139
  writeOwnerOnlyServiceManifest(unitPath, generateSystemdUnit(agentsBin));
1938
1140
  execFileSync('systemctl', ['--user', 'daemon-reload'], { encoding: 'utf-8' });
1939
1141
  execFileSync('systemctl', ['--user', 'enable', daemonSystemdUnitName()], { encoding: 'utf-8' });
1940
1142
  execFileSync('systemctl', ['--user', 'start', daemonSystemdUnitName()], { encoding: 'utf-8' });
1941
- // Launch issued — the child needs this lock to claim (RUSH-2417).
1942
1143
  releaseLock();
1943
1144
  const pid = waitForPid(3000) ?? readServiceManagerPid();
1944
1145
  if (pid)
1945
1146
  return { pid, method: 'systemd' };
1946
- // systemctl returned success but no PID surfaced — fall through to a
1947
- // plain detached spawn rather than reporting a null PID.
1948
1147
  }
1949
1148
  catch {
1950
- // start threw — fall through to detached spawn
1951
1149
  }
1952
1150
  }
1953
1151
  else {
@@ -1957,74 +1155,19 @@ function startDaemonLocked(agentsBin, releaseLock) {
1957
1155
  }
1958
1156
  return startDetached({ agentsBin });
1959
1157
  }
1960
- /**
1961
- * Resolve how to launch the daemon: `node <entry> __daemon-run`, matching the
1962
- * exact form that works under a direct `__daemon-run`.
1963
- *
1964
- * We spawn the Node runtime (`process.execPath`) with the CLI entry as an
1965
- * argument rather than executing the entry path directly. Executing the `.js`
1966
- * path relies on its shebang on POSIX, and on Windows CreateProcess can't run a
1967
- * `.js`/shim directly at all — it gets launched through a transient
1968
- * console-owning wrapper (cmd.exe / the npm shim). When that wrapper exits it
1969
- * closes its console, and the detached daemon sharing that console receives a
1970
- * console-close event that trips its shutdown handler — the daemon comes up,
1971
- * binds its sockets, then tears itself down ~36ms later (#556).
1972
- * Going through `process.execPath` means a real PE/binary is spawned with
1973
- * `detached: true` and no console, so nothing signals the daemon after launch.
1974
- *
1975
- * When the entry isn't a Node script (e.g. a native compiled launcher), run it
1976
- * directly — it owns its own runtime resolution.
1977
- */
1978
1158
  export function getDaemonLaunch(agentsBin = getAgentsBinPath()) {
1979
1159
  const { warnings } = validateDaemonBinary(agentsBin);
1980
1160
  for (const w of warnings)
1981
1161
  process.stderr.write(`[agents] ${w}\n`);
1982
1162
  return getCliLaunch(['__daemon-run'], agentsBin);
1983
1163
  }
1984
- /**
1985
- * The directory of the Node runtime that generated this service manifest, kept
1986
- * first on the daemon's PATH. Both the shim's shebang and any child routine
1987
- * process then resolve the exact Node that installed the service — never an
1988
- * ancient system node or a pruned nvm version. Replaces the old hardcoded
1989
- * `~/.nvm/versions/node/v24.0.0/bin`, which went stale the moment that patch
1990
- * release was upgraded away and bricked the daemon fleet-wide.
1991
- */
1992
1164
  function daemonNodeBinDir() {
1993
1165
  return path.dirname(process.execPath);
1994
1166
  }
1995
- /**
1996
- * Login-shell user-bin dirs a service-manager-started daemon would otherwise
1997
- * miss. systemd/launchd pin PATH and never source `~/.profile`, so they never
1998
- * see `~/.rush/bin` (where `rush` lands) or `~/.local/bin` (XDG user-bin).
1999
- * Monitor `notify` and dispatched `agents run` children inherit this PATH;
2000
- * without these dirs the rush-backed owner channel fails with
2001
- * `rush CLI not found on PATH` (PHNX-3075) while an interactive shell on the
2002
- * same box succeeds. Uses the same HOME the manifest bakes (RUSH-2639).
2003
- */
2004
1167
  function daemonUserBinDirs() {
2005
1168
  const home = serviceManifestHomeEnv().HOME;
2006
1169
  return [path.join(home, '.rush', 'bin'), localBinDir(home)];
2007
1170
  }
2008
- /**
2009
- * The full PATH value the daemon service manifest pins, in order: the directory
2010
- * of the `agents` shim itself FIRST, then the Node runtime dir, then login-shell
2011
- * user-bin dirs (`~/.rush/bin`, `~/.local/bin`), then the platform's system dirs.
2012
- *
2013
- * The shim's own dir must lead so a scheduled `command` routine that shells out
2014
- * to the bare name `agents` (`/bin/sh -c 'agents repo pull system'`) resolves the
2015
- * SAME binary the daemon is running. When the Node runtime dir came first, a
2016
- * stale `agents` install inside that dir (common with nvm or an npm global in the
2017
- * same Node prefix) shadowed the current binary and routines failed with an
2018
- * `unknown command` error against the wrong build.
2019
- *
2020
- * The Node runtime dir stays second so the shim's shebang (`#!/usr/bin/env node`)
2021
- * still resolves the exact Node that installed the service — never an ancient
2022
- * system node or a pruned nvm version. User-bin dirs sit after that pair so a
2023
- * `~/.local/bin/agents` cannot shadow the daemon binary, but `rush` (and other
2024
- * login-shell CLIs) still resolve. Deduped across the whole list, so a
2025
- * Node/shim dir that already appears among the system dirs (e.g. a
2026
- * `/usr/local/bin` install) never doubles.
2027
- */
2028
1171
  function daemonPathValue(agentsBin, systemDirs) {
2029
1172
  return [...new Set([
2030
1173
  path.dirname(agentsBin),
@@ -2033,34 +1176,9 @@ function daemonPathValue(agentsBin, systemDirs) {
2033
1176
  ...systemDirs,
2034
1177
  ])].join(':');
2035
1178
  }
2036
- /**
2037
- * Build the argv to relaunch the `agents` CLI with the given subcommand args.
2038
- *
2039
- * Resolves the real on-disk binary via getAgentsBinPath(), then dispatches: a
2040
- * `.js` entry runs under node (`node <entry> …`), a native/compiled binary runs
2041
- * directly (`<bin> …`).
2042
- *
2043
- * Callers MUST route self-spawns through this rather than hand-rolling
2044
- * `[process.execPath, process.argv[1], …]`: under the compiled standalone binary
2045
- * (#315) `process.argv[1]` is the bun virtual entry `/$bunfs/root/agents`, so the
2046
- * hand-rolled form becomes `agents /$bunfs/root/agents …` → the CLI receives the
2047
- * bunfs path as a subcommand and dies with "unknown command '/$bunfs/root/agents'".
2048
- * getAgentsBinPath() resolves that virtual entry to the physical process.execPath.
2049
- */
2050
1179
  export function getAgentsInvocation(subArgs, agentsBin = getAgentsBinPath()) {
2051
1180
  return getCliLaunch(subArgs, agentsBin);
2052
1181
  }
2053
- /**
2054
- * A daemon binary living under an ephemeral path — a git worktree, or a temp
2055
- * directory (`/tmp`, `/var/folders`, `/dev/shm`) — is a latent wedge. The daemon
2056
- * is long-lived but resolves its own job modules by dynamic `import()` rooted at
2057
- * this entry (getAgentsBinPath → process.argv[1]). If that directory is later
2058
- * removed (`git worktree remove`, a `/tmp` cleanup, a review/verify checkout
2059
- * teardown) the running daemon keeps ENOENT-ing on every job it loads —
2060
- * `anchorDaemonCwd` rescues the cwd, but nothing can re-root a deleted module
2061
- * tree. Returns a human phrase naming the ephemeral kind, or null for a stable
2062
- * install path (version home, a global npm prefix, a normal source checkout).
2063
- */
2064
1182
  export function describeEphemeralDaemonRoot(binPath) {
2065
1183
  if (/[/\\]\.agents[/\\]worktrees[/\\]/.test(binPath))
2066
1184
  return 'a git worktree';
@@ -2090,25 +1208,14 @@ export function startDetached(opts = {}) {
2090
1208
  const logPath = opts.logPath ?? getDaemonLogPath();
2091
1209
  const logFd = fs.openSync(logPath, 'a');
2092
1210
  const { command, args } = getDaemonLaunch(agentsBin);
2093
- // fdStdio: the log-file fds make windowsHide inert (libuv skips
2094
- // CREATE_NO_WINDOW when a stdio fd is inherited), so on Windows the daemon
2095
- // must DETACH to own no console — otherwise it shares the launcher's console
2096
- // and a console-close event tears it down when the launcher exits (#556).
2097
1211
  const child = spawn(command, args, {
2098
1212
  stdio: ['ignore', logFd, logFd],
2099
1213
  ...backgroundSpawnOptions({ cwd: os.homedir(), fdStdio: true }),
2100
1214
  env: opts.env ?? process.env,
2101
1215
  });
2102
- // A failed spawn (ENOENT/EACCES) emits 'error' asynchronously; without a
2103
- // listener that would crash the parent as an unhandled EventEmitter error.
2104
- // The synchronous `!child.pid` guard below is what reports the failure loudly.
2105
1216
  child.on('error', () => { });
2106
1217
  child.unref();
2107
1218
  fs.closeSync(logFd);
2108
- // `spawn` leaves `pid` undefined only when the process could not be created.
2109
- // Returning null here (the old `child.pid || null`) let callers report
2110
- // "PID: null" as if the daemon had started — a start with no PID is a failed
2111
- // start, so fail loudly instead of manufacturing a phantom success.
2112
1219
  if (!child.pid) {
2113
1220
  throw new Error(`Failed to start daemon: spawning '${command}' produced no PID (binary missing or not executable?)`);
2114
1221
  }
@@ -2125,11 +1232,6 @@ function waitForPid(timeoutMs) {
2125
1232
  }
2126
1233
  return readDaemonPid();
2127
1234
  }
2128
- /**
2129
- * Read the pid a state file claims, or null when it is absent/unreadable/not
2130
- * pid-shaped. The lifetime marker stores `<pid>:<epochMs>`; the heartbeat
2131
- * stores JSON with a `pid`.
2132
- */
2133
1235
  function claimedPid(read) {
2134
1236
  try {
2135
1237
  return read();
@@ -2138,17 +1240,6 @@ function claimedPid(read) {
2138
1240
  return null;
2139
1241
  }
2140
1242
  }
2141
- /**
2142
- * The lifetime marker, heartbeat, and instance-registry entry, described so
2143
- * {@link stopDaemon} can assert them the same way it asserts the two sockets.
2144
- *
2145
- * Ownership, not mere presence, decides: a file naming a pid that is alive and
2146
- * is not the daemon we just stopped belongs to a DIFFERENT daemon (a successor
2147
- * that started during the stop, or a peer serving this state dir), and deleting
2148
- * it would break that live daemon — the same reasoning the broker-socket branch
2149
- * above uses for a standalone owner. Everything else is residue from a provably
2150
- * dead owner and is reclaimed.
2151
- */
2152
1243
  export function stopResidueArtifacts(stoppedPid, survivors = []) {
2153
1244
  const artifacts = [];
2154
1245
  const lifetimePath = path.join(getDaemonDir(), LIFETIME_FILE);
@@ -2165,7 +1256,7 @@ export function stopResidueArtifacts(stoppedPid, survivors = []) {
2165
1256
  reclaim: () => { try {
2166
1257
  fs.unlinkSync(lifetimePath);
2167
1258
  }
2168
- catch { /* raced with a fresh start */ } },
1259
+ catch { } },
2169
1260
  stillPresent: () => fs.existsSync(lifetimePath),
2170
1261
  });
2171
1262
  const heartbeatPath = getHeartbeatPath();
@@ -2173,33 +1264,16 @@ export function stopResidueArtifacts(stoppedPid, survivors = []) {
2173
1264
  artifacts.push({
2174
1265
  label: 'daemon heartbeat',
2175
1266
  present: fs.existsSync(heartbeatPath),
2176
- // A stale heartbeat is not cosmetic: resolveLiveDaemonPid() trusts a FRESH
2177
- // one to re-adopt a daemon whose pid file was lost, so leaving one behind
2178
- // can make a dead daemon read as running.
2179
1267
  ownedByLiveOther: hb !== null && (survivors.includes(hb.pid)
2180
1268
  || (hb.pid !== stoppedPid && isAlive(hb.pid))),
2181
1269
  reclaim: () => removeHeartbeat(),
2182
1270
  stillPresent: () => fs.existsSync(heartbeatPath),
2183
1271
  });
2184
- // POSIX-only, matching registerDaemonInstance/unregisterDaemonInstance.
2185
1272
  if (process.platform !== 'win32' && stoppedPid !== null) {
2186
1273
  const markerPath = path.join(getDaemonInstancesDir(), String(stoppedPid));
2187
1274
  artifacts.push({
2188
1275
  label: 'daemon instance registry entry',
2189
1276
  present: fs.existsSync(markerPath),
2190
- // The marker is named by pid, so it is unambiguously this daemon's — but
2191
- // "this daemon" is only residue once it is actually DEAD. If the kill did
2192
- // not land, deleting the marker erases the very record
2193
- // `findSurvivingStateDirDaemons` enumerates, so the next `agents daemon
2194
- // stop` would find an empty registry and a cleared pid file and report
2195
- // `ok: true` with the daemon still running.
2196
- //
2197
- // "Dead" is decided by the caller's OWN survivor scan, not by `isAlive`:
2198
- // a SIGKILLed child is a zombie until its parent reaps it, and `kill(pid,
2199
- // 0)` succeeds on a zombie. Keyed off `isAlive` this kept the entry of a
2200
- // daemon that was already gone, so the stop stopped being able to report
2201
- // its own state truthfully. The survivor scan matches a live
2202
- // `__daemon-run`, which a zombie is not.
2203
1277
  ownedByLiveOther: survivors.includes(stoppedPid),
2204
1278
  reclaim: () => unregisterDaemonInstance(stoppedPid),
2205
1279
  stillPresent: () => fs.existsSync(markerPath),
@@ -2207,22 +1281,6 @@ export function stopResidueArtifacts(stoppedPid, survivors = []) {
2207
1281
  }
2208
1282
  return artifacts;
2209
1283
  }
2210
- /**
2211
- * Live `__daemon-run` processes still registered in THIS state dir's instance
2212
- * registry, excluding `exclude`. State-dir-scoped by construction: the registry
2213
- * lives inside this state dir, so a daemon serving a DIFFERENT state dir (a test
2214
- * fixture with its own HOME, a separate install/home) registers elsewhere and is
2215
- * invisible here — it is never a stop/takeover target. POSIX-only (the registry
2216
- * and its `ps` liveness probe are); `[]` on Windows.
2217
- *
2218
- * Exported for `agents daemon status`/`doctor`/`services` (RUSH-2368): those
2219
- * commands previously flagged every `__daemon-run` on the box (a raw `ps` scan)
2220
- * as a "duplicate" of this daemon, which misreported test fixtures under their
2221
- * own HOME — and therefore their own state dir and registry — as strays to
2222
- * kill. This registry read is the same scope the reaper (`reapStrayDaemons`)
2223
- * and the stop postcondition (`stopDaemon`) already use, so the display and the
2224
- * reaper agree on what a duplicate is.
2225
- */
2226
1284
  function findStateDirDaemonProcesses(exclude) {
2227
1285
  const live = [];
2228
1286
  const unverified = [];
@@ -2239,7 +1297,7 @@ function findStateDirDaemonProcesses(exclude) {
2239
1297
  for (const name of entries) {
2240
1298
  const pid = parseInt(name, 10);
2241
1299
  if (isNaN(pid) || String(pid) !== name)
2242
- continue; // not a pid marker
1300
+ continue;
2243
1301
  if (exclude.has(pid))
2244
1302
  continue;
2245
1303
  const identity = daemonProcessIdentity(pid);
@@ -2253,17 +1311,7 @@ function findStateDirDaemonProcesses(exclude) {
2253
1311
  export function findSurvivingStateDirDaemons(exclude) {
2254
1312
  return findStateDirDaemonProcesses(exclude).live;
2255
1313
  }
2256
- /**
2257
- * Stop the daemon and ASSERT its postcondition (SING-12, RUSH-2355), unloading it
2258
- * from launchd/systemd if applicable.
2259
- *
2260
- * The SIGTERM → grace → killTree sequence is unchanged; what it adds is
2261
- * verification: after the daemon is gone it checks that no `__daemon-run` for
2262
- * THIS state dir survives and reclaims the state files a killTree escalation
2263
- * (which skips the graceful handleShutdown) can leave stale. The browser IPC
2264
- * socket is no longer among them — it left with the standalone `browser` CLI
2265
- * (PHNX-4101). It never reports success on an unverified stop.
2266
- */
1314
+ // Stop crosses the same lifecycle lock as start and claim, preventing teardown from racing takeover.
2267
1315
  export function stopDaemon() {
2268
1316
  const releaseLock = acquireLifecycleLock();
2269
1317
  if (!releaseLock) {
@@ -2296,7 +1344,6 @@ function pathIdentityMatches(filePath, expected) {
2296
1344
  const current = readPathIdentity(filePath);
2297
1345
  return current !== null && current.dev === expected.dev && current.ino === expected.ino;
2298
1346
  }
2299
- /** daemon.lock is held for this entire read-signal-verify-cleanup transaction. */
2300
1347
  function stopDaemonLocked() {
2301
1348
  const platform = os.platform();
2302
1349
  const released = [];
@@ -2314,9 +1361,6 @@ function stopDaemonLocked() {
2314
1361
  detachedChildren: listLiveRoutineChildren(),
2315
1362
  };
2316
1363
  }
2317
- // Capture the target and its path-bound resources while lifecycle writers are
2318
- // excluded. resolveLiveDaemonPid(true) rejects a reused/non-daemon pid before
2319
- // any service-manager teardown or direct signal and repairs only under lock.
2320
1364
  const pid = resolveLiveDaemonPid(true);
2321
1365
  if (platform === 'darwin') {
2322
1366
  const plistPath = getLaunchdPlistPath();
@@ -2337,7 +1381,7 @@ function stopDaemonLocked() {
2337
1381
  try {
2338
1382
  fs.unlinkSync(plistPath);
2339
1383
  }
2340
- catch { /* plist already removed */ }
1384
+ catch { }
2341
1385
  }
2342
1386
  }
2343
1387
  if (platform === 'linux') {
@@ -2360,14 +1404,11 @@ function stopDaemonLocked() {
2360
1404
  try {
2361
1405
  fs.unlinkSync(unitPath);
2362
1406
  }
2363
- catch { /* unit file already removed */ }
1407
+ catch { }
2364
1408
  }
2365
1409
  }
2366
1410
  if (pid) {
2367
1411
  if (process.platform === 'win32') {
2368
- // Windows has no graceful termination signal — terminate the daemon and
2369
- // its job/browser child tree in one shot (taskkill /T), so stop doesn't
2370
- // report success while children keep running.
2371
1412
  if (isLiveDaemon(pid)) {
2372
1413
  killTree(pid);
2373
1414
  escalated = true;
@@ -2375,22 +1416,11 @@ function stopDaemonLocked() {
2375
1416
  }
2376
1417
  }
2377
1418
  else {
2378
- // Revalidate immediately before the signal: the pid may have exited and
2379
- // been reused since the ownership snapshot above.
2380
1419
  if (isLiveDaemon(pid)) {
2381
1420
  try {
2382
1421
  process.kill(pid, 'SIGTERM');
2383
1422
  }
2384
- catch { /* process already exited */ }
2385
- // Wait for it to actually go. This used to be a setTimeout escalation plus
2386
- // an immediate removeDaemonPid(), which had two failure modes: in a
2387
- // short-lived process (the npm postinstall) the timer never fired at all,
2388
- // and clearing the pid file while the old daemon still ran made
2389
- // isDaemonRunning() report false, so startDaemon() launched a SECOND
2390
- // daemon. Its hosted broker then unlinked the live socket and rebound,
2391
- // orphaning the first broker with every unlocked bundle still in its RAM
2392
- // and unreachable — two brokers on one socket path, seen on a real machine
2393
- // after an install into a second prefix.
1423
+ catch { }
2394
1424
  if (!waitForExit(pid, STOP_GRACE_MS) && isLiveDaemon(pid)) {
2395
1425
  killTree(pid);
2396
1426
  escalated = true;
@@ -2399,13 +1429,9 @@ function stopDaemonLocked() {
2399
1429
  }
2400
1430
  }
2401
1431
  }
2402
- // ── Assert the postcondition (SING-12) ────────────────────────────────────
2403
- // No `__daemon-run` for this state dir may survive the stop.
2404
1432
  const stateDirProcesses = findStateDirDaemonProcesses(new Set([process.pid]));
2405
1433
  const survivors = stateDirProcesses.live;
2406
1434
  const unverifiedSurvivors = stateDirProcesses.unverified;
2407
- // The registry is best-effort and may be missing, so always re-check the
2408
- // direct target as well. This is the only check available on Windows.
2409
1435
  if (pid && !survivors.includes(pid) && !unverifiedSurvivors.includes(pid)) {
2410
1436
  const identity = daemonProcessIdentity(pid);
2411
1437
  if (identity === 'daemon')
@@ -2425,9 +1451,6 @@ function stopDaemonLocked() {
2425
1451
  if (pid && !targetStillOwnsResources) {
2426
1452
  released.push('daemon process');
2427
1453
  }
2428
- // Delete the registration only after the target is provably gone, and only
2429
- // if the file still names that target. A replacement value belongs to a
2430
- // successor (or another writer) and is both preserved and reported.
2431
1454
  const currentPid = readDaemonPid();
2432
1455
  if (pid !== null && !targetStillOwnsResources) {
2433
1456
  if (removeDaemonPidIfOwned(pid))
@@ -2443,19 +1466,6 @@ function stopDaemonLocked() {
2443
1466
  else if (pid === null && currentPid !== null) {
2444
1467
  surviving.push(`daemon pid registration changed to ${currentPid} during stop`);
2445
1468
  }
2446
- // The browser IPC socket is the standalone `browser` CLI's now (PHNX-4101):
2447
- // the daemon no longer binds it, so there is nothing to reclaim here. browser-cli
2448
- // owns its own socket lifecycle under `~/.agents/.cache/helpers/browser/`.
2449
- // ── The state files a killed daemon cannot clean up itself (RUSH-2421) ─────
2450
- // handleShutdown removes the lifetime marker, the heartbeat and this pid's
2451
- // instance-registry entry — but it only runs on the GRACEFUL path. Every
2452
- // escalation above (killTree, and the whole win32 branch) skips it, so those
2453
- // three outlive the daemon and the stop reported `ok: true` while its state
2454
- // dir still described a daemon that no longer exists. Each is stale metadata
2455
- // with real consequences: a leftover heartbeat is what `resolveLiveDaemonPid`
2456
- // consults to re-adopt a "live" daemon, and a leftover registry entry is what
2457
- // `reapStrayDaemons` enumerates. Same shape as the sockets above — reclaim
2458
- // what a provably dead owner left, never touch what a live one owns.
2459
1469
  for (const artifact of stopResidueArtifacts(pid, [...survivors, ...unverifiedSurvivors])) {
2460
1470
  if (!artifact.present) {
2461
1471
  released.push(artifact.label);
@@ -2471,8 +1481,6 @@ function stopDaemonLocked() {
2471
1481
  else
2472
1482
  released.push(`${artifact.label} (reclaimed)`);
2473
1483
  }
2474
- // In-flight detached routine children survive on purpose (SING-11a) — report,
2475
- // never kill: severing a live agent mid-run is worse than a daemon restart.
2476
1484
  const detachedChildren = listLiveRoutineChildren();
2477
1485
  return {
2478
1486
  ok: surviving.length === 0,
@@ -2483,14 +1491,6 @@ function stopDaemonLocked() {
2483
1491
  detachedChildren,
2484
1492
  };
2485
1493
  }
2486
- /**
2487
- * Get current daemon status including running state, PID, enabled job count, and
2488
- * the supervised-restart history `agents daemon status` renders (PHNX-4116).
2489
- *
2490
- * There is no `wedged` state: a stalled daemon exits for a supervised
2491
- * systemd/launchd restart rather than sitting unresponsive, so the daemon is
2492
- * simply `running` or `stopped`, and its recent restarts are reported instead.
2493
- */
2494
1494
  export function getDaemonStatus() {
2495
1495
  const running = isDaemonRunning();
2496
1496
  const pid = readDaemonPid();
@@ -2498,12 +1498,12 @@ export function getDaemonStatus() {
2498
1498
  try {
2499
1499
  jobCount = listAllJobs().filter((j) => j.enabled).length;
2500
1500
  }
2501
- catch { /* job listing failed */ }
1501
+ catch { }
2502
1502
  let binaryPath = null;
2503
1503
  try {
2504
1504
  binaryPath = getAgentsBinPath();
2505
1505
  }
2506
- catch { /* resolution failed */ }
1506
+ catch { }
2507
1507
  const recentRestarts = readRecentDaemonRestarts(Date.now() - 24 * 60 * 60 * 1000);
2508
1508
  const lastRestart = recentRestarts.length > 0 ? recentRestarts[recentRestarts.length - 1] : null;
2509
1509
  return {
@@ -2519,7 +1519,6 @@ export function getDaemonStatus() {
2519
1519
  lastRestartAt: lastRestart ? lastRestart.at : null,
2520
1520
  };
2521
1521
  }
2522
- /** Read the daemon log, optionally limited to the last N lines. */
2523
1522
  export function readDaemonLog(lines) {
2524
1523
  const logPath = getDaemonLogPath();
2525
1524
  if (!fs.existsSync(logPath))
@@ -2530,15 +1529,11 @@ export function readDaemonLog(lines) {
2530
1529
  const allLines = content.split('\n');
2531
1530
  return allLines.slice(-lines).join('\n');
2532
1531
  }
2533
- /** Send SIGHUP to the daemon to trigger a job reload. */
2534
1532
  export function signalDaemonReload() {
2535
1533
  const pid = readDaemonPid();
2536
1534
  if (!pid)
2537
1535
  return false;
2538
1536
  if (process.platform === 'win32') {
2539
- // Windows has no SIGHUP, so signal-based live reload isn't available. Sending
2540
- // it would throw; instead report "not reloaded" so callers tell the user to
2541
- // restart the daemon to pick up job changes.
2542
1537
  return false;
2543
1538
  }
2544
1539
  try {