@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
@@ -102,6 +102,35 @@ export function createRemoteWorktree(target, repoPath, worktreeName, opts = {})
102
102
  remoteGit(target, gitRoot, ['worktree', 'add', '-b', branchName, worktreePath, `origin/${base}`], 120000, opts);
103
103
  return worktreePath;
104
104
  }
105
+ /**
106
+ * How many commits the host checkout at `repoPath` is behind `origin/<default>` —
107
+ * the remote analog of the local {@link commitsBehindDefault} staleness probe, and
108
+ * the exact case from the incident this guard exists for (a distributed team
109
+ * pointed at a 71-commit-stale checkout on another box).
110
+ *
111
+ * `ensureRemoteRepo` already fetched `origin` when it provisioned/reused the
112
+ * checkout right before this runs, so the remote-tracking ref is usually fresh and
113
+ * this reads it WITHOUT a second fetch: resolve the default branch, then
114
+ * `rev-list --count HEAD..origin/<default>`. (That reuse fetch is best-effort —
115
+ * an offline host leaves the ref stale, so this under-reports rather than blocks;
116
+ * `createRemoteWorktree` re-fetches at launch so the teammate's base is still
117
+ * fresh regardless.) Returns null on any git/ssh error (unreachable host, non-repo
118
+ * path) — the caller treats null as "can't tell, don't block".
119
+ */
120
+ export function remoteCommitsBehindDefault(target, repoPath, opts = {}) {
121
+ assertValidSshTarget(target);
122
+ try {
123
+ const base = remoteDefaultBranch(target, repoPath, opts);
124
+ const raw = remoteGit(target, repoPath, ['rev-list', '--count', `HEAD..origin/${base}`], 30000, opts);
125
+ const behind = parseInt(raw, 10);
126
+ if (!Number.isFinite(behind))
127
+ return null;
128
+ return { behind, base };
129
+ }
130
+ catch {
131
+ return null;
132
+ }
133
+ }
105
134
  // Team-name → repos-dir slug: same allowlist a worktree name uses, so it lands
106
135
  // safely in a path (`~/.agents/repos/<slug>`) with no shell metacharacters.
107
136
  const SLUG_RE = /[^A-Za-z0-9_-]/g;
@@ -30,7 +30,7 @@ export interface PlacementTeam {
30
30
  * device name to its `agents.max-concurrent` cap (from the device doc — read
31
31
  * locally via `readMaxConcurrentCaps`, never probed over SSH). Teams counts
32
32
  * the team's OWN roster against the cap (device-global counting would need an
33
- * SSH probe per candidate — out of the hot path; Factory auto-launch is the
33
+ * SSH probe per candidate — out of the hot path; AGI EXT auto-launch is the
34
34
  * device-wide counter). Only the least-loaded AUTO-PICK (cascade step 3)
35
35
  * honors caps: an explicit pin or a pool of one is the user's own choice and
36
36
  * is never second-guessed.
@@ -132,7 +132,7 @@ export function pickLeastLoaded(devices, roster, maxConcurrent) {
132
132
  .map((d) => `${d} (${load.get(d) ?? 0}/${maxConcurrent[d]})`)
133
133
  .join(', ');
134
134
  throw new Error(`Every device in the pool is at its agents.max-concurrent cap: ${detail}. ` +
135
- `Raise a cap with 'agents devices configure <name> --max-agents N' or add a device to the pool.`);
135
+ `Raise a cap with 'agents devices config <name> agents.max-concurrent N' or add a device to the pool.`);
136
136
  }
137
137
  // Iterate the pool in declared order so the first device wins ties.
138
138
  let best = eligible[0];
@@ -27,6 +27,30 @@ export declare function gitDiff(worktreePath: string, maxBytes?: number): Promis
27
27
  * Falls back to `main` when origin/HEAD isn't set.
28
28
  */
29
29
  export declare function localDefaultBranch(gitRoot: string): Promise<string>;
30
+ /**
31
+ * How many commits the checkout at `repoDir` is behind freshly-fetched
32
+ * `origin/<default>` — the staleness the `teams add` guard checks before pointing
33
+ * a team at a repo.
34
+ *
35
+ * Fetches `origin` FIRST, on purpose: the exact failure this guards (a team
36
+ * pointed at a repo "without fetching first" — a 71-commit-stale s1 checkout in
37
+ * the real incident) leaves the remote-tracking ref itself stale, so a naive
38
+ * `HEAD..origin/<default>` reads 0 and hides the drift. After the fetch the count
39
+ * is against the true remote.
40
+ *
41
+ * Measures the passed checkout's OWN root ({@link getGitRoot} / `--show-toplevel`,
42
+ * worktree-correct) — NOT {@link getMainRepoRoot}: for a `--use-worktree` shared
43
+ * worktree (or a caller standing inside a linked worktree), the teammate runs in
44
+ * THAT worktree, whose HEAD differs from the main checkout's, so folding to the
45
+ * main root would report the wrong tree's staleness. `origin/<default>` resolves
46
+ * from the shared object store regardless of which worktree we stand in. Returns
47
+ * null when `repoDir` isn't a git repo, origin is unreachable, or git errors — the
48
+ * caller treats null as "can't tell, don't block".
49
+ */
50
+ export declare function commitsBehindDefault(repoDir: string): Promise<{
51
+ behind: number;
52
+ base: string;
53
+ } | null>;
30
54
  /**
31
55
  * Create a new git worktree for a teammate, branched off the freshly-fetched
32
56
  * default branch. Fetches `origin` first and bases the branch on
@@ -100,6 +100,48 @@ export async function localDefaultBranch(gitRoot) {
100
100
  }
101
101
  return 'main';
102
102
  }
103
+ /**
104
+ * How many commits the checkout at `repoDir` is behind freshly-fetched
105
+ * `origin/<default>` — the staleness the `teams add` guard checks before pointing
106
+ * a team at a repo.
107
+ *
108
+ * Fetches `origin` FIRST, on purpose: the exact failure this guards (a team
109
+ * pointed at a repo "without fetching first" — a 71-commit-stale s1 checkout in
110
+ * the real incident) leaves the remote-tracking ref itself stale, so a naive
111
+ * `HEAD..origin/<default>` reads 0 and hides the drift. After the fetch the count
112
+ * is against the true remote.
113
+ *
114
+ * Measures the passed checkout's OWN root ({@link getGitRoot} / `--show-toplevel`,
115
+ * worktree-correct) — NOT {@link getMainRepoRoot}: for a `--use-worktree` shared
116
+ * worktree (or a caller standing inside a linked worktree), the teammate runs in
117
+ * THAT worktree, whose HEAD differs from the main checkout's, so folding to the
118
+ * main root would report the wrong tree's staleness. `origin/<default>` resolves
119
+ * from the shared object store regardless of which worktree we stand in. Returns
120
+ * null when `repoDir` isn't a git repo, origin is unreachable, or git errors — the
121
+ * caller treats null as "can't tell, don't block".
122
+ */
123
+ export async function commitsBehindDefault(repoDir) {
124
+ const gitRoot = await getGitRoot(repoDir).catch(() => null);
125
+ if (!gitRoot)
126
+ return null;
127
+ try {
128
+ await execFileAsync('git', ['fetch', 'origin'], { cwd: gitRoot });
129
+ }
130
+ catch {
131
+ return null; // offline / no origin — can't assess staleness, don't block a team.
132
+ }
133
+ const base = await localDefaultBranch(gitRoot);
134
+ try {
135
+ const { stdout } = await execFileAsync('git', ['rev-list', '--count', `HEAD..origin/${base}`], { cwd: gitRoot });
136
+ const behind = parseInt(stdout.trim(), 10);
137
+ if (!Number.isFinite(behind))
138
+ return null;
139
+ return { behind, base };
140
+ }
141
+ catch {
142
+ return null; // no origin/<default> tracking ref, detached probe, etc.
143
+ }
144
+ }
103
145
  /**
104
146
  * Create a new git worktree for a teammate, branched off the freshly-fetched
105
147
  * default branch. Fetches `origin` first and bases the branch on
@@ -23,8 +23,17 @@ export declare const EDITOR_VARIANTS: EditorVariant[];
23
23
  * it, so a `command`/`cwd` containing `&` (or `=`) would be mis-split by a naive
24
24
  * multi-param query. base64url is `[A-Za-z0-9_-]` only (no `&`, `=`, `%`, `+`,
25
25
  * `/`), so it survives that decode untouched and round-trips exactly.
26
+ *
27
+ * Optional `meta.agent` / `meta.sessionId` / `meta.title` let the extension set
28
+ * the tab chip and status bar without sniffing the local process tree — required
29
+ * when `command` is a remote attach (`ssh … tmux attach`) with no agent binary
30
+ * on this box (#2478).
26
31
  */
27
- export declare function spawnUri(scheme: string, cwd: string, command: string[], direction?: SplitDirection): string;
32
+ export declare function spawnUri(scheme: string, cwd: string, command: string[], direction?: SplitDirection, meta?: {
33
+ agent?: string;
34
+ sessionId?: string;
35
+ title?: string;
36
+ }): string;
28
37
  /** Build a backend bound to one editor variant. */
29
38
  export declare function makeVscodiumAgentBackend(variant: EditorVariant): TerminalBackend;
30
39
  /** Default backend: VSCodium (`codium` CLI, `vscodium://` scheme). */
@@ -41,14 +41,25 @@ function appExists(p) {
41
41
  * it, so a `command`/`cwd` containing `&` (or `=`) would be mis-split by a naive
42
42
  * multi-param query. base64url is `[A-Za-z0-9_-]` only (no `&`, `=`, `%`, `+`,
43
43
  * `/`), so it survives that decode untouched and round-trips exactly.
44
+ *
45
+ * Optional `meta.agent` / `meta.sessionId` / `meta.title` let the extension set
46
+ * the tab chip and status bar without sniffing the local process tree — required
47
+ * when `command` is a remote attach (`ssh … tmux attach`) with no agent binary
48
+ * on this box (#2478).
44
49
  */
45
- export function spawnUri(scheme, cwd, command, direction) {
50
+ export function spawnUri(scheme, cwd, command, direction, meta) {
46
51
  const payload = {
47
52
  command: command.join(' '),
48
53
  cwd,
49
54
  };
50
55
  if (direction)
51
56
  payload.split = direction;
57
+ if (meta?.agent)
58
+ payload.agent = meta.agent;
59
+ if (meta?.sessionId)
60
+ payload.sessionId = meta.sessionId;
61
+ if (meta?.title)
62
+ payload.title = meta.title;
52
63
  const p = Buffer.from(JSON.stringify(payload), 'utf8').toString('base64url');
53
64
  return `${scheme}://${EXTENSION_AUTHORITY}/spawn?p=${p}`;
54
65
  }
@@ -60,11 +71,11 @@ export function makeVscodiumAgentBackend(variant) {
60
71
  isAvailable(ctx) {
61
72
  return ctx.platform === 'darwin' && appExists(variant.app);
62
73
  },
63
- buildTab(cwd, command) {
64
- return { argv: [variant.cli, '--open-url', spawnUri(variant.scheme, cwd, command)] };
74
+ buildTab(cwd, command, meta) {
75
+ return { argv: [variant.cli, '--open-url', spawnUri(variant.scheme, cwd, command, undefined, meta)] };
65
76
  },
66
- buildSplit(cwd, command, direction) {
67
- return { argv: [variant.cli, '--open-url', spawnUri(variant.scheme, cwd, command, direction)] };
77
+ buildSplit(cwd, command, direction, meta) {
78
+ return { argv: [variant.cli, '--open-url', spawnUri(variant.scheme, cwd, command, direction, meta)] };
68
79
  },
69
80
  };
70
81
  }
@@ -21,6 +21,10 @@ export declare function openSurface(req: LaunchRequest, opts?: OpenOptions): Pro
21
21
  export interface SurfaceItem {
22
22
  cwd: string;
23
23
  command: string[];
24
+ /** Optional harness identity for editor-backed backends (vscodium-agent). */
25
+ agent?: string;
26
+ sessionId?: string;
27
+ title?: string;
24
28
  }
25
29
  export interface BuildRequestsOptions {
26
30
  backend: Backend;
@@ -8,9 +8,12 @@ export function specForRequest(req) {
8
8
  const backend = BACKENDS[req.backend];
9
9
  if (!backend)
10
10
  throw new Error(`unknown backend: ${req.backend}`);
11
+ const meta = req.agent || req.sessionId || req.title
12
+ ? { agent: req.agent, sessionId: req.sessionId, title: req.title }
13
+ : undefined;
11
14
  if (req.layout === 'tab')
12
- return backend.buildTab(req.cwd, req.command);
13
- return backend.buildSplit(req.cwd, req.command, req.layout === 'split-down' ? 'down' : 'right');
15
+ return backend.buildTab(req.cwd, req.command, meta);
16
+ return backend.buildSplit(req.cwd, req.command, req.layout === 'split-down' ? 'down' : 'right', meta);
14
17
  }
15
18
  /** Open a single surface for one request. Never throws — failures come back in the result. */
16
19
  export async function openSurface(req, opts = {}) {
@@ -35,6 +38,9 @@ export function buildRequests(items, opts) {
35
38
  cwd: item.cwd,
36
39
  command: item.command,
37
40
  host: opts.host,
41
+ agent: item.agent,
42
+ sessionId: item.sessionId,
43
+ title: item.title,
38
44
  }));
39
45
  }
40
46
  /**
@@ -25,6 +25,21 @@ export interface LaunchSpec {
25
25
  /** argv to run (e.g. `['osascript','-e',script]` or `['tmux','split-window',…]`). */
26
26
  argv: string[];
27
27
  }
28
+ /**
29
+ * Optional identity the caller already knows about the surface. The
30
+ * vscodium-agent backend forwards these into the swarm-ext `/spawn` URI so the
31
+ * extension can set the tab chip/name/session without sniffing the local
32
+ * process tree (required for remote `ssh … tmux attach` resumes — #2478).
33
+ * Other backends ignore them.
34
+ */
35
+ export interface SurfaceMeta {
36
+ /** Harness id: claude, codex, grok, … */
37
+ agent?: string;
38
+ /** Canonical session id. */
39
+ sessionId?: string;
40
+ /** Optional pre-baked tab title. */
41
+ title?: string;
42
+ }
28
43
  /** A single "open this command as this surface" instruction. */
29
44
  export interface LaunchRequest {
30
45
  backend: Backend;
@@ -35,6 +50,10 @@ export interface LaunchRequest {
35
50
  command: string[];
36
51
  /** undefined / 'local' = this machine; otherwise a resolvable host alias. */
37
52
  host?: string;
53
+ /** Optional agent identity for editor-backed backends. */
54
+ agent?: string;
55
+ sessionId?: string;
56
+ title?: string;
38
57
  }
39
58
  /** Outcome of opening one surface. Never throws for launch failures — reports them. */
40
59
  export interface LaunchResult {
@@ -53,7 +72,7 @@ export interface TerminalBackend {
53
72
  /** Can this backend be driven here? (platform + app installed / inside tmux). */
54
73
  isAvailable(ctx: EngineContext): boolean;
55
74
  /** Command that opens a new tab running `command` in `cwd`. */
56
- buildTab(cwd: string, command: string[]): LaunchSpec;
75
+ buildTab(cwd: string, command: string[], meta?: SurfaceMeta): LaunchSpec;
57
76
  /** Command that splits the current surface, running `command` in `cwd`. */
58
- buildSplit(cwd: string, command: string[], direction: SplitDirection): LaunchSpec;
77
+ buildSplit(cwd: string, command: string[], direction: SplitDirection, meta?: SurfaceMeta): LaunchSpec;
59
78
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import * as fs from 'node:fs';
2
+ import { setRefreshLockRootForTest, withRefreshLease } from '../refresh-coordinator.js';
3
+ const [lockRoot, resultPath, countPath, key] = process.argv.slice(2);
4
+ setRefreshLockRootForTest(lockRoot);
5
+ await withRefreshLease({
6
+ scope: 'cross-process-test',
7
+ key,
8
+ readCompleted: () => {
9
+ try {
10
+ return Number(fs.readFileSync(resultPath, 'utf-8'));
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ },
16
+ isCompleted: (value) => value === 1,
17
+ refresh: async () => {
18
+ fs.appendFileSync(countPath, 'refresh\n');
19
+ await new Promise((resolve) => setTimeout(resolve, 100));
20
+ fs.writeFileSync(resultPath, '1');
21
+ return 1;
22
+ },
23
+ });
@@ -0,0 +1,53 @@
1
+ export type TicketSource = 'linear' | 'github';
2
+ export interface TicketComment {
3
+ body: string;
4
+ createdAt?: string;
5
+ author?: string;
6
+ }
7
+ export interface TicketRow {
8
+ id: string;
9
+ source: TicketSource;
10
+ title: string;
11
+ description?: string;
12
+ status: 'todo' | 'in_progress' | 'done';
13
+ priority?: 'urgent' | 'high' | 'medium' | 'low';
14
+ metadata: {
15
+ identifier?: string;
16
+ url?: string;
17
+ labels?: string[];
18
+ assignee?: string;
19
+ assigneeKind?: 'user' | 'agent';
20
+ state?: string;
21
+ createdAt?: string;
22
+ dueDate?: string;
23
+ project?: string;
24
+ repo?: string;
25
+ comments?: TicketComment[];
26
+ images?: string[];
27
+ };
28
+ }
29
+ export interface TicketListResult {
30
+ tickets: TicketRow[];
31
+ cycleInfo: {
32
+ name: string;
33
+ startsAt: string;
34
+ endsAt: string;
35
+ } | null;
36
+ sources: {
37
+ linear: {
38
+ available: boolean;
39
+ error?: string;
40
+ };
41
+ github: {
42
+ available: boolean;
43
+ error?: string;
44
+ };
45
+ };
46
+ }
47
+ export interface TicketListOptions {
48
+ cwd: string;
49
+ linear: boolean;
50
+ github: boolean;
51
+ githubAssignedOnly: boolean;
52
+ }
53
+ export declare function listTickets(options: TicketListOptions): Promise<TicketListResult>;
@@ -0,0 +1,153 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const run = promisify(execFile);
4
+ const AGENT_ASSIGNEE = /^(claude|codex|gemini|cursor|opencode|antigravity|grok|kimi|droid)$/i;
5
+ function assigneeKind(name) {
6
+ if (!name)
7
+ return undefined;
8
+ return AGENT_ASSIGNEE.test(name.trim()) ? 'agent' : 'user';
9
+ }
10
+ function imageUrls(...bodies) {
11
+ const urls = new Set();
12
+ const pattern = /!\[[^\]]*\]\(\s*(https?:\/\/[^)\s]+)|<img\b[^>]*?\bsrc\s*=\s*["'](https?:\/\/[^"']+)/gi;
13
+ for (const body of bodies) {
14
+ if (typeof body !== 'string')
15
+ continue;
16
+ let match;
17
+ while ((match = pattern.exec(body)))
18
+ urls.add(match[1] || match[2]);
19
+ }
20
+ return urls.size > 0 ? [...urls] : undefined;
21
+ }
22
+ function errorMessage(error) {
23
+ if (error instanceof Error)
24
+ return error.message;
25
+ return String(error);
26
+ }
27
+ async function readLinear(cwd) {
28
+ const { stdout } = await run('linear', ['tasks', '--json'], {
29
+ cwd,
30
+ timeout: 15_000,
31
+ maxBuffer: 16 * 1024 * 1024,
32
+ });
33
+ const data = JSON.parse(stdout);
34
+ const cycle = data?.cycle;
35
+ const cycleInfo = cycle?.startsAt && cycle?.endsAt
36
+ ? { name: String(cycle.name ?? ''), startsAt: String(cycle.startsAt), endsAt: String(cycle.endsAt) }
37
+ : null;
38
+ const priority = {
39
+ 1: 'urgent',
40
+ 2: 'high',
41
+ 3: 'medium',
42
+ 4: 'low',
43
+ };
44
+ const tickets = (Array.isArray(data?.issues) ? data.issues : []).map((issue) => {
45
+ const labels = (issue.labels?.nodes ?? []).map((label) => String(label.name));
46
+ const comments = (issue.comments?.nodes ?? []).map((comment) => ({
47
+ body: String(comment.body ?? ''),
48
+ createdAt: comment.createdAt ? String(comment.createdAt) : undefined,
49
+ author: comment.user?.name ? String(comment.user.name) : undefined,
50
+ }));
51
+ const stateType = String(issue.state?.type ?? '');
52
+ const status = stateType === 'started'
53
+ ? 'in_progress'
54
+ : stateType === 'completed' || stateType === 'canceled'
55
+ ? 'done'
56
+ : 'todo';
57
+ const identifier = String(issue.identifier ?? issue.id ?? '');
58
+ return {
59
+ id: `linear:${identifier}`,
60
+ source: 'linear',
61
+ title: String(issue.title ?? ''),
62
+ description: issue.description ? String(issue.description) : undefined,
63
+ status,
64
+ priority: priority[Number(issue.priority)],
65
+ metadata: {
66
+ identifier,
67
+ url: issue.url ? String(issue.url) : undefined,
68
+ labels,
69
+ assignee: issue.assignee?.name ? String(issue.assignee.name) : undefined,
70
+ assigneeKind: assigneeKind(issue.assignee?.name),
71
+ state: issue.state?.name ? String(issue.state.name) : undefined,
72
+ createdAt: issue.createdAt ? String(issue.createdAt) : undefined,
73
+ dueDate: issue.dueDate ? String(issue.dueDate) : undefined,
74
+ project: issue.project?.name ? String(issue.project.name) : undefined,
75
+ comments,
76
+ images: imageUrls(issue.description, ...comments.map(comment => comment.body)),
77
+ },
78
+ };
79
+ });
80
+ return { tickets, cycleInfo };
81
+ }
82
+ async function readGithub(cwd, assignedOnly) {
83
+ const repo = (await run('gh', ['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner'], {
84
+ cwd,
85
+ timeout: 5_000,
86
+ })).stdout.trim();
87
+ if (!repo)
88
+ throw new Error('No GitHub repository resolved for this workspace.');
89
+ const args = [
90
+ 'issue', 'list', '--repo', repo, '--state', 'open', '--limit', '50',
91
+ '--json', 'number,title,state,labels,assignees,url,body,createdAt',
92
+ ];
93
+ if (assignedOnly)
94
+ args.push('--assignee', '@me');
95
+ const { stdout } = await run('gh', args, { cwd, timeout: 15_000, maxBuffer: 16 * 1024 * 1024 });
96
+ const issues = JSON.parse(stdout);
97
+ return issues.map((issue) => {
98
+ const assignee = issue.assignees?.[0]?.login ? String(issue.assignees[0].login) : undefined;
99
+ const number = Number(issue.number);
100
+ return {
101
+ id: `github:${number}`,
102
+ source: 'github',
103
+ title: String(issue.title ?? ''),
104
+ description: issue.body ? String(issue.body) : undefined,
105
+ status: String(issue.state ?? '').toLowerCase() === 'closed' ? 'done' : 'todo',
106
+ metadata: {
107
+ identifier: `#${number}`,
108
+ url: issue.url ? String(issue.url) : undefined,
109
+ labels: (issue.labels ?? []).map((label) => String(label.name)),
110
+ assignee,
111
+ assigneeKind: assigneeKind(assignee),
112
+ state: String(issue.state ?? '').toLowerCase(),
113
+ createdAt: issue.createdAt ? String(issue.createdAt) : undefined,
114
+ repo,
115
+ images: imageUrls(issue.body),
116
+ },
117
+ };
118
+ });
119
+ }
120
+ export async function listTickets(options) {
121
+ const result = {
122
+ tickets: [],
123
+ cycleInfo: null,
124
+ sources: {
125
+ linear: { available: false },
126
+ github: { available: false },
127
+ },
128
+ };
129
+ const [linear, github] = await Promise.all([
130
+ options.linear
131
+ ? readLinear(options.cwd).then(value => ({ ok: true, value })).catch(error => ({ ok: false, error }))
132
+ : Promise.resolve(null),
133
+ options.github
134
+ ? readGithub(options.cwd, options.githubAssignedOnly).then(value => ({ ok: true, value })).catch(error => ({ ok: false, error }))
135
+ : Promise.resolve(null),
136
+ ]);
137
+ if (linear?.ok) {
138
+ result.sources.linear.available = true;
139
+ result.tickets.push(...linear.value.tickets);
140
+ result.cycleInfo = linear.value.cycleInfo;
141
+ }
142
+ else if (linear) {
143
+ result.sources.linear.error = errorMessage(linear.error);
144
+ }
145
+ if (github?.ok) {
146
+ result.sources.github.available = true;
147
+ result.tickets.push(...github.value);
148
+ }
149
+ else if (github) {
150
+ result.sources.github.error = errorMessage(github.error);
151
+ }
152
+ return result;
153
+ }