@phnx-labs/agents-cli 1.22.35 → 1.22.37

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 (487) hide show
  1. package/CHANGELOG.md +666 -2
  2. package/README.md +75 -35
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1211 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/attach.js +17 -4
  9. package/dist/commands/audit.d.ts +8 -8
  10. package/dist/commands/audit.js +57 -47
  11. package/dist/commands/browser.js +15 -11
  12. package/dist/commands/cloud.js +1 -1
  13. package/dist/commands/commands.js +0 -11
  14. package/dist/commands/computer-actions.js +33 -0
  15. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  16. package/dist/commands/computer-sessions-picker.js +141 -0
  17. package/dist/commands/computer.d.ts +16 -0
  18. package/dist/commands/computer.js +37 -0
  19. package/dist/commands/config.d.ts +17 -0
  20. package/dist/commands/config.js +401 -0
  21. package/dist/commands/cp.d.ts +84 -0
  22. package/dist/commands/cp.js +231 -0
  23. package/dist/commands/daemon.js +243 -14
  24. package/dist/commands/detach-core.d.ts +1 -1
  25. package/dist/commands/detach-core.js +12 -2
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +64 -5
  28. package/dist/commands/events.d.ts +24 -12
  29. package/dist/commands/events.js +144 -28
  30. package/dist/commands/exec.js +85 -41
  31. package/dist/commands/feed.d.ts +1 -1
  32. package/dist/commands/feed.js +16 -8
  33. package/dist/commands/focus.d.ts +33 -1
  34. package/dist/commands/focus.js +177 -17
  35. package/dist/commands/funnel.d.ts +1 -1
  36. package/dist/commands/go.js +9 -8
  37. package/dist/commands/harness-wizard.d.ts +1 -0
  38. package/dist/commands/harness-wizard.js +18 -20
  39. package/dist/commands/harness.d.ts +2 -0
  40. package/dist/commands/harness.js +59 -26
  41. package/dist/commands/hooks.js +0 -11
  42. package/dist/commands/inspect.d.ts +94 -1
  43. package/dist/commands/inspect.js +866 -40
  44. package/dist/commands/lease.d.ts +4 -4
  45. package/dist/commands/lease.js +6 -6
  46. package/dist/commands/login.js +0 -13
  47. package/dist/commands/logs.d.ts +2 -2
  48. package/dist/commands/logs.js +2 -2
  49. package/dist/commands/mcp.js +7 -2
  50. package/dist/commands/memory.js +7 -2
  51. package/dist/commands/message.d.ts +1 -1
  52. package/dist/commands/message.js +37 -6
  53. package/dist/commands/models.js +4 -0
  54. package/dist/commands/monitors.d.ts +0 -1
  55. package/dist/commands/monitors.js +199 -16
  56. package/dist/commands/open.d.ts +18 -0
  57. package/dist/commands/open.js +57 -0
  58. package/dist/commands/packages.js +2 -107
  59. package/dist/commands/plugins.js +6 -3
  60. package/dist/commands/profiles.d.ts +1 -0
  61. package/dist/commands/profiles.js +16 -160
  62. package/dist/commands/projects.d.ts +28 -0
  63. package/dist/commands/projects.js +125 -5
  64. package/dist/commands/reconnect.js +9 -3
  65. package/dist/commands/repo.js +42 -1
  66. package/dist/commands/resource-view.d.ts +17 -0
  67. package/dist/commands/resource-view.js +36 -14
  68. package/dist/commands/resume.js +9 -2
  69. package/dist/commands/routines.d.ts +0 -2
  70. package/dist/commands/routines.js +473 -289
  71. package/dist/commands/secrets.js +52 -9
  72. package/dist/commands/sessions-export.d.ts +47 -0
  73. package/dist/commands/sessions-export.js +116 -6
  74. package/dist/commands/sessions-import.d.ts +17 -0
  75. package/dist/commands/sessions-import.js +114 -6
  76. package/dist/commands/sessions-migrate.d.ts +27 -0
  77. package/dist/commands/sessions-migrate.js +50 -9
  78. package/dist/commands/sessions-picker.js +23 -4
  79. package/dist/commands/sessions-resume.d.ts +5 -3
  80. package/dist/commands/sessions-resume.js +30 -8
  81. package/dist/commands/sessions-watch.d.ts +2 -0
  82. package/dist/commands/sessions-watch.js +53 -0
  83. package/dist/commands/sessions.d.ts +66 -3
  84. package/dist/commands/sessions.js +298 -47
  85. package/dist/commands/set.d.ts +1 -1
  86. package/dist/commands/set.js +2 -2
  87. package/dist/commands/setup-browser.js +2 -2
  88. package/dist/commands/setup-mine.js +0 -1
  89. package/dist/commands/setup-preferences.js +1 -1
  90. package/dist/commands/setup-share.js +34 -4
  91. package/dist/commands/setup.d.ts +5 -0
  92. package/dist/commands/setup.js +26 -0
  93. package/dist/commands/share.d.ts +67 -0
  94. package/dist/commands/share.js +275 -12
  95. package/dist/commands/skills.js +0 -11
  96. package/dist/commands/snapshot.js +1 -1
  97. package/dist/commands/ssh.d.ts +18 -0
  98. package/dist/commands/ssh.js +549 -210
  99. package/dist/commands/sync.d.ts +5 -0
  100. package/dist/commands/sync.js +212 -32
  101. package/dist/commands/teams.d.ts +13 -0
  102. package/dist/commands/teams.js +187 -30
  103. package/dist/commands/tickets.d.ts +2 -0
  104. package/dist/commands/tickets.js +43 -0
  105. package/dist/commands/update.js +2 -4
  106. package/dist/commands/usage.js +5 -3
  107. package/dist/commands/versions.js +11 -5
  108. package/dist/commands/view.js +15 -7
  109. package/dist/commands/webhook.d.ts +2 -2
  110. package/dist/commands/webhook.js +7 -7
  111. package/dist/index.d.ts +18 -2
  112. package/dist/index.js +53 -1264
  113. package/dist/lib/account-catalog.d.ts +18 -0
  114. package/dist/lib/account-catalog.js +38 -0
  115. package/dist/lib/account-provider-registry.d.ts +18 -0
  116. package/dist/lib/account-provider-registry.js +59 -0
  117. package/dist/lib/account-registry.d.ts +40 -0
  118. package/dist/lib/account-registry.js +239 -0
  119. package/dist/lib/account-schema.d.ts +44 -0
  120. package/dist/lib/account-schema.js +91 -0
  121. package/dist/lib/account-state-service.d.ts +21 -0
  122. package/dist/lib/account-state-service.js +60 -0
  123. package/dist/lib/activity.d.ts +1 -1
  124. package/dist/lib/activity.js +8 -1
  125. package/dist/lib/add-dir.d.ts +80 -0
  126. package/dist/lib/add-dir.js +241 -0
  127. package/dist/lib/agent-cli-commands.d.ts +11 -0
  128. package/dist/lib/agent-cli-commands.js +30 -0
  129. package/dist/lib/agents.js +44 -36
  130. package/dist/lib/answer-router.js +1 -1
  131. package/dist/lib/audit/log.d.ts +10 -27
  132. package/dist/lib/audit/log.js +20 -33
  133. package/dist/lib/auth-health.d.ts +9 -2
  134. package/dist/lib/auth-health.js +42 -9
  135. package/dist/lib/auto-pull-worker.js +7 -3
  136. package/dist/lib/auto-pull.d.ts +44 -3
  137. package/dist/lib/auto-pull.js +88 -5
  138. package/dist/lib/binary-shadow.d.ts +28 -0
  139. package/dist/lib/binary-shadow.js +121 -0
  140. package/dist/lib/brand.js +9 -3
  141. package/dist/lib/browser/ipc.d.ts +30 -0
  142. package/dist/lib/browser/ipc.js +81 -4
  143. package/dist/lib/browser/profiles.d.ts +3 -2
  144. package/dist/lib/browser/profiles.js +65 -22
  145. package/dist/lib/browser/service.d.ts +4 -0
  146. package/dist/lib/browser/service.js +30 -3
  147. package/dist/lib/browser/sessions-list.d.ts +22 -2
  148. package/dist/lib/browser/sessions-list.js +54 -6
  149. package/dist/lib/browser/stream.d.ts +2 -0
  150. package/dist/lib/browser/stream.js +1 -0
  151. package/dist/lib/browser/types.d.ts +19 -0
  152. package/dist/lib/byok-usage.d.ts +9 -2
  153. package/dist/lib/byok-usage.js +133 -31
  154. package/dist/lib/cli-entry.d.ts +11 -0
  155. package/dist/lib/cli-entry.js +46 -0
  156. package/dist/lib/cloud/host.d.ts +1 -1
  157. package/dist/lib/cloud/host.js +2 -2
  158. package/dist/lib/cloud/registry.js +1 -1
  159. package/dist/lib/cloud/types.d.ts +1 -1
  160. package/dist/lib/commands.d.ts +2 -0
  161. package/dist/lib/commands.js +2 -0
  162. package/dist/lib/computer/sessions-list.d.ts +150 -0
  163. package/dist/lib/computer/sessions-list.js +363 -0
  164. package/dist/lib/config-keys.d.ts +86 -0
  165. package/dist/lib/config-keys.js +193 -0
  166. package/dist/lib/config-machine-keys.d.ts +12 -0
  167. package/dist/lib/config-machine-keys.js +17 -0
  168. package/dist/lib/config-transfer.js +3 -4
  169. package/dist/lib/crabbox/cli.d.ts +2 -2
  170. package/dist/lib/crabbox/cli.js +3 -3
  171. package/dist/lib/daemon-health.d.ts +22 -0
  172. package/dist/lib/daemon-health.js +33 -3
  173. package/dist/lib/daemon-services.d.ts +50 -0
  174. package/dist/lib/daemon-services.js +147 -0
  175. package/dist/lib/daemon-ticks.d.ts +35 -66
  176. package/dist/lib/daemon-ticks.js +77 -159
  177. package/dist/lib/daemon.d.ts +72 -4
  178. package/dist/lib/daemon.js +792 -202
  179. package/dist/lib/deeplink/register.d.ts +49 -0
  180. package/dist/lib/deeplink/register.js +253 -0
  181. package/dist/lib/deeplink/url.d.ts +34 -0
  182. package/dist/lib/deeplink/url.js +78 -0
  183. package/dist/lib/device-config.d.ts +124 -29
  184. package/dist/lib/device-config.js +346 -141
  185. package/dist/lib/devices/config-migration.d.ts +42 -0
  186. package/dist/lib/devices/config-migration.js +203 -0
  187. package/dist/lib/devices/connect.js +14 -7
  188. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  189. package/dist/lib/devices/doctor-findings.js +20 -1
  190. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  191. package/dist/lib/devices/harness-inventory.js +0 -0
  192. package/dist/lib/devices/health.d.ts +1 -1
  193. package/dist/lib/devices/health.js +1 -1
  194. package/dist/lib/devices/pending.d.ts +22 -1
  195. package/dist/lib/devices/pending.js +67 -2
  196. package/dist/lib/devices/registry.d.ts +0 -25
  197. package/dist/lib/devices/registry.js +2 -83
  198. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  199. package/dist/lib/devices/resolve-profile.js +44 -0
  200. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  201. package/dist/lib/devices/rollout-verify.js +193 -0
  202. package/dist/lib/devices/ssh-config.js +10 -6
  203. package/dist/lib/event-families.d.ts +28 -0
  204. package/dist/lib/event-families.js +159 -0
  205. package/dist/lib/event-stream.d.ts +9 -1
  206. package/dist/lib/event-stream.js +26 -9
  207. package/dist/lib/events.d.ts +9 -1
  208. package/dist/lib/events.js +21 -6
  209. package/dist/lib/exec.d.ts +30 -0
  210. package/dist/lib/exec.js +219 -121
  211. package/dist/lib/feed-broadcast.d.ts +25 -0
  212. package/dist/lib/feed-broadcast.js +33 -0
  213. package/dist/lib/feed.d.ts +1 -1
  214. package/dist/lib/feed.js +12 -2
  215. package/dist/lib/fleet/capture.js +15 -0
  216. package/dist/lib/fleet/manifest.js +9 -0
  217. package/dist/lib/fleet/types.d.ts +9 -0
  218. package/dist/lib/fleet-status.js +10 -8
  219. package/dist/lib/git.d.ts +20 -6
  220. package/dist/lib/git.js +121 -17
  221. package/dist/lib/hosts/dispatch.d.ts +8 -3
  222. package/dist/lib/hosts/dispatch.js +29 -3
  223. package/dist/lib/hosts/logs.d.ts +2 -2
  224. package/dist/lib/hosts/logs.js +2 -2
  225. package/dist/lib/hosts/option.js +1 -1
  226. package/dist/lib/hosts/passthrough.d.ts +2 -3
  227. package/dist/lib/hosts/passthrough.js +10 -24
  228. package/dist/lib/hosts/progress.js +2 -2
  229. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  230. package/dist/lib/hosts/providers/devices.js +18 -12
  231. package/dist/lib/hosts/ready.d.ts +5 -1
  232. package/dist/lib/hosts/ready.js +9 -3
  233. package/dist/lib/hosts/reconcile.d.ts +2 -2
  234. package/dist/lib/hosts/reconcile.js +2 -2
  235. package/dist/lib/hosts/registry.js +14 -9
  236. package/dist/lib/hosts/remote-cmd.js +1 -1
  237. package/dist/lib/hosts/remote-os.d.ts +9 -6
  238. package/dist/lib/hosts/remote-os.js +13 -6
  239. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  240. package/dist/lib/hosts/routing-flag.js +41 -0
  241. package/dist/lib/hosts/run-target.js +1 -1
  242. package/dist/lib/hosts/session-index.js +1 -1
  243. package/dist/lib/hosts/tasks.d.ts +6 -6
  244. package/dist/lib/hosts/tasks.js +4 -4
  245. package/dist/lib/hosts/types.js +1 -2
  246. package/dist/lib/installations/resolve.js +2 -8
  247. package/dist/lib/isolation-boundary-report.js +0 -1
  248. package/dist/lib/linear-cache.d.ts +7 -0
  249. package/dist/lib/linear-cache.js +31 -4
  250. package/dist/lib/linear-project-counts.d.ts +1 -1
  251. package/dist/lib/linear-project-counts.js +2 -3
  252. package/dist/lib/linear-projects.js +1 -1
  253. package/dist/lib/loop.d.ts +2 -2
  254. package/dist/lib/loop.js +1 -1
  255. package/dist/lib/mailbox-target.d.ts +1 -1
  256. package/dist/lib/mailbox-target.js +1 -1
  257. package/dist/lib/manifest.js +7 -4
  258. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  259. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  260. package/dist/lib/menubar/snapshot.d.ts +3 -2
  261. package/dist/lib/menubar/snapshot.js +6 -2
  262. package/dist/lib/migrate-fold.d.ts +33 -0
  263. package/dist/lib/migrate-fold.js +130 -0
  264. package/dist/lib/migrate.d.ts +34 -34
  265. package/dist/lib/migrate.js +106 -128
  266. package/dist/lib/model-tier-overrides.d.ts +1 -1
  267. package/dist/lib/model-tier-overrides.js +15 -2
  268. package/dist/lib/monitors/config.d.ts +17 -3
  269. package/dist/lib/monitors/config.js +52 -18
  270. package/dist/lib/monitors/engine.d.ts +32 -1
  271. package/dist/lib/monitors/engine.js +94 -11
  272. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  273. package/dist/lib/monitors/fingerprint.js +100 -0
  274. package/dist/lib/monitors/remote.d.ts +47 -0
  275. package/dist/lib/monitors/remote.js +81 -0
  276. package/dist/lib/monitors/state.d.ts +39 -0
  277. package/dist/lib/monitors/state.js +56 -0
  278. package/dist/lib/onepassword.d.ts +17 -0
  279. package/dist/lib/onepassword.js +52 -22
  280. package/dist/lib/open-url.js +1 -1
  281. package/dist/lib/picker.d.ts +14 -2
  282. package/dist/lib/picker.js +35 -13
  283. package/dist/lib/placement.d.ts +1 -1
  284. package/dist/lib/placement.js +1 -1
  285. package/dist/lib/pr-land-detach.d.ts +32 -0
  286. package/dist/lib/pr-land-detach.js +79 -0
  287. package/dist/lib/profiles-presets.js +13 -0
  288. package/dist/lib/profiles.d.ts +2 -0
  289. package/dist/lib/profiles.js +44 -1
  290. package/dist/lib/project-focus.d.ts +1 -1
  291. package/dist/lib/project-focus.js +1 -1
  292. package/dist/lib/project-probe.d.ts +4 -1
  293. package/dist/lib/project-probe.js +5 -4
  294. package/dist/lib/project-resources.js +2 -18
  295. package/dist/lib/project-root.d.ts +16 -0
  296. package/dist/lib/project-root.js +20 -2
  297. package/dist/lib/projects.d.ts +20 -1
  298. package/dist/lib/projects.js +78 -1
  299. package/dist/lib/refresh-coordinator.d.ts +24 -0
  300. package/dist/lib/refresh-coordinator.js +52 -0
  301. package/dist/lib/registry.d.ts +2 -2
  302. package/dist/lib/registry.js +1 -1
  303. package/dist/lib/resource-aliases.d.ts +13 -0
  304. package/dist/lib/resource-aliases.js +26 -0
  305. package/dist/lib/resources/types.d.ts +1 -1
  306. package/dist/lib/resources.d.ts +16 -0
  307. package/dist/lib/resources.js +66 -10
  308. package/dist/lib/rotate.d.ts +3 -4
  309. package/dist/lib/rotate.js +4 -5
  310. package/dist/lib/routine-activation.d.ts +22 -2
  311. package/dist/lib/routine-activation.js +63 -16
  312. package/dist/lib/routine-context.d.ts +9 -2
  313. package/dist/lib/routine-context.js +21 -6
  314. package/dist/lib/routines-project.d.ts +58 -48
  315. package/dist/lib/routines-project.js +190 -159
  316. package/dist/lib/routines.d.ts +41 -6
  317. package/dist/lib/routines.js +92 -34
  318. package/dist/lib/run-defaults.d.ts +5 -0
  319. package/dist/lib/run-defaults.js +11 -1
  320. package/dist/lib/runner.d.ts +10 -8
  321. package/dist/lib/runner.js +122 -39
  322. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  323. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  324. package/dist/lib/secrets/agent.d.ts +10 -3
  325. package/dist/lib/secrets/agent.js +43 -8
  326. package/dist/lib/secrets/bundles.d.ts +1 -0
  327. package/dist/lib/secrets/bundles.js +92 -80
  328. package/dist/lib/secrets/index.js +32 -9
  329. package/dist/lib/secrets/install-helper.d.ts +4 -4
  330. package/dist/lib/secrets/install-helper.js +4 -4
  331. package/dist/lib/secrets/push.d.ts +40 -6
  332. package/dist/lib/secrets/push.js +58 -11
  333. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  334. package/dist/lib/secrets/read-backoff.js +1 -1
  335. package/dist/lib/secrets/remote.d.ts +24 -0
  336. package/dist/lib/secrets/remote.js +54 -4
  337. package/dist/lib/self-update.d.ts +108 -0
  338. package/dist/lib/self-update.js +276 -1
  339. package/dist/lib/session/active.d.ts +89 -5
  340. package/dist/lib/session/active.js +165 -10
  341. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  342. package/dist/lib/session/actor-sidecar.js +2 -1
  343. package/dist/lib/session/db.d.ts +176 -2
  344. package/dist/lib/session/db.js +484 -17
  345. package/dist/lib/session/discover.js +27 -4
  346. package/dist/lib/session/hook-sessions.js +2 -2
  347. package/dist/lib/session/host-link.d.ts +2 -2
  348. package/dist/lib/session/host-link.js +2 -2
  349. package/dist/lib/session/pid-registry.d.ts +21 -0
  350. package/dist/lib/session/pid-registry.js +57 -0
  351. package/dist/lib/session/remote-active.js +15 -1
  352. package/dist/lib/session/remote.js +2 -2
  353. package/dist/lib/session/session-cache.d.ts +14 -7
  354. package/dist/lib/session/session-cache.js +51 -9
  355. package/dist/lib/session/state.d.ts +2 -2
  356. package/dist/lib/session/state.js +1 -1
  357. package/dist/lib/session/sync/config.d.ts +10 -10
  358. package/dist/lib/session/sync/config.js +10 -10
  359. package/dist/lib/session/sync/r2.d.ts +34 -0
  360. package/dist/lib/session/sync/r2.js +123 -0
  361. package/dist/lib/session/throughput.d.ts +1 -1
  362. package/dist/lib/session/throughput.js +1 -1
  363. package/dist/lib/session/types.d.ts +23 -1
  364. package/dist/lib/session/types.js +15 -0
  365. package/dist/lib/session/viewing-in.d.ts +1 -1
  366. package/dist/lib/session/viewing-in.js +1 -1
  367. package/dist/lib/session/watch.d.ts +101 -0
  368. package/dist/lib/session/watch.js +242 -0
  369. package/dist/lib/share/config.d.ts +4 -0
  370. package/dist/lib/share/config.js +1 -0
  371. package/dist/lib/share/provision.d.ts +38 -0
  372. package/dist/lib/share/provision.js +50 -0
  373. package/dist/lib/share/publish.d.ts +40 -1
  374. package/dist/lib/share/publish.js +116 -3
  375. package/dist/lib/share/worker-template.js +71 -6
  376. package/dist/lib/shims.d.ts +17 -3
  377. package/dist/lib/shims.js +98 -26
  378. package/dist/lib/signin-badge.js +3 -2
  379. package/dist/lib/skills.js +2 -0
  380. package/dist/lib/smart-launch.d.ts +8 -8
  381. package/dist/lib/smart-launch.js +80 -59
  382. package/dist/lib/ssh-exec.d.ts +1 -1
  383. package/dist/lib/ssh-exec.js +1 -1
  384. package/dist/lib/staleness/prune.d.ts +88 -0
  385. package/dist/lib/staleness/prune.js +69 -0
  386. package/dist/lib/staleness/registry.d.ts +1 -1
  387. package/dist/lib/staleness/writers/commands.js +34 -2
  388. package/dist/lib/staleness/writers/hooks.js +16 -0
  389. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  390. package/dist/lib/staleness/writers/skills.js +19 -0
  391. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  392. package/dist/lib/staleness/writers/subagents.js +0 -4
  393. package/dist/lib/staleness/writers/types.d.ts +32 -0
  394. package/dist/lib/startup/command-registry.d.ts +6 -12
  395. package/dist/lib/startup/command-registry.js +11 -31
  396. package/dist/lib/startup/dev-build.d.ts +10 -0
  397. package/dist/lib/startup/dev-build.js +13 -1
  398. package/dist/lib/startup/spellcheck.d.ts +18 -0
  399. package/dist/lib/startup/spellcheck.js +45 -0
  400. package/dist/lib/state.d.ts +36 -9
  401. package/dist/lib/state.js +96 -46
  402. package/dist/lib/subagents-registry.d.ts +0 -7
  403. package/dist/lib/subagents-registry.js +38 -65
  404. package/dist/lib/subagents.d.ts +0 -33
  405. package/dist/lib/subagents.js +0 -75
  406. package/dist/lib/sync-umbrella.js +1 -1
  407. package/dist/lib/teams/agents.d.ts +41 -1
  408. package/dist/lib/teams/agents.js +187 -9
  409. package/dist/lib/teams/api.d.ts +11 -1
  410. package/dist/lib/teams/api.js +11 -2
  411. package/dist/lib/teams/delivery.d.ts +41 -0
  412. package/dist/lib/teams/delivery.js +60 -0
  413. package/dist/lib/teams/registry.d.ts +14 -0
  414. package/dist/lib/teams/registry.js +51 -1
  415. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  416. package/dist/lib/teams/remoteWorktree.js +29 -0
  417. package/dist/lib/teams/scheduler.d.ts +1 -1
  418. package/dist/lib/teams/scheduler.js +1 -1
  419. package/dist/lib/teams/worktree.d.ts +24 -0
  420. package/dist/lib/teams/worktree.js +42 -0
  421. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  422. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  423. package/dist/lib/terminal/engine.d.ts +4 -0
  424. package/dist/lib/terminal/engine.js +8 -2
  425. package/dist/lib/terminal/types.d.ts +21 -2
  426. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  427. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  428. package/dist/lib/tickets/list.d.ts +53 -0
  429. package/dist/lib/tickets/list.js +153 -0
  430. package/dist/lib/tmux/orphan-reap.d.ts +320 -0
  431. package/dist/lib/tmux/orphan-reap.js +644 -0
  432. package/dist/lib/tmux/session.d.ts +68 -3
  433. package/dist/lib/tmux/session.js +95 -5
  434. package/dist/lib/triggers/handlers.d.ts +20 -0
  435. package/dist/lib/triggers/handlers.js +6 -1
  436. package/dist/lib/types.d.ts +46 -34
  437. package/dist/lib/usage-fleet.d.ts +32 -0
  438. package/dist/lib/usage-fleet.js +125 -0
  439. package/dist/lib/usage-refresh.d.ts +3 -3
  440. package/dist/lib/usage-refresh.js +19 -16
  441. package/dist/lib/usage.d.ts +51 -47
  442. package/dist/lib/usage.js +145 -153
  443. package/dist/lib/version-duplicates.js +2 -2
  444. package/dist/lib/versions.d.ts +56 -13
  445. package/dist/lib/versions.js +195 -45
  446. package/dist/lib/watchdog/log.d.ts +1 -1
  447. package/dist/lib/watchdog/log.js +3 -3
  448. package/dist/lib/watchdog/rotate.d.ts +6 -6
  449. package/dist/lib/watchdog/rotate.js +6 -6
  450. package/dist/lib/workflows.d.ts +1 -1
  451. package/dist/lib/yaml-io.d.ts +47 -0
  452. package/dist/lib/yaml-io.js +55 -0
  453. package/package.json +2 -1
  454. package/scripts/install-helper.js +2 -2
  455. package/scripts/postinstall.js +23 -20
  456. package/dist/commands/defaults.d.ts +0 -7
  457. package/dist/commands/defaults.js +0 -107
  458. package/dist/commands/export.d.ts +0 -11
  459. package/dist/commands/export.js +0 -215
  460. package/dist/commands/helper.d.ts +0 -12
  461. package/dist/commands/helper.js +0 -87
  462. package/dist/commands/hosts.d.ts +0 -11
  463. package/dist/commands/hosts.js +0 -330
  464. package/dist/commands/lock.d.ts +0 -12
  465. package/dist/commands/lock.js +0 -70
  466. package/dist/commands/pull.d.ts +0 -17
  467. package/dist/commands/pull.js +0 -39
  468. package/dist/commands/push.d.ts +0 -14
  469. package/dist/commands/push.js +0 -30
  470. package/dist/commands/wallet.d.ts +0 -20
  471. package/dist/commands/wallet.js +0 -216
  472. package/dist/commands/worktree.d.ts +0 -19
  473. package/dist/commands/worktree.js +0 -272
  474. package/dist/lib/account-labels.d.ts +0 -24
  475. package/dist/lib/account-labels.js +0 -72
  476. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  477. package/dist/lib/auto-dispatch-linear.js +0 -107
  478. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  479. package/dist/lib/auto-dispatch-provider.js +0 -30
  480. package/dist/lib/auto-dispatch.d.ts +0 -93
  481. package/dist/lib/auto-dispatch.js +0 -128
  482. package/dist/lib/export.d.ts +0 -72
  483. package/dist/lib/export.js +0 -269
  484. package/dist/lib/lock.d.ts +0 -93
  485. package/dist/lib/lock.js +0 -207
  486. package/dist/lib/wallet/index.d.ts +0 -78
  487. package/dist/lib/wallet/index.js +0 -253
@@ -1,47 +1,24 @@
1
1
  /**
2
- * Project-level routine opt-in, source tracking, and user-layer sync.
2
+ * Project routine discovery, source tracking, and user-layer sync.
3
3
  *
4
- * Project YAML under `<project>/.agents/routines/*.yml` is inspection-only by
5
- * default (a cloned public repo must never auto-fire agent prompts). After an
6
- * explicit opt-in, routines are materialised into `~/.agents/routines/` with
7
- * `source:` provenance so the daemon which only loads user + system layers —
8
- * can fire them. `syncProjectRoutines` refreshes the user-layer copies when
9
- * project YAML changes (also invoked on daemon SIGHUP).
4
+ * Project YAML under `<project>/.agents/routines/*.yml` never fires on its own
5
+ * (a cloned repo must not auto-run agent prompts). A routine has exactly one
6
+ * state enabled or disabled owned by this device's `meta.deviceRoutines`
7
+ * list, never by the project YAML's own `enabled:` field. `agents routines
8
+ * enable <name>` materialises the routine into `~/.agents/routines/` with
9
+ * `source:` provenance (so the daemon, which loads only user + system layers,
10
+ * can see it) and flips the device flag on — one action. `discoverProjectRoutines`
11
+ * surfaces not-yet-materialised routines from the user's registered projects so
12
+ * `list` shows them as disabled. `syncProjectRoutines` refreshes materialised
13
+ * copies from their source YAML (also invoked on daemon SIGHUP).
10
14
  */
11
- import { type JobSource } from './routines.js';
15
+ import { type JobConfig, type JobSource } from './routines.js';
12
16
  /** Expand `~/…` and resolve to an absolute path. */
13
17
  export declare function expandProjectPath(p: string): string;
14
18
  /** Store paths home-relative when under $HOME so they travel across machines. */
15
19
  export declare function displayProjectPath(abs: string): string;
16
- /** Project roots currently opted into daemon firing (absolute paths). */
17
- export declare function listEnabledProjectRoots(): string[];
18
- /** True when this project root is on the opt-in allowlist. */
19
- export declare function isProjectRoutinesEnabled(projectRoot: string): boolean;
20
- /**
21
- * True when the project's own `agents.yaml` opts into project routines:
22
- * `routines: { enable: true }`. This is an additional source of opt-in that
23
- * still requires the project to be present on disk; it does not auto-enable
24
- * every clone — the project must declare it, and `sync` / `enable-project`
25
- * still materialises consent into the user layer.
26
- */
27
- export declare function projectAgentsYamlEnablesRoutines(projectRoot: string): boolean;
28
20
  /** Resolve the project root (parent of `.agents/`) from a cwd, or null. */
29
21
  export declare function resolveProjectRoot(cwd?: string): string | null;
30
- /**
31
- * Opt a project root into daemon firing. Returns true when newly added,
32
- * false when it was already enabled.
33
- */
34
- export declare function enableProjectRoutines(projectRoot: string): boolean;
35
- /**
36
- * Remove a project root from the opt-in allowlist. Optionally deletes the
37
- * user-layer copies that were materialised from it.
38
- */
39
- export declare function disableProjectRoutines(projectRoot: string, opts?: {
40
- removeSynced?: boolean;
41
- }): {
42
- removed: boolean;
43
- deletedJobs: string[];
44
- };
45
22
  /** Git provenance for a project root (best-effort; never throws). */
46
23
  export declare function readProjectGitSource(projectRoot: string): Pick<JobSource, 'repo' | 'branch' | 'commit'>;
47
24
  /** List project routine YAML files (name + absolute path). */
@@ -63,11 +40,15 @@ export interface SyncProjectResult {
63
40
  }>;
64
41
  }
65
42
  /**
66
- * Materialise one project's routines into the user layer.
43
+ * Refresh one project's already-materialised routines from its source YAML.
67
44
  * - Overwrites user copies that already carry matching `source.projectPath`
68
45
  * - Never clobbers a hand-authored user routine (no source / different source)
69
46
  * - Removes user copies from this project whose YAML disappeared
70
- * - Activates materialized routines on this device without mutating definitions
47
+ *
48
+ * Sync NEVER touches the device enable flag: a routine's enabled/disabled state
49
+ * is owned solely by `meta.deviceRoutines` (via `agents routines enable/disable`),
50
+ * never by the project YAML's own `enabled:` field. That is what keeps a cloned
51
+ * repo from auto-firing — refreshing a definition can never turn it on.
71
52
  */
72
53
  export declare function syncProjectRoutines(projectRoot: string): SyncProjectResult;
73
54
  export interface SyncAllResult {
@@ -75,23 +56,52 @@ export interface SyncAllResult {
75
56
  /** Project roots that were listed but missing on disk. */
76
57
  missing: string[];
77
58
  }
59
+ /** Distinct project roots that already have at least one materialised routine. */
60
+ export declare function materialisedProjectRoots(): string[];
78
61
  /**
79
- * Sync every project root on the user allowlist (`meta.routines.projects`),
80
- * plus any explicit `extraRoots`. Project `agents.yaml` `routines.enable`
81
- * alone never opts a path in enable-project is required.
62
+ * Refresh every materialised project routine from its source YAML. The set of
63
+ * roots is derived from what the user has already enabled/materialised (their
64
+ * `source.projectPath`), not from any allowlistenabling a routine is the only
65
+ * thing that brings its project into the refresh set. Also runs on daemon SIGHUP.
82
66
  */
83
67
  export declare function syncAllProjectRoutines(opts?: {
84
68
  extraRoots?: string[];
85
69
  }): SyncAllResult;
70
+ /** A project routine available to enable, not yet materialised on this device. */
71
+ export interface DiscoveredProjectRoutine {
72
+ name: string;
73
+ projectRoot: string;
74
+ file: string;
75
+ /** Display config for `list` (always disabled — enablement is a local act). */
76
+ config: JobConfig;
77
+ }
86
78
  /**
87
- * Discover project routines at cwd for the setup UX. Returns null when no
88
- * project `.agents/routines` dir exists.
79
+ * Project routines from registered projects that are NOT already materialised
80
+ * in the user layer. These surface in `agents routines list` as disabled rows so
81
+ * the single enabled/disabled model is visible, and `enable <name>` resolves a
82
+ * name against them. A routine whose name already exists as a user/system
83
+ * routine is omitted (that materialised copy is the live one).
89
84
  */
90
- export declare function discoverProjectRoutinesAt(cwd?: string): {
85
+ export declare function discoverProjectRoutines(): DiscoveredProjectRoutine[];
86
+ /**
87
+ * Resolve a routine name to a project source for `enable <name>`: first the cwd
88
+ * project, then registered projects. Returns null when the name matches no
89
+ * project routine, or throws-by-return when it is ambiguous across projects.
90
+ */
91
+ export declare function findProjectRoutine(name: string, cwd?: string): {
91
92
  projectRoot: string;
92
- files: Array<{
93
- name: string;
94
- path: string;
95
- }>;
96
- enabled: boolean;
93
+ file: string;
94
+ } | {
95
+ ambiguous: string[];
97
96
  } | null;
97
+ /**
98
+ * Materialise one project routine into the user layer WITHOUT enabling it. The
99
+ * caller (`agents routines enable`) flips the device flag separately, so a
100
+ * materialise can never by itself make a routine fire. Returns the written
101
+ * config, or an error string.
102
+ */
103
+ export declare function materialiseProjectRoutine(projectRoot: string, name: string): {
104
+ job: JobConfig;
105
+ } | {
106
+ error: string;
107
+ };
@@ -1,21 +1,26 @@
1
1
  /**
2
- * Project-level routine opt-in, source tracking, and user-layer sync.
2
+ * Project routine discovery, source tracking, and user-layer sync.
3
3
  *
4
- * Project YAML under `<project>/.agents/routines/*.yml` is inspection-only by
5
- * default (a cloned public repo must never auto-fire agent prompts). After an
6
- * explicit opt-in, routines are materialised into `~/.agents/routines/` with
7
- * `source:` provenance so the daemon which only loads user + system layers —
8
- * can fire them. `syncProjectRoutines` refreshes the user-layer copies when
9
- * project YAML changes (also invoked on daemon SIGHUP).
4
+ * Project YAML under `<project>/.agents/routines/*.yml` never fires on its own
5
+ * (a cloned repo must not auto-run agent prompts). A routine has exactly one
6
+ * state enabled or disabled owned by this device's `meta.deviceRoutines`
7
+ * list, never by the project YAML's own `enabled:` field. `agents routines
8
+ * enable <name>` materialises the routine into `~/.agents/routines/` with
9
+ * `source:` provenance (so the daemon, which loads only user + system layers,
10
+ * can see it) and flips the device flag on — one action. `discoverProjectRoutines`
11
+ * surfaces not-yet-materialised routines from the user's registered projects so
12
+ * `list` shows them as disabled. `syncProjectRoutines` refreshes materialised
13
+ * copies from their source YAML (also invoked on daemon SIGHUP).
10
14
  */
11
15
  import * as fs from 'fs';
12
16
  import * as os from 'os';
13
17
  import * as path from 'path';
14
18
  import * as yaml from 'yaml';
15
19
  import { execFileSync } from 'child_process';
16
- import { getProjectAgentsDir, getProjectRoutinesDir, readMeta, updateMeta, ensureAgentsDir, } from './state.js';
17
- import { readJob, writeJob, setJobEnabled, deleteJob, listJobs, validateJob, } from './routines.js';
20
+ import { getProjectAgentsDir, getProjectRoutinesDir, ensureAgentsDir, } from './state.js';
21
+ import { readJob, writeJob, deleteJob, listJobs, validateJob, } from './routines.js';
18
22
  import { parseOwnerRepoFromRemote } from './registry.js';
23
+ import { listProjectDefs, projectDirsAbs } from './projects.js';
19
24
  import { isSafeSegmentName } from './paths.js';
20
25
  /** Expand `~/…` and resolve to an absolute path. */
21
26
  export function expandProjectPath(p) {
@@ -36,52 +41,6 @@ export function displayProjectPath(abs) {
36
41
  }
37
42
  return resolved;
38
43
  }
39
- /** Project roots currently opted into daemon firing (absolute paths). */
40
- export function listEnabledProjectRoots() {
41
- const meta = readMeta();
42
- const raw = meta.routines?.projects ?? [];
43
- const out = [];
44
- const seen = new Set();
45
- for (const p of raw) {
46
- if (typeof p !== 'string' || p.trim() === '')
47
- continue;
48
- const abs = expandProjectPath(p);
49
- if (seen.has(abs))
50
- continue;
51
- seen.add(abs);
52
- out.push(abs);
53
- }
54
- return out;
55
- }
56
- /** True when this project root is on the opt-in allowlist. */
57
- export function isProjectRoutinesEnabled(projectRoot) {
58
- const abs = expandProjectPath(projectRoot);
59
- return listEnabledProjectRoots().some((p) => p === abs);
60
- }
61
- /**
62
- * True when the project's own `agents.yaml` opts into project routines:
63
- * `routines: { enable: true }`. This is an additional source of opt-in that
64
- * still requires the project to be present on disk; it does not auto-enable
65
- * every clone — the project must declare it, and `sync` / `enable-project`
66
- * still materialises consent into the user layer.
67
- */
68
- export function projectAgentsYamlEnablesRoutines(projectRoot) {
69
- const agentsYaml = path.join(expandProjectPath(projectRoot), 'agents.yaml');
70
- if (!fs.existsSync(agentsYaml))
71
- return false;
72
- try {
73
- const parsed = yaml.parse(fs.readFileSync(agentsYaml, 'utf-8'));
74
- if (!parsed || typeof parsed !== 'object')
75
- return false;
76
- const routines = parsed.routines;
77
- if (!routines || typeof routines !== 'object')
78
- return false;
79
- return routines.enable === true;
80
- }
81
- catch {
82
- return false;
83
- }
84
- }
85
44
  /** Resolve the project root (parent of `.agents/`) from a cwd, or null. */
86
45
  export function resolveProjectRoot(cwd = process.cwd()) {
87
46
  const agentsDir = getProjectAgentsDir(cwd);
@@ -89,63 +48,6 @@ export function resolveProjectRoot(cwd = process.cwd()) {
89
48
  return null;
90
49
  return path.dirname(agentsDir);
91
50
  }
92
- /**
93
- * Opt a project root into daemon firing. Returns true when newly added,
94
- * false when it was already enabled.
95
- */
96
- export function enableProjectRoutines(projectRoot) {
97
- const abs = expandProjectPath(projectRoot);
98
- const stored = displayProjectPath(abs);
99
- let added = false;
100
- updateMeta((meta) => {
101
- const projects = [...(meta.routines?.projects ?? [])];
102
- const already = projects.some((p) => expandProjectPath(p) === abs);
103
- if (already)
104
- return meta;
105
- projects.push(stored);
106
- added = true;
107
- return {
108
- ...meta,
109
- routines: {
110
- ...(meta.routines ?? {}),
111
- projects,
112
- },
113
- };
114
- });
115
- return added;
116
- }
117
- /**
118
- * Remove a project root from the opt-in allowlist. Optionally deletes the
119
- * user-layer copies that were materialised from it.
120
- */
121
- export function disableProjectRoutines(projectRoot, opts = {}) {
122
- const abs = expandProjectPath(projectRoot);
123
- let removed = false;
124
- updateMeta((meta) => {
125
- const projects = meta.routines?.projects ?? [];
126
- const next = projects.filter((p) => expandProjectPath(p) !== abs);
127
- if (next.length === projects.length)
128
- return meta;
129
- removed = true;
130
- return {
131
- ...meta,
132
- routines: {
133
- ...(meta.routines ?? {}),
134
- projects: next,
135
- },
136
- };
137
- });
138
- const deletedJobs = [];
139
- if (opts.removeSynced) {
140
- for (const job of listJobs()) {
141
- if (job.source?.kind === 'project' && expandProjectPath(job.source.projectPath) === abs) {
142
- if (deleteJob(job.name))
143
- deletedJobs.push(job.name);
144
- }
145
- }
146
- }
147
- return { removed, deletedJobs };
148
- }
149
51
  /** Git provenance for a project root (best-effort; never throws). */
150
52
  export function readProjectGitSource(projectRoot) {
151
53
  const abs = expandProjectPath(projectRoot);
@@ -216,11 +118,15 @@ function readProjectJobFile(filePath) {
216
118
  }
217
119
  }
218
120
  /**
219
- * Materialise one project's routines into the user layer.
121
+ * Refresh one project's already-materialised routines from its source YAML.
220
122
  * - Overwrites user copies that already carry matching `source.projectPath`
221
123
  * - Never clobbers a hand-authored user routine (no source / different source)
222
124
  * - Removes user copies from this project whose YAML disappeared
223
- * - Activates materialized routines on this device without mutating definitions
125
+ *
126
+ * Sync NEVER touches the device enable flag: a routine's enabled/disabled state
127
+ * is owned solely by `meta.deviceRoutines` (via `agents routines enable/disable`),
128
+ * never by the project YAML's own `enabled:` field. That is what keeps a cloned
129
+ * repo from auto-firing — refreshing a definition can never turn it on.
224
130
  */
225
131
  export function syncProjectRoutines(projectRoot) {
226
132
  ensureAgentsDir();
@@ -244,37 +150,41 @@ export function syncProjectRoutines(projectRoot) {
244
150
  const seenNames = new Set();
245
151
  for (const file of files) {
246
152
  seenNames.add(file.name);
153
+ // Refresh only routines the user already materialised from THIS project.
154
+ // A project file with no existing user-layer copy is "available, not
155
+ // enabled" — it surfaces via `discoverProjectRoutines` and is materialised
156
+ // by `agents routines enable <name>`, never auto-pulled by a refresh.
157
+ const existing = readJob(file.name);
158
+ if (!existing)
159
+ continue;
160
+ const existingSource = existing.source;
161
+ const fromThisProject = existingSource?.kind === 'project'
162
+ && expandProjectPath(existingSource.projectPath) === abs;
163
+ if (!fromThisProject) {
164
+ result.skipped.push({
165
+ name: file.name,
166
+ reason: existingSource
167
+ ? `user-layer routine already exists from another source (${existingSource.projectPath})`
168
+ : 'user-layer routine already exists (hand-authored); not overwriting without source match',
169
+ });
170
+ continue;
171
+ }
247
172
  const job = readProjectJobFile(file.path);
248
173
  if (!job) {
249
174
  result.errors.push({ name: file.name, error: 'unreadable or invalid YAML' });
250
175
  continue;
251
176
  }
252
- const existing = readJob(file.name);
253
- if (existing) {
254
- const existingSource = existing.source;
255
- const fromThisProject = existingSource?.kind === 'project'
256
- && expandProjectPath(existingSource.projectPath) === abs;
257
- if (!fromThisProject) {
258
- result.skipped.push({
259
- name: file.name,
260
- reason: existingSource
261
- ? `user-layer routine already exists from another source (${existingSource.projectPath})`
262
- : 'user-layer routine already exists (hand-authored); not overwriting without source match',
263
- });
264
- continue;
265
- }
266
- // Preserve user-layer devices pin when project YAML omits it (same overlay
267
- // semantics as listJobs project discovery).
268
- if (job.devices === undefined && existing.devices && existing.devices.length > 0) {
269
- job.devices = existing.devices;
270
- }
271
- // Carry the original creation stamp across. A sync rebuilds the config
272
- // from the PROJECT yaml, which never carries `createdAt`, so without this
273
- // every `agents routines sync` would re-stamp it to now — walking the
274
- // overdue floor forward and hiding real missed fires for project routines.
275
- if (existing.createdAt)
276
- job.createdAt = existing.createdAt;
177
+ // Preserve user-layer devices pin when project YAML omits it (same overlay
178
+ // semantics as listJobs project discovery).
179
+ if (job.devices === undefined && existing.devices && existing.devices.length > 0) {
180
+ job.devices = existing.devices;
277
181
  }
182
+ // Carry the original creation stamp across. A sync rebuilds the config
183
+ // from the PROJECT yaml, which never carries `createdAt`, so without this
184
+ // every `agents routines sync` would re-stamp it to now — walking the
185
+ // overdue floor forward and hiding real missed fires for project routines.
186
+ if (existing.createdAt)
187
+ job.createdAt = existing.createdAt;
278
188
  // Surface repo for list/display when project has a GitHub origin.
279
189
  if (git.repo && !job.repo)
280
190
  job.repo = git.repo;
@@ -286,8 +196,9 @@ export function syncProjectRoutines(projectRoot) {
286
196
  continue;
287
197
  }
288
198
  try {
199
+ // Refresh the definition only. Enablement lives in meta.deviceRoutines and
200
+ // is never derived from the project YAML here.
289
201
  writeJob(job);
290
- setJobEnabled(job.name, job.enabled);
291
202
  result.synced.push(file.name);
292
203
  }
293
204
  catch (err) {
@@ -307,13 +218,23 @@ export function syncProjectRoutines(projectRoot) {
307
218
  }
308
219
  return result;
309
220
  }
221
+ /** Distinct project roots that already have at least one materialised routine. */
222
+ export function materialisedProjectRoots() {
223
+ const roots = new Set();
224
+ for (const job of listJobs()) {
225
+ if (job.source?.kind === 'project')
226
+ roots.add(expandProjectPath(job.source.projectPath));
227
+ }
228
+ return [...roots];
229
+ }
310
230
  /**
311
- * Sync every project root on the user allowlist (`meta.routines.projects`),
312
- * plus any explicit `extraRoots`. Project `agents.yaml` `routines.enable`
313
- * alone never opts a path in enable-project is required.
231
+ * Refresh every materialised project routine from its source YAML. The set of
232
+ * roots is derived from what the user has already enabled/materialised (their
233
+ * `source.projectPath`), not from any allowlistenabling a routine is the only
234
+ * thing that brings its project into the refresh set. Also runs on daemon SIGHUP.
314
235
  */
315
236
  export function syncAllProjectRoutines(opts = {}) {
316
- const roots = new Set(listEnabledProjectRoots());
237
+ const roots = new Set(materialisedProjectRoots());
317
238
  for (const r of opts.extraRoots ?? [])
318
239
  roots.add(expandProjectPath(r));
319
240
  const projects = [];
@@ -328,22 +249,132 @@ export function syncAllProjectRoutines(opts = {}) {
328
249
  return { projects, missing };
329
250
  }
330
251
  /**
331
- * Discover project routines at cwd for the setup UX. Returns null when no
332
- * project `.agents/routines` dir exists.
252
+ * Absolute local checkout roots for every registered project, deduped. This is
253
+ * the discovery universe for project routines: bounded to projects the user
254
+ * registered (`agents projects`), never an arbitrary filesystem scan.
333
255
  */
334
- export function discoverProjectRoutinesAt(cwd = process.cwd()) {
335
- const projectRoot = resolveProjectRoot(cwd);
336
- if (!projectRoot)
337
- return null;
338
- const routinesDir = getProjectRoutinesDir(projectRoot);
339
- if (!routinesDir || !fs.existsSync(routinesDir))
340
- return null;
341
- const files = listProjectRoutineFiles(projectRoot);
342
- if (files.length === 0)
256
+ function registeredProjectRoots() {
257
+ const roots = new Set();
258
+ for (const def of listProjectDefs()) {
259
+ for (const dir of projectDirsAbs(def, { forRemote: false })) {
260
+ if (dir)
261
+ roots.add(path.resolve(dir));
262
+ }
263
+ }
264
+ return [...roots];
265
+ }
266
+ /**
267
+ * Project routines from registered projects that are NOT already materialised
268
+ * in the user layer. These surface in `agents routines list` as disabled rows so
269
+ * the single enabled/disabled model is visible, and `enable <name>` resolves a
270
+ * name against them. A routine whose name already exists as a user/system
271
+ * routine is omitted (that materialised copy is the live one).
272
+ */
273
+ export function discoverProjectRoutines() {
274
+ const materialisedNames = new Set(listJobs().map((j) => j.name));
275
+ const out = [];
276
+ const seen = new Set();
277
+ for (const root of registeredProjectRoots()) {
278
+ const files = listProjectRoutineFiles(root).filter((f) => !materialisedNames.has(f.name) && !seen.has(f.name));
279
+ if (files.length === 0)
280
+ continue;
281
+ const git = readProjectGitSource(root); // once per root, not per routine
282
+ for (const file of files) {
283
+ const job = readProjectJobFile(file.path);
284
+ if (!job)
285
+ continue;
286
+ seen.add(file.name);
287
+ job.name = file.name;
288
+ job.source = {
289
+ kind: 'project',
290
+ projectPath: expandProjectPath(root),
291
+ ...(git.repo ? { repo: git.repo } : {}),
292
+ ...(git.branch ? { branch: git.branch } : {}),
293
+ ...(git.commit ? { commit: git.commit } : {}),
294
+ };
295
+ if (git.repo && !job.repo)
296
+ job.repo = git.repo;
297
+ job.enabled = false; // available, not enabled — never inferred from the repo YAML
298
+ out.push({ name: file.name, projectRoot: expandProjectPath(root), file: file.path, config: job });
299
+ }
300
+ }
301
+ return out;
302
+ }
303
+ /**
304
+ * Resolve a routine name to a project source for `enable <name>`: first the cwd
305
+ * project, then registered projects. Returns null when the name matches no
306
+ * project routine, or throws-by-return when it is ambiguous across projects.
307
+ */
308
+ export function findProjectRoutine(name, cwd = process.cwd()) {
309
+ const cwdRoot = resolveProjectRoot(cwd);
310
+ if (cwdRoot) {
311
+ const match = listProjectRoutineFiles(cwdRoot).find((f) => f.name === name);
312
+ if (match)
313
+ return { projectRoot: expandProjectPath(cwdRoot), file: match.path };
314
+ }
315
+ const hits = [];
316
+ const seenRoots = new Set();
317
+ for (const root of registeredProjectRoots()) {
318
+ const abs = expandProjectPath(root);
319
+ if (seenRoots.has(abs))
320
+ continue;
321
+ seenRoots.add(abs);
322
+ const match = listProjectRoutineFiles(abs).find((f) => f.name === name);
323
+ if (match)
324
+ hits.push({ projectRoot: abs, file: match.path });
325
+ }
326
+ if (hits.length === 0)
343
327
  return null;
344
- return {
345
- projectRoot,
346
- files,
347
- enabled: isProjectRoutinesEnabled(projectRoot) || projectAgentsYamlEnablesRoutines(projectRoot),
328
+ if (hits.length > 1)
329
+ return { ambiguous: hits.map((h) => displayProjectPath(h.projectRoot)) };
330
+ return hits[0];
331
+ }
332
+ /**
333
+ * Materialise one project routine into the user layer WITHOUT enabling it. The
334
+ * caller (`agents routines enable`) flips the device flag separately, so a
335
+ * materialise can never by itself make a routine fire. Returns the written
336
+ * config, or an error string.
337
+ */
338
+ export function materialiseProjectRoutine(projectRoot, name) {
339
+ ensureAgentsDir();
340
+ const abs = expandProjectPath(projectRoot);
341
+ const match = listProjectRoutineFiles(abs).find((f) => f.name === name);
342
+ if (!match)
343
+ return { error: `no routine '${name}' under ${displayProjectPath(abs)}/.agents/routines` };
344
+ const job = readProjectJobFile(match.path);
345
+ if (!job)
346
+ return { error: `routine '${name}' is unreadable or invalid YAML` };
347
+ const existing = readJob(name);
348
+ if (existing) {
349
+ const src = existing.source;
350
+ const fromThisProject = src?.kind === 'project' && expandProjectPath(src.projectPath) === abs;
351
+ if (!fromThisProject) {
352
+ return {
353
+ error: src
354
+ ? `a routine named '${name}' already exists from another source (${src.projectPath})`
355
+ : `a hand-authored routine named '${name}' already exists; rename one before enabling`,
356
+ };
357
+ }
358
+ if (existing.createdAt)
359
+ job.createdAt = existing.createdAt;
360
+ if (job.devices === undefined && existing.devices && existing.devices.length > 0) {
361
+ job.devices = existing.devices;
362
+ }
363
+ }
364
+ const git = readProjectGitSource(abs);
365
+ job.name = name;
366
+ job.source = {
367
+ kind: 'project',
368
+ projectPath: abs,
369
+ ...(git.repo ? { repo: git.repo } : {}),
370
+ ...(git.branch ? { branch: git.branch } : {}),
371
+ ...(git.commit ? { commit: git.commit } : {}),
348
372
  };
373
+ if (git.repo && !job.repo)
374
+ job.repo = git.repo;
375
+ const errors = validateJob(job);
376
+ if (errors.length > 0)
377
+ return { error: errors.join('; ') };
378
+ writeJob(job);
379
+ return { job };
349
380
  }
@@ -543,15 +543,14 @@ export declare function checkJobDeviceEligibility(config: Pick<JobConfig, 'name'
543
543
  /**
544
544
  * List all job configs, scanning project > user > system routine dirs.
545
545
  * Higher layers shadow lower ones of the same name (first-seen wins): a project
546
- * routine shadows a user routine, and a user routine shadows a built-in system
547
- * routine (`~/.agents/.system/routines/`, shipped via gh:phnx-labs/.agents-system).
546
+ * routine shadows a user routine, and a user routine shadows a system routine
547
+ * (`~/.agents/.system/routines/`, shipped via gh:phnx-labs/.agents-system).
548
548
  * When a same-name project routine wins for inspection, the user-layer
549
549
  * `devices` allowlist is overlaid only if the project routine does not declare
550
550
  * its own allowlist, so CWD project discovery cannot hide an operational fleet
551
551
  * pin or erase a project-authored one.
552
552
  * Project discovery is opt-in via `cwd`; the daemon (which calls `listJobs()`
553
- * with no argument) sees user + system routines, so a built-in routine fires for
554
- * every install unless the user overrides or disables it by name.
553
+ * with no argument) sees user + system routines.
555
554
  */
556
555
  export declare function listJobs(cwd?: string): JobConfig[];
557
556
  /**
@@ -560,10 +559,29 @@ export declare function listJobs(cwd?: string): JobConfig[];
560
559
  * the project routine does not declare its own allowlist, for the same reason
561
560
  * as listJobs().
562
561
  * Project discovery is opt-in via `cwd`; daemon callers pass no argument and
563
- * resolve user + system routines (a user routine of the same name shadows a
564
- * built-in system routine).
562
+ * resolve user + system routines.
565
563
  */
566
564
  export declare function readJob(name: string, cwd?: string): JobConfig | null;
565
+ /**
566
+ * The outcome of reading one routine file: a config, or the reason it is inert.
567
+ * Every `problem` here means the daemon will not run the routine.
568
+ */
569
+ export type RoutineReadResult = {
570
+ config: JobConfig;
571
+ problem: null;
572
+ } | {
573
+ config: null;
574
+ problem: string;
575
+ };
576
+ /**
577
+ * Read one routine file, preserving WHY it failed.
578
+ *
579
+ * `readJobFile` collapses all four fail-closed paths to `null`, which is right
580
+ * for the loaders (an inert routine must not run) but leaves a broken routine
581
+ * invisible in every view — the one routine an operator most needs to see. Same
582
+ * reading, reason kept, for diagnostic surfaces like `agents inspect --routines`.
583
+ */
584
+ export declare function readJobFileResult(filePath: string): RoutineReadResult;
567
585
  /** Write a job config to disk, omitting fields that match defaults.
568
586
  *
569
587
  * Updates the one existing supported extension (.yml or .yaml) atomically.
@@ -732,6 +750,23 @@ export declare function discoverJobsFromRepo(repoPath: string): Array<{
732
750
  }>;
733
751
  /** Check whether a job with the given name exists on disk. */
734
752
  export declare function jobExists(name: string): boolean;
753
+ /**
754
+ * True when `sourcePath` already IS the canonical user-layer file for `name`.
755
+ *
756
+ * `agents routines add <file>` copies a definition into the routines dir, but
757
+ * users routinely point it at the file that already lives there — the release
758
+ * train's own `~/.agents/routines/release-train.yml`. `writeJob` would then
759
+ * re-serialize that file in place and, per {@link serializeJob}, delete every
760
+ * key absent from the canonical output — silently dropping the legacy
761
+ * `devices:` pin from config tracked in the git-backed `~/.agents` repo
762
+ * (RUSH-2517). Callers use this to skip the write when there is nothing to
763
+ * copy.
764
+ *
765
+ * Compares real paths so a symlinked `~/.agents` (the normal layout) still
766
+ * matches, and falls back to a resolved-path compare when either side cannot be
767
+ * realpath'd.
768
+ */
769
+ export declare function isCanonicalRoutineSource(sourcePath: string, name: string): boolean;
735
770
  /** Get the filesystem path of a job's YAML config file, or null if not found. */
736
771
  export declare function getJobPath(name: string): string | null;
737
772
  /**