rovecode 0.3.3 → 0.4.0-beta.2

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 (491) hide show
  1. package/CHANGELOG.md +512 -0
  2. package/README.md +33 -48
  3. package/bin/rovecode.js +24 -0
  4. package/dist/cli/app-dybnr56b.js +2 -0
  5. package/dist/cli/ask-user-p8hq4xgj.js +2 -0
  6. package/dist/cli/auth-login-ewpgw5sm.js +2 -0
  7. package/dist/cli/auth-m8p9grty.js +2 -0
  8. package/dist/cli/bench-xv3ypwev.js +9 -0
  9. package/dist/cli/catalog-737wb2s0.js +2 -0
  10. package/dist/cli/cli-arhg40m0.js +2 -0
  11. package/dist/cli/client-cf2pxx8q.js +2 -0
  12. package/dist/cli/commands-3p7e4xxs.js +2 -0
  13. package/dist/cli/connect-3q93d7cb.js +2 -0
  14. package/dist/cli/context-cmd-eqxmxhzq.js +2 -0
  15. package/dist/cli/context-report-hbw9zfes.js +2 -0
  16. package/dist/cli/count-remote-mby98cd0.js +2 -0
  17. package/dist/cli/design-122y0axd.js +2 -0
  18. package/dist/cli/dispatch-b4egzvvh.js +2 -0
  19. package/dist/cli/doctor-x4jkv72e.js +3 -0
  20. package/dist/cli/executor-ftvg6tsy.js +2 -0
  21. package/dist/cli/export-pdgdhkch.js +2 -0
  22. package/dist/cli/files-cez9a96p.js +2 -0
  23. package/dist/cli/gauntlet-r3xxaszc.js +2 -0
  24. package/dist/cli/gauntlet-runner-r515m7kk.js +10 -0
  25. package/dist/cli/gauntlet-wave3-bnkjk2v2.js +5 -0
  26. package/dist/cli/gauntlet-wave4-acs9s60q.js +14 -0
  27. package/dist/cli/hashline-ewg5hbe3.js +2 -0
  28. package/dist/cli/http-n0kehsk8.js +5 -0
  29. package/dist/cli/index-z5qt1s76.js +2 -0
  30. package/dist/cli/install-80mp63kx.js +2 -0
  31. package/dist/cli/loop-12twjcat.js +2 -0
  32. package/dist/cli/main-01pv9206.js +4 -0
  33. package/dist/cli/main-0jys2ccn.js +3 -0
  34. package/dist/cli/main-1ztz6fkj.js +10 -0
  35. package/dist/cli/main-23q7cmww.js +9 -0
  36. package/dist/cli/main-2rzbexn2.js +3 -0
  37. package/dist/cli/main-2wyax8k9.js +9 -0
  38. package/dist/cli/main-2yeveeve.js +6 -0
  39. package/dist/cli/main-2z3dek0b.js +3 -0
  40. package/dist/cli/main-2zgsknth.js +3 -0
  41. package/dist/cli/main-45ejth3a.js +4 -0
  42. package/dist/cli/main-45rn3trk.js +22 -0
  43. package/dist/cli/main-4p4e2w7x.js +4 -0
  44. package/dist/cli/main-4y0tnfpa.js +16 -0
  45. package/dist/cli/main-5py0rkmc.js +4 -0
  46. package/dist/cli/main-6dtqmbt6.js +7 -0
  47. package/dist/cli/main-6h9x282m.js +4 -0
  48. package/dist/cli/main-6vjeds42.js +3 -0
  49. package/dist/cli/main-78gq4bt9.js +6 -0
  50. package/dist/cli/main-7jd5vh3x.js +4 -0
  51. package/dist/cli/main-7kt6r53y.js +4 -0
  52. package/dist/cli/main-8c1tbazx.js +58 -0
  53. package/dist/cli/main-9a9rnh47.js +19 -0
  54. package/dist/cli/main-9ht36z12.js +3 -0
  55. package/dist/cli/main-a2yfvcy9.js +7 -0
  56. package/dist/cli/main-a3f51n0x.js +5 -0
  57. package/dist/cli/main-b8zq261k.js +3 -0
  58. package/dist/cli/main-bxtvnf6d.js +13 -0
  59. package/dist/cli/main-edxc3yzt.js +4 -0
  60. package/dist/cli/main-evgz4mp5.js +21 -0
  61. package/dist/cli/main-f33fc5je.js +9 -0
  62. package/dist/cli/main-fvnpq46y.js +12 -0
  63. package/dist/cli/main-gbbty4d4.js +3 -0
  64. package/dist/cli/main-gth53dnt.js +25 -0
  65. package/dist/cli/main-hqbz10aw.js +9 -0
  66. package/dist/cli/main-hrrvcfan.js +38 -0
  67. package/dist/cli/main-hzwtsb2m.js +5 -0
  68. package/dist/cli/main-j7ttv0sd.js +34 -0
  69. package/dist/cli/main-jak598k9.js +5 -0
  70. package/dist/cli/main-kba6zeyd.js +6 -0
  71. package/dist/cli/main-kwwsz6rq.js +3 -0
  72. package/dist/cli/main-m8vm17zq.js +3 -0
  73. package/dist/cli/main-mg4f96e1.js +3 -0
  74. package/dist/cli/main-mg9b20ac.js +18 -0
  75. package/dist/cli/main-mgb9ccnx.js +3 -0
  76. package/dist/cli/main-mjt2p7aj.js +3 -0
  77. package/dist/cli/main-n6qrdbmy.js +3 -0
  78. package/dist/cli/main-na7wse0x.js +5 -0
  79. package/dist/cli/main-nqveez48.js +4 -0
  80. package/dist/cli/main-ntqef02r.js +10 -0
  81. package/dist/cli/main-nvc3yjay.js +136 -0
  82. package/dist/cli/main-p0cfn6nr.js +16 -0
  83. package/dist/cli/main-qj2djy17.js +19 -0
  84. package/dist/cli/main-qsevpgsv.js +3 -0
  85. package/dist/cli/main-qvarybsp.js +3 -0
  86. package/dist/cli/main-rebtt91r.js +5 -0
  87. package/dist/cli/main-rpg7h8mb.js +3 -0
  88. package/dist/cli/main-rsy72qmw.js +15 -0
  89. package/dist/cli/main-rvetps99.js +18 -0
  90. package/dist/cli/main-s4bb0jav.js +3 -0
  91. package/dist/cli/main-s9v8k74e.js +3 -0
  92. package/dist/cli/main-tjvwmscs.js +3 -0
  93. package/dist/cli/main-tkgarpjj.js +4 -0
  94. package/dist/cli/main-v8y60bb2.js +3 -0
  95. package/dist/cli/main-vhrrq337.js +3 -0
  96. package/dist/cli/main-vp2dfb7s.js +4 -0
  97. package/dist/cli/main-vqbr22sz.js +8 -0
  98. package/dist/cli/main-vxnwe5xx.js +18 -0
  99. package/dist/cli/main-wgph00xf.js +5 -0
  100. package/dist/cli/main-wk2csfnj.js +5 -0
  101. package/dist/cli/main-wm997zjx.js +3 -0
  102. package/dist/cli/main-wpkyraxh.js +3 -0
  103. package/dist/cli/main-wqt32p5x.js +4 -0
  104. package/dist/cli/main-x9ct6y1a.js +3 -0
  105. package/dist/cli/main-xfekqh9m.js +7 -0
  106. package/dist/cli/main-xt9zc3n6.js +7 -0
  107. package/dist/cli/main-xx2z3zh5.js +4 -0
  108. package/dist/cli/main-y5c82rxr.js +3 -0
  109. package/dist/cli/main-yrjt2sqt.js +14 -0
  110. package/dist/cli/main-ys6zj3yr.js +3 -0
  111. package/dist/cli/main-ywbxshqc.js +8 -0
  112. package/dist/cli/main-z13755t8.js +25 -0
  113. package/dist/cli/main-zc7pyrbj.js +4 -0
  114. package/dist/cli/main.js +279 -0
  115. package/dist/cli/market-cmd-bm5xvn9f.js +5 -0
  116. package/dist/cli/mcp-login-bthtfpt7.js +2 -0
  117. package/dist/cli/mcp-market-cmd-mbeshfyd.js +2 -0
  118. package/dist/cli/notify-54v5z9dz.js +2 -0
  119. package/dist/cli/oauth-g5gme95c.js +2 -0
  120. package/dist/cli/output-satndjap.js +16 -0
  121. package/dist/cli/profiles-sfhpbq3m.js +2 -0
  122. package/dist/cli/provider-config-hv3xtdt4.js +2 -0
  123. package/dist/cli/provider-kwzq6g84.js +2 -0
  124. package/dist/cli/registry-fh0hdnyn.js +2 -0
  125. package/dist/cli/registry-y1y8e94r.js +2 -0
  126. package/dist/cli/repl-t4z03mqq.js +11 -0
  127. package/dist/cli/resume-fqt4chg8.js +2 -0
  128. package/dist/cli/run-flags-rysbag9t.js +2 -0
  129. package/dist/cli/runtime-j19fjbsa.js +2 -0
  130. package/dist/cli/sandbox-config-g4qxd7y5.js +2 -0
  131. package/dist/cli/server-r0b6bksk.js +5 -0
  132. package/dist/cli/session-arg-txmn5g4x.js +2 -0
  133. package/dist/cli/session-ed250d9j.js +2 -0
  134. package/dist/cli/sessions-cmd-adw7svfn.js +7 -0
  135. package/dist/cli/settings-y9rzcqx8.js +2 -0
  136. package/dist/cli/setup-jmbr11j0.js +2 -0
  137. package/dist/cli/sextant-smoke-tcth0vea.js +5 -0
  138. package/dist/cli/skills-cmd-zbdy99v6.js +2 -0
  139. package/dist/cli/smoke-1bg937kx.js +8 -0
  140. package/dist/cli/start-chat-p01cdks3.js +12 -0
  141. package/dist/cli/stream-4wmyaypz.js +2 -0
  142. package/dist/cli/task-eg4s093s.js +2 -0
  143. package/dist/cli/tasks-12v9rr9k.js +2 -0
  144. package/dist/cli/thinking-a5ngvqyh.js +2 -0
  145. package/dist/cli/todo-1wxpcecx.js +2 -0
  146. package/dist/cli/tools-2ftsya7w.js +2 -0
  147. package/dist/cli/tools-x1tj4fxm.js +2 -0
  148. package/dist/cli/trust-cmd-hccxehzb.js +2 -0
  149. package/dist/cli/update-check-ygt3vd7m.js +2 -0
  150. package/dist/cli/update-cmd-v23qhr8c.js +2 -0
  151. package/dist/cli/voice-g1gtck92.js +2 -0
  152. package/dist/cli/webfetch-0nnrjgb5.js +2 -0
  153. package/dist/cli/websearch-f0vr2p7d.js +2 -0
  154. package/dist/cli/workspace-9rq1w4ta.js +2 -0
  155. package/dist/lib/index.js +62 -0
  156. package/dist/lib/models-index.json +1 -0
  157. package/dist/lib/plugins.js +6 -0
  158. package/dist/lib/providers.js +17 -0
  159. package/dist/lib/public-api.js +20 -0
  160. package/dist/rovecode.exe +4 -0
  161. package/package.json +83 -72
  162. package/bin/rovecode.ts +0 -21
  163. package/src/acp/server.ts +0 -374
  164. package/src/cli/auth-login.ts +0 -122
  165. package/src/cli/connect.ts +0 -244
  166. package/src/cli/context-cmd.ts +0 -199
  167. package/src/cli/dispatch.ts +0 -82
  168. package/src/cli/doctor.ts +0 -362
  169. package/src/cli/export.ts +0 -276
  170. package/src/cli/help.ts +0 -293
  171. package/src/cli/is-tui-invocation.ts +0 -8
  172. package/src/cli/main.ts +0 -583
  173. package/src/cli/market-cmd.ts +0 -658
  174. package/src/cli/mcp-login.ts +0 -141
  175. package/src/cli/mcp-market-cmd.ts +0 -302
  176. package/src/cli/output.ts +0 -382
  177. package/src/cli/repl.ts +0 -250
  178. package/src/cli/repomap-root.ts +0 -14
  179. package/src/cli/resume.ts +0 -57
  180. package/src/cli/run-flags.ts +0 -43
  181. package/src/cli/run-limits.ts +0 -78
  182. package/src/cli/runtime.ts +0 -931
  183. package/src/cli/session-arg.ts +0 -30
  184. package/src/cli/sessions-cmd.ts +0 -145
  185. package/src/cli/setup.ts +0 -153
  186. package/src/cli/skills-cmd.ts +0 -194
  187. package/src/cli/start-chat.ts +0 -65
  188. package/src/cli/trust-cmd.ts +0 -52
  189. package/src/coding/bash.ts +0 -148
  190. package/src/coding/checkpoints.ts +0 -327
  191. package/src/coding/diff.ts +0 -138
  192. package/src/coding/files.ts +0 -341
  193. package/src/coding/hashline.ts +0 -274
  194. package/src/coding/lsp-gate.ts +0 -254
  195. package/src/coding/lsp-servers.ts +0 -147
  196. package/src/coding/lsp.ts +0 -283
  197. package/src/coding/repomap-cache.ts +0 -99
  198. package/src/coding/repomap-files.ts +0 -192
  199. package/src/coding/repomap.ts +0 -481
  200. package/src/core/agents.ts +0 -255
  201. package/src/core/compaction.ts +0 -259
  202. package/src/core/config.ts +0 -289
  203. package/src/core/context-report.ts +0 -228
  204. package/src/core/context.ts +0 -60
  205. package/src/core/count-remote.ts +0 -107
  206. package/src/core/execpolicy-rules.ts +0 -196
  207. package/src/core/execpolicy.ts +0 -385
  208. package/src/core/executor.ts +0 -454
  209. package/src/core/guardrails.ts +0 -400
  210. package/src/core/hooks.ts +0 -411
  211. package/src/core/images.ts +0 -230
  212. package/src/core/intro.ts +0 -266
  213. package/src/core/loop.ts +0 -567
  214. package/src/core/modes.ts +0 -372
  215. package/src/core/orchestrator.ts +0 -245
  216. package/src/core/proc-group.ts +0 -48
  217. package/src/core/project-trust.ts +0 -98
  218. package/src/core/reflection.ts +0 -165
  219. package/src/core/sandbox-config.ts +0 -186
  220. package/src/core/session-id.ts +0 -24
  221. package/src/core/session-images.ts +0 -73
  222. package/src/core/session-ops.ts +0 -183
  223. package/src/core/session-text.ts +0 -29
  224. package/src/core/session.ts +0 -469
  225. package/src/core/settings.ts +0 -170
  226. package/src/core/tasks.ts +0 -646
  227. package/src/core/token-scale.ts +0 -108
  228. package/src/core/tools.ts +0 -309
  229. package/src/core/trust.ts +0 -104
  230. package/src/core/types.ts +0 -330
  231. package/src/core/update-check.ts +0 -171
  232. package/src/core/usage.ts +0 -204
  233. package/src/core/validate.ts +0 -121
  234. package/src/core/verify-gate.ts +0 -159
  235. package/src/core/verify.ts +0 -236
  236. package/src/core/voice.ts +0 -158
  237. package/src/core/win-job.ts +0 -183
  238. package/src/core/workspace.ts +0 -184
  239. package/src/design/audit.ts +0 -797
  240. package/src/design/direction.ts +0 -190
  241. package/src/design/rules.ts +0 -157
  242. package/src/eval/bench.ts +0 -150
  243. package/src/eval/gauntlet-runner.ts +0 -215
  244. package/src/eval/gauntlet-support.ts +0 -84
  245. package/src/eval/gauntlet-wave3.ts +0 -269
  246. package/src/eval/gauntlet-wave4.ts +0 -217
  247. package/src/eval/gauntlet.ts +0 -253
  248. package/src/index.ts +0 -17
  249. package/src/lanes/agy.ts +0 -95
  250. package/src/lanes/approval.ts +0 -24
  251. package/src/lanes/claude.ts +0 -129
  252. package/src/lanes/codex.ts +0 -127
  253. package/src/lanes/events.ts +0 -130
  254. package/src/lanes/job.ts +0 -142
  255. package/src/lanes/opencode.ts +0 -122
  256. package/src/lanes/process.ts +0 -184
  257. package/src/lanes/progress.ts +0 -183
  258. package/src/lanes/registry.ts +0 -178
  259. package/src/lanes/runner.ts +0 -124
  260. package/src/lanes/types.ts +0 -112
  261. package/src/market/catalogs/mcp-docs.json +0 -111
  262. package/src/market/catalogs/plugins.json +0 -111
  263. package/src/market/catalogs/skills.json +0 -478
  264. package/src/market/clone.ts +0 -72
  265. package/src/market/context-cost.ts +0 -121
  266. package/src/market/digest.ts +0 -106
  267. package/src/market/index.ts +0 -22
  268. package/src/market/install.ts +0 -578
  269. package/src/market/manifest.ts +0 -187
  270. package/src/market/prereq.ts +0 -145
  271. package/src/market/registry.ts +0 -363
  272. package/src/market/resolve.ts +0 -111
  273. package/src/market/types.ts +0 -236
  274. package/src/market/validate.ts +0 -227
  275. package/src/mcp/client.ts +0 -449
  276. package/src/mcp/config.ts +0 -252
  277. package/src/mcp/local-package.ts +0 -211
  278. package/src/mcp/market-catalog.ts +0 -84
  279. package/src/mcp/market-install.ts +0 -289
  280. package/src/mcp/market.ts +0 -362
  281. package/src/mcp/oauth.ts +0 -251
  282. package/src/mcp/prompts-resources.ts +0 -249
  283. package/src/mcp/shared.ts +0 -149
  284. package/src/mcp/status.ts +0 -67
  285. package/src/mcp/tools.ts +0 -275
  286. package/src/mcp/transport.ts +0 -122
  287. package/src/mcp/trust.ts +0 -25
  288. package/src/memory/blocks.ts +0 -278
  289. package/src/memory/recall.ts +0 -355
  290. package/src/memory/scope.ts +0 -182
  291. package/src/memory/store.ts +0 -105
  292. package/src/memory/tools.ts +0 -99
  293. package/src/plugins/cli.ts +0 -119
  294. package/src/plugins/discover.ts +0 -108
  295. package/src/plugins/index.ts +0 -50
  296. package/src/plugins/install.ts +0 -184
  297. package/src/plugins/load.ts +0 -124
  298. package/src/plugins/manifest.ts +0 -92
  299. package/src/plugins/state.ts +0 -83
  300. package/src/providers/auth.ts +0 -408
  301. package/src/providers/cache.ts +0 -223
  302. package/src/providers/catalog-local.ts +0 -160
  303. package/src/providers/catalog.ts +0 -421
  304. package/src/providers/middleware-context.ts +0 -86
  305. package/src/providers/middleware.ts +0 -373
  306. package/src/providers/model-list.ts +0 -23
  307. package/src/providers/oauth/common.ts +0 -105
  308. package/src/providers/oauth/device-code.ts +0 -107
  309. package/src/providers/oauth/github-copilot.ts +0 -146
  310. package/src/providers/oauth/loopback.ts +0 -158
  311. package/src/providers/oauth/openai.ts +0 -163
  312. package/src/providers/oauth/openrouter.ts +0 -89
  313. package/src/providers/oauth/pkce.ts +0 -45
  314. package/src/providers/oauth/registry.ts +0 -39
  315. package/src/providers/oauth/seam.ts +0 -89
  316. package/src/providers/profile-glm53.ts +0 -111
  317. package/src/providers/profile-sonnet5-persona.ts +0 -65
  318. package/src/providers/profile-sonnet5-voice.ts +0 -23
  319. package/src/providers/profiles.ts +0 -156
  320. package/src/providers/provider-config.ts +0 -311
  321. package/src/providers/registry.ts +0 -333
  322. package/src/providers/responses.ts +0 -209
  323. package/src/providers/retry.ts +0 -234
  324. package/src/providers/router.ts +0 -294
  325. package/src/providers/sse.ts +0 -26
  326. package/src/providers/stream-errors.ts +0 -117
  327. package/src/providers/stream.ts +0 -566
  328. package/src/providers/thinking.ts +0 -189
  329. package/src/providers/wire-messages.ts +0 -129
  330. package/src/providers/wire-responses.ts +0 -79
  331. package/src/providers/wire-select.ts +0 -53
  332. package/src/server/http.ts +0 -291
  333. package/src/server/openapi.ts +0 -246
  334. package/src/sextant/card-hits.ts +0 -102
  335. package/src/sextant/card-keys.ts +0 -55
  336. package/src/sextant/context-source.ts +0 -157
  337. package/src/sextant/crew-cards.ts +0 -350
  338. package/src/sextant/draw-agents.ts +0 -273
  339. package/src/sextant/draw-code.ts +0 -388
  340. package/src/sextant/draw-context.ts +0 -222
  341. package/src/sextant/draw-frame.ts +0 -164
  342. package/src/sextant/draw-market.ts +0 -573
  343. package/src/sextant/draw-messages.ts +0 -386
  344. package/src/sextant/draw-pet.ts +0 -230
  345. package/src/sextant/draw-plan.ts +0 -187
  346. package/src/sextant/draw-tabs.ts +0 -85
  347. package/src/sextant/draw-util.ts +0 -65
  348. package/src/sextant/draw-wizard.ts +0 -378
  349. package/src/sextant/engine.ts +0 -230
  350. package/src/sextant/frame-hits.ts +0 -25
  351. package/src/sextant/frame.ts +0 -101
  352. package/src/sextant/git-status.ts +0 -197
  353. package/src/sextant/grid.ts +0 -59
  354. package/src/sextant/input.ts +0 -119
  355. package/src/sextant/keys.ts +0 -521
  356. package/src/sextant/layout.ts +0 -86
  357. package/src/sextant/local-commands.ts +0 -169
  358. package/src/sextant/market-source.ts +0 -287
  359. package/src/sextant/mentions.ts +0 -200
  360. package/src/sextant/message-hits.ts +0 -26
  361. package/src/sextant/model.ts +0 -387
  362. package/src/sextant/overlays.ts +0 -456
  363. package/src/sextant/panel-hits.ts +0 -38
  364. package/src/sextant/pet.ts +0 -399
  365. package/src/sextant/screen.ts +0 -324
  366. package/src/sextant/scroll-hits.ts +0 -66
  367. package/src/sextant/scrollbar.ts +0 -82
  368. package/src/sextant/sextant-bridge.ts +0 -174
  369. package/src/sextant/sextant-cards.ts +0 -142
  370. package/src/sextant/sextant-diff-base.ts +0 -63
  371. package/src/sextant/sextant-files.ts +0 -154
  372. package/src/sextant/sextant-frame-loop.ts +0 -335
  373. package/src/sextant/sextant-renderer.ts +0 -574
  374. package/src/sextant/sextant-repo.ts +0 -140
  375. package/src/sextant/theme.ts +0 -66
  376. package/src/sextant/tool-rows.ts +0 -189
  377. package/src/sextant/types.ts +0 -493
  378. package/src/skills/index.ts +0 -387
  379. package/src/skills/pack.ts +0 -220
  380. package/src/skills/spec.ts +0 -162
  381. package/src/skills/tools.ts +0 -69
  382. package/src/skills/versioned.ts +0 -227
  383. package/src/telemetry/otel-export.ts +0 -122
  384. package/src/telemetry/otel-lanes.ts +0 -89
  385. package/src/telemetry/otel-logs.ts +0 -131
  386. package/src/telemetry/otel-metrics.ts +0 -136
  387. package/src/telemetry/otel.ts +0 -397
  388. package/src/telemetry/otlp.ts +0 -76
  389. package/src/tools/ask-user.ts +0 -156
  390. package/src/tools/bash-bg.ts +0 -94
  391. package/src/tools/bash-jobs.ts +0 -237
  392. package/src/tools/design.ts +0 -151
  393. package/src/tools/evalcell.ts +0 -338
  394. package/src/tools/html-text.ts +0 -139
  395. package/src/tools/provider.ts +0 -149
  396. package/src/tools/task.ts +0 -250
  397. package/src/tools/todo.ts +0 -320
  398. package/src/tools/webfetch.ts +0 -332
  399. package/src/tools/websearch.ts +0 -359
  400. package/src/tui/agents-cmd.ts +0 -41
  401. package/src/tui/app.ts +0 -749
  402. package/src/tui/attach.ts +0 -127
  403. package/src/tui/boot-notes.ts +0 -41
  404. package/src/tui/builtin-prompts.ts +0 -59
  405. package/src/tui/checkpoints-cmd.ts +0 -70
  406. package/src/tui/clipboard-image.ts +0 -81
  407. package/src/tui/clipboard.ts +0 -78
  408. package/src/tui/commands.ts +0 -283
  409. package/src/tui/config-view.ts +0 -53
  410. package/src/tui/context-cmds.ts +0 -282
  411. package/src/tui/cost.ts +0 -108
  412. package/src/tui/crash-guard.ts +0 -173
  413. package/src/tui/focus-terminal.ts +0 -34
  414. package/src/tui/git-cmds.ts +0 -273
  415. package/src/tui/git-plain.ts +0 -58
  416. package/src/tui/info-cmd.ts +0 -150
  417. package/src/tui/input-plain.ts +0 -76
  418. package/src/tui/mcp-cmd.ts +0 -128
  419. package/src/tui/memory-note.ts +0 -77
  420. package/src/tui/modes-cmd.ts +0 -45
  421. package/src/tui/notify-seq.ts +0 -100
  422. package/src/tui/notify.ts +0 -318
  423. package/src/tui/overlays.ts +0 -97
  424. package/src/tui/pi-renderer.ts +0 -428
  425. package/src/tui/providers-cmd.ts +0 -377
  426. package/src/tui/reasoning-view.ts +0 -56
  427. package/src/tui/renderer.ts +0 -128
  428. package/src/tui/replay-marker.ts +0 -29
  429. package/src/tui/session-cmd.ts +0 -148
  430. package/src/tui/session-manage.ts +0 -95
  431. package/src/tui/sextant-attach.ts +0 -102
  432. package/src/tui/sextant-io.ts +0 -202
  433. package/src/tui/sextant-smoke.ts +0 -110
  434. package/src/tui/shell-cmd.ts +0 -158
  435. package/src/tui/smoke.ts +0 -72
  436. package/src/tui/staged-terminal.ts +0 -50
  437. package/src/tui/startup.ts +0 -12
  438. package/src/tui/theme.ts +0 -59
  439. package/src/tui/todo-label.ts +0 -7
  440. package/src/tui/trust-card.ts +0 -107
  441. package/src/tui/tui-commands.ts +0 -87
  442. package/tsconfig.json +0 -30
  443. package/vendor/pi-tui/LICENSE +0 -21
  444. package/vendor/pi-tui/PATCHES.md +0 -12
  445. package/vendor/pi-tui/PROVENANCE.md +0 -12
  446. package/vendor/pi-tui/README.upstream.md +0 -854
  447. package/vendor/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  448. package/vendor/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  449. package/vendor/pi-tui/src/alt-screen-search.ts +0 -158
  450. package/vendor/pi-tui/src/autocomplete.ts +0 -827
  451. package/vendor/pi-tui/src/components/alt-screen-flash.ts +0 -52
  452. package/vendor/pi-tui/src/components/box.ts +0 -138
  453. package/vendor/pi-tui/src/components/cancellable-loader.ts +0 -41
  454. package/vendor/pi-tui/src/components/editor.ts +0 -2364
  455. package/vendor/pi-tui/src/components/h-stack.ts +0 -45
  456. package/vendor/pi-tui/src/components/image.ts +0 -128
  457. package/vendor/pi-tui/src/components/input.ts +0 -448
  458. package/vendor/pi-tui/src/components/loader.ts +0 -93
  459. package/vendor/pi-tui/src/components/markdown.ts +0 -1016
  460. package/vendor/pi-tui/src/components/scroll-view.ts +0 -217
  461. package/vendor/pi-tui/src/components/select-list.ts +0 -230
  462. package/vendor/pi-tui/src/components/settings-list.ts +0 -277
  463. package/vendor/pi-tui/src/components/spacer.ts +0 -29
  464. package/vendor/pi-tui/src/components/stack.ts +0 -155
  465. package/vendor/pi-tui/src/components/text.ts +0 -108
  466. package/vendor/pi-tui/src/components/truncated-text.ts +0 -66
  467. package/vendor/pi-tui/src/components/v-stack.ts +0 -34
  468. package/vendor/pi-tui/src/editor-component.ts +0 -75
  469. package/vendor/pi-tui/src/fuzzy.ts +0 -138
  470. package/vendor/pi-tui/src/index.ts +0 -149
  471. package/vendor/pi-tui/src/keybindings.ts +0 -321
  472. package/vendor/pi-tui/src/keys.ts +0 -1402
  473. package/vendor/pi-tui/src/kill-ring.ts +0 -47
  474. package/vendor/pi-tui/src/latex.ts +0 -1381
  475. package/vendor/pi-tui/src/layout-node.ts +0 -52
  476. package/vendor/pi-tui/src/layout.ts +0 -411
  477. package/vendor/pi-tui/src/native-modifiers.ts +0 -60
  478. package/vendor/pi-tui/src/native-module-path.ts +0 -32
  479. package/vendor/pi-tui/src/stdin-buffer.ts +0 -445
  480. package/vendor/pi-tui/src/terminal-colors.ts +0 -74
  481. package/vendor/pi-tui/src/terminal-image.ts +0 -701
  482. package/vendor/pi-tui/src/terminal.ts +0 -554
  483. package/vendor/pi-tui/src/tui-alt-screen.ts +0 -1379
  484. package/vendor/pi-tui/src/tui-main-screen.ts +0 -655
  485. package/vendor/pi-tui/src/tui.ts +0 -1264
  486. package/vendor/pi-tui/src/undo-stack.ts +0 -29
  487. package/vendor/pi-tui/src/utils.ts +0 -1327
  488. package/vendor/pi-tui/src/word-navigation.ts +0 -118
  489. package/vendor/pi-tui/test/test-themes.ts +0 -39
  490. package/vendor/pi-tui/test/virtual-terminal.ts +0 -219
  491. /package/{src/providers → dist/cli}/models-index.json +0 -0
@@ -0,0 +1,4 @@
1
+ [diffend] Oversized file quarantined before diffing.
2
+ name: package/dist/rovecode.exe
3
+ size: 114340864 bytes
4
+ sha256: ff057ad0a8c0c91df39cce1afca1d617db8f6a90e2db806111d94547f15e83f4
package/package.json CHANGED
@@ -1,72 +1,83 @@
1
- {
2
- "name": "rovecode",
3
- "version": "0.3.3",
4
- "license": "AGPL-3.0-only",
5
- "author": "9Code Labs",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/9Code-Labs/rovecode.git"
9
- },
10
- "homepage": "https://www.rovecode.dev",
11
- "description": "Rovecode: a coding agent for the terminal. Research-derived harness on Bun/TypeScript with evidence-based ports from open-source harnesses (sextant TUI, MCP, ACP, headless server, repo-map, shadow-git checkpoints, execpolicy, model routers).",
12
- "type": "module",
13
- "module": "src/index.ts",
14
- "bin": {
15
- "rovecode": "bin/rovecode.ts"
16
- },
17
- "files": [
18
- "bin",
19
- "src",
20
- "vendor",
21
- "tsconfig.json",
22
- "THIRD_PARTY_NOTICES.md"
23
- ],
24
- "engines": {
25
- "bun": ">=1.3.14"
26
- },
27
- "scripts": {
28
- "build": "bun run scripts/build.ts",
29
- "build:cli": "bun -e \"require('node:fs').rmSync('dist/cli', { recursive: true, force: true })\" && bun build --target=bun --splitting --sourcemap=external src/cli/main.ts --outdir dist/cli && bun -e \"require('node:fs').copyFileSync('src/providers/models-index.json', 'dist/cli/models-index.json')\" && bun run smoke:cli && bun run smoke:dist",
30
- "smoke:cli": "bun dist/cli/main.js --version",
31
- "smoke:dist": "bun dist/cli/main.js smoke-tui --sextant",
32
- "test": "bun test",
33
- "gauntlet": "bun src/cli/main.ts gauntlet",
34
- "typecheck": "tsc --noEmit",
35
- "check": "node scripts/build-model-index.mjs --check && tsc --noEmit && bun test",
36
- "smoke": "bun src/cli/main.ts smoke-tui --sextant",
37
- "publish:site": "bash scripts/publish-site-data.sh",
38
- "build:model-index": "node scripts/build-model-index.mjs"
39
- },
40
- "dependencies": {
41
- "@ast-grep/napi": "^0.45.3",
42
- "@modelcontextprotocol/sdk": "^1.30.0",
43
- "@zed-industries/agent-client-protocol": "^0.4.5",
44
- "diff": "^9.0.0",
45
- "get-east-asian-width": "1.6.0",
46
- "gpt-tokenizer": "^4.0.0",
47
- "marked": "18.0.11",
48
- "tokenlens": "^1.3.1"
49
- },
50
- "devDependencies": {
51
- "@opencode-ai/models": "^0.0.64",
52
- "@types/bun": "latest",
53
- "@xterm/headless": "6.0.0",
54
- "typescript": "^5.9.3"
55
- },
56
- "keywords": [
57
- "coding-agent",
58
- "cli",
59
- "terminal",
60
- "tui",
61
- "ai",
62
- "llm",
63
- "agent",
64
- "bun",
65
- "typescript",
66
- "mcp",
67
- "agpl"
68
- ],
69
- "bugs": {
70
- "url": "https://github.com/9Code-Labs/rovecode/issues"
71
- }
72
- }
1
+ {
2
+ "name": "rovecode",
3
+ "version": "0.4.0-beta.2",
4
+ "license": "AGPL-3.0-only",
5
+ "author": "9Code Labs",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/9Code-Labs/rovecode-community.git"
9
+ },
10
+ "homepage": "https://github.com/9Code-Labs/rovecode-community#readme",
11
+ "description": "Rovecode: a coding agent for the terminal. Research-derived harness on Bun/TypeScript with evidence-based ports from open-source harnesses (sextant TUI, MCP, ACP, headless server, repo-map, shadow-git checkpoints, execpolicy, model routers). The npm tarball ships the minified bundle; this public repository is its AGPL source.",
12
+ "type": "module",
13
+ "module": "./dist/lib/index.js",
14
+ "exports": {
15
+ ".": "./dist/lib/index.js",
16
+ "./extensions": "./dist/lib/public-api.js",
17
+ "./plugins": "./dist/lib/plugins.js",
18
+ "./providers": "./dist/lib/providers.js",
19
+ "./package.json": "./package.json"
20
+ },
21
+ "bin": {
22
+ "rovecode": "bin/rovecode.js"
23
+ },
24
+ "files": [
25
+ "bin",
26
+ "dist",
27
+ "README.md",
28
+ "CHANGELOG.md",
29
+ "LICENSE",
30
+ "THIRD_PARTY_NOTICES.md"
31
+ ],
32
+ "engines": {
33
+ "bun": ">=1.3.14"
34
+ },
35
+ "scripts": {
36
+ "build": "bun run scripts/build.ts",
37
+ "build:cli": "bun -e \"require('node:fs').rmSync('dist/cli', { recursive: true, force: true })\" && bun build --target=bun --splitting --sourcemap=external src/cli/main.ts --outdir dist/cli && bun -e \"require('node:fs').copyFileSync('src/providers/models-index.json', 'dist/cli/models-index.json')\" && bun run smoke:cli && bun run smoke:dist",
38
+ "build:npm": "bun run build:npm:cli && bun run build:npm:lib && bun run smoke:npm",
39
+ "build:npm:cli": "bun -e \"require('node:fs').rmSync('dist/cli', { recursive: true, force: true })\" && bun build --target=bun --minify --splitting --packages=external src/cli/main.ts --outdir dist/cli && bun -e \"require('node:fs').copyFileSync('src/providers/models-index.json', 'dist/cli/models-index.json')\"",
40
+ "build:npm:lib": "bun -e \"require('node:fs').rmSync('dist/lib', { recursive: true, force: true })\" && bun build --target=bun --minify --packages=external src/index.ts --outfile dist/lib/index.js && bun build --target=bun --minify --packages=external src/public-api.ts --outfile dist/lib/public-api.js && bun build --target=bun --minify --packages=external src/plugins/index.ts --outfile dist/lib/plugins.js && bun build --target=bun --minify --packages=external src/providers/stream.ts --outfile dist/lib/providers.js && bun -e \"require('node:fs').copyFileSync('src/providers/models-index.json', 'dist/lib/models-index.json')\"",
41
+ "smoke:npm": "bun dist/cli/main.js --version && bun dist/cli/main.js smoke-tui --sextant",
42
+ "prepack": "bun run build:npm",
43
+ "smoke:cli": "bun dist/cli/main.js --version",
44
+ "smoke:dist": "bun dist/cli/main.js smoke-tui --sextant",
45
+ "test": "bun test",
46
+ "gauntlet": "bun src/cli/main.ts gauntlet",
47
+ "typecheck": "tsc --noEmit",
48
+ "check": "node scripts/build-model-index.mjs --check && tsc --noEmit && bun test",
49
+ "smoke": "bun src/cli/main.ts smoke-tui --sextant",
50
+ "build:model-index": "node scripts/build-model-index.mjs",
51
+ "check:boundary": "node scripts/check-public-boundary.mjs",
52
+ "check:product-boundary": "node scripts/check-product-boundary.mjs",
53
+ "check:links": "node scripts/check-doc-links.mjs",
54
+ "ci": "bun run check:boundary && bun run check:product-boundary && bun run check:links && bun run typecheck && bun test && bun run build:cli",
55
+ "release:check": "bun run ci && bun run build:npm && npm pack --dry-run",
56
+ "release:stage": "bun run scripts/stage-release.ts",
57
+ "quality:offline": "bun run scripts/harness-quality.ts"
58
+ },
59
+ "dependencies": {
60
+ "@ast-grep/napi": "^0.45.3",
61
+ "@modelcontextprotocol/sdk": "^1.30.0",
62
+ "@zed-industries/agent-client-protocol": "^0.4.5",
63
+ "diff": "^9.0.0",
64
+ "get-east-asian-width": "1.6.0",
65
+ "gpt-tokenizer": "^4.0.0",
66
+ "marked": "18.0.11",
67
+ "tokenlens": "^1.3.1"
68
+ },
69
+ "devDependencies": {
70
+ "@opencode-ai/models": "^0.0.64",
71
+ "@types/bun": "latest",
72
+ "@xterm/headless": "6.0.0",
73
+ "typescript": "^5.9.3"
74
+ },
75
+ "bugs": {
76
+ "url": "https://github.com/9Code-Labs/rovecode-community/issues"
77
+ },
78
+ "publishConfig": {
79
+ "access": "public",
80
+ "provenance": true,
81
+ "tag": "beta"
82
+ }
83
+ }
package/bin/rovecode.ts DELETED
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env bun
2
- /** Entrypoint wrapper: routes TUI invocations through the pre-bundled dist/cli/main.js for fast
3
- * cold start (~90 ms vs ~230 ms), and falls back to src/cli/main.ts for lightweight subcommands
4
- * (--help, --version, provider, model, …) which are already instant from source.
5
- * Run `bun run build:cli` to produce dist/cli/main.js; re-run after `git pull`. */
6
- import { existsSync } from "node:fs";
7
- import { join } from "node:path";
8
- import { isTuiInvocation } from "../src/cli/is-tui-invocation.ts";
9
-
10
- const bundled = join(import.meta.dir, "..", "dist", "cli", "main.js");
11
- const useDist = isTuiInvocation(process.argv) && existsSync(bundled);
12
-
13
- if (process.env.ROVECODE_TRACE_BOOT === "1") {
14
- process.stderr.write(`[boot] dist=${useDist}\n`);
15
- }
16
-
17
- if (useDist) {
18
- await import(bundled);
19
- } else {
20
- await import("../src/cli/main.ts");
21
- }
package/src/acp/server.ts DELETED
@@ -1,374 +0,0 @@
1
- /** ACP agent endpoint (port #15): `rovecode acp` speaks Agent Client Protocol v1
2
- * over stdio via the official SDK (@zed-industries/agent-client-protocol@0.4.5,
3
- * Apache-2.0), mapped onto the ONE agentLoop (ADR-003).
4
- *
5
- * Mapping:
6
- * initialize → protocol v1 + capabilities (no loadSession; text + image prompts, port #34)
7
- * prompt image blocks → ImagePart via imageFromBase64 (the bytes decide the type; the TUI's
8
- * per-image size cap and ≤8-per-message count cap apply), staged on the
9
- * session store so the loop's user message carries them (no loop change);
10
- * any bad block → JSON-RPC invalid params {error} before a run starts
11
- * session/new → bootRuntime (same stores/tools/config as repl/tui); a sandbox
12
- * misconfig / unavailable rung in the client's cwd (port #27)
13
- * → JSON-RPC invalid params {cwd, error: one-line message}
14
- * session/prompt → agentLoop run; RunEvents stream out as session/update
15
- * message_update → agent_message_chunk
16
- * tool_execution_* → tool_call / tool_call_update
17
- * tool_call_failed → tool_call created directly in "failed" status
18
- * approval (ADR-005) → session/request_permission; declined/cancelled/unsupported → deny
19
- * run_end done/budget → stopReason end_turn / max_turn_requests
20
- * run_end error → JSON-RPC error response (RequestError is the ACP error
21
- * channel — the SDK converts it to a wire-level response,
22
- * so the never-throw seam ends at this boundary by design)
23
- * session/cancel → aborts the run's AbortController (kills the in-flight
24
- * provider fetch and tool subprocesses mid-turn — port #21),
25
- * races any outstanding permission ask to deny, then closes
26
- * the generator → "cancelled"
27
- */
28
-
29
- import {
30
- AgentSideConnection, RequestError, PROTOCOL_VERSION, ndJsonStream,
31
- type Agent, type Stream,
32
- type InitializeRequest, type InitializeResponse,
33
- type AuthenticateRequest, type AuthenticateResponse,
34
- type NewSessionRequest, type NewSessionResponse,
35
- type PromptRequest, type PromptResponse, type CancelNotification,
36
- type ContentBlock, type SessionNotification, type ToolCallContent,
37
- type ToolKind as AcpToolKind,
38
- } from "@zed-industries/agent-client-protocol";
39
- import { basename } from "node:path";
40
- import { noModelHint } from "../core/voice.ts";
41
- import { Readable, Writable } from "node:stream";
42
- import { agentLoop, SteeringQueue } from "../core/loop.ts";
43
- import { bootRuntime, type Runtime } from "../cli/runtime.ts";
44
- import { checkImageCount, imageFromBase64 } from "../core/images.ts";
45
- import { SandboxConfigError } from "../core/sandbox-config.ts";
46
- import type { ApprovalFn, ImagePart, RunEvent, StreamFn } from "../core/types.ts";
47
-
48
- export interface AcpOptions {
49
- /** test/dev override threaded into createRuntime; undefined = provider from env */
50
- stream?: StreamFn | null;
51
- /** allow-all permissions: no ACP permission round-trips (ROVECODE_YOLO parity) */
52
- yolo?: boolean;
53
- }
54
-
55
- type SessionUpdate = SessionNotification["update"];
56
- type RunStatus = "done" | "stopped" | "error" | "budget";
57
-
58
- interface AcpSessionState {
59
- rt: Runtime;
60
- steering: SteeringQueue;
61
- active: {
62
- gen: AsyncGenerator<RunEvent>;
63
- cancelled: boolean;
64
- /** per-run controller (port #21): session/cancel aborts it, killing the
65
- * in-flight provider fetch and every ToolContext.signal consumer */
66
- abort: AbortController;
67
- /** resolves null when session/cancel lands — raced against an outstanding
68
- * request_permission so a hung client cannot wedge the session (HIGH-G2) */
69
- onCancel: Promise<null>;
70
- fireCancel: () => void;
71
- } | null;
72
- permSeq: number;
73
- }
74
-
75
- // ---------- translation helpers (RunEvent / house shapes → ACP shapes) ----------
76
-
77
- export interface PromptParts {
78
- /** the loop's goal text: text blocks, resource links, inlined embedded text resources */
79
- goal: string;
80
- /** port #34: decoded image blocks, in prompt order */
81
- images: ImagePart[];
82
- /** the FIRST problem (unsupported/mismatched mime, oversize, more than 8 images) — the caller
83
- * rejects the whole prompt, nothing is half-sent */
84
- error?: string;
85
- }
86
-
87
- /** Prompt content blocks → goal text + image parts. Baseline blocks (text, resource_link) per
88
- * spec; embedded text resources are inlined; image blocks decode through imageFromBase64 (the
89
- * bytes decide the type — a disagreeing mimeType is an error, like the TUI's loader) under the
90
- * same per-image size cap and per-message count cap as /attach; audio stays unsupported. */
91
- export function promptParts(blocks: ContentBlock[]): PromptParts {
92
- const parts: string[] = [];
93
- const images: ImagePart[] = [];
94
- let error: string | undefined;
95
- for (const b of blocks) {
96
- if (b.type === "text") parts.push(b.text);
97
- else if (b.type === "resource_link") parts.push(`[resource: ${b.uri}]`);
98
- else if (b.type === "resource" && "text" in b.resource) {
99
- parts.push(`<context uri="${b.resource.uri}">\n${b.resource.text}\n</context>`);
100
- } else if (b.type === "image") {
101
- const name = b.uri && !b.uri.startsWith("data:") ? basename(b.uri) : undefined; // display name: the file the client sent
102
- const res = imageFromBase64(b.data, b.mimeType, name !== undefined ? { name } : {});
103
- if ("error" in res) error ??= res.error; else images.push(res);
104
- } else parts.push(`[unsupported ${b.type} content omitted]`);
105
- }
106
- error ??= checkImageCount(images.length);
107
- const goal = parts.join("\n");
108
- return error === undefined ? { goal, images } : { goal, images, error };
109
- }
110
-
111
- /** Text-only view of a prompt (image blocks travel separately — promptParts). */
112
- export function promptText(blocks: ContentBlock[]): string { return promptParts(blocks).goal; }
113
-
114
- const TOOL_KINDS: Record<string, AcpToolKind> = {
115
- read: "read", edit: "edit", write: "edit", bash: "execute",
116
- skill_view: "read", skills_list: "search", mcp_list: "search",
117
- mcp_call: "other", memory_edit: "other", web_fetch: "fetch",
118
- };
119
-
120
- export function kindFor(tool: string): AcpToolKind {
121
- return TOOL_KINDS[tool] ?? "other";
122
- }
123
-
124
- /** Human title for a tool call: name plus the most salient argument. */
125
- export function titleFor(tool: string, args: unknown): string {
126
- if (args && typeof args === "object") {
127
- const a = args as Record<string, unknown>;
128
- const salient = a.path ?? a.command ?? a.name ?? a.url;
129
- if (salient !== undefined) return `${tool}: ${String(salient).slice(0, 120)}`;
130
- }
131
- return tool;
132
- }
133
-
134
- function asRawInput(args: unknown): Record<string, unknown> {
135
- if (args && typeof args === "object" && !Array.isArray(args)) return args as Record<string, unknown>;
136
- return args === undefined ? {} : { value: args };
137
- }
138
-
139
- function textContent(text: string): ToolCallContent[] {
140
- return [{ type: "content", content: { type: "text", text } }];
141
- }
142
-
143
- /** RunEvent → session/update payload; null for events with no ACP counterpart
144
- * (run_start, turn_start/end, steer, compaction — lifecycle stays house-side). */
145
- export function updateForEvent(ev: RunEvent): SessionUpdate | null {
146
- switch (ev.type) {
147
- case "message_update":
148
- return { sessionUpdate: "agent_message_chunk", content: { type: "text", text: ev.delta } };
149
- case "tool_execution_start":
150
- return {
151
- sessionUpdate: "tool_call", toolCallId: ev.callId, title: titleFor(ev.tool, ev.args),
152
- kind: kindFor(ev.tool), status: "in_progress", rawInput: asRawInput(ev.args),
153
- };
154
- case "tool_execution_update":
155
- return { sessionUpdate: "tool_call_update", toolCallId: ev.callId, content: textContent(ev.note) };
156
- case "tool_execution_end":
157
- return {
158
- sessionUpdate: "tool_call_update", toolCallId: ev.callId,
159
- status: ev.ok ? "completed" : "failed",
160
- content: textContent(ev.output), rawOutput: { output: ev.output },
161
- };
162
- case "tool_call_failed":
163
- // calls rejected before execution (permission_denied / truncated / not_found /
164
- // invalid_args) never got a tool_call create — create directly in failed status
165
- return {
166
- sessionUpdate: "tool_call", toolCallId: ev.callId, title: `tool call failed (${ev.reason})`,
167
- kind: "other", status: "failed", content: textContent(ev.detail),
168
- };
169
- default:
170
- return null;
171
- }
172
- }
173
-
174
- // ---------- the ACP agent ----------
175
-
176
- export class RovecodeAcpAgent implements Agent {
177
- private readonly sessions = new Map<string, AcpSessionState>();
178
-
179
- constructor(private readonly conn: AgentSideConnection, private readonly opts: AcpOptions = {}) {}
180
-
181
- async initialize(_params: InitializeRequest): Promise<InitializeResponse> {
182
- // we implement exactly v1: reply with our version; older clients disconnect (spec rule)
183
- return {
184
- protocolVersion: PROTOCOL_VERSION,
185
- agentCapabilities: {
186
- loadSession: false,
187
- promptCapabilities: { image: true, audio: false, embeddedContext: true }, // image: port #34 (promptParts)
188
- },
189
- authMethods: [],
190
- };
191
- }
192
-
193
- async authenticate(_params: AuthenticateRequest): Promise<AuthenticateResponse> {
194
- return {}; // no auth methods advertised; provider credentials come from env
195
- }
196
-
197
- async newSession(params: NewSessionRequest): Promise<NewSessionResponse> {
198
- // v1 scope: params.mcpServers is not wired into the runtime — the runtime
199
- // already loads project-level .rovecode/mcp.json + .mcp.json (port #3)
200
- let rt: Runtime;
201
- try {
202
- rt = await bootRuntime({ cwd: params.cwd, stream: this.opts.stream });
203
- } catch (e) {
204
- // port #27: the client's cwd asked for a rung this machine cannot provide (or
205
- // its sandbox.json is broken) — invalid params carrying the one-line message,
206
- // the same shape as "unknown session" below (the parameter names something
207
- // we cannot serve); the agent process stays up for the next session/new
208
- if (e instanceof SandboxConfigError) throw RequestError.invalidParams({ cwd: params.cwd, error: e.message });
209
- throw e;
210
- }
211
- // live registry: once the user runs `rovecode provider add` / `rovecode auth set`, the next
212
- // session/new succeeds without restarting the agent process
213
- const noProvider = rt.noProviderReason();
214
- if (!rt.stream || noProvider !== null) {
215
- throw RequestError.authRequired({
216
- details: noProvider ?? noModelHint("cli"),
217
- });
218
- }
219
- this.sessions.set(rt.sessionId, { rt, steering: rt.steering, active: null, permSeq: 0 }); // port #26: runtime queue → task notes reach the next prompt
220
- return { sessionId: rt.sessionId };
221
- }
222
-
223
- async prompt(params: PromptRequest): Promise<PromptResponse> {
224
- const s = this.sessions.get(params.sessionId);
225
- if (!s) throw RequestError.invalidParams({ sessionId: params.sessionId, error: "unknown session" });
226
- if (s.active) throw RequestError.invalidRequest({ error: "a prompt is already running for this session" });
227
- const stream = s.rt.stream;
228
- const noProvider = s.rt.noProviderReason();
229
- if (!stream || noProvider !== null) throw RequestError.authRequired(noProvider !== null ? { details: noProvider } : undefined);
230
-
231
- const { goal, images, error } = promptParts(params.prompt);
232
- // port #34: a bad image block (not png/jpeg/gif/webp, mime disagrees with the bytes, oversize,
233
- // 9+ images) rejects the prompt as invalid params BEFORE any run — same "nothing staged" outcome
234
- // as the TUI's error note; the session stays usable for the corrected prompt
235
- if (error !== undefined) throw RequestError.invalidParams({ error });
236
- const model = { provider: s.rt.provider?.id ?? "mock", model: s.rt.defaultModel || "default" };
237
- const def = s.rt.buildDef(model);
238
- const cfg = s.rt.buildCfg(this.opts.yolo ?? false, this.approvalFor(params.sessionId, s));
239
- const abort = new AbortController(); // port #21: one controller per run
240
- s.rt.tasks.bindRun(abort.signal); // port #26: session/cancel also cancels the run's background tasks
241
- const deps = {
242
- stream, registry: s.rt.registry, store: s.rt.store,
243
- tools: s.rt.registry.list().map((t) => t.schema), guard: s.rt.guard,
244
- hooks: s.rt.hooks, // port #29: .rovecode/hooks.{ts,js} of the session cwd
245
- cwd: s.rt.cwd, // HIGH-G1: the client's authoritative session cwd reaches ToolContext
246
- signal: abort.signal, // port #21: session/cancel kills in-flight fetch/tools mid-turn
247
- };
248
-
249
- // port #34: the store folds the staged images into the loop's user message when it lands in
250
- // append() — the same seam TUI /attach uses; the active guard above means no other user entry
251
- // can slip in between (task steers drain AFTER the goal message, loop.ts)
252
- if (images.length > 0) s.rt.store.stageAttachments(images);
253
- const gen = agentLoop(def, goal, {}, cfg, deps, s.steering);
254
- let fireCancel: () => void = () => {};
255
- const onCancel = new Promise<null>((resolve) => { fireCancel = () => resolve(null); });
256
- const active = { gen, cancelled: false, abort, onCancel, fireCancel };
257
- s.active = active;
258
- let end: { status: RunStatus; summary: string } | null = null;
259
- try {
260
- for await (const ev of gen) {
261
- if (active.cancelled) break; // session/cancel landed; loop finally aborts tools
262
- if (ev.type === "run_end") { end = { status: ev.status, summary: ev.summary }; break; }
263
- const update = updateForEvent(ev);
264
- if (update) await this.conn.sessionUpdate({ sessionId: params.sessionId, update });
265
- }
266
- } finally {
267
- s.active = null;
268
- }
269
-
270
- if (active.cancelled || end === null) return { stopReason: "cancelled" };
271
- switch (end.status) {
272
- case "done": return { stopReason: "end_turn" };
273
- case "budget": return { stopReason: "max_turn_requests" };
274
- case "stopped": return { stopReason: "cancelled" };
275
- case "error": throw RequestError.internalError({ details: end.summary });
276
- }
277
- }
278
-
279
- async cancel(params: CancelNotification): Promise<void> {
280
- const active = this.sessions.get(params.sessionId)?.active;
281
- if (!active) return;
282
- active.cancelled = true;
283
- // port #21: abort the run's controller FIRST — the in-flight provider fetch
284
- // dies and tool subprocesses are killed mid-turn, so the generator below
285
- // reaches a settle point quickly instead of finishing the turn.
286
- active.abort.abort();
287
- // HIGH-G2: unblock an outstanding request_permission (→ deny) — without
288
- // this a crashed client / closed popup leaves the run suspended inside the
289
- // approval await forever and the session permanently "already running".
290
- active.fireCancel();
291
- // close the generator as the follow-through: runs the loop's finally blocks.
292
- // Queues behind any pending next(), so the settle stays cooperative.
293
- await active.gen.return(undefined as never).then(() => undefined, () => undefined);
294
- }
295
-
296
- /** MED-G3: close every session runtime's MCP children. runAcpStdio calls this
297
- * when stdin closes — without it, `rovecode acp` in an MCP-configured project
298
- * outlives the client (children keep running until the parent is killed). */
299
- async shutdown(): Promise<void> {
300
- const closing: Promise<unknown>[] = [];
301
- for (const s of this.sessions.values()) {
302
- s.rt.tasks.cancelAll(); // port #26: background children die with the agent, never after it
303
- s.rt.bashJobs.dispose(); // #55: background shell jobs die with their session
304
- closing.push(s.rt.hooks.close()); // port #29: session_close per session runtime
305
- if (s.rt.mcp) closing.push(s.rt.mcp.close().catch(() => {}));
306
- }
307
- await Promise.all(closing);
308
- }
309
-
310
- /** ADR-005 approval seam → session/request_permission. Deny is the safe default:
311
- * declined, cancelled, unknown option, or a client that errors (unsupported). */
312
- private approvalFor(sessionId: string, s: AcpSessionState): ApprovalFn {
313
- return async (req) => {
314
- const toolCallId = `perm-${++s.permSeq}`;
315
- let outcome: { outcome: "cancelled" } | { outcome: "selected"; optionId: string };
316
- try {
317
- const ask = this.conn.requestPermission({
318
- sessionId,
319
- toolCall: {
320
- toolCallId, title: titleFor(req.tool, req.revisedArgs), kind: kindFor(req.tool),
321
- status: "pending", rawInput: asRawInput(req.revisedArgs),
322
- },
323
- options: [
324
- { optionId: "allow-once", name: "Allow once", kind: "allow_once" },
325
- { optionId: "allow-always", name: "Allow always", kind: "allow_always" },
326
- { optionId: "reject-once", name: "Deny", kind: "reject_once" },
327
- ],
328
- });
329
- void ask.then(() => undefined, () => undefined); // raced loser must not surface as unhandled
330
- // HIGH-G2: session/cancel must be able to interrupt an outstanding ask
331
- // (client crash / closed popup) — cancel wins the race and maps to deny
332
- const resp = s.active ? await Promise.race([ask, s.active.onCancel]) : await ask;
333
- if (resp === null) return "deny"; // cancelled mid-permission
334
- outcome = resp.outcome;
335
- } catch {
336
- return "deny"; // client rejected the request itself → unsupported → deny
337
- }
338
- if (outcome.outcome !== "selected") return "deny";
339
- if (outcome.optionId === "allow-once") return "once";
340
- if (outcome.optionId === "allow-always") return "always";
341
- return "deny";
342
- };
343
- }
344
- }
345
-
346
- // ---------- wiring ----------
347
-
348
- /** Attach an ACP agent to a bidirectional message stream (tests use an
349
- * in-process duplex; the CLI uses stdio via runAcpStdio). The agent handle is
350
- * returned alongside the connection so callers can shutdown() its sessions. */
351
- export function serveAcp(io: Stream, opts: AcpOptions = {}): { conn: AgentSideConnection; agent: RovecodeAcpAgent } {
352
- let agent!: RovecodeAcpAgent; // the factory runs synchronously inside the ctor
353
- const conn = new AgentSideConnection((c) => (agent = new RovecodeAcpAgent(c, opts)), io);
354
- return { conn, agent };
355
- }
356
-
357
- /** `rovecode acp`: serve ACP v1 over stdio until the client closes stdin.
358
- * stdout carries protocol frames only — nothing else may print there. */
359
- export function runAcpStdio(opts: AcpOptions = {}): Promise<void> {
360
- // node:stream/web and lib.dom stream types diverge on getReader() overloads;
361
- // the runtime objects are the same web streams, so bridge via unknown
362
- const io = ndJsonStream(
363
- Writable.toWeb(process.stdout) as unknown as WritableStream<Uint8Array>,
364
- Readable.toWeb(process.stdin) as unknown as ReadableStream<Uint8Array>,
365
- );
366
- const { agent } = serveAcp(io, opts);
367
- return new Promise<void>((resolve) => {
368
- // MED-G3: reap MCP children before resolving, or the process outlives a
369
- // closed editor in MCP-configured projects (children hold the event loop)
370
- const done = () => { void agent.shutdown().then(() => resolve(), () => resolve()); };
371
- process.stdin.once("end", done);
372
- process.stdin.once("close", done);
373
- });
374
- }