@phnx-labs/agents-cli 1.12.0 → 1.14.1

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 (496) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/README.md +293 -300
  3. package/dist/commands/alias.d.ts +11 -0
  4. package/dist/commands/alias.js +117 -0
  5. package/dist/commands/beta.d.ts +2 -0
  6. package/dist/commands/beta.js +53 -0
  7. package/dist/commands/cloud.d.ts +10 -0
  8. package/dist/commands/cloud.js +408 -0
  9. package/dist/commands/commands.d.ts +9 -1
  10. package/dist/commands/commands.js +24 -172
  11. package/dist/commands/daemon.d.ts +8 -1
  12. package/dist/commands/daemon.js +13 -5
  13. package/dist/commands/doctor.d.ts +15 -0
  14. package/dist/commands/doctor.js +132 -0
  15. package/dist/commands/drive.d.ts +8 -1
  16. package/dist/commands/drive.js +20 -3
  17. package/dist/commands/exec.d.ts +8 -1
  18. package/dist/commands/exec.js +207 -20
  19. package/dist/commands/factory.d.ts +19 -0
  20. package/dist/commands/factory.js +71 -0
  21. package/dist/commands/fork.d.ts +8 -1
  22. package/dist/commands/fork.js +11 -4
  23. package/dist/commands/hooks.d.ts +9 -1
  24. package/dist/commands/hooks.js +30 -182
  25. package/dist/commands/init.d.ts +15 -1
  26. package/dist/commands/init.js +168 -74
  27. package/dist/commands/mcp.d.ts +9 -1
  28. package/dist/commands/mcp.js +11 -7
  29. package/dist/commands/models.d.ts +8 -1
  30. package/dist/commands/models.js +45 -6
  31. package/dist/commands/packages.d.ts +8 -1
  32. package/dist/commands/packages.js +13 -7
  33. package/dist/commands/permissions.d.ts +9 -1
  34. package/dist/commands/permissions.js +3 -3
  35. package/dist/commands/plugins.d.ts +8 -1
  36. package/dist/commands/plugins.js +13 -2
  37. package/dist/commands/profiles.d.ts +11 -0
  38. package/dist/commands/profiles.js +291 -0
  39. package/dist/commands/prune.d.ts +22 -0
  40. package/dist/commands/prune.js +191 -0
  41. package/dist/commands/pty.d.ts +1 -1
  42. package/dist/commands/pty.js +2 -1
  43. package/dist/commands/pull.d.ts +8 -1
  44. package/dist/commands/pull.js +93 -129
  45. package/dist/commands/refresh-memory.d.ts +7 -1
  46. package/dist/commands/refresh-memory.js +7 -1
  47. package/dist/commands/repo.d.ts +15 -0
  48. package/dist/commands/repo.js +570 -0
  49. package/dist/commands/resource-view.d.ts +10 -3
  50. package/dist/commands/resource-view.js +18 -5
  51. package/dist/commands/routines.d.ts +8 -1
  52. package/dist/commands/routines.js +17 -4
  53. package/dist/commands/rules.d.ts +9 -1
  54. package/dist/commands/rules.js +16 -11
  55. package/dist/commands/secrets.d.ts +10 -0
  56. package/dist/commands/secrets.js +511 -0
  57. package/dist/commands/sessions-picker.d.ts +2 -1
  58. package/dist/commands/sessions-picker.js +88 -11
  59. package/dist/commands/sessions-tail.d.ts +19 -0
  60. package/dist/commands/sessions-tail.js +235 -0
  61. package/dist/commands/sessions.d.ts +2 -1
  62. package/dist/commands/sessions.js +288 -7
  63. package/dist/commands/skills.d.ts +9 -1
  64. package/dist/commands/skills.js +28 -178
  65. package/dist/commands/status.d.ts +7 -1
  66. package/dist/commands/status.js +7 -1
  67. package/dist/commands/subagents.d.ts +8 -1
  68. package/dist/commands/subagents.js +11 -1
  69. package/dist/commands/sync.d.ts +8 -1
  70. package/dist/commands/sync.js +8 -1
  71. package/dist/commands/teams-picker.d.ts +4 -1
  72. package/dist/commands/teams-picker.js +55 -3
  73. package/dist/commands/teams.d.ts +15 -1
  74. package/dist/commands/teams.js +323 -69
  75. package/dist/commands/usage.d.ts +11 -0
  76. package/dist/commands/usage.js +60 -0
  77. package/dist/commands/utils.d.ts +6 -1
  78. package/dist/commands/utils.js +6 -1
  79. package/dist/commands/versions.d.ts +8 -1
  80. package/dist/commands/versions.js +4 -3
  81. package/dist/commands/view.d.ts +47 -2
  82. package/dist/commands/view.js +353 -20
  83. package/dist/index.d.ts +7 -2
  84. package/dist/index.js +205 -38
  85. package/dist/lib/acp/client.d.ts +31 -0
  86. package/dist/lib/acp/client.js +117 -0
  87. package/dist/lib/acp/harnesses.d.ts +26 -0
  88. package/dist/lib/acp/harnesses.js +65 -0
  89. package/dist/lib/acp/run.d.ts +18 -0
  90. package/dist/lib/acp/run.js +39 -0
  91. package/dist/lib/agents.d.ts +74 -2
  92. package/dist/lib/agents.js +207 -23
  93. package/dist/lib/artifact-actions.d.ts +8 -4
  94. package/dist/lib/artifact-actions.js +8 -6
  95. package/dist/lib/auto-pull-worker.d.ts +11 -0
  96. package/dist/lib/auto-pull-worker.js +121 -0
  97. package/dist/lib/auto-pull.d.ts +31 -0
  98. package/dist/lib/auto-pull.js +97 -0
  99. package/dist/lib/beta.d.ts +23 -0
  100. package/dist/lib/beta.js +90 -0
  101. package/dist/lib/capabilities.d.ts +29 -0
  102. package/dist/lib/capabilities.js +74 -0
  103. package/dist/lib/cloud/codex.d.ts +25 -0
  104. package/dist/lib/cloud/codex.js +250 -0
  105. package/dist/lib/cloud/factory.d.ts +31 -0
  106. package/dist/lib/cloud/factory.js +53 -0
  107. package/dist/lib/cloud/registry.d.ts +15 -0
  108. package/dist/lib/cloud/registry.js +67 -0
  109. package/dist/lib/cloud/rush.d.ts +75 -0
  110. package/dist/lib/cloud/rush.js +438 -0
  111. package/dist/lib/cloud/store.d.ts +22 -0
  112. package/dist/lib/cloud/store.js +115 -0
  113. package/dist/lib/cloud/stream.d.ts +23 -0
  114. package/dist/lib/cloud/stream.js +194 -0
  115. package/dist/lib/cloud/types.d.ts +205 -0
  116. package/dist/lib/cloud/types.js +34 -0
  117. package/dist/lib/command-skills.d.ts +20 -0
  118. package/dist/lib/command-skills.js +142 -0
  119. package/dist/lib/commands.d.ts +22 -2
  120. package/dist/lib/commands.js +51 -11
  121. package/dist/lib/convert.d.ts +10 -1
  122. package/dist/lib/convert.js +9 -1
  123. package/dist/lib/daemon.d.ts +21 -1
  124. package/dist/lib/daemon.js +97 -4
  125. package/dist/lib/drive-sync.d.ts +18 -1
  126. package/dist/lib/drive-sync.js +57 -15
  127. package/dist/lib/exec.d.ts +25 -5
  128. package/dist/lib/exec.js +72 -27
  129. package/dist/lib/fs-walk.d.ts +2 -0
  130. package/dist/lib/fs-walk.js +40 -0
  131. package/dist/lib/fuzzy.d.ts +53 -0
  132. package/dist/lib/fuzzy.js +72 -0
  133. package/dist/lib/gemini-settings.d.ts +4 -0
  134. package/dist/lib/gemini-settings.js +33 -0
  135. package/dist/lib/git.d.ts +12 -2
  136. package/dist/lib/git.js +17 -6
  137. package/dist/lib/help.d.ts +20 -1
  138. package/dist/lib/help.js +45 -6
  139. package/dist/lib/hooks/match.d.ts +32 -0
  140. package/dist/lib/hooks/match.js +120 -0
  141. package/dist/lib/hooks.d.ts +17 -4
  142. package/dist/lib/hooks.js +191 -21
  143. package/dist/lib/manifest.d.ts +6 -1
  144. package/dist/lib/manifest.js +15 -4
  145. package/dist/lib/markdown.d.ts +0 -1
  146. package/dist/lib/markdown.js +6 -1
  147. package/dist/lib/mcp.d.ts +0 -1
  148. package/dist/lib/mcp.js +29 -33
  149. package/dist/lib/memory-compile.d.ts +13 -3
  150. package/dist/lib/memory-compile.js +31 -9
  151. package/dist/lib/memory.d.ts +14 -7
  152. package/dist/lib/memory.js +67 -38
  153. package/dist/lib/migrate.d.ts +8 -0
  154. package/dist/lib/migrate.js +85 -0
  155. package/dist/lib/models.d.ts +25 -11
  156. package/dist/lib/models.js +405 -16
  157. package/dist/lib/onepassword.d.ts +63 -0
  158. package/dist/lib/onepassword.js +186 -0
  159. package/dist/lib/paths.d.ts +8 -0
  160. package/dist/lib/paths.js +20 -0
  161. package/dist/lib/permissions.d.ts +24 -2
  162. package/dist/lib/permissions.js +117 -48
  163. package/dist/lib/picker.d.ts +10 -1
  164. package/dist/lib/picker.js +15 -1
  165. package/dist/lib/plugins.d.ts +7 -1
  166. package/dist/lib/plugins.js +10 -1
  167. package/dist/lib/profiles-presets.d.ts +24 -0
  168. package/dist/lib/profiles-presets.js +103 -0
  169. package/dist/lib/profiles.d.ts +69 -0
  170. package/dist/lib/profiles.js +144 -0
  171. package/dist/lib/pty-client.d.ts +1 -1
  172. package/dist/lib/pty-client.js +0 -1
  173. package/dist/lib/pty-server.d.ts +16 -2
  174. package/dist/lib/pty-server.js +92 -3
  175. package/dist/lib/registry.d.ts +23 -3
  176. package/dist/lib/registry.js +153 -8
  177. package/dist/lib/resources.d.ts +28 -1
  178. package/dist/lib/resources.js +79 -1
  179. package/dist/lib/rotate.d.ts +79 -0
  180. package/dist/lib/rotate.js +285 -0
  181. package/dist/lib/routines.d.ts +29 -1
  182. package/dist/lib/routines.js +32 -5
  183. package/dist/lib/runner.d.ts +14 -1
  184. package/dist/lib/runner.js +22 -3
  185. package/dist/lib/sandbox.d.ts +16 -1
  186. package/dist/lib/sandbox.js +39 -16
  187. package/dist/lib/scheduler.d.ts +8 -1
  188. package/dist/lib/scheduler.js +8 -1
  189. package/dist/lib/secrets/AgentsKeychain.app/Contents/CodeResources +0 -0
  190. package/dist/lib/secrets/AgentsKeychain.app/Contents/Info.plist +22 -0
  191. package/dist/lib/secrets/AgentsKeychain.app/Contents/MacOS/AgentsKeychain +0 -0
  192. package/dist/lib/secrets/AgentsKeychain.app/Contents/_CodeSignature/CodeResources +123 -0
  193. package/dist/lib/secrets/AgentsKeychain.app/Contents/embedded.provisionprofile +0 -0
  194. package/dist/lib/secrets/bundles.d.ts +39 -0
  195. package/dist/lib/secrets/bundles.js +189 -0
  196. package/dist/lib/secrets/index.d.ts +55 -0
  197. package/dist/lib/secrets/index.js +211 -0
  198. package/dist/lib/secrets/profiles.d.ts +10 -0
  199. package/dist/lib/secrets/profiles.js +13 -0
  200. package/dist/lib/session/active.d.ts +43 -0
  201. package/dist/lib/session/active.js +392 -0
  202. package/dist/lib/session/artifacts.d.ts +16 -0
  203. package/dist/lib/session/artifacts.js +95 -0
  204. package/dist/lib/session/cloud.d.ts +30 -0
  205. package/dist/lib/session/cloud.js +121 -0
  206. package/dist/lib/session/db.d.ts +23 -2
  207. package/dist/lib/session/db.js +76 -12
  208. package/dist/lib/session/discover.d.ts +19 -4
  209. package/dist/lib/session/discover.js +344 -48
  210. package/dist/lib/session/parse.d.ts +28 -1
  211. package/dist/lib/session/parse.js +267 -9
  212. package/dist/lib/session/prompt.d.ts +9 -1
  213. package/dist/lib/session/prompt.js +17 -3
  214. package/dist/lib/session/render.d.ts +13 -1
  215. package/dist/lib/session/render.js +20 -1
  216. package/dist/lib/session/team-filter.d.ts +9 -1
  217. package/dist/lib/session/team-filter.js +11 -2
  218. package/dist/lib/session/types.d.ts +24 -2
  219. package/dist/lib/session/types.js +10 -2
  220. package/dist/lib/shims.d.ts +93 -5
  221. package/dist/lib/shims.js +380 -67
  222. package/dist/lib/skills.d.ts +27 -2
  223. package/dist/lib/skills.js +127 -65
  224. package/dist/lib/sqlite.d.ts +43 -0
  225. package/dist/lib/sqlite.js +94 -0
  226. package/dist/lib/state.d.ts +114 -22
  227. package/dist/lib/state.js +323 -138
  228. package/dist/lib/subagents.d.ts +9 -1
  229. package/dist/lib/subagents.js +70 -63
  230. package/dist/lib/sync-manifest.d.ts +81 -0
  231. package/dist/lib/sync-manifest.js +450 -0
  232. package/dist/lib/teams/agents.d.ts +103 -5
  233. package/dist/lib/teams/agents.js +414 -91
  234. package/dist/lib/teams/api.d.ts +26 -3
  235. package/dist/lib/teams/api.js +63 -3
  236. package/dist/lib/teams/debug.d.ts +6 -1
  237. package/dist/lib/teams/debug.js +6 -1
  238. package/dist/lib/teams/file_ops.d.ts +7 -1
  239. package/dist/lib/teams/file_ops.js +7 -1
  240. package/dist/lib/teams/index.d.ts +15 -0
  241. package/dist/lib/teams/index.js +14 -0
  242. package/dist/lib/teams/parsers.d.ts +4 -1
  243. package/dist/lib/teams/parsers.js +11 -1
  244. package/dist/lib/teams/persistence.d.ts +15 -1
  245. package/dist/lib/teams/persistence.js +102 -20
  246. package/dist/lib/teams/registry.d.ts +12 -1
  247. package/dist/lib/teams/registry.js +116 -33
  248. package/dist/lib/teams/summarizer.d.ts +15 -1
  249. package/dist/lib/teams/summarizer.js +14 -1
  250. package/dist/lib/teams/supervisor.d.ts +48 -0
  251. package/dist/lib/teams/supervisor.js +73 -0
  252. package/dist/lib/template.d.ts +8 -6
  253. package/dist/lib/template.js +8 -6
  254. package/dist/lib/types.d.ts +147 -8
  255. package/dist/lib/types.js +26 -3
  256. package/dist/lib/usage.d.ts +48 -1
  257. package/dist/lib/usage.js +97 -16
  258. package/dist/lib/version-duplicates.d.ts +21 -0
  259. package/dist/lib/version-duplicates.js +90 -0
  260. package/dist/lib/versions.d.ts +39 -4
  261. package/dist/lib/versions.js +401 -111
  262. package/package.json +33 -18
  263. package/scripts/postinstall.js +126 -30
  264. package/dist/commands/__tests__/sessions.test.d.ts +0 -2
  265. package/dist/commands/__tests__/sessions.test.d.ts.map +0 -1
  266. package/dist/commands/__tests__/sessions.test.js +0 -636
  267. package/dist/commands/__tests__/sessions.test.js.map +0 -1
  268. package/dist/commands/commands.d.ts.map +0 -1
  269. package/dist/commands/commands.js.map +0 -1
  270. package/dist/commands/daemon.d.ts.map +0 -1
  271. package/dist/commands/daemon.js.map +0 -1
  272. package/dist/commands/drive.d.ts.map +0 -1
  273. package/dist/commands/drive.js.map +0 -1
  274. package/dist/commands/exec.d.ts.map +0 -1
  275. package/dist/commands/exec.js.map +0 -1
  276. package/dist/commands/fork.d.ts.map +0 -1
  277. package/dist/commands/fork.js.map +0 -1
  278. package/dist/commands/hooks.d.ts.map +0 -1
  279. package/dist/commands/hooks.js.map +0 -1
  280. package/dist/commands/init.d.ts.map +0 -1
  281. package/dist/commands/init.js.map +0 -1
  282. package/dist/commands/mcp.d.ts.map +0 -1
  283. package/dist/commands/mcp.js.map +0 -1
  284. package/dist/commands/models.d.ts.map +0 -1
  285. package/dist/commands/models.js.map +0 -1
  286. package/dist/commands/packages.d.ts.map +0 -1
  287. package/dist/commands/packages.js.map +0 -1
  288. package/dist/commands/permissions.d.ts.map +0 -1
  289. package/dist/commands/permissions.js.map +0 -1
  290. package/dist/commands/plugins.d.ts.map +0 -1
  291. package/dist/commands/plugins.js.map +0 -1
  292. package/dist/commands/pty.d.ts.map +0 -1
  293. package/dist/commands/pty.js.map +0 -1
  294. package/dist/commands/pull.d.ts.map +0 -1
  295. package/dist/commands/pull.js.map +0 -1
  296. package/dist/commands/push.d.ts +0 -3
  297. package/dist/commands/push.d.ts.map +0 -1
  298. package/dist/commands/push.js +0 -180
  299. package/dist/commands/push.js.map +0 -1
  300. package/dist/commands/refresh-memory.d.ts.map +0 -1
  301. package/dist/commands/refresh-memory.js.map +0 -1
  302. package/dist/commands/resource-view.d.ts.map +0 -1
  303. package/dist/commands/resource-view.js.map +0 -1
  304. package/dist/commands/routines.d.ts.map +0 -1
  305. package/dist/commands/routines.js.map +0 -1
  306. package/dist/commands/rules.d.ts.map +0 -1
  307. package/dist/commands/rules.js.map +0 -1
  308. package/dist/commands/sessions-picker.d.ts.map +0 -1
  309. package/dist/commands/sessions-picker.js.map +0 -1
  310. package/dist/commands/sessions.d.ts.map +0 -1
  311. package/dist/commands/sessions.js.map +0 -1
  312. package/dist/commands/skills.d.ts.map +0 -1
  313. package/dist/commands/skills.js.map +0 -1
  314. package/dist/commands/status.d.ts.map +0 -1
  315. package/dist/commands/status.js.map +0 -1
  316. package/dist/commands/subagents.d.ts.map +0 -1
  317. package/dist/commands/subagents.js.map +0 -1
  318. package/dist/commands/sync.d.ts.map +0 -1
  319. package/dist/commands/sync.js.map +0 -1
  320. package/dist/commands/teams-picker.d.ts.map +0 -1
  321. package/dist/commands/teams-picker.js.map +0 -1
  322. package/dist/commands/teams.d.ts.map +0 -1
  323. package/dist/commands/teams.js.map +0 -1
  324. package/dist/commands/utils.d.ts.map +0 -1
  325. package/dist/commands/utils.js.map +0 -1
  326. package/dist/commands/versions.d.ts.map +0 -1
  327. package/dist/commands/versions.js.map +0 -1
  328. package/dist/commands/view.d.ts.map +0 -1
  329. package/dist/commands/view.js.map +0 -1
  330. package/dist/index.d.ts.map +0 -1
  331. package/dist/index.js.map +0 -1
  332. package/dist/lib/__tests__/bugfixes.test.d.ts +0 -2
  333. package/dist/lib/__tests__/bugfixes.test.d.ts.map +0 -1
  334. package/dist/lib/__tests__/bugfixes.test.js +0 -192
  335. package/dist/lib/__tests__/bugfixes.test.js.map +0 -1
  336. package/dist/lib/__tests__/exec.test.d.ts +0 -2
  337. package/dist/lib/__tests__/exec.test.d.ts.map +0 -1
  338. package/dist/lib/__tests__/exec.test.js +0 -446
  339. package/dist/lib/__tests__/exec.test.js.map +0 -1
  340. package/dist/lib/__tests__/git-sync.test.d.ts +0 -2
  341. package/dist/lib/__tests__/git-sync.test.d.ts.map +0 -1
  342. package/dist/lib/__tests__/git-sync.test.js +0 -138
  343. package/dist/lib/__tests__/git-sync.test.js.map +0 -1
  344. package/dist/lib/__tests__/hooks.test.d.ts +0 -2
  345. package/dist/lib/__tests__/hooks.test.d.ts.map +0 -1
  346. package/dist/lib/__tests__/hooks.test.js +0 -203
  347. package/dist/lib/__tests__/hooks.test.js.map +0 -1
  348. package/dist/lib/__tests__/memory-compile.test.d.ts +0 -2
  349. package/dist/lib/__tests__/memory-compile.test.d.ts.map +0 -1
  350. package/dist/lib/__tests__/memory-compile.test.js +0 -95
  351. package/dist/lib/__tests__/memory-compile.test.js.map +0 -1
  352. package/dist/lib/__tests__/models.test.d.ts +0 -2
  353. package/dist/lib/__tests__/models.test.d.ts.map +0 -1
  354. package/dist/lib/__tests__/models.test.js +0 -184
  355. package/dist/lib/__tests__/models.test.js.map +0 -1
  356. package/dist/lib/__tests__/usage.test.d.ts +0 -2
  357. package/dist/lib/__tests__/usage.test.d.ts.map +0 -1
  358. package/dist/lib/__tests__/usage.test.js +0 -218
  359. package/dist/lib/__tests__/usage.test.js.map +0 -1
  360. package/dist/lib/agents.d.ts.map +0 -1
  361. package/dist/lib/agents.js.map +0 -1
  362. package/dist/lib/artifact-actions.d.ts.map +0 -1
  363. package/dist/lib/artifact-actions.js.map +0 -1
  364. package/dist/lib/commands.d.ts.map +0 -1
  365. package/dist/lib/commands.js.map +0 -1
  366. package/dist/lib/convert.d.ts.map +0 -1
  367. package/dist/lib/convert.js.map +0 -1
  368. package/dist/lib/daemon.d.ts.map +0 -1
  369. package/dist/lib/daemon.js.map +0 -1
  370. package/dist/lib/drive-sync.d.ts.map +0 -1
  371. package/dist/lib/drive-sync.js.map +0 -1
  372. package/dist/lib/exec.d.ts.map +0 -1
  373. package/dist/lib/exec.js.map +0 -1
  374. package/dist/lib/factory.d.ts +0 -57
  375. package/dist/lib/factory.d.ts.map +0 -1
  376. package/dist/lib/factory.js +0 -110
  377. package/dist/lib/factory.js.map +0 -1
  378. package/dist/lib/git.d.ts.map +0 -1
  379. package/dist/lib/git.js.map +0 -1
  380. package/dist/lib/help.d.ts.map +0 -1
  381. package/dist/lib/help.js.map +0 -1
  382. package/dist/lib/hooks.d.ts.map +0 -1
  383. package/dist/lib/hooks.js.map +0 -1
  384. package/dist/lib/manifest.d.ts.map +0 -1
  385. package/dist/lib/manifest.js.map +0 -1
  386. package/dist/lib/markdown.d.ts.map +0 -1
  387. package/dist/lib/markdown.js.map +0 -1
  388. package/dist/lib/mcp.d.ts.map +0 -1
  389. package/dist/lib/mcp.js.map +0 -1
  390. package/dist/lib/memory-compile.d.ts.map +0 -1
  391. package/dist/lib/memory-compile.js.map +0 -1
  392. package/dist/lib/memory.d.ts.map +0 -1
  393. package/dist/lib/memory.js.map +0 -1
  394. package/dist/lib/models.d.ts.map +0 -1
  395. package/dist/lib/models.js.map +0 -1
  396. package/dist/lib/permissions.d.ts.map +0 -1
  397. package/dist/lib/permissions.js.map +0 -1
  398. package/dist/lib/picker.d.ts.map +0 -1
  399. package/dist/lib/picker.js.map +0 -1
  400. package/dist/lib/plugins.d.ts.map +0 -1
  401. package/dist/lib/plugins.js.map +0 -1
  402. package/dist/lib/pty-client.d.ts.map +0 -1
  403. package/dist/lib/pty-client.js.map +0 -1
  404. package/dist/lib/pty-server.d.ts.map +0 -1
  405. package/dist/lib/pty-server.js.map +0 -1
  406. package/dist/lib/registry.d.ts.map +0 -1
  407. package/dist/lib/registry.js.map +0 -1
  408. package/dist/lib/resources.d.ts.map +0 -1
  409. package/dist/lib/resources.js.map +0 -1
  410. package/dist/lib/routines.d.ts.map +0 -1
  411. package/dist/lib/routines.js.map +0 -1
  412. package/dist/lib/runner.d.ts.map +0 -1
  413. package/dist/lib/runner.js.map +0 -1
  414. package/dist/lib/sandbox.d.ts.map +0 -1
  415. package/dist/lib/sandbox.js.map +0 -1
  416. package/dist/lib/scheduler.d.ts.map +0 -1
  417. package/dist/lib/scheduler.js.map +0 -1
  418. package/dist/lib/session/__tests__/db.test.d.ts +0 -2
  419. package/dist/lib/session/__tests__/db.test.d.ts.map +0 -1
  420. package/dist/lib/session/__tests__/db.test.js +0 -54
  421. package/dist/lib/session/__tests__/db.test.js.map +0 -1
  422. package/dist/lib/session/__tests__/discover.test.d.ts +0 -2
  423. package/dist/lib/session/__tests__/discover.test.d.ts.map +0 -1
  424. package/dist/lib/session/__tests__/discover.test.js +0 -63
  425. package/dist/lib/session/__tests__/discover.test.js.map +0 -1
  426. package/dist/lib/session/__tests__/prompt.test.d.ts +0 -2
  427. package/dist/lib/session/__tests__/prompt.test.d.ts.map +0 -1
  428. package/dist/lib/session/__tests__/prompt.test.js +0 -44
  429. package/dist/lib/session/__tests__/prompt.test.js.map +0 -1
  430. package/dist/lib/session/__tests__/render.test.d.ts +0 -2
  431. package/dist/lib/session/__tests__/render.test.d.ts.map +0 -1
  432. package/dist/lib/session/__tests__/render.test.js +0 -602
  433. package/dist/lib/session/__tests__/render.test.js.map +0 -1
  434. package/dist/lib/session/db.d.ts.map +0 -1
  435. package/dist/lib/session/db.js.map +0 -1
  436. package/dist/lib/session/discover.d.ts.map +0 -1
  437. package/dist/lib/session/discover.js.map +0 -1
  438. package/dist/lib/session/parse.d.ts.map +0 -1
  439. package/dist/lib/session/parse.js.map +0 -1
  440. package/dist/lib/session/prompt.d.ts.map +0 -1
  441. package/dist/lib/session/prompt.js.map +0 -1
  442. package/dist/lib/session/prompt.test.d.ts +0 -2
  443. package/dist/lib/session/prompt.test.d.ts.map +0 -1
  444. package/dist/lib/session/prompt.test.js +0 -57
  445. package/dist/lib/session/prompt.test.js.map +0 -1
  446. package/dist/lib/session/render.d.ts.map +0 -1
  447. package/dist/lib/session/render.js.map +0 -1
  448. package/dist/lib/session/team-filter.d.ts.map +0 -1
  449. package/dist/lib/session/team-filter.js.map +0 -1
  450. package/dist/lib/session/team-filter.test.d.ts +0 -2
  451. package/dist/lib/session/team-filter.test.d.ts.map +0 -1
  452. package/dist/lib/session/team-filter.test.js +0 -157
  453. package/dist/lib/session/team-filter.test.js.map +0 -1
  454. package/dist/lib/session/types.d.ts.map +0 -1
  455. package/dist/lib/session/types.js.map +0 -1
  456. package/dist/lib/shims.d.ts.map +0 -1
  457. package/dist/lib/shims.js.map +0 -1
  458. package/dist/lib/skills.d.ts.map +0 -1
  459. package/dist/lib/skills.js.map +0 -1
  460. package/dist/lib/state.d.ts.map +0 -1
  461. package/dist/lib/state.js.map +0 -1
  462. package/dist/lib/subagents.d.ts.map +0 -1
  463. package/dist/lib/subagents.js.map +0 -1
  464. package/dist/lib/teams/agents.d.ts.map +0 -1
  465. package/dist/lib/teams/agents.js.map +0 -1
  466. package/dist/lib/teams/api.d.ts.map +0 -1
  467. package/dist/lib/teams/api.js.map +0 -1
  468. package/dist/lib/teams/cloud.d.ts +0 -11
  469. package/dist/lib/teams/cloud.d.ts.map +0 -1
  470. package/dist/lib/teams/cloud.js +0 -169
  471. package/dist/lib/teams/cloud.js.map +0 -1
  472. package/dist/lib/teams/debug.d.ts.map +0 -1
  473. package/dist/lib/teams/debug.js.map +0 -1
  474. package/dist/lib/teams/file_ops.d.ts.map +0 -1
  475. package/dist/lib/teams/file_ops.js.map +0 -1
  476. package/dist/lib/teams/parsers.d.ts.map +0 -1
  477. package/dist/lib/teams/parsers.js.map +0 -1
  478. package/dist/lib/teams/persistence.d.ts.map +0 -1
  479. package/dist/lib/teams/persistence.js.map +0 -1
  480. package/dist/lib/teams/ralph.d.ts +0 -8
  481. package/dist/lib/teams/ralph.d.ts.map +0 -1
  482. package/dist/lib/teams/ralph.js +0 -59
  483. package/dist/lib/teams/ralph.js.map +0 -1
  484. package/dist/lib/teams/registry.d.ts.map +0 -1
  485. package/dist/lib/teams/registry.js.map +0 -1
  486. package/dist/lib/teams/summarizer.d.ts.map +0 -1
  487. package/dist/lib/teams/summarizer.js.map +0 -1
  488. package/dist/lib/template.d.ts.map +0 -1
  489. package/dist/lib/template.js.map +0 -1
  490. package/dist/lib/types.d.ts.map +0 -1
  491. package/dist/lib/types.js.map +0 -1
  492. package/dist/lib/usage.d.ts.map +0 -1
  493. package/dist/lib/usage.js.map +0 -1
  494. package/dist/lib/versions.d.ts.map +0 -1
  495. package/dist/lib/versions.js.map +0 -1
  496. package/scripts/rebuild-sqlite.sh +0 -46
@@ -0,0 +1,438 @@
1
+ /**
2
+ * Rush Cloud provider -- dispatches tasks to the Factory Floor via api.prix.dev.
3
+ *
4
+ * Auth: reads the session token from ~/.rush/user.yaml (written by `rush login`).
5
+ * Requires the Rush GitHub App installed on the target repo.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import * as os from 'os';
10
+ import * as crypto from 'crypto';
11
+ import * as yaml from 'yaml';
12
+ import { getAgentsDir } from '../state.js';
13
+ import { resolveDispatchRepos } from './types.js';
14
+ import { parseSSE } from './stream.js';
15
+ import { listInstalledVersions, getVersionHomePath } from '../versions.js';
16
+ import { getAccountInfo } from '../agents.js';
17
+ import { loadClaudeOauth } from '../usage.js';
18
+ const PROXY_BASE = 'https://api.prix.dev';
19
+ const USER_YAML = path.join(os.homedir(), '.rush', 'user.yaml');
20
+ // Persistent consent record for uploading Claude OAuth blobs to Rush Cloud.
21
+ // Created on first explicit consent (env var or flag); subsequent dispatches
22
+ // see it and proceed without re-prompting.
23
+ const RUSH_CONSENT_PATH = path.join(getAgentsDir(), 'cloud', 'rush-consent.json');
24
+ const RUSH_CONSENT_ENV = 'AGENTS_RUSH_UPLOAD_TOKENS';
25
+ function hasRushUploadConsent(opts) {
26
+ if (process.env[RUSH_CONSENT_ENV] === '1')
27
+ return true;
28
+ const po = opts?.providerOptions;
29
+ if (po?.uploadAccountTokens === true)
30
+ return true;
31
+ return fs.existsSync(RUSH_CONSENT_PATH);
32
+ }
33
+ function recordRushUploadConsent(grantedBy) {
34
+ try {
35
+ fs.mkdirSync(path.dirname(RUSH_CONSENT_PATH), { recursive: true });
36
+ const body = { granted_at: new Date().toISOString(), granted_by: grantedBy };
37
+ fs.writeFileSync(RUSH_CONSENT_PATH, JSON.stringify(body, null, 2), { mode: 0o600 });
38
+ }
39
+ catch {
40
+ // Non-fatal: consent persistence is a UX optimization, not a security
41
+ // boundary. Worst case, the user is asked to consent again next dispatch.
42
+ }
43
+ }
44
+ /** Map a Factory Floor status string to the canonical CloudTaskStatus enum. */
45
+ function mapStatus(s) {
46
+ switch (s) {
47
+ case 'allocating': return 'allocating';
48
+ case 'running': return 'running';
49
+ case 'needs_review': return 'input_required';
50
+ case 'completed': return 'completed';
51
+ case 'failed': return 'failed';
52
+ case 'cancelled': return 'cancelled';
53
+ default: return 'running';
54
+ }
55
+ }
56
+ /** Read the Rush session access token from ~/.rush/user.yaml. */
57
+ function readToken() {
58
+ if (!fs.existsSync(USER_YAML)) {
59
+ throw new Error('Not logged in to Rush. Run `rush login` first.');
60
+ }
61
+ const raw = fs.readFileSync(USER_YAML, 'utf-8');
62
+ const data = yaml.parse(raw);
63
+ const token = data?.session?.access_token;
64
+ if (!token) {
65
+ throw new Error('No session token in ~/.rush/user.yaml. Run `rush login` first.');
66
+ }
67
+ return token;
68
+ }
69
+ /** Read the user's email from the Rush session config, if available. */
70
+ function readEmail() {
71
+ try {
72
+ const raw = fs.readFileSync(USER_YAML, 'utf-8');
73
+ const data = yaml.parse(raw);
74
+ return data?.session?.email;
75
+ }
76
+ catch {
77
+ return undefined;
78
+ }
79
+ }
80
+ /** Make an authenticated request to the Rush API proxy. */
81
+ async function api(method, endpoint, token, body) {
82
+ const url = endpoint.startsWith('http') ? endpoint : `${PROXY_BASE}${endpoint}`;
83
+ const headers = {
84
+ 'Authorization': `Bearer ${token}`,
85
+ 'Content-Type': 'application/json',
86
+ };
87
+ return fetch(url, {
88
+ method,
89
+ headers,
90
+ body: body ? JSON.stringify(body) : undefined,
91
+ });
92
+ }
93
+ /** Find the GitHub App installation ID for a given owner/repo pair. */
94
+ async function findInstallation(token, owner, repo) {
95
+ const res = await api('GET', '/api/v1/github/app/installations', token);
96
+ if (!res.ok) {
97
+ throw new Error(`Failed to fetch GitHub installations (${res.status}). Is the Rush GitHub App installed?`);
98
+ }
99
+ const data = await res.json();
100
+ for (const inst of data.installations ?? []) {
101
+ if (inst.account_login?.toLowerCase() === owner.toLowerCase()) {
102
+ if (inst.repository_selection === 'all')
103
+ return inst.id;
104
+ if (inst.repositories?.some(r => r.name.toLowerCase() === repo.toLowerCase())) {
105
+ return inst.id;
106
+ }
107
+ }
108
+ }
109
+ throw new Error(`No GitHub App installation found for ${owner}/${repo}. Install the Rush GitHub App at https://github.com/apps/prix-cloud.`);
110
+ }
111
+ /** sha256 → hex. */
112
+ function sha256(input) {
113
+ return crypto.createHash('sha256').update(input).digest('hex');
114
+ }
115
+ /**
116
+ * Strip tokens/credentials from a server error body before surfacing it.
117
+ * If the body is JSON with a `message` or `error` field, prefer that.
118
+ * Otherwise truncate and redact anything that looks like a bearer token or JWT.
119
+ */
120
+ function sanitizeErrorBody(body) {
121
+ const MAX_LEN = 300;
122
+ try {
123
+ const parsed = JSON.parse(body);
124
+ const msg = (parsed.message ?? parsed.error ?? parsed.detail);
125
+ if (typeof msg === 'string')
126
+ return msg.slice(0, MAX_LEN);
127
+ }
128
+ catch { /* not JSON, fall through */ }
129
+ let safe = body.slice(0, MAX_LEN);
130
+ safe = safe.replace(/eyJ[A-Za-z0-9_-]{20,}/g, '[REDACTED_TOKEN]');
131
+ safe = safe.replace(/Bearer\s+\S+/gi, 'Bearer [REDACTED]');
132
+ safe = safe.replace(/"(access_token|refresh_token|credentials_json)"\s*:\s*"[^"]*"/g, '"$1":"[REDACTED]"');
133
+ if (body.length > MAX_LEN)
134
+ safe += '...';
135
+ return safe;
136
+ }
137
+ /**
138
+ * Pull `prompt_code` out of a JSON-encoded error body. Returns null when the
139
+ * body isn't JSON or doesn't carry one — caller falls through to the generic
140
+ * dispatch-failed path.
141
+ */
142
+ function parsePromptCode(body) {
143
+ try {
144
+ const parsed = JSON.parse(body);
145
+ return typeof parsed.prompt_code === 'string' ? parsed.prompt_code : null;
146
+ }
147
+ catch {
148
+ return null;
149
+ }
150
+ }
151
+ /**
152
+ * Read the raw OAuth credentials for one Claude version. On Mac, prefer the
153
+ * Keychain blob (canonical). On Linux/CI, fall back to `.claude/.credentials.json`
154
+ * inside the version home (where the Linux Claude CLI stores its OAuth).
155
+ *
156
+ * Returns null when no credentials are findable — caller treats as "version
157
+ * is installed but not signed in" and skips it from the manifest.
158
+ */
159
+ async function readClaudeCredentialsBlob(home) {
160
+ if (process.platform === 'darwin') {
161
+ const oauth = await loadClaudeOauth(home);
162
+ if (oauth && oauth.accessToken) {
163
+ return JSON.stringify(oauth);
164
+ }
165
+ }
166
+ const credsPath = path.join(home, '.claude', '.credentials.json');
167
+ try {
168
+ if (fs.existsSync(credsPath)) {
169
+ const raw = fs.readFileSync(credsPath, 'utf-8').trim();
170
+ if (raw)
171
+ return raw;
172
+ }
173
+ }
174
+ catch {
175
+ // fall through to null
176
+ }
177
+ return null;
178
+ }
179
+ /**
180
+ * Build a manifest of the user's local Claude installations to send on every
181
+ * cloud dispatch. The manifest is the contract the server uses to detect when
182
+ * the user has added a new account or rotated a token.
183
+ *
184
+ * Returns null when no Claude versions are signed in (the dispatch falls back
185
+ * to the platform-wide key, current behavior).
186
+ */
187
+ export async function buildAccountManifest() {
188
+ const versions = listInstalledVersions('claude');
189
+ if (versions.length === 0)
190
+ return null;
191
+ const entries = [];
192
+ for (const version of versions) {
193
+ const home = getVersionHomePath('claude', version);
194
+ const info = await getAccountInfo('claude', home);
195
+ if (!info.email)
196
+ continue;
197
+ const blob = await readClaudeCredentialsBlob(home);
198
+ if (!blob)
199
+ continue;
200
+ entries.push({ version, email: info.email, cred_fp: sha256(blob) });
201
+ }
202
+ if (entries.length === 0)
203
+ return null;
204
+ entries.sort((a, b) => a.version.localeCompare(b.version));
205
+ const fp = sha256(JSON.stringify(entries));
206
+ return { fp, versions: entries };
207
+ }
208
+ /**
209
+ * Re-load OAuth blobs for the given versions so they can be uploaded to the
210
+ * server on a retry. Only the versions named in the manifest are loaded — we
211
+ * never upload tokens for versions the server hasn't asked about.
212
+ */
213
+ export async function buildAccountTokensPayload(versions) {
214
+ const out = [];
215
+ for (const version of versions) {
216
+ const home = getVersionHomePath('claude', version);
217
+ const blob = await readClaudeCredentialsBlob(home);
218
+ if (!blob)
219
+ continue;
220
+ out.push({ version, credentials_json: blob });
221
+ }
222
+ return out;
223
+ }
224
+ /**
225
+ * Build the POST body for /api/v1/cloud-runs. Exported so tests can verify
226
+ * the back-compat shape (singular fields + repos[]) without needing real
227
+ * GitHub installations or a live Rush session. `findInstallation` is the
228
+ * only other I/O and it's tested by the halo/proxy integration suite.
229
+ */
230
+ export function buildDispatchBody(input) {
231
+ if (input.resolvedRepos.length === 0) {
232
+ throw new Error('buildDispatchBody: resolvedRepos must have at least one entry');
233
+ }
234
+ const primary = input.resolvedRepos[0];
235
+ const body = {
236
+ agent: input.agent ?? 'claude',
237
+ prompt: input.prompt,
238
+ repos: input.resolvedRepos,
239
+ mode: input.mode,
240
+ };
241
+ if (input.resolvedRepos.length === 1) {
242
+ body.installation_id = primary.installation_id;
243
+ body.repo_owner = primary.repo_owner;
244
+ body.repo_name = primary.repo_name;
245
+ }
246
+ if (input.accountManifest) {
247
+ body.account_manifest = input.accountManifest;
248
+ }
249
+ if (input.accountTokens && input.accountTokens.length > 0) {
250
+ body.account_tokens = input.accountTokens;
251
+ }
252
+ return body;
253
+ }
254
+ export class RushCloudProvider {
255
+ id = 'rush';
256
+ name = 'Rush Cloud';
257
+ capabilities() {
258
+ return {
259
+ available: fs.existsSync(USER_YAML),
260
+ dispatch: true,
261
+ status: true,
262
+ list: true,
263
+ stream: true,
264
+ cancel: true,
265
+ message: true,
266
+ multiRepo: true,
267
+ skills: false,
268
+ images: false,
269
+ };
270
+ }
271
+ async dispatch(options) {
272
+ const repos = resolveDispatchRepos(options);
273
+ if (repos.length === 0) {
274
+ throw new Error('Rush Cloud requires --repo <owner/repo> (or --repo repeated for multi-repo).');
275
+ }
276
+ // Validate each repo's shape and resolve its installation_id up front.
277
+ // Any bad entry fails the whole dispatch — we never want a half-started
278
+ // multi-repo run that only found installations for some of the repos.
279
+ const token = readToken();
280
+ const parsed = repos.map((full) => {
281
+ const parts = full.split('/');
282
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
283
+ throw new Error(`Invalid repo format: ${JSON.stringify(full)}. Use owner/repo.`);
284
+ }
285
+ return { full, owner: parts[0], name: parts[1] };
286
+ });
287
+ const resolvedRepos = await Promise.all(parsed.map(async (r) => ({
288
+ installation_id: await findInstallation(token, r.owner, r.name),
289
+ repo_owner: r.owner,
290
+ repo_name: r.name,
291
+ })));
292
+ const accountManifest = await buildAccountManifest();
293
+ const body = buildDispatchBody({
294
+ agent: options.agent,
295
+ prompt: options.prompt,
296
+ mode: options.providerOptions?.mode,
297
+ resolvedRepos,
298
+ accountManifest,
299
+ });
300
+ let res = await api('POST', '/api/v1/cloud-runs', token, body);
301
+ // Server detects drift (new account or rotated token) by comparing the
302
+ // manifest's fp against what's stored. It returns 401 with a prompt_code
303
+ // telling the client to re-upload the actual token blobs and retry once.
304
+ if (res.status === 401 && accountManifest) {
305
+ const errBody = await res.clone().text();
306
+ const promptCode = parsePromptCode(errBody);
307
+ if (promptCode === 'NEW_ACCOUNT' || promptCode === 'TOKEN_ROTATED') {
308
+ // Refuse to silently exfiltrate Claude OAuth credentials. The retry
309
+ // path below reads accessToken+refreshToken from every installed
310
+ // Claude version and POSTs them to api.prix.dev. That's an explicit
311
+ // data-flow decision the user has to opt into.
312
+ if (!hasRushUploadConsent(options)) {
313
+ throw new Error([
314
+ `Rush Cloud asked to sync your Claude credentials (reason: ${promptCode.toLowerCase()}).`,
315
+ `This would upload accessToken + refreshToken from every installed Claude version`,
316
+ `to ${PROXY_BASE} so Factory Floor pods can act as your Anthropic account.`,
317
+ ``,
318
+ `To consent, re-run with one of:`,
319
+ ` AGENTS_RUSH_UPLOAD_TOKENS=1 agents cloud run ...`,
320
+ ` agents cloud run --upload-account-tokens ... # if your CLI exposes this flag`,
321
+ ``,
322
+ `Consent will be recorded at ${RUSH_CONSENT_PATH} so you won't be asked again.`,
323
+ `Remove that file to revoke.`,
324
+ ].join('\n'));
325
+ }
326
+ // Always-on stderr notice (no isTTY gate). Scripts and CI need to see
327
+ // this in their captured stderr / logs.
328
+ const grantedBy = process.env[RUSH_CONSENT_ENV] === '1' ? 'env'
329
+ : options.providerOptions?.uploadAccountTokens === true ? 'flag'
330
+ : 'manual';
331
+ process.stderr.write(`[rush] uploading Claude OAuth credentials to ${PROXY_BASE} (reason: ${promptCode.toLowerCase()}, consent: ${grantedBy})\n`);
332
+ const accountTokens = await buildAccountTokensPayload(accountManifest.versions.map((v) => v.version));
333
+ const retryBody = buildDispatchBody({
334
+ agent: options.agent,
335
+ prompt: options.prompt,
336
+ mode: options.providerOptions?.mode,
337
+ resolvedRepos,
338
+ accountManifest,
339
+ accountTokens,
340
+ });
341
+ res = await api('POST', '/api/v1/cloud-runs', token, retryBody);
342
+ // Persist consent on first successful upload so we don't re-prompt
343
+ // every time tokens rotate.
344
+ if (res.ok && grantedBy !== 'manual') {
345
+ recordRushUploadConsent(grantedBy);
346
+ }
347
+ }
348
+ }
349
+ if (!res.ok) {
350
+ const text = await res.text();
351
+ throw new Error(`Dispatch failed (${res.status}): ${sanitizeErrorBody(text)}`);
352
+ }
353
+ const data = await res.json();
354
+ const now = new Date().toISOString();
355
+ return {
356
+ id: data.execution_id,
357
+ provider: 'rush',
358
+ status: 'queued',
359
+ agent: options.agent ?? 'claude',
360
+ prompt: options.prompt,
361
+ repo: repos[0],
362
+ repos: repos,
363
+ branch: options.branch,
364
+ createdAt: now,
365
+ updatedAt: now,
366
+ };
367
+ }
368
+ async status(taskId) {
369
+ const token = readToken();
370
+ const res = await api('GET', `/api/v1/cloud-runs/${taskId}`, token);
371
+ if (!res.ok) {
372
+ throw new Error(`Failed to get task status (${res.status}).`);
373
+ }
374
+ const data = await res.json();
375
+ return {
376
+ id: taskId,
377
+ provider: 'rush',
378
+ status: mapStatus(data.status),
379
+ agent: data.agent || undefined,
380
+ prompt: data.prompt || '',
381
+ repo: data.repo_owner && data.repo_name ? `${data.repo_owner}/${data.repo_name}` : undefined,
382
+ branch: data.branch || undefined,
383
+ prUrl: data.pr_url || undefined,
384
+ summary: data.summary || undefined,
385
+ createdAt: data.created_at || new Date().toISOString(),
386
+ updatedAt: data.updated_at || new Date().toISOString(),
387
+ };
388
+ }
389
+ async list(filter) {
390
+ const token = readToken();
391
+ const params = new URLSearchParams();
392
+ if (filter?.status)
393
+ params.set('status', filter.status);
394
+ const qs = params.toString() ? `?${params.toString()}` : '';
395
+ const res = await api('GET', `/api/v1/cloud-runs${qs}`, token);
396
+ if (!res.ok) {
397
+ throw new Error(`Failed to list tasks (${res.status}).`);
398
+ }
399
+ const data = await res.json();
400
+ return (data.executions ?? []).map((e) => ({
401
+ id: e.execution_id,
402
+ provider: 'rush',
403
+ status: mapStatus(e.status),
404
+ agent: e.agent || undefined,
405
+ prompt: e.prompt || '',
406
+ repo: e.repo_owner && e.repo_name ? `${e.repo_owner}/${e.repo_name}` : undefined,
407
+ branch: e.branch || undefined,
408
+ prUrl: e.pr_url || undefined,
409
+ summary: e.summary || undefined,
410
+ createdAt: e.created_at || '',
411
+ updatedAt: e.updated_at || '',
412
+ }));
413
+ }
414
+ async *stream(taskId) {
415
+ const token = readToken();
416
+ const res = await fetch(`${PROXY_BASE}/api/v1/cloud-runs/${taskId}/stream`, {
417
+ headers: { 'Authorization': `Bearer ${token}` },
418
+ });
419
+ if (!res.ok) {
420
+ throw new Error(`Failed to connect to stream (${res.status}).`);
421
+ }
422
+ yield* parseSSE(res);
423
+ }
424
+ async cancel(taskId) {
425
+ const token = readToken();
426
+ const res = await api('DELETE', `/api/v1/cloud-runs/${taskId}`, token);
427
+ if (!res.ok) {
428
+ throw new Error(`Failed to cancel task (${res.status}).`);
429
+ }
430
+ }
431
+ async message(taskId, content) {
432
+ const token = readToken();
433
+ const res = await api('POST', `/api/v1/cloud-runs/${taskId}/message`, token, { content });
434
+ if (!res.ok) {
435
+ throw new Error(`Failed to send message (${res.status}).`);
436
+ }
437
+ }
438
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Local SQLite persistence for cloud-dispatched tasks.
3
+ *
4
+ * Every dispatch, status poll, and list query flows through this module so
5
+ * that task history survives across CLI invocations without hitting the
6
+ * remote provider each time.
7
+ */
8
+ import type { CloudTask, CloudProviderId, CloudTaskStatus } from './types.js';
9
+ /** Persist a task snapshot, replacing any existing row with the same ID. */
10
+ export declare function insertTask(task: CloudTask): void;
11
+ /** Update a task's status and optionally patch summary, PR URL, or branch. */
12
+ export declare function updateTaskStatus(id: string, status: CloudTaskStatus, extra?: Partial<Pick<CloudTask, 'summary' | 'prUrl' | 'branch'>>): void;
13
+ /** Fetch a single task by its provider-assigned ID, or null if not found locally. */
14
+ export declare function getTaskById(id: string): CloudTask | null;
15
+ /** List tasks with optional provider/status filters, ordered newest-first. */
16
+ export declare function listTasks(filter?: {
17
+ provider?: CloudProviderId;
18
+ status?: CloudTaskStatus;
19
+ limit?: number;
20
+ }): CloudTask[];
21
+ /** Return tasks still in a transient state (queued, allocating, running, input_required). */
22
+ export declare function listActiveTasks(): CloudTask[];
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Local SQLite persistence for cloud-dispatched tasks.
3
+ *
4
+ * Every dispatch, status poll, and list query flows through this module so
5
+ * that task history survives across CLI invocations without hitting the
6
+ * remote provider each time.
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import Database from '../sqlite.js';
11
+ import { getAgentsDir } from '../state.js';
12
+ const CLOUD_DIR = path.join(getAgentsDir(), 'cloud');
13
+ const DB_PATH = path.join(CLOUD_DIR, 'tasks.db');
14
+ const SCHEMA = `
15
+ CREATE TABLE IF NOT EXISTS tasks (
16
+ id TEXT PRIMARY KEY,
17
+ provider TEXT NOT NULL,
18
+ status TEXT NOT NULL,
19
+ agent TEXT,
20
+ prompt TEXT NOT NULL,
21
+ repo TEXT,
22
+ branch TEXT,
23
+ pr_url TEXT,
24
+ summary TEXT,
25
+ created_at TEXT NOT NULL,
26
+ updated_at TEXT NOT NULL,
27
+ provider_data TEXT
28
+ );
29
+ CREATE INDEX IF NOT EXISTS idx_tasks_provider ON tasks(provider);
30
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
31
+ CREATE INDEX IF NOT EXISTS idx_tasks_created ON tasks(created_at DESC);
32
+ `;
33
+ let _db = null;
34
+ /** Lazy-initialize the SQLite connection, creating the database and schema on first access. */
35
+ function db() {
36
+ if (_db)
37
+ return _db;
38
+ fs.mkdirSync(CLOUD_DIR, { recursive: true });
39
+ _db = new Database(DB_PATH);
40
+ _db.pragma('journal_mode = WAL');
41
+ _db.exec(SCHEMA);
42
+ return _db;
43
+ }
44
+ /** Persist a task snapshot, replacing any existing row with the same ID. */
45
+ export function insertTask(task) {
46
+ db().prepare(`
47
+ INSERT OR REPLACE INTO tasks (id, provider, status, agent, prompt, repo, branch, pr_url, summary, created_at, updated_at)
48
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
49
+ `).run(task.id, task.provider, task.status, task.agent ?? null, task.prompt, task.repo ?? null, task.branch ?? null, task.prUrl ?? null, task.summary ?? null, task.createdAt, task.updatedAt);
50
+ }
51
+ /** Update a task's status and optionally patch summary, PR URL, or branch. */
52
+ export function updateTaskStatus(id, status, extra) {
53
+ const now = new Date().toISOString();
54
+ const sets = ['status = ?', 'updated_at = ?'];
55
+ const params = [status, now];
56
+ if (extra?.summary !== undefined) {
57
+ sets.push('summary = ?');
58
+ params.push(extra.summary);
59
+ }
60
+ if (extra?.prUrl !== undefined) {
61
+ sets.push('pr_url = ?');
62
+ params.push(extra.prUrl);
63
+ }
64
+ if (extra?.branch !== undefined) {
65
+ sets.push('branch = ?');
66
+ params.push(extra.branch);
67
+ }
68
+ params.push(id);
69
+ db().prepare(`UPDATE tasks SET ${sets.join(', ')} WHERE id = ?`).run(...params);
70
+ }
71
+ /** Fetch a single task by its provider-assigned ID, or null if not found locally. */
72
+ export function getTaskById(id) {
73
+ const row = db().prepare('SELECT * FROM tasks WHERE id = ?').get(id);
74
+ return row ? rowToTask(row) : null;
75
+ }
76
+ /** List tasks with optional provider/status filters, ordered newest-first. */
77
+ export function listTasks(filter) {
78
+ const clauses = [];
79
+ const params = [];
80
+ if (filter?.provider) {
81
+ clauses.push('provider = ?');
82
+ params.push(filter.provider);
83
+ }
84
+ if (filter?.status) {
85
+ clauses.push('status = ?');
86
+ params.push(filter.status);
87
+ }
88
+ const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
89
+ const limit = filter?.limit ?? 50;
90
+ const rows = db().prepare(`SELECT * FROM tasks ${where} ORDER BY created_at DESC LIMIT ?`).all(...params, limit);
91
+ return rows.map(rowToTask);
92
+ }
93
+ const TERMINAL_STATUSES = ['completed', 'failed', 'cancelled'];
94
+ /** Return tasks still in a transient state (queued, allocating, running, input_required). */
95
+ export function listActiveTasks() {
96
+ const placeholders = TERMINAL_STATUSES.map(() => '?').join(', ');
97
+ const rows = db().prepare(`SELECT * FROM tasks WHERE status NOT IN (${placeholders}) ORDER BY created_at DESC`).all(...TERMINAL_STATUSES);
98
+ return rows.map(rowToTask);
99
+ }
100
+ /** Map a raw SQLite row to a typed CloudTask, converting snake_case columns to camelCase. */
101
+ function rowToTask(row) {
102
+ return {
103
+ id: row.id,
104
+ provider: row.provider,
105
+ status: row.status,
106
+ agent: row.agent || undefined,
107
+ prompt: row.prompt,
108
+ repo: row.repo || undefined,
109
+ branch: row.branch || undefined,
110
+ prUrl: row.pr_url || undefined,
111
+ summary: row.summary || undefined,
112
+ createdAt: row.created_at,
113
+ updatedAt: row.updated_at,
114
+ };
115
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Server-Sent Events parser and terminal renderer for cloud task output.
3
+ *
4
+ * Used by `agents cloud logs -f` to stream live output from a running task
5
+ * and by the post-dispatch follow mode to show progress inline.
6
+ */
7
+ import type { CloudEvent } from './types.js';
8
+ /**
9
+ * Parse a Server-Sent Events stream into CloudEvents.
10
+ * Handles `event:`, `data:`, keepalive comments, and multi-line data.
11
+ */
12
+ export declare function parseSSE(response: Response): AsyncIterable<CloudEvent>;
13
+ /**
14
+ * Render a stream of CloudEvents to the terminal.
15
+ * Returns the final status and summary when the stream ends.
16
+ */
17
+ export declare function renderStream(events: AsyncIterable<CloudEvent>, options?: {
18
+ json?: boolean;
19
+ }): Promise<{
20
+ status: string;
21
+ summary?: string;
22
+ prUrl?: string;
23
+ }>;