@phnx-labs/agents-cli 1.22.35 → 1.22.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/CHANGELOG.md +708 -2
  2. package/README.md +83 -43
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.d.ts +15 -0
  5. package/dist/bootstrap.js +1212 -0
  6. package/dist/commands/accounts.d.ts +4 -11
  7. package/dist/commands/accounts.js +159 -27
  8. package/dist/commands/artifacts-setup.d.ts +53 -0
  9. package/dist/commands/artifacts-setup.js +161 -0
  10. package/dist/commands/artifacts.d.ts +18 -0
  11. package/dist/commands/artifacts.js +58 -0
  12. package/dist/commands/attach.js +17 -4
  13. package/dist/commands/audit.d.ts +8 -8
  14. package/dist/commands/audit.js +57 -47
  15. package/dist/commands/browser.js +17 -11
  16. package/dist/commands/cloud.js +1 -1
  17. package/dist/commands/commands.js +0 -11
  18. package/dist/commands/computer-actions.js +33 -0
  19. package/dist/commands/computer-sessions-picker.d.ts +21 -0
  20. package/dist/commands/computer-sessions-picker.js +141 -0
  21. package/dist/commands/computer.d.ts +16 -0
  22. package/dist/commands/computer.js +37 -0
  23. package/dist/commands/config.d.ts +17 -0
  24. package/dist/commands/config.js +401 -0
  25. package/dist/commands/cp.d.ts +84 -0
  26. package/dist/commands/cp.js +231 -0
  27. package/dist/commands/daemon.js +243 -14
  28. package/dist/commands/detach-core.d.ts +1 -1
  29. package/dist/commands/detach-core.js +12 -2
  30. package/dist/commands/detach.js +1 -1
  31. package/dist/commands/doctor.js +64 -5
  32. package/dist/commands/events.d.ts +24 -12
  33. package/dist/commands/events.js +144 -28
  34. package/dist/commands/exec.js +86 -42
  35. package/dist/commands/feed.d.ts +1 -1
  36. package/dist/commands/feed.js +16 -8
  37. package/dist/commands/focus.d.ts +33 -1
  38. package/dist/commands/focus.js +177 -17
  39. package/dist/commands/funnel.d.ts +1 -1
  40. package/dist/commands/go.js +9 -8
  41. package/dist/commands/harness-wizard.d.ts +1 -0
  42. package/dist/commands/harness-wizard.js +18 -20
  43. package/dist/commands/harness.d.ts +2 -0
  44. package/dist/commands/harness.js +59 -26
  45. package/dist/commands/hooks.js +0 -11
  46. package/dist/commands/inspect.d.ts +94 -1
  47. package/dist/commands/inspect.js +866 -40
  48. package/dist/commands/lease.d.ts +4 -4
  49. package/dist/commands/lease.js +6 -6
  50. package/dist/commands/login.js +0 -13
  51. package/dist/commands/logs.d.ts +2 -2
  52. package/dist/commands/logs.js +2 -2
  53. package/dist/commands/mcp.js +7 -2
  54. package/dist/commands/memory.js +7 -2
  55. package/dist/commands/message.d.ts +1 -1
  56. package/dist/commands/message.js +37 -6
  57. package/dist/commands/models.js +71 -0
  58. package/dist/commands/monitors.d.ts +0 -1
  59. package/dist/commands/monitors.js +199 -16
  60. package/dist/commands/open.d.ts +18 -0
  61. package/dist/commands/open.js +57 -0
  62. package/dist/commands/packages.js +2 -107
  63. package/dist/commands/plugins.js +6 -3
  64. package/dist/commands/profiles.d.ts +1 -0
  65. package/dist/commands/profiles.js +16 -160
  66. package/dist/commands/projects.d.ts +28 -0
  67. package/dist/commands/projects.js +125 -5
  68. package/dist/commands/reconnect.js +9 -3
  69. package/dist/commands/repo.js +42 -1
  70. package/dist/commands/resource-view.d.ts +17 -0
  71. package/dist/commands/resource-view.js +36 -14
  72. package/dist/commands/resume.js +9 -2
  73. package/dist/commands/routines.d.ts +0 -2
  74. package/dist/commands/routines.js +473 -289
  75. package/dist/commands/secrets.js +52 -9
  76. package/dist/commands/sessions-export.d.ts +47 -0
  77. package/dist/commands/sessions-export.js +116 -6
  78. package/dist/commands/sessions-import.d.ts +17 -0
  79. package/dist/commands/sessions-import.js +114 -6
  80. package/dist/commands/sessions-migrate.d.ts +27 -0
  81. package/dist/commands/sessions-migrate.js +50 -9
  82. package/dist/commands/sessions-picker.js +23 -4
  83. package/dist/commands/sessions-resume.d.ts +5 -3
  84. package/dist/commands/sessions-resume.js +30 -8
  85. package/dist/commands/sessions-watch.d.ts +2 -0
  86. package/dist/commands/sessions-watch.js +53 -0
  87. package/dist/commands/sessions.d.ts +66 -3
  88. package/dist/commands/sessions.js +298 -47
  89. package/dist/commands/setup-browser.js +2 -2
  90. package/dist/commands/setup-mine.js +0 -1
  91. package/dist/commands/setup-preferences.js +1 -1
  92. package/dist/commands/setup.d.ts +5 -0
  93. package/dist/commands/setup.js +31 -5
  94. package/dist/commands/share.d.ts +87 -7
  95. package/dist/commands/share.js +320 -58
  96. package/dist/commands/skills.js +0 -11
  97. package/dist/commands/snapshot.js +1 -1
  98. package/dist/commands/ssh.d.ts +18 -0
  99. package/dist/commands/ssh.js +549 -210
  100. package/dist/commands/sync.d.ts +5 -0
  101. package/dist/commands/sync.js +212 -32
  102. package/dist/commands/teams.d.ts +13 -0
  103. package/dist/commands/teams.js +187 -30
  104. package/dist/commands/tickets.d.ts +2 -0
  105. package/dist/commands/tickets.js +43 -0
  106. package/dist/commands/update.js +2 -4
  107. package/dist/commands/usage.js +5 -3
  108. package/dist/commands/versions.js +11 -5
  109. package/dist/commands/view.js +15 -7
  110. package/dist/commands/webhook.d.ts +2 -2
  111. package/dist/commands/webhook.js +7 -7
  112. package/dist/index.d.ts +18 -2
  113. package/dist/index.js +53 -1264
  114. package/dist/lib/account-catalog.d.ts +18 -0
  115. package/dist/lib/account-catalog.js +38 -0
  116. package/dist/lib/account-provider-registry.d.ts +18 -0
  117. package/dist/lib/account-provider-registry.js +59 -0
  118. package/dist/lib/account-registry.d.ts +40 -0
  119. package/dist/lib/account-registry.js +239 -0
  120. package/dist/lib/account-schema.d.ts +44 -0
  121. package/dist/lib/account-schema.js +91 -0
  122. package/dist/lib/account-state-service.d.ts +21 -0
  123. package/dist/lib/account-state-service.js +60 -0
  124. package/dist/lib/activity.d.ts +1 -1
  125. package/dist/lib/activity.js +8 -1
  126. package/dist/lib/add-dir.d.ts +80 -0
  127. package/dist/lib/add-dir.js +241 -0
  128. package/dist/lib/agent-cli-commands.d.ts +11 -0
  129. package/dist/lib/agent-cli-commands.js +30 -0
  130. package/dist/lib/agents.js +44 -36
  131. package/dist/lib/answer-router.js +1 -1
  132. package/dist/lib/audit/log.d.ts +10 -27
  133. package/dist/lib/audit/log.js +20 -33
  134. package/dist/lib/auth-health.d.ts +9 -2
  135. package/dist/lib/auth-health.js +42 -9
  136. package/dist/lib/auto-pull-worker.js +7 -3
  137. package/dist/lib/auto-pull.d.ts +44 -3
  138. package/dist/lib/auto-pull.js +88 -5
  139. package/dist/lib/binary-shadow.d.ts +28 -0
  140. package/dist/lib/binary-shadow.js +121 -0
  141. package/dist/lib/brand.js +9 -3
  142. package/dist/lib/browser/hygiene.d.ts +90 -0
  143. package/dist/lib/browser/hygiene.js +146 -0
  144. package/dist/lib/browser/ipc.d.ts +30 -0
  145. package/dist/lib/browser/ipc.js +93 -4
  146. package/dist/lib/browser/profiles.d.ts +3 -2
  147. package/dist/lib/browser/profiles.js +65 -22
  148. package/dist/lib/browser/service.d.ts +79 -1
  149. package/dist/lib/browser/service.js +231 -14
  150. package/dist/lib/browser/sessions-list.d.ts +22 -2
  151. package/dist/lib/browser/sessions-list.js +54 -6
  152. package/dist/lib/browser/stream.d.ts +2 -0
  153. package/dist/lib/browser/stream.js +1 -0
  154. package/dist/lib/browser/types.d.ts +63 -1
  155. package/dist/lib/byok-usage.d.ts +9 -2
  156. package/dist/lib/byok-usage.js +133 -31
  157. package/dist/lib/cli-entry.d.ts +11 -0
  158. package/dist/lib/cli-entry.js +46 -0
  159. package/dist/lib/cloud/host.d.ts +1 -1
  160. package/dist/lib/cloud/host.js +2 -2
  161. package/dist/lib/cloud/registry.js +1 -1
  162. package/dist/lib/cloud/types.d.ts +1 -1
  163. package/dist/lib/commands.d.ts +2 -0
  164. package/dist/lib/commands.js +2 -0
  165. package/dist/lib/computer/sessions-list.d.ts +150 -0
  166. package/dist/lib/computer/sessions-list.js +363 -0
  167. package/dist/lib/config-keys.d.ts +86 -0
  168. package/dist/lib/config-keys.js +193 -0
  169. package/dist/lib/config-machine-keys.d.ts +12 -0
  170. package/dist/lib/config-machine-keys.js +17 -0
  171. package/dist/lib/config-transfer.js +3 -4
  172. package/dist/lib/crabbox/cli.d.ts +2 -2
  173. package/dist/lib/crabbox/cli.js +3 -3
  174. package/dist/lib/daemon-health.d.ts +22 -0
  175. package/dist/lib/daemon-health.js +33 -3
  176. package/dist/lib/daemon-services.d.ts +50 -0
  177. package/dist/lib/daemon-services.js +147 -0
  178. package/dist/lib/daemon-ticks.d.ts +35 -66
  179. package/dist/lib/daemon-ticks.js +77 -159
  180. package/dist/lib/daemon.d.ts +72 -4
  181. package/dist/lib/daemon.js +792 -202
  182. package/dist/lib/deeplink/register.d.ts +49 -0
  183. package/dist/lib/deeplink/register.js +253 -0
  184. package/dist/lib/deeplink/url.d.ts +34 -0
  185. package/dist/lib/deeplink/url.js +78 -0
  186. package/dist/lib/device-config.d.ts +124 -29
  187. package/dist/lib/device-config.js +346 -141
  188. package/dist/lib/devices/config-migration.d.ts +42 -0
  189. package/dist/lib/devices/config-migration.js +203 -0
  190. package/dist/lib/devices/connect.js +14 -7
  191. package/dist/lib/devices/doctor-findings.d.ts +4 -1
  192. package/dist/lib/devices/doctor-findings.js +20 -1
  193. package/dist/lib/devices/harness-inventory.d.ts +11 -2
  194. package/dist/lib/devices/harness-inventory.js +0 -0
  195. package/dist/lib/devices/health.d.ts +1 -1
  196. package/dist/lib/devices/health.js +1 -1
  197. package/dist/lib/devices/pending.d.ts +22 -1
  198. package/dist/lib/devices/pending.js +67 -2
  199. package/dist/lib/devices/registry.d.ts +0 -25
  200. package/dist/lib/devices/registry.js +2 -83
  201. package/dist/lib/devices/resolve-profile.d.ts +20 -0
  202. package/dist/lib/devices/resolve-profile.js +44 -0
  203. package/dist/lib/devices/rollout-verify.d.ts +101 -0
  204. package/dist/lib/devices/rollout-verify.js +193 -0
  205. package/dist/lib/devices/ssh-config.js +10 -6
  206. package/dist/lib/event-families.d.ts +28 -0
  207. package/dist/lib/event-families.js +159 -0
  208. package/dist/lib/event-stream.d.ts +9 -1
  209. package/dist/lib/event-stream.js +26 -9
  210. package/dist/lib/events.d.ts +9 -1
  211. package/dist/lib/events.js +21 -6
  212. package/dist/lib/exec.d.ts +30 -0
  213. package/dist/lib/exec.js +219 -121
  214. package/dist/lib/feed-broadcast.d.ts +25 -0
  215. package/dist/lib/feed-broadcast.js +33 -0
  216. package/dist/lib/feed.d.ts +1 -1
  217. package/dist/lib/feed.js +12 -2
  218. package/dist/lib/fleet/capture.js +15 -0
  219. package/dist/lib/fleet/manifest.js +9 -0
  220. package/dist/lib/fleet/types.d.ts +9 -0
  221. package/dist/lib/fleet-status.js +10 -8
  222. package/dist/lib/git.d.ts +21 -7
  223. package/dist/lib/git.js +122 -18
  224. package/dist/lib/hosts/dispatch.d.ts +8 -3
  225. package/dist/lib/hosts/dispatch.js +29 -3
  226. package/dist/lib/hosts/logs.d.ts +2 -2
  227. package/dist/lib/hosts/logs.js +2 -2
  228. package/dist/lib/hosts/option.js +1 -1
  229. package/dist/lib/hosts/passthrough.d.ts +2 -3
  230. package/dist/lib/hosts/passthrough.js +10 -24
  231. package/dist/lib/hosts/progress.js +2 -2
  232. package/dist/lib/hosts/providers/devices.d.ts +3 -3
  233. package/dist/lib/hosts/providers/devices.js +18 -12
  234. package/dist/lib/hosts/ready.d.ts +5 -1
  235. package/dist/lib/hosts/ready.js +9 -3
  236. package/dist/lib/hosts/reconcile.d.ts +2 -2
  237. package/dist/lib/hosts/reconcile.js +2 -2
  238. package/dist/lib/hosts/registry.js +14 -9
  239. package/dist/lib/hosts/remote-cmd.js +1 -1
  240. package/dist/lib/hosts/remote-os.d.ts +9 -6
  241. package/dist/lib/hosts/remote-os.js +13 -6
  242. package/dist/lib/hosts/routing-flag.d.ts +23 -0
  243. package/dist/lib/hosts/routing-flag.js +41 -0
  244. package/dist/lib/hosts/run-target.js +1 -1
  245. package/dist/lib/hosts/session-index.js +1 -1
  246. package/dist/lib/hosts/tasks.d.ts +6 -6
  247. package/dist/lib/hosts/tasks.js +4 -4
  248. package/dist/lib/hosts/types.js +1 -2
  249. package/dist/lib/installations/resolve.js +2 -8
  250. package/dist/lib/isolation-boundary-report.js +0 -1
  251. package/dist/lib/linear-cache.d.ts +7 -0
  252. package/dist/lib/linear-cache.js +31 -4
  253. package/dist/lib/linear-project-counts.d.ts +1 -1
  254. package/dist/lib/linear-project-counts.js +2 -3
  255. package/dist/lib/linear-projects.js +1 -1
  256. package/dist/lib/loop.d.ts +2 -2
  257. package/dist/lib/loop.js +1 -1
  258. package/dist/lib/mailbox-target.d.ts +1 -1
  259. package/dist/lib/mailbox-target.js +1 -1
  260. package/dist/lib/manifest.js +7 -4
  261. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  262. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  263. package/dist/lib/menubar/snapshot.d.ts +3 -2
  264. package/dist/lib/menubar/snapshot.js +6 -2
  265. package/dist/lib/migrate-fold.d.ts +33 -0
  266. package/dist/lib/migrate-fold.js +130 -0
  267. package/dist/lib/migrate.d.ts +34 -34
  268. package/dist/lib/migrate.js +106 -128
  269. package/dist/lib/model-tier-overrides.d.ts +1 -1
  270. package/dist/lib/model-tier-overrides.js +15 -2
  271. package/dist/lib/monitors/config.d.ts +17 -3
  272. package/dist/lib/monitors/config.js +52 -18
  273. package/dist/lib/monitors/engine.d.ts +32 -1
  274. package/dist/lib/monitors/engine.js +94 -11
  275. package/dist/lib/monitors/fingerprint.d.ts +46 -0
  276. package/dist/lib/monitors/fingerprint.js +100 -0
  277. package/dist/lib/monitors/remote.d.ts +47 -0
  278. package/dist/lib/monitors/remote.js +81 -0
  279. package/dist/lib/monitors/state.d.ts +39 -0
  280. package/dist/lib/monitors/state.js +56 -0
  281. package/dist/lib/onepassword.d.ts +17 -0
  282. package/dist/lib/onepassword.js +52 -22
  283. package/dist/lib/open-url.js +1 -1
  284. package/dist/lib/picker.d.ts +14 -2
  285. package/dist/lib/picker.js +35 -13
  286. package/dist/lib/placement.d.ts +1 -1
  287. package/dist/lib/placement.js +1 -1
  288. package/dist/lib/pr-land-detach.d.ts +32 -0
  289. package/dist/lib/pr-land-detach.js +79 -0
  290. package/dist/lib/profiles-presets.js +13 -0
  291. package/dist/lib/profiles.d.ts +2 -0
  292. package/dist/lib/profiles.js +44 -1
  293. package/dist/lib/project-focus.d.ts +1 -1
  294. package/dist/lib/project-focus.js +1 -1
  295. package/dist/lib/project-probe.d.ts +4 -1
  296. package/dist/lib/project-probe.js +5 -4
  297. package/dist/lib/project-resources.js +2 -18
  298. package/dist/lib/project-root.d.ts +16 -0
  299. package/dist/lib/project-root.js +20 -2
  300. package/dist/lib/projects.d.ts +20 -1
  301. package/dist/lib/projects.js +78 -1
  302. package/dist/lib/refresh-coordinator.d.ts +24 -0
  303. package/dist/lib/refresh-coordinator.js +52 -0
  304. package/dist/lib/registry.d.ts +2 -2
  305. package/dist/lib/registry.js +1 -1
  306. package/dist/lib/resource-aliases.d.ts +13 -0
  307. package/dist/lib/resource-aliases.js +26 -0
  308. package/dist/lib/resources/types.d.ts +1 -1
  309. package/dist/lib/resources.d.ts +16 -0
  310. package/dist/lib/resources.js +66 -10
  311. package/dist/lib/rotate.d.ts +3 -4
  312. package/dist/lib/rotate.js +4 -5
  313. package/dist/lib/routine-activation.d.ts +22 -2
  314. package/dist/lib/routine-activation.js +63 -16
  315. package/dist/lib/routine-context.d.ts +9 -2
  316. package/dist/lib/routine-context.js +21 -6
  317. package/dist/lib/routines-project.d.ts +58 -48
  318. package/dist/lib/routines-project.js +190 -159
  319. package/dist/lib/routines.d.ts +44 -7
  320. package/dist/lib/routines.js +92 -34
  321. package/dist/lib/run-defaults.d.ts +5 -0
  322. package/dist/lib/run-defaults.js +11 -1
  323. package/dist/lib/runner.d.ts +10 -8
  324. package/dist/lib/runner.js +122 -39
  325. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  326. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  327. package/dist/lib/secrets/agent.d.ts +10 -3
  328. package/dist/lib/secrets/agent.js +43 -8
  329. package/dist/lib/secrets/bundles.d.ts +1 -0
  330. package/dist/lib/secrets/bundles.js +92 -80
  331. package/dist/lib/secrets/index.js +32 -9
  332. package/dist/lib/secrets/install-helper.d.ts +4 -4
  333. package/dist/lib/secrets/install-helper.js +4 -4
  334. package/dist/lib/secrets/push.d.ts +40 -6
  335. package/dist/lib/secrets/push.js +58 -11
  336. package/dist/lib/secrets/read-backoff.d.ts +1 -1
  337. package/dist/lib/secrets/read-backoff.js +1 -1
  338. package/dist/lib/secrets/remote.d.ts +24 -0
  339. package/dist/lib/secrets/remote.js +54 -4
  340. package/dist/lib/self-update.d.ts +108 -0
  341. package/dist/lib/self-update.js +276 -1
  342. package/dist/lib/session/active.d.ts +89 -5
  343. package/dist/lib/session/active.js +165 -10
  344. package/dist/lib/session/actor-sidecar.d.ts +1 -1
  345. package/dist/lib/session/actor-sidecar.js +2 -1
  346. package/dist/lib/session/db.d.ts +176 -2
  347. package/dist/lib/session/db.js +484 -17
  348. package/dist/lib/session/discover.js +27 -4
  349. package/dist/lib/session/hook-sessions.js +2 -2
  350. package/dist/lib/session/host-link.d.ts +2 -2
  351. package/dist/lib/session/host-link.js +2 -2
  352. package/dist/lib/session/pid-registry.d.ts +21 -0
  353. package/dist/lib/session/pid-registry.js +57 -0
  354. package/dist/lib/session/remote-active.js +15 -1
  355. package/dist/lib/session/remote.js +2 -2
  356. package/dist/lib/session/session-cache.d.ts +14 -7
  357. package/dist/lib/session/session-cache.js +51 -9
  358. package/dist/lib/session/state.d.ts +2 -2
  359. package/dist/lib/session/state.js +1 -1
  360. package/dist/lib/session/sync/config.d.ts +10 -10
  361. package/dist/lib/session/sync/config.js +10 -10
  362. package/dist/lib/session/sync/r2.d.ts +34 -0
  363. package/dist/lib/session/sync/r2.js +123 -0
  364. package/dist/lib/session/throughput.d.ts +1 -1
  365. package/dist/lib/session/throughput.js +1 -1
  366. package/dist/lib/session/types.d.ts +23 -1
  367. package/dist/lib/session/types.js +15 -0
  368. package/dist/lib/session/viewing-in.d.ts +1 -1
  369. package/dist/lib/session/viewing-in.js +1 -1
  370. package/dist/lib/session/watch.d.ts +101 -0
  371. package/dist/lib/session/watch.js +242 -0
  372. package/dist/lib/share/analytics.js +1 -1
  373. package/dist/lib/share/capture.d.ts +1 -1
  374. package/dist/lib/share/capture.js +3 -3
  375. package/dist/lib/share/config.d.ts +6 -2
  376. package/dist/lib/share/config.js +6 -5
  377. package/dist/lib/share/delete.js +3 -3
  378. package/dist/lib/share/provision.d.ts +38 -0
  379. package/dist/lib/share/provision.js +51 -1
  380. package/dist/lib/share/publish.d.ts +40 -1
  381. package/dist/lib/share/publish.js +119 -6
  382. package/dist/lib/share/worker-template.d.ts +12 -1
  383. package/dist/lib/share/worker-template.js +83 -7
  384. package/dist/lib/shims.d.ts +17 -3
  385. package/dist/lib/shims.js +98 -26
  386. package/dist/lib/signin-badge.js +3 -2
  387. package/dist/lib/skills.js +2 -0
  388. package/dist/lib/smart-launch.d.ts +8 -8
  389. package/dist/lib/smart-launch.js +80 -59
  390. package/dist/lib/ssh-exec.d.ts +1 -1
  391. package/dist/lib/ssh-exec.js +1 -1
  392. package/dist/lib/staleness/prune.d.ts +88 -0
  393. package/dist/lib/staleness/prune.js +69 -0
  394. package/dist/lib/staleness/registry.d.ts +1 -1
  395. package/dist/lib/staleness/writers/commands.js +34 -2
  396. package/dist/lib/staleness/writers/hooks.js +16 -0
  397. package/dist/lib/staleness/writers/kinds.d.ts +6 -0
  398. package/dist/lib/staleness/writers/skills.js +19 -0
  399. package/dist/lib/staleness/writers/subagents.d.ts +2 -3
  400. package/dist/lib/staleness/writers/subagents.js +0 -4
  401. package/dist/lib/staleness/writers/types.d.ts +32 -0
  402. package/dist/lib/startup/command-registry.d.ts +16 -14
  403. package/dist/lib/startup/command-registry.js +26 -37
  404. package/dist/lib/startup/dev-build.d.ts +10 -0
  405. package/dist/lib/startup/dev-build.js +13 -1
  406. package/dist/lib/startup/spellcheck.d.ts +18 -0
  407. package/dist/lib/startup/spellcheck.js +45 -0
  408. package/dist/lib/state.d.ts +36 -9
  409. package/dist/lib/state.js +96 -46
  410. package/dist/lib/subagents-registry.d.ts +0 -7
  411. package/dist/lib/subagents-registry.js +38 -65
  412. package/dist/lib/subagents.d.ts +0 -33
  413. package/dist/lib/subagents.js +0 -75
  414. package/dist/lib/sync-umbrella.js +1 -1
  415. package/dist/lib/teams/agents.d.ts +41 -1
  416. package/dist/lib/teams/agents.js +187 -9
  417. package/dist/lib/teams/api.d.ts +11 -1
  418. package/dist/lib/teams/api.js +11 -2
  419. package/dist/lib/teams/delivery.d.ts +41 -0
  420. package/dist/lib/teams/delivery.js +60 -0
  421. package/dist/lib/teams/registry.d.ts +14 -0
  422. package/dist/lib/teams/registry.js +51 -1
  423. package/dist/lib/teams/remoteWorktree.d.ts +19 -0
  424. package/dist/lib/teams/remoteWorktree.js +29 -0
  425. package/dist/lib/teams/scheduler.d.ts +1 -1
  426. package/dist/lib/teams/scheduler.js +1 -1
  427. package/dist/lib/teams/worktree.d.ts +24 -0
  428. package/dist/lib/teams/worktree.js +42 -0
  429. package/dist/lib/terminal/backends/vscodium-agent.d.ts +10 -1
  430. package/dist/lib/terminal/backends/vscodium-agent.js +16 -5
  431. package/dist/lib/terminal/engine.d.ts +4 -0
  432. package/dist/lib/terminal/engine.js +8 -2
  433. package/dist/lib/terminal/types.d.ts +21 -2
  434. package/dist/lib/testdata/refresh-coordinator-worker.d.ts +1 -0
  435. package/dist/lib/testdata/refresh-coordinator-worker.js +23 -0
  436. package/dist/lib/tickets/list.d.ts +53 -0
  437. package/dist/lib/tickets/list.js +153 -0
  438. package/dist/lib/tmux/orphan-reap.d.ts +316 -0
  439. package/dist/lib/tmux/orphan-reap.js +638 -0
  440. package/dist/lib/tmux/session.d.ts +68 -3
  441. package/dist/lib/tmux/session.js +96 -5
  442. package/dist/lib/triggers/handlers.d.ts +20 -0
  443. package/dist/lib/triggers/handlers.js +16 -1
  444. package/dist/lib/triggers/webhook.js +10 -0
  445. package/dist/lib/types.d.ts +47 -35
  446. package/dist/lib/usage-fleet.d.ts +32 -0
  447. package/dist/lib/usage-fleet.js +125 -0
  448. package/dist/lib/usage-refresh.d.ts +3 -3
  449. package/dist/lib/usage-refresh.js +19 -16
  450. package/dist/lib/usage.d.ts +51 -47
  451. package/dist/lib/usage.js +145 -153
  452. package/dist/lib/version-duplicates.js +2 -2
  453. package/dist/lib/versions.d.ts +56 -13
  454. package/dist/lib/versions.js +195 -45
  455. package/dist/lib/watchdog/log.d.ts +1 -1
  456. package/dist/lib/watchdog/log.js +3 -3
  457. package/dist/lib/watchdog/rotate.d.ts +6 -6
  458. package/dist/lib/watchdog/rotate.js +6 -6
  459. package/dist/lib/workflows.d.ts +1 -1
  460. package/dist/lib/yaml-io.d.ts +47 -0
  461. package/dist/lib/yaml-io.js +55 -0
  462. package/package.json +2 -1
  463. package/scripts/install-helper.js +2 -2
  464. package/scripts/postinstall.js +23 -20
  465. package/dist/commands/defaults.d.ts +0 -7
  466. package/dist/commands/defaults.js +0 -107
  467. package/dist/commands/export.d.ts +0 -11
  468. package/dist/commands/export.js +0 -215
  469. package/dist/commands/helper.d.ts +0 -12
  470. package/dist/commands/helper.js +0 -87
  471. package/dist/commands/hosts.d.ts +0 -11
  472. package/dist/commands/hosts.js +0 -330
  473. package/dist/commands/lock.d.ts +0 -12
  474. package/dist/commands/lock.js +0 -70
  475. package/dist/commands/pull.d.ts +0 -17
  476. package/dist/commands/pull.js +0 -39
  477. package/dist/commands/push.d.ts +0 -14
  478. package/dist/commands/push.js +0 -30
  479. package/dist/commands/set.d.ts +0 -15
  480. package/dist/commands/set.js +0 -79
  481. package/dist/commands/setup-share.d.ts +0 -17
  482. package/dist/commands/setup-share.js +0 -85
  483. package/dist/commands/wallet.d.ts +0 -20
  484. package/dist/commands/wallet.js +0 -216
  485. package/dist/commands/worktree.d.ts +0 -19
  486. package/dist/commands/worktree.js +0 -272
  487. package/dist/lib/account-labels.d.ts +0 -24
  488. package/dist/lib/account-labels.js +0 -72
  489. package/dist/lib/auto-dispatch-linear.d.ts +0 -18
  490. package/dist/lib/auto-dispatch-linear.js +0 -107
  491. package/dist/lib/auto-dispatch-provider.d.ts +0 -10
  492. package/dist/lib/auto-dispatch-provider.js +0 -30
  493. package/dist/lib/auto-dispatch.d.ts +0 -93
  494. package/dist/lib/auto-dispatch.js +0 -128
  495. package/dist/lib/export.d.ts +0 -72
  496. package/dist/lib/export.js +0 -269
  497. package/dist/lib/lock.d.ts +0 -93
  498. package/dist/lib/lock.js +0 -207
  499. package/dist/lib/wallet/index.d.ts +0 -78
  500. package/dist/lib/wallet/index.js +0 -253
@@ -1,85 +0,0 @@
1
- /**
2
- * `agents setup share` — interactive wizard to configure the `agents share`
3
- * endpoint (Cloudflare R2 + Worker). A friendly front door over the existing
4
- * `agents share setup` (provision) and `agents share join` flows, reusing their
5
- * exact logic so there is a single source of truth for provisioning.
6
- *
7
- * Idempotent: re-running shows the current endpoint and offers to reconfigure.
8
- */
9
- import chalk from 'chalk';
10
- import { DEFAULT_BUCKET_NAME, DEFAULT_CF_BUNDLE, DEFAULT_WORKER_NAME, readShareConfig, } from '../lib/share/config.js';
11
- import { runShareProvision, runShareJoin } from './share.js';
12
- import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
13
- /**
14
- * Interactive share setup. Returns true if the user configured (or already had)
15
- * an endpoint, false if they skipped. Never throws on user cancel — callers
16
- * (the `agents setup` hub) rely on that to keep the fresh-machine flow going.
17
- */
18
- export async function runShareWizard() {
19
- if (!isInteractiveTerminal()) {
20
- console.error(chalk.red('agents setup share needs an interactive terminal. ' +
21
- 'Non-interactively, use `agents share setup` (provision) or `agents share join [url]`.'));
22
- return false;
23
- }
24
- const existing = readShareConfig();
25
- if (existing) {
26
- console.log(chalk.dim(`Share is already configured → ${chalk.green(existing.baseUrl)}`));
27
- console.log(chalk.dim(` worker ${existing.workerName} · bucket ${existing.bucketName} · account ${existing.accountId}`));
28
- const { confirm } = await import('@inquirer/prompts');
29
- const reconfigure = await confirm({ message: 'Reconfigure the share endpoint?', default: false });
30
- if (!reconfigure) {
31
- console.log(chalk.dim('Keeping the current endpoint.'));
32
- return true;
33
- }
34
- }
35
- const { select } = await import('@inquirer/prompts');
36
- const mode = await select({
37
- message: 'How do you want to publish shared links?',
38
- choices: [
39
- {
40
- name: 'Provision my own (Cloudflare R2 + Worker)',
41
- value: 'provision',
42
- description: 'One-time: creates a bucket + Worker on your Cloudflare account (~$0). Needs a Cloudflare API token.',
43
- },
44
- {
45
- name: 'Join an existing endpoint (a teammate already provisioned one)',
46
- value: 'join',
47
- description: 'Use synced config when present, or paste the base URL + write token from the endpoint owner.',
48
- },
49
- ],
50
- });
51
- if (mode === 'provision') {
52
- await runShareProvision({
53
- bundle: DEFAULT_CF_BUNDLE,
54
- worker: DEFAULT_WORKER_NAME,
55
- bucket: DEFAULT_BUCKET_NAME,
56
- });
57
- return true;
58
- }
59
- const { input } = await import('@inquirer/prompts');
60
- const baseUrl = await input({
61
- message: 'Endpoint base URL (e.g. https://share.agents-cli.sh)',
62
- validate: (v) => (v.trim().startsWith('http') ? true : 'Enter the full https:// URL of the endpoint.'),
63
- });
64
- await runShareJoin(baseUrl.trim());
65
- return true;
66
- }
67
- /** Register `agents setup share` under the parent `setup` command. */
68
- export function registerSetupShareCommand(setupCmd) {
69
- setupCmd
70
- .command('share')
71
- .description('Configure the `agents share` endpoint (Cloudflare R2 + Worker) — provision your own or join one.')
72
- .action(async () => {
73
- try {
74
- await runShareWizard();
75
- }
76
- catch (err) {
77
- if (isPromptCancelled(err)) {
78
- console.log(chalk.yellow('\nCancelled'));
79
- return;
80
- }
81
- console.error(chalk.red(err.message));
82
- process.exitCode = 1;
83
- }
84
- });
85
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * `agents wallet` — a device-local credit-card vault backed by macOS Keychain.
3
- *
4
- * UX intent matches Apple Wallet: list cards freely (no biometric), reveal
5
- * a card with Touch ID. Card numbers never leave the device. This is NOT
6
- * Apple Pay — we store the real PAN, not a network DPAN, and do not generate
7
- * per-transaction cryptograms. The help text reflects this.
8
- *
9
- * Bundle layout:
10
- * ~/.agents/wallet/cards.json metadata (id, last4, brand, exp)
11
- * agents-cli.secrets.wallet.<id> JSON {pan, cvc, cardholder}
12
- */
13
- import type { Command } from 'commander';
14
- import { type CardMetadata } from '../lib/wallet/index.js';
15
- /** Width of the id column (incl. its 2-space gap): full UUID >=104, short id >=80, none below. */
16
- export declare function walletIdWidth(cols: number): number;
17
- /** Nickname column width. Shrinks so the whole row fits even at the 60-col floor. */
18
- export declare function walletNickWidth(cols: number): number;
19
- export declare function renderRow(c: CardMetadata, cols?: number): string;
20
- export declare function registerWalletCommands(program: Command): void;
@@ -1,216 +0,0 @@
1
- /**
2
- * `agents wallet` — a device-local credit-card vault backed by macOS Keychain.
3
- *
4
- * UX intent matches Apple Wallet: list cards freely (no biometric), reveal
5
- * a card with Touch ID. Card numbers never leave the device. This is NOT
6
- * Apple Pay — we store the real PAN, not a network DPAN, and do not generate
7
- * per-transaction cryptograms. The help text reflects this.
8
- *
9
- * Bundle layout:
10
- * ~/.agents/wallet/cards.json metadata (id, last4, brand, exp)
11
- * agents-cli.secrets.wallet.<id> JSON {pan, cvc, cardholder}
12
- */
13
- import chalk from 'chalk';
14
- import { terminalWidth, truncateToWidth } from '../lib/session/width.js';
15
- import { addCard, detectBrand, isValidLuhn, listCards, removeCard, renameCard, showCard, } from '../lib/wallet/index.js';
16
- import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
17
- import { setHelpSections } from '../lib/help.js';
18
- function brandLabel(b) {
19
- switch (b) {
20
- case 'visa': return 'Visa';
21
- case 'mastercard': return 'Mastercard';
22
- case 'amex': return 'American Express';
23
- case 'discover': return 'Discover';
24
- case 'diners': return 'Diners Club';
25
- case 'jcb': return 'JCB';
26
- case 'unionpay': return 'UnionPay';
27
- default: return 'Card';
28
- }
29
- }
30
- function formatExp(month, year) {
31
- return `${month}/${year.slice(-2)}`;
32
- }
33
- /** Width of the id column (incl. its 2-space gap): full UUID >=104, short id >=80, none below. */
34
- export function walletIdWidth(cols) {
35
- return cols >= 104 ? 2 + 36 : cols >= 80 ? 2 + 8 : 0;
36
- }
37
- /** Nickname column width. Shrinks so the whole row fits even at the 60-col floor. */
38
- export function walletNickWidth(cols) {
39
- const rest = 2 + 1 + 18 + 1 + 10 + 1 + 9 + walletIdWidth(cols); // everything but the nickname
40
- return Math.max(8, Math.min(24, cols - rest));
41
- }
42
- export function renderRow(c, cols = terminalWidth()) {
43
- const nickW = walletNickWidth(cols);
44
- const nick = truncateToWidth(c.nickname, nickW).padEnd(nickW);
45
- const brand = brandLabel(c.brand).padEnd(18);
46
- const last4 = `•••• ${c.last4}`.padEnd(10);
47
- const exp = formatExp(c.exp_month, c.exp_year);
48
- // Full 36-char UUID pushed rows to ~106 chars; size the id to the terminal.
49
- const id = cols >= 104 ? c.id : cols >= 80 ? c.id.slice(0, 8) : '';
50
- const idCol = id ? ` ${chalk.gray(id)}` : '';
51
- return ` ${chalk.cyan(nick)} ${brand} ${last4} ${chalk.gray('exp ' + exp)}${idCol}`;
52
- }
53
- async function promptString(message, validate) {
54
- const { input } = await import('@inquirer/prompts');
55
- return await input({ message, validate });
56
- }
57
- async function promptSecret(message) {
58
- const { password } = await import('@inquirer/prompts');
59
- return await password({ message, mask: true });
60
- }
61
- function requireTTY(action) {
62
- if (!isInteractiveTerminal()) {
63
- throw new Error(`'agents wallet ${action}' requires an interactive terminal.`);
64
- }
65
- }
66
- export function registerWalletCommands(program) {
67
- const cmd = program
68
- .command('wallet')
69
- .description('Device-local credit-card vault backed by macOS Keychain (Touch ID required to reveal). ' +
70
- 'Encrypted at rest, never leaves your device. Not Apple Pay — stores real PANs, no tokenization.');
71
- setHelpSections(cmd, {
72
- examples: `
73
- $ agents wallet add # interactive: PAN, CVC, expiry, nickname
74
- $ agents wallet list # last 4 only, no Touch ID prompt
75
- $ agents wallet show personal-amex # Touch ID required, reveals full card
76
- $ agents wallet rename personal-amex "Travel"
77
- $ agents wallet remove personal-amex
78
- `,
79
- });
80
- cmd
81
- .command('add')
82
- .description('Add a card to the vault. Interactive prompt for PAN, CVC, expiry, cardholder, nickname.')
83
- .option('--nickname <name>', 'Set the nickname non-interactively (still prompts for PAN/CVC)')
84
- .option('--stdin-json', 'Read all fields as a JSON object on stdin (for IPC callers). Emits the new card metadata as JSON to stdout.')
85
- .action(async (opts) => {
86
- try {
87
- if (opts.stdinJson) {
88
- const raw = await new Promise((resolve, reject) => {
89
- const chunks = [];
90
- process.stdin.on('data', (c) => {
91
- chunks.push(typeof c === 'string' ? Buffer.from(c) : c);
92
- });
93
- process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
94
- process.stdin.on('error', reject);
95
- });
96
- const input = JSON.parse(raw);
97
- const meta = addCard(input);
98
- process.stdout.write(JSON.stringify({ card: meta }) + '\n');
99
- return;
100
- }
101
- requireTTY('add');
102
- const pan = (await promptSecret('Card number')).replace(/\s+/g, '');
103
- if (!/^\d+$/.test(pan))
104
- throw new Error('PAN must contain only digits.');
105
- if (!isValidLuhn(pan))
106
- throw new Error('PAN failed Luhn checksum — typo?');
107
- const brand = detectBrand(pan);
108
- console.log(chalk.gray(`Detected: ${brandLabel(brand)} •••• ${pan.slice(-4)}`));
109
- const exp_month = await promptString('Expiration month (MM)', (v) => {
110
- const n = Number(v);
111
- return Number.isInteger(n) && n >= 1 && n <= 12 ? true : 'Month must be 1-12';
112
- });
113
- const exp_year = await promptString('Expiration year (YY or YYYY)', (v) => {
114
- const d = v.replace(/\D/g, '');
115
- return d.length === 2 || d.length === 4 ? true : 'Year must be 2 or 4 digits';
116
- });
117
- const cvc = (await promptSecret('CVC')).replace(/\s+/g, '');
118
- if (!/^\d{3,4}$/.test(cvc))
119
- throw new Error('CVC must be 3 or 4 digits.');
120
- const cardholder = await promptString('Cardholder name (as printed)');
121
- const nickname = opts.nickname?.trim() || await promptString('Nickname (e.g. Personal Amex)', (v) => v.trim() ? true : 'Required');
122
- const meta = addCard({ nickname, pan, cvc, cardholder, exp_month, exp_year });
123
- console.log(chalk.green(`Added ${brandLabel(meta.brand)} •••• ${meta.last4} as '${meta.nickname}' (id: ${meta.id})`));
124
- }
125
- catch (err) {
126
- if (isPromptCancelled(err))
127
- return;
128
- console.error(chalk.red(err.message));
129
- process.exit(1);
130
- }
131
- });
132
- cmd
133
- .command('list')
134
- .alias('ls')
135
- .description('List stored cards (metadata only — last 4, brand, expiry). No biometric prompt.')
136
- .option('--json', 'Emit JSON to stdout')
137
- .action((opts) => {
138
- try {
139
- const cards = listCards();
140
- if (opts.json) {
141
- process.stdout.write(JSON.stringify({ cards }, null, 2) + '\n');
142
- return;
143
- }
144
- if (cards.length === 0) {
145
- console.log(chalk.gray('No cards in wallet. Try: agents wallet add'));
146
- return;
147
- }
148
- const walletCols = terminalWidth();
149
- const nickW = walletNickWidth(walletCols);
150
- const idHeader = walletIdWidth(walletCols) ? ' ID' : '';
151
- console.log(chalk.bold(` ${'NICKNAME'.padEnd(nickW)} ${'BRAND'.padEnd(18)} ${'LAST4'.padEnd(10)} EXP${idHeader}`));
152
- for (const c of cards)
153
- console.log(renderRow(c, walletCols));
154
- }
155
- catch (err) {
156
- console.error(chalk.red(err.message));
157
- process.exit(1);
158
- }
159
- });
160
- cmd
161
- .command('show <id>')
162
- .description('Reveal a card. Touch ID required. Argument is a card id or nickname.')
163
- .option('--json', 'Emit JSON to stdout (still triggers Touch ID)')
164
- .action((id, opts) => {
165
- try {
166
- const full = showCard(id);
167
- if (opts.json) {
168
- process.stdout.write(JSON.stringify(full, null, 2) + '\n');
169
- return;
170
- }
171
- console.log();
172
- console.log(chalk.bold(` ${full.nickname}`));
173
- console.log(` ${chalk.gray('Brand ')} ${brandLabel(full.brand)}`);
174
- console.log(` ${chalk.gray('Number ')} ${full.pan.match(/.{1,4}/g)?.join(' ') ?? full.pan}`);
175
- console.log(` ${chalk.gray('CVC ')} ${full.cvc}`);
176
- console.log(` ${chalk.gray('Expires ')} ${formatExp(full.exp_month, full.exp_year)}`);
177
- console.log(` ${chalk.gray('Holder ')} ${full.cardholder}`);
178
- console.log();
179
- }
180
- catch (err) {
181
- console.error(chalk.red(err.message));
182
- process.exit(1);
183
- }
184
- });
185
- cmd
186
- .command('remove <id>')
187
- .alias('rm')
188
- .description('Remove a card from the vault. Argument is a card id or nickname.')
189
- .action((id) => {
190
- try {
191
- const meta = removeCard(id);
192
- if (!meta) {
193
- console.error(chalk.red(`No card found matching '${id}'.`));
194
- process.exit(1);
195
- }
196
- console.log(chalk.green(`Removed '${meta.nickname}' (${brandLabel(meta.brand)} •••• ${meta.last4}).`));
197
- }
198
- catch (err) {
199
- console.error(chalk.red(err.message));
200
- process.exit(1);
201
- }
202
- });
203
- cmd
204
- .command('rename <id> <new-nickname>')
205
- .description('Rename a card. Argument is the current id or nickname.')
206
- .action((id, newNickname) => {
207
- try {
208
- const meta = renameCard(id, newNickname);
209
- console.log(chalk.green(`Renamed to '${meta.nickname}'.`));
210
- }
211
- catch (err) {
212
- console.error(chalk.red(err.message));
213
- process.exit(1);
214
- }
215
- });
216
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * agents worktree -- provision, release, and prune per-terminal git worktrees.
3
- *
4
- * Used by surfaces that want to spawn each agent terminal in an isolated
5
- * working tree (Companion extension opt-in toggle). Mirrors the in-process
6
- * worktree helpers in lib/teams/worktree.ts but exposes them as a CLI so
7
- * other processes (IDE extensions, shell aliases, hooks) can call them.
8
- *
9
- * agents worktree provision <terminal-id> -> prints absolute worktree path
10
- * agents worktree release <terminal-id> -> removes if clean + merged
11
- * agents worktree prune -> removes every clean+merged one
12
- *
13
- * Worktrees live at <repo>/.agents/worktrees/<terminal-id>, on a branch
14
- * named agents/<terminal-id>. New branches start at the freshly-fetched
15
- * origin/<default> (not local HEAD), matching lib/teams/worktree.ts and the
16
- * agent-system rule that keeps coding-agent worktrees under .agents/.
17
- */
18
- import type { Command } from 'commander';
19
- export declare function registerWorktreeCommands(program: Command): void;
@@ -1,272 +0,0 @@
1
- import chalk from 'chalk';
2
- import { die } from '../lib/format.js';
3
- import { getGitRoot } from '../lib/git.js';
4
- import { execFile } from 'child_process';
5
- import { promisify } from 'util';
6
- import * as fs from 'fs/promises';
7
- import * as fsSync from 'fs';
8
- import * as path from 'path';
9
- import { setHelpSections } from '../lib/help.js';
10
- const execFileAsync = promisify(execFile);
11
- const WORKTREE_SUBDIR = path.join('.agents', 'worktrees');
12
- const BRANCH_PREFIX = 'agents/';
13
- function isValidTerminalId(id) {
14
- // Allow letters, digits, dot, dash, underscore. Reject anything else so a
15
- // hostile or buggy caller can't inject path traversal or shell metachars.
16
- return /^[A-Za-z0-9._-]+$/.test(id) && id.length > 0 && id.length <= 128;
17
- }
18
- // Thin command-layer wrapper over the shared lib/git.ts `getGitRoot`: turns its
19
- // throw into a clean `die()` message. The git plumbing lives in one place now.
20
- async function gitRoot(cwd) {
21
- try {
22
- return await getGitRoot(cwd);
23
- }
24
- catch {
25
- die(`Not inside a git repo: ${cwd}`);
26
- }
27
- }
28
- function worktreePathFor(root, terminalId) {
29
- return path.join(root, WORKTREE_SUBDIR, terminalId);
30
- }
31
- function branchNameFor(terminalId) {
32
- return `${BRANCH_PREFIX}${terminalId}`;
33
- }
34
- async function inspect(root, terminalId) {
35
- const wt = worktreePathFor(root, terminalId);
36
- const branch = branchNameFor(terminalId);
37
- const exists = fsSync.existsSync(wt);
38
- if (!exists) {
39
- return { exists: false, dirty: false, aheadOfUpstream: false, hasUpstream: false, branchMerged: false };
40
- }
41
- let dirty = false;
42
- try {
43
- const { stdout } = await execFileAsync('git', ['status', '--porcelain'], { cwd: wt });
44
- dirty = stdout.trim().length > 0;
45
- }
46
- catch {
47
- dirty = true; // err on the side of caution
48
- }
49
- let hasUpstream = false;
50
- let aheadOfUpstream = false;
51
- try {
52
- await execFileAsync('git', ['rev-parse', '--abbrev-ref', '@{u}'], { cwd: wt });
53
- hasUpstream = true;
54
- const { stdout } = await execFileAsync('git', ['rev-list', '--count', '@{u}..HEAD'], { cwd: wt });
55
- aheadOfUpstream = parseInt(stdout.trim(), 10) > 0;
56
- }
57
- catch {
58
- hasUpstream = false; // never pushed -- treat as "has commits we'd lose"
59
- }
60
- let branchMerged = false;
61
- try {
62
- const { stdout } = await execFileAsync('git', ['branch', '--merged', 'origin/main', '--list', branch], { cwd: root });
63
- branchMerged = stdout.trim().length > 0;
64
- }
65
- catch {
66
- branchMerged = false;
67
- }
68
- return { exists, dirty, aheadOfUpstream, hasUpstream, branchMerged };
69
- }
70
- /** Resolve origin/HEAD → default branch name; falls back to `main`. */
71
- async function defaultBranch(root) {
72
- try {
73
- await execFileAsync('git', ['remote', 'set-head', 'origin', '--auto'], { cwd: root });
74
- }
75
- catch {
76
- // offline / no origin
77
- }
78
- try {
79
- const { stdout } = await execFileAsync('git', ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'], { cwd: root });
80
- const base = stdout.trim().replace(/^origin\//, '');
81
- if (base)
82
- return base;
83
- }
84
- catch {
85
- // no origin/HEAD
86
- }
87
- return 'main';
88
- }
89
- async function provision(root, terminalId) {
90
- const wt = worktreePathFor(root, terminalId);
91
- const branch = branchNameFor(terminalId);
92
- if (fsSync.existsSync(wt))
93
- return wt;
94
- await fs.mkdir(path.dirname(wt), { recursive: true });
95
- // If the branch already exists (e.g. left over from a previous run), reuse
96
- // it instead of failing. Surfaces typically reuse a terminal-id when
97
- // restoring a session.
98
- let branchExists = false;
99
- try {
100
- await execFileAsync('git', ['rev-parse', '--verify', `refs/heads/${branch}`], { cwd: root });
101
- branchExists = true;
102
- }
103
- catch {
104
- branchExists = false;
105
- }
106
- if (branchExists) {
107
- await execFileAsync('git', ['worktree', 'add', wt, branch], { cwd: root });
108
- return wt;
109
- }
110
- // New branch: fetch + base on origin/<default>, never local HEAD (stale trap).
111
- const base = await defaultBranch(root);
112
- try {
113
- await execFileAsync('git', ['fetch', 'origin'], { cwd: root });
114
- }
115
- catch (err) {
116
- const detail = (err?.stderr || err?.message || String(err)).toString().trim();
117
- die(`git fetch origin failed in ${root}` +
118
- (detail ? `: ${detail}` : '') +
119
- `. Cannot provision a worktree from a stale remote-tracking ref.`);
120
- }
121
- await execFileAsync('git', ['worktree', 'add', '-b', branch, wt, `origin/${base}`], { cwd: root });
122
- return wt;
123
- }
124
- async function release(root, terminalId, force) {
125
- const wt = worktreePathFor(root, terminalId);
126
- const branch = branchNameFor(terminalId);
127
- if (!fsSync.existsSync(wt)) {
128
- // Already gone; treat as success but tell the caller.
129
- return { removed: false, reason: 'worktree does not exist' };
130
- }
131
- if (!force) {
132
- const report = await inspect(root, terminalId);
133
- if (report.dirty)
134
- return { removed: false, reason: 'worktree has uncommitted changes' };
135
- if (!report.hasUpstream) {
136
- // Local-only commits exist if HEAD differs from origin/main.
137
- try {
138
- const { stdout } = await execFileAsync('git', ['rev-list', '--count', 'origin/main..HEAD'], { cwd: wt });
139
- if (parseInt(stdout.trim(), 10) > 0) {
140
- return { removed: false, reason: 'branch has local commits not on origin/main' };
141
- }
142
- }
143
- catch {
144
- return { removed: false, reason: 'cannot verify branch state vs origin/main' };
145
- }
146
- }
147
- if (report.aheadOfUpstream)
148
- return { removed: false, reason: 'branch has unpushed commits' };
149
- }
150
- try {
151
- await execFileAsync('git', ['worktree', 'remove', force ? '--force' : '', wt].filter(Boolean), { cwd: root });
152
- }
153
- catch (err) {
154
- if (err.message?.includes('is not a working tree')) {
155
- await execFileAsync('git', ['worktree', 'prune'], { cwd: root });
156
- }
157
- else {
158
- throw err;
159
- }
160
- }
161
- // Delete the branch if it's safe to do so. -d (lowercase) refuses to drop
162
- // an unmerged branch by itself, which is exactly the safety net we want.
163
- try {
164
- await execFileAsync('git', ['branch', '-d', branch], { cwd: root });
165
- }
166
- catch {
167
- // Branch may not exist or may not be merged. We already validated above;
168
- // leaving the branch behind is preferable to silently dropping commits.
169
- }
170
- return { removed: true };
171
- }
172
- async function listAgentWorktrees(root) {
173
- const dir = path.join(root, WORKTREE_SUBDIR);
174
- if (!fsSync.existsSync(dir))
175
- return [];
176
- const entries = await fs.readdir(dir, { withFileTypes: true });
177
- return entries.filter(e => e.isDirectory()).map(e => e.name);
178
- }
179
- export function registerWorktreeCommands(program) {
180
- const wt = program
181
- .command('worktree')
182
- .description('Provision, release, and prune per-terminal git worktrees for agent isolation.');
183
- setHelpSections(wt, {
184
- examples: `
185
- # Create (or reuse) an isolated worktree for an agent terminal — prints the path
186
- agents worktree provision CC-1747509823-3
187
-
188
- # Remove the worktree if it's clean and merged/pushed
189
- agents worktree release CC-1747509823-3
190
-
191
- # Preview what 'prune' would release across all agent worktrees
192
- agents worktree prune --dry-run
193
-
194
- # Release every agent worktree that's safe to remove
195
- agents worktree prune
196
- `,
197
- notes: `
198
- Worktrees live at <repo>/.agents/worktrees/<terminal-id> on branch agents/<terminal-id>.
199
- Use --force on 'release' to skip safety checks (DANGEROUS — discards unpushed work).
200
- `,
201
- });
202
- wt.command('provision <terminal-id>')
203
- .description('Create (or reuse) an isolated worktree for an agent terminal. Prints the absolute path.')
204
- .option('--root <path>', 'Repo root (defaults to current working directory)')
205
- .action(async (terminalId, opts) => {
206
- if (!isValidTerminalId(terminalId)) {
207
- die(`Invalid terminal-id: ${terminalId} (allowed: [A-Za-z0-9._-], <=128 chars)`);
208
- }
209
- const root = await gitRoot(opts.root ?? process.cwd());
210
- const wtPath = await provision(root, terminalId);
211
- console.log(wtPath);
212
- });
213
- wt.command('release <terminal-id>')
214
- .description('Remove the worktree if clean and the branch is merged or has no unpushed commits.')
215
- .option('--root <path>', 'Repo root (defaults to current working directory)')
216
- .option('--force', 'Skip safety checks (DANGEROUS: discards unpushed work)')
217
- .action(async (terminalId, opts) => {
218
- if (!isValidTerminalId(terminalId)) {
219
- die(`Invalid terminal-id: ${terminalId} (allowed: [A-Za-z0-9._-], <=128 chars)`);
220
- }
221
- const root = await gitRoot(opts.root ?? process.cwd());
222
- const result = await release(root, terminalId, Boolean(opts.force));
223
- if (result.removed) {
224
- console.log(chalk.green(`removed ${worktreePathFor(root, terminalId)}`));
225
- }
226
- else {
227
- console.log(chalk.yellow(`kept ${worktreePathFor(root, terminalId)} (${result.reason})`));
228
- }
229
- });
230
- wt.command('prune')
231
- .description('Try to release every agent worktree under .agents/worktrees/. Skips dirty or unpushed ones.')
232
- .option('--root <path>', 'Repo root (defaults to current working directory)')
233
- .option('--dry-run', 'Report what would be removed without touching anything')
234
- .action(async (opts) => {
235
- const root = await gitRoot(opts.root ?? process.cwd());
236
- const ids = await listAgentWorktrees(root);
237
- if (ids.length === 0) {
238
- console.log(chalk.gray('no agent worktrees to prune'));
239
- return;
240
- }
241
- for (const id of ids) {
242
- if (!isValidTerminalId(id)) {
243
- console.log(chalk.yellow(`skip ${id} (name not in expected format)`));
244
- continue;
245
- }
246
- if (opts.dryRun) {
247
- const report = await inspect(root, id);
248
- const blocker = report.dirty
249
- ? 'dirty'
250
- : report.aheadOfUpstream
251
- ? 'unpushed'
252
- : !report.hasUpstream
253
- ? 'never pushed'
254
- : null;
255
- if (blocker) {
256
- console.log(chalk.yellow(`keep ${id} (${blocker})`));
257
- }
258
- else {
259
- console.log(chalk.green(`remove ${id}`));
260
- }
261
- continue;
262
- }
263
- const result = await release(root, id, false);
264
- if (result.removed) {
265
- console.log(chalk.green(`removed ${id}`));
266
- }
267
- else {
268
- console.log(chalk.yellow(`kept ${id} (${result.reason})`));
269
- }
270
- }
271
- });
272
- }
@@ -1,24 +0,0 @@
1
- import type { AgentId } from './types.js';
2
- export interface AccountLabel {
3
- agent: AgentId;
4
- fingerprint: string;
5
- }
6
- export interface AccountLabelsDocument {
7
- labels: Record<string, AccountLabel>;
8
- }
9
- export interface DiscoveredAccount {
10
- agent: AgentId;
11
- fingerprint: string;
12
- display: string;
13
- versions: string[];
14
- label: string | null;
15
- }
16
- export declare function identityFingerprint(agent: string, accountKey: string): string;
17
- export declare function accountLabelsPath(base?: string): string;
18
- export declare function readAccountLabels(base?: string): AccountLabelsDocument;
19
- export declare function nameAccount(label: string, agent: AgentId, fingerprint: string, base?: string): void;
20
- export declare function renameAccountLabel(oldLabel: string, newLabel: string, base?: string): void;
21
- export declare function removeAccountLabel(label: string, base?: string): void;
22
- export declare function labelForFingerprint(agent: AgentId, fingerprint: string, doc?: AccountLabelsDocument): string | null;
23
- export declare function discoverAccounts(agentIds?: readonly AgentId[]): Promise<DiscoveredAccount[]>;
24
- export declare function resolveAccountLabel(agent: AgentId, label: string): Promise<string>;