rovecode 0.4.0-beta.3 → 0.4.0

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 (432) hide show
  1. package/README.md +57 -72
  2. package/THIRD_PARTY_NOTICES.md +0 -44
  3. package/bin/rovecode.ts +21 -0
  4. package/package.json +16 -38
  5. package/src/account/keys.ts +97 -0
  6. package/src/account/login.ts +158 -0
  7. package/src/account/provision.ts +47 -0
  8. package/src/account/store.ts +63 -0
  9. package/src/acp/server.ts +373 -0
  10. package/src/cli/account-cmd.ts +116 -0
  11. package/src/cli/connect.ts +244 -0
  12. package/src/cli/context-cmd.ts +199 -0
  13. package/src/cli/dispatch.ts +109 -0
  14. package/src/cli/doctor.ts +324 -0
  15. package/src/cli/export.ts +278 -0
  16. package/src/cli/help.ts +240 -0
  17. package/src/cli/is-tui-invocation.ts +8 -0
  18. package/src/cli/main.ts +599 -0
  19. package/src/cli/market-cmd.ts +658 -0
  20. package/src/cli/mcp-market-cmd.ts +299 -0
  21. package/src/cli/output.ts +382 -0
  22. package/src/cli/repl.ts +172 -0
  23. package/src/cli/resume.ts +32 -0
  24. package/src/cli/run-limits.ts +78 -0
  25. package/src/cli/runtime.ts +792 -0
  26. package/src/cli/setup.ts +187 -0
  27. package/src/cli/update-cmd.ts +78 -0
  28. package/src/cli/workflow-cmd.ts +100 -0
  29. package/src/coding/checkpoints.ts +270 -0
  30. package/src/coding/diff.ts +136 -0
  31. package/src/coding/files.ts +339 -0
  32. package/src/coding/hashline.ts +319 -0
  33. package/src/coding/lsp.ts +406 -0
  34. package/src/coding/repomap-cache.ts +99 -0
  35. package/src/coding/repomap-files.ts +110 -0
  36. package/src/coding/repomap.ts +392 -0
  37. package/src/core/compaction.ts +399 -0
  38. package/src/core/config.ts +289 -0
  39. package/src/core/context-report.ts +228 -0
  40. package/src/core/context.ts +60 -0
  41. package/src/core/count-remote.ts +107 -0
  42. package/src/core/execpolicy-rules.ts +196 -0
  43. package/src/core/execpolicy.ts +385 -0
  44. package/src/core/executor.ts +397 -0
  45. package/src/core/guardrails.ts +400 -0
  46. package/src/core/hooks.ts +398 -0
  47. package/src/core/images.ts +230 -0
  48. package/src/core/intro.ts +236 -0
  49. package/src/core/loop.ts +621 -0
  50. package/src/core/modes.ts +372 -0
  51. package/src/core/orchestrator.ts +207 -0
  52. package/src/core/reflection.ts +165 -0
  53. package/src/core/sandbox-config.ts +167 -0
  54. package/src/core/session-images.ts +73 -0
  55. package/src/core/session.ts +398 -0
  56. package/src/core/settings.ts +98 -0
  57. package/src/core/stuck-detector.ts +273 -0
  58. package/src/core/tasks.ts +374 -0
  59. package/src/core/token-scale.ts +108 -0
  60. package/src/core/tool-output-budget.ts +166 -0
  61. package/src/core/tools.ts +288 -0
  62. package/src/core/types.ts +330 -0
  63. package/src/core/update-check.ts +171 -0
  64. package/src/core/update.ts +158 -0
  65. package/src/core/usage.ts +204 -0
  66. package/src/core/validate.ts +121 -0
  67. package/src/core/verify-gate.ts +159 -0
  68. package/src/core/verify.ts +237 -0
  69. package/src/core/voice.ts +158 -0
  70. package/src/core/win-job.ts +183 -0
  71. package/src/design/audit.ts +797 -0
  72. package/src/design/direction.ts +190 -0
  73. package/src/design/rules.ts +157 -0
  74. package/src/eval/bench.ts +150 -0
  75. package/src/eval/gauntlet-runner.ts +218 -0
  76. package/src/eval/gauntlet.ts +226 -0
  77. package/src/eval/grader.ts +186 -0
  78. package/src/eval/record.ts +202 -0
  79. package/src/eval/redact.ts +141 -0
  80. package/src/eval/replay.ts +147 -0
  81. package/src/eval/trajectory.ts +373 -0
  82. package/src/index.ts +17 -0
  83. package/src/market/catalogs/mcp-docs.json +111 -0
  84. package/src/market/catalogs/plugins.json +111 -0
  85. package/src/market/catalogs/skills.json +478 -0
  86. package/src/market/clone.ts +72 -0
  87. package/src/market/context-cost.ts +121 -0
  88. package/src/market/digest.ts +106 -0
  89. package/src/market/index.ts +22 -0
  90. package/src/market/install.ts +578 -0
  91. package/src/market/manifest.ts +187 -0
  92. package/src/market/prereq.ts +145 -0
  93. package/src/market/registry.ts +363 -0
  94. package/src/market/resolve.ts +111 -0
  95. package/src/market/types.ts +236 -0
  96. package/src/market/validate.ts +227 -0
  97. package/src/mcp/client.ts +431 -0
  98. package/src/mcp/config.ts +239 -0
  99. package/src/mcp/local-package.ts +211 -0
  100. package/src/mcp/market-catalog.ts +84 -0
  101. package/src/mcp/market-install.ts +289 -0
  102. package/src/mcp/market.ts +0 -0
  103. package/src/mcp/tools.ts +131 -0
  104. package/src/mcp/trust.ts +49 -0
  105. package/src/memory/blocks.ts +175 -0
  106. package/src/memory/recall.ts +355 -0
  107. package/src/memory/store.ts +105 -0
  108. package/src/memory/tools.ts +99 -0
  109. package/src/plugins/cli.ts +123 -0
  110. package/src/plugins/discover.ts +108 -0
  111. package/src/plugins/index.ts +50 -0
  112. package/src/plugins/init.ts +140 -0
  113. package/src/plugins/install.ts +184 -0
  114. package/src/plugins/load.ts +149 -0
  115. package/src/plugins/manifest.ts +106 -0
  116. package/src/plugins/state.ts +83 -0
  117. package/src/providers/auth.ts +293 -0
  118. package/src/providers/cache.ts +223 -0
  119. package/src/providers/catalog-local.ts +160 -0
  120. package/src/providers/catalog.ts +408 -0
  121. package/src/providers/middleware-context.ts +86 -0
  122. package/src/providers/middleware.ts +373 -0
  123. package/src/providers/profile-glm53.ts +111 -0
  124. package/src/providers/profile-sonnet5-persona.ts +65 -0
  125. package/src/providers/profile-sonnet5-voice.ts +23 -0
  126. package/src/providers/profiles.ts +156 -0
  127. package/src/providers/provider-config.ts +311 -0
  128. package/src/providers/registry.ts +302 -0
  129. package/src/providers/response-validation.ts +80 -0
  130. package/src/providers/retry.ts +234 -0
  131. package/src/providers/router.ts +294 -0
  132. package/src/providers/sse.ts +26 -0
  133. package/src/providers/stream-errors.ts +117 -0
  134. package/src/providers/stream.ts +569 -0
  135. package/src/providers/thinking.ts +189 -0
  136. package/src/providers/wire-messages.ts +129 -0
  137. package/src/sdk/client.ts +225 -0
  138. package/src/sdk/index.ts +3 -0
  139. package/src/server/dashboard.ts +144 -0
  140. package/src/server/http.ts +343 -0
  141. package/src/server/openapi.ts +246 -0
  142. package/src/sextant/card-hits.ts +102 -0
  143. package/src/sextant/card-keys.ts +55 -0
  144. package/src/sextant/context-source.ts +157 -0
  145. package/src/sextant/draw-agents.ts +273 -0
  146. package/src/sextant/draw-code.ts +388 -0
  147. package/src/sextant/draw-context.ts +222 -0
  148. package/src/sextant/draw-frame.ts +164 -0
  149. package/src/sextant/draw-market.ts +573 -0
  150. package/src/sextant/draw-messages.ts +386 -0
  151. package/src/sextant/draw-pet.ts +230 -0
  152. package/src/sextant/draw-plan.ts +159 -0
  153. package/src/sextant/draw-tabs.ts +85 -0
  154. package/src/sextant/draw-util.ts +65 -0
  155. package/src/sextant/engine.ts +230 -0
  156. package/src/sextant/frame-hits.ts +25 -0
  157. package/src/sextant/frame.ts +101 -0
  158. package/src/sextant/git-status.ts +197 -0
  159. package/src/sextant/grid.ts +59 -0
  160. package/src/sextant/input.ts +119 -0
  161. package/src/sextant/keys.ts +488 -0
  162. package/src/sextant/layout.ts +86 -0
  163. package/src/sextant/local-commands.ts +156 -0
  164. package/src/sextant/market-source.ts +287 -0
  165. package/src/sextant/mentions.ts +141 -0
  166. package/src/sextant/message-hits.ts +26 -0
  167. package/src/sextant/model.ts +387 -0
  168. package/src/sextant/overlays.ts +451 -0
  169. package/src/sextant/panel-hits.ts +38 -0
  170. package/src/sextant/pet.ts +399 -0
  171. package/src/sextant/screen.ts +324 -0
  172. package/src/sextant/scroll-hits.ts +66 -0
  173. package/src/sextant/scrollbar.ts +82 -0
  174. package/src/sextant/selection.ts +123 -0
  175. package/src/sextant/sextant-bridge.ts +174 -0
  176. package/src/sextant/sextant-cards.ts +142 -0
  177. package/src/sextant/sextant-diff-base.ts +63 -0
  178. package/src/sextant/sextant-files.ts +154 -0
  179. package/src/sextant/sextant-frame-loop.ts +314 -0
  180. package/src/sextant/sextant-renderer.ts +478 -0
  181. package/src/sextant/sextant-repo.ts +131 -0
  182. package/src/sextant/theme.ts +66 -0
  183. package/src/sextant/tool-rows.ts +189 -0
  184. package/src/sextant/types.ts +473 -0
  185. package/src/skills/index.ts +306 -0
  186. package/src/skills/tools.ts +69 -0
  187. package/src/skills/versioned.ts +227 -0
  188. package/src/telemetry/otel.ts +353 -0
  189. package/src/telemetry/otlp.ts +68 -0
  190. package/src/tools/ask-user.ts +156 -0
  191. package/src/tools/design.ts +151 -0
  192. package/src/tools/evalcell.ts +338 -0
  193. package/src/tools/html-text.ts +139 -0
  194. package/src/tools/provider.ts +149 -0
  195. package/src/tools/task.ts +216 -0
  196. package/src/tools/todo.ts +320 -0
  197. package/src/tools/webfetch.ts +331 -0
  198. package/src/tui/app.ts +608 -0
  199. package/src/tui/attach.ts +127 -0
  200. package/src/tui/checkpoints-cmd.ts +70 -0
  201. package/src/tui/clipboard-image.ts +81 -0
  202. package/src/tui/commands.ts +277 -0
  203. package/src/tui/cost.ts +108 -0
  204. package/src/tui/info-cmd.ts +144 -0
  205. package/src/tui/mcp-cmd.ts +128 -0
  206. package/src/tui/modes-cmd.ts +45 -0
  207. package/src/tui/overlays.ts +97 -0
  208. package/src/tui/pi-renderer.ts +424 -0
  209. package/src/tui/providers-cmd.ts +366 -0
  210. package/src/tui/renderer.ts +101 -0
  211. package/src/tui/replay-marker.ts +29 -0
  212. package/src/tui/session-cmd.ts +146 -0
  213. package/src/tui/sextant-attach.ts +68 -0
  214. package/src/tui/sextant-io.ts +184 -0
  215. package/src/tui/sextant-smoke.ts +110 -0
  216. package/src/tui/smoke.ts +72 -0
  217. package/src/tui/theme.ts +59 -0
  218. package/src/tui/todo-label.ts +7 -0
  219. package/src/workflow/engine.ts +266 -0
  220. package/tsconfig.json +30 -0
  221. package/vendor/pi-tui/LICENSE +21 -0
  222. package/vendor/pi-tui/PATCHES.md +12 -0
  223. package/vendor/pi-tui/PROVENANCE.md +12 -0
  224. package/vendor/pi-tui/README.upstream.md +854 -0
  225. package/vendor/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  226. package/vendor/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  227. package/vendor/pi-tui/src/alt-screen-search.ts +158 -0
  228. package/vendor/pi-tui/src/autocomplete.ts +827 -0
  229. package/vendor/pi-tui/src/components/alt-screen-flash.ts +52 -0
  230. package/vendor/pi-tui/src/components/box.ts +138 -0
  231. package/vendor/pi-tui/src/components/cancellable-loader.ts +41 -0
  232. package/vendor/pi-tui/src/components/editor.ts +2364 -0
  233. package/vendor/pi-tui/src/components/h-stack.ts +45 -0
  234. package/vendor/pi-tui/src/components/image.ts +128 -0
  235. package/vendor/pi-tui/src/components/input.ts +448 -0
  236. package/vendor/pi-tui/src/components/loader.ts +93 -0
  237. package/vendor/pi-tui/src/components/markdown.ts +1016 -0
  238. package/vendor/pi-tui/src/components/scroll-view.ts +217 -0
  239. package/vendor/pi-tui/src/components/select-list.ts +230 -0
  240. package/vendor/pi-tui/src/components/settings-list.ts +277 -0
  241. package/vendor/pi-tui/src/components/spacer.ts +29 -0
  242. package/vendor/pi-tui/src/components/stack.ts +155 -0
  243. package/vendor/pi-tui/src/components/text.ts +108 -0
  244. package/vendor/pi-tui/src/components/truncated-text.ts +66 -0
  245. package/vendor/pi-tui/src/components/v-stack.ts +34 -0
  246. package/vendor/pi-tui/src/editor-component.ts +75 -0
  247. package/vendor/pi-tui/src/fuzzy.ts +138 -0
  248. package/vendor/pi-tui/src/index.ts +149 -0
  249. package/vendor/pi-tui/src/keybindings.ts +321 -0
  250. package/vendor/pi-tui/src/keys.ts +1402 -0
  251. package/vendor/pi-tui/src/kill-ring.ts +47 -0
  252. package/vendor/pi-tui/src/latex.ts +1381 -0
  253. package/vendor/pi-tui/src/layout-node.ts +52 -0
  254. package/vendor/pi-tui/src/layout.ts +411 -0
  255. package/vendor/pi-tui/src/native-modifiers.ts +60 -0
  256. package/vendor/pi-tui/src/native-module-path.ts +32 -0
  257. package/vendor/pi-tui/src/stdin-buffer.ts +445 -0
  258. package/vendor/pi-tui/src/terminal-colors.ts +74 -0
  259. package/vendor/pi-tui/src/terminal-image.ts +701 -0
  260. package/vendor/pi-tui/src/terminal.ts +554 -0
  261. package/vendor/pi-tui/src/tui-alt-screen.ts +1379 -0
  262. package/vendor/pi-tui/src/tui-main-screen.ts +655 -0
  263. package/vendor/pi-tui/src/tui.ts +1264 -0
  264. package/vendor/pi-tui/src/undo-stack.ts +29 -0
  265. package/vendor/pi-tui/src/utils.ts +1327 -0
  266. package/vendor/pi-tui/src/word-navigation.ts +118 -0
  267. package/vendor/pi-tui/test/test-themes.ts +39 -0
  268. package/vendor/pi-tui/test/virtual-terminal.ts +219 -0
  269. package/CHANGELOG.md +0 -527
  270. package/bin/rovecode.js +0 -24
  271. package/dist/cli/app-j6gn14w3.js +0 -2
  272. package/dist/cli/ask-user-cwstt8fz.js +0 -2
  273. package/dist/cli/auth-login-9bbp9915.js +0 -2
  274. package/dist/cli/auth-m8p9grty.js +0 -2
  275. package/dist/cli/bench-16zqdms5.js +0 -9
  276. package/dist/cli/catalog-1xchffa4.js +0 -2
  277. package/dist/cli/cli-1n1zb64f.js +0 -2
  278. package/dist/cli/client-2t9gjkck.js +0 -2
  279. package/dist/cli/commands-exafvm2b.js +0 -2
  280. package/dist/cli/connect-6zde0kn3.js +0 -2
  281. package/dist/cli/context-cmd-5t43wgqt.js +0 -2
  282. package/dist/cli/context-report-kt01pw8y.js +0 -2
  283. package/dist/cli/count-remote-ap7x3vh6.js +0 -2
  284. package/dist/cli/design-ne5zszyh.js +0 -2
  285. package/dist/cli/dispatch-2r5myxye.js +0 -2
  286. package/dist/cli/doctor-ws4fh4tn.js +0 -3
  287. package/dist/cli/executor-bdrjn634.js +0 -2
  288. package/dist/cli/export-1mxb9g5p.js +0 -2
  289. package/dist/cli/files-g104xghh.js +0 -2
  290. package/dist/cli/gauntlet-07xrjpj7.js +0 -2
  291. package/dist/cli/gauntlet-runner-xvy64436.js +0 -10
  292. package/dist/cli/gauntlet-wave3-jm91yt5w.js +0 -5
  293. package/dist/cli/gauntlet-wave4-r13py7p1.js +0 -14
  294. package/dist/cli/hashline-znvrat11.js +0 -2
  295. package/dist/cli/http-xafw6fsh.js +0 -143
  296. package/dist/cli/index-1sgjm25y.js +0 -2
  297. package/dist/cli/init-g2m0tn4m.js +0 -51
  298. package/dist/cli/install-avaqjjqq.js +0 -2
  299. package/dist/cli/loop-mmpfft01.js +0 -2
  300. package/dist/cli/main-0904f6ps.js +0 -5
  301. package/dist/cli/main-0ab9fc26.js +0 -9
  302. package/dist/cli/main-0jys2ccn.js +0 -3
  303. package/dist/cli/main-0mtcdbs7.js +0 -3
  304. package/dist/cli/main-0z1w2zsg.js +0 -3
  305. package/dist/cli/main-1dchs7xv.js +0 -18
  306. package/dist/cli/main-1ereejm1.js +0 -3
  307. package/dist/cli/main-1k1kw6b5.js +0 -3
  308. package/dist/cli/main-27y4sm2k.js +0 -38
  309. package/dist/cli/main-2wwjex5j.js +0 -58
  310. package/dist/cli/main-2yeveeve.js +0 -6
  311. package/dist/cli/main-2yfck9b5.js +0 -3
  312. package/dist/cli/main-2zmzgkwh.js +0 -3
  313. package/dist/cli/main-351pz3z7.js +0 -7
  314. package/dist/cli/main-3gjqfh7a.js +0 -6
  315. package/dist/cli/main-3nf3kgve.js +0 -3
  316. package/dist/cli/main-3pjrb2hd.js +0 -3
  317. package/dist/cli/main-3rxcvgna.js +0 -19
  318. package/dist/cli/main-4b3jgy66.js +0 -19
  319. package/dist/cli/main-4wndhjdc.js +0 -7
  320. package/dist/cli/main-4xcmvxnk.js +0 -3
  321. package/dist/cli/main-5tbz0wbz.js +0 -4
  322. package/dist/cli/main-5ywnwthm.js +0 -3
  323. package/dist/cli/main-6b62vkz0.js +0 -14
  324. package/dist/cli/main-6dnk69vp.js +0 -3
  325. package/dist/cli/main-6genrmhs.js +0 -136
  326. package/dist/cli/main-73g7eff4.js +0 -15
  327. package/dist/cli/main-7c5thhjd.js +0 -5
  328. package/dist/cli/main-7rn6bqje.js +0 -3
  329. package/dist/cli/main-80haw7qk.js +0 -4
  330. package/dist/cli/main-875s60s2.js +0 -4
  331. package/dist/cli/main-8kjxbpw4.js +0 -8
  332. package/dist/cli/main-90ds1z4e.js +0 -10
  333. package/dist/cli/main-9etavkew.js +0 -3
  334. package/dist/cli/main-a9njrkk1.js +0 -3
  335. package/dist/cli/main-aecrjq2d.js +0 -12
  336. package/dist/cli/main-ck9asesq.js +0 -9
  337. package/dist/cli/main-cta9racd.js +0 -4
  338. package/dist/cli/main-ddv7j2ag.js +0 -3
  339. package/dist/cli/main-dfreez27.js +0 -10
  340. package/dist/cli/main-f7rw7des.js +0 -3
  341. package/dist/cli/main-ggcn7rd7.js +0 -5
  342. package/dist/cli/main-gzkmycnv.js +0 -3
  343. package/dist/cli/main-hq51jg8v.js +0 -18
  344. package/dist/cli/main-jft389w9.js +0 -8
  345. package/dist/cli/main-k1eqkg83.js +0 -3
  346. package/dist/cli/main-k2y8a2aw.js +0 -9
  347. package/dist/cli/main-kcpbykxz.js +0 -4
  348. package/dist/cli/main-kd488vje.js +0 -22
  349. package/dist/cli/main-kh32yvgk.js +0 -5
  350. package/dist/cli/main-kqxnqjnv.js +0 -25
  351. package/dist/cli/main-kyn0xnsg.js +0 -3
  352. package/dist/cli/main-m1kk6fp5.js +0 -21
  353. package/dist/cli/main-mv40pcr2.js +0 -4
  354. package/dist/cli/main-n0t3973w.js +0 -3
  355. package/dist/cli/main-nqveez48.js +0 -4
  356. package/dist/cli/main-pknhvrmj.js +0 -3
  357. package/dist/cli/main-pn1w7a7j.js +0 -3
  358. package/dist/cli/main-prxxs70n.js +0 -4
  359. package/dist/cli/main-q3vsesf9.js +0 -3
  360. package/dist/cli/main-qsevpgsv.js +0 -3
  361. package/dist/cli/main-rdgdw24b.js +0 -25
  362. package/dist/cli/main-rfth4tbm.js +0 -16
  363. package/dist/cli/main-rg0wn0xf.js +0 -5
  364. package/dist/cli/main-sdmxhtv8.js +0 -4
  365. package/dist/cli/main-skbp13js.js +0 -18
  366. package/dist/cli/main-t4xnd213.js +0 -7
  367. package/dist/cli/main-vqak588n.js +0 -4
  368. package/dist/cli/main-w2n1303f.js +0 -9
  369. package/dist/cli/main-wbrdspr2.js +0 -5
  370. package/dist/cli/main-wsrg79c1.js +0 -7
  371. package/dist/cli/main-x4r0fne4.js +0 -5
  372. package/dist/cli/main-xea2f3tn.js +0 -6
  373. package/dist/cli/main-xg704a3c.js +0 -3
  374. package/dist/cli/main-xvnrabfp.js +0 -16
  375. package/dist/cli/main-xy53xf0r.js +0 -4
  376. package/dist/cli/main-y1fqy60y.js +0 -3
  377. package/dist/cli/main-yn8cd281.js +0 -34
  378. package/dist/cli/main-yr0ksc0h.js +0 -4
  379. package/dist/cli/main-z2ex2vyf.js +0 -4
  380. package/dist/cli/main-z3aayzvq.js +0 -3
  381. package/dist/cli/main-zaqh35jg.js +0 -3
  382. package/dist/cli/main-zc2e8e46.js +0 -4
  383. package/dist/cli/main-zzrfw6cf.js +0 -13
  384. package/dist/cli/main.js +0 -280
  385. package/dist/cli/market-cmd-e14kmx9n.js +0 -5
  386. package/dist/cli/mcp-login-wq7ktdek.js +0 -2
  387. package/dist/cli/mcp-market-cmd-9mg3jecy.js +0 -2
  388. package/dist/cli/notify-b7qc0cjb.js +0 -2
  389. package/dist/cli/oauth-z8whcgfx.js +0 -2
  390. package/dist/cli/output-b3ewj3ps.js +0 -16
  391. package/dist/cli/profiles-6mr5he5e.js +0 -2
  392. package/dist/cli/provider-config-g7j42q8x.js +0 -2
  393. package/dist/cli/provider-jr1y8vvm.js +0 -2
  394. package/dist/cli/registry-s8yk86g0.js +0 -2
  395. package/dist/cli/registry-t6p8d4mn.js +0 -2
  396. package/dist/cli/repl-bajwe1mh.js +0 -11
  397. package/dist/cli/resume-rwn9nz7y.js +0 -2
  398. package/dist/cli/run-flags-nah7ndpt.js +0 -2
  399. package/dist/cli/runtime-n7gafzhb.js +0 -2
  400. package/dist/cli/sandbox-config-emdy18x4.js +0 -2
  401. package/dist/cli/server-b0nvs2bn.js +0 -5
  402. package/dist/cli/session-arg-y75wd4kj.js +0 -2
  403. package/dist/cli/session-j62evmjq.js +0 -2
  404. package/dist/cli/sessions-cmd-tsnwz0ns.js +0 -7
  405. package/dist/cli/settings-df10wfez.js +0 -2
  406. package/dist/cli/setup-jzvv72fg.js +0 -2
  407. package/dist/cli/sextant-smoke-37m81ke6.js +0 -5
  408. package/dist/cli/skills-cmd-gjxnxnhx.js +0 -2
  409. package/dist/cli/smoke-p7748apt.js +0 -8
  410. package/dist/cli/start-chat-s4st3mm0.js +0 -12
  411. package/dist/cli/stream-gmeyewds.js +0 -2
  412. package/dist/cli/task-gh0kkp3n.js +0 -2
  413. package/dist/cli/tasks-z1kfpe8e.js +0 -2
  414. package/dist/cli/thinking-0eqkrz6t.js +0 -2
  415. package/dist/cli/todo-5brcrt9m.js +0 -2
  416. package/dist/cli/tools-7pzm0vj9.js +0 -2
  417. package/dist/cli/tools-s635p6s8.js +0 -2
  418. package/dist/cli/trust-cmd-cjav8zgm.js +0 -2
  419. package/dist/cli/update-check-pt31bm2f.js +0 -2
  420. package/dist/cli/update-cmd-tk131s9t.js +0 -2
  421. package/dist/cli/voice-56nabd8d.js +0 -2
  422. package/dist/cli/webfetch-xd8q596m.js +0 -2
  423. package/dist/cli/websearch-5hkf98k1.js +0 -2
  424. package/dist/cli/workflow-cmd-cy3cvzjp.js +0 -4
  425. package/dist/cli/workspace-q10g5z3e.js +0 -2
  426. package/dist/lib/index.js +0 -62
  427. package/dist/lib/models-index.json +0 -1
  428. package/dist/lib/plugins.js +0 -55
  429. package/dist/lib/providers.js +0 -17
  430. package/dist/lib/public-api.js +0 -20
  431. package/dist/lib/sdk.js +0 -360
  432. /package/{dist/cli → src/providers}/models-index.json +0 -0
@@ -0,0 +1,72 @@
1
+ /** Cloning at a ref, and the one subtle decision in it.
2
+ *
3
+ * `--ref` takes a branch, a tag or a commit, and git needs a DIFFERENT command for the last one:
4
+ * `clone --depth 1 --branch <x>` works for a branch or a tag and fails for a bare commit, so a commit has
5
+ * to go through `init` + `fetch --depth 1 <url> <sha>` + `checkout FETCH_HEAD`.
6
+ *
7
+ * We do not decide which one `<x>` is by looking at it. `/^[0-9a-f]{7,40}$/` is a guess, and a wrong guess
8
+ * here installs the wrong tree silently: `abcdef` is a perfectly legal branch name, and a repository that
9
+ * has one would be pinned to a commit that merely shares the spelling. Git's answer is a fact, so we ask
10
+ * git: try the branch form, and use the commit form only when that fails.
11
+ *
12
+ * ORDER IS A DECISION, not a side effect. When a name is BOTH a branch and the short id of some commit,
13
+ * the branch wins, because someone typing `--ref` almost always means a name. That is why the branch form
14
+ * is tried first, and the manifest records `resolvedBy` so the question "was this a branch or a commit?"
15
+ * has an answer afterwards rather than a shrug.
16
+ *
17
+ * One deliberate refusal: fetching a bare SHA needs `uploadpack.allowReachableSHA1InWant` on the server,
18
+ * and plenty of hosts leave it off. When that is refused we STOP and say so. The alternative — quietly
19
+ * dropping `--depth` and cloning the entire history — turns a pin into a very long download the person
20
+ * did not ask for, and they would have no idea why. */
21
+
22
+ export type Spawn = (cmd: string[], cwd: string) => Promise<{ code: number; stderr: string }>;
23
+
24
+ export type ResolvedBy = "branch" | "commit" | "default";
25
+
26
+ export interface CloneResult {
27
+ ok: true;
28
+ /** which form of the command actually produced the tree */
29
+ resolvedBy: ResolvedBy;
30
+ }
31
+ export type CloneOutcome = CloneResult | { ok: false; error: string };
32
+
33
+ /** the last line of git's complaint, which is the part a person can act on */
34
+ const lastLine = (stderr: string): string => stderr.trim().split("\n").at(-1)?.trim() ?? "";
35
+
36
+ /** a server that will not serve a bare commit says so in one of a few ways; all of them mean the same
37
+ * thing to us, and none of them should be answered by fetching more */
38
+ function refusesBareSha(stderr: string): boolean {
39
+ return /allow.*sha1.*in.?want|not our ref|unadvertised object|Server does not allow request for unadvertised object/i.test(stderr);
40
+ }
41
+
42
+ /** Clone `url` into `dir` (which must exist and be empty), optionally at `ref`. */
43
+ /** `--` before every positional, on purpose. git parses options wherever it finds them, so a value that
44
+ * begins with a dash is read as an option no matter which slot it sits in: a ref or a URL spelled
45
+ * `--upload-pack=...` becomes an instruction rather than a name. Catalog data cannot reach here in that
46
+ * shape (`url()` filters it), but `market install <git-url>` and `--ref` come straight from a command
47
+ * line. The marker costs one argument and says "what follows is a value", which is the claim we mean. */
48
+ export async function cloneAtRef(spawn: Spawn, url: string, dir: string, ref?: string): Promise<CloneOutcome> {
49
+ if (ref === undefined || ref.trim() === "") {
50
+ const r = await spawn(["git", "clone", "--depth", "1", "--quiet", "--", url, "."], dir);
51
+ return r.code === 0 ? { ok: true, resolvedBy: "default" } : { ok: false, error: `git clone failed (exit ${r.code})${lastLine(r.stderr) ? `: ${lastLine(r.stderr)}` : ""}` };
52
+ }
53
+
54
+ // 1. a branch or a tag — the common case, and the winner when a name is both
55
+ const branch = await spawn(["git", "clone", "--depth", "1", "--quiet", "--branch", ref, "--", url, "."], dir);
56
+ if (branch.code === 0) return { ok: true, resolvedBy: "branch" };
57
+
58
+ // 2. a commit. Not a fallback for "anything went wrong": if the failure was the network or auth, the
59
+ // fetch will fail the same way and we report THAT, not a misleading "no such ref".
60
+ const init = await spawn(["git", "init", "--quiet"], dir);
61
+ if (init.code !== 0) return { ok: false, error: `git init failed (exit ${init.code})${lastLine(init.stderr) ? `: ${lastLine(init.stderr)}` : ""}` };
62
+ const fetch = await spawn(["git", "fetch", "--depth", "1", "--quiet", "--", url, ref], dir);
63
+ if (fetch.code !== 0) {
64
+ if (refusesBareSha(fetch.stderr)) {
65
+ return { ok: false, error: `${url} will not serve the single commit ${ref} (the server has uploadpack.allowReachableSHA1InWant off) — give a branch or tag instead, or ask the host to enable it` };
66
+ }
67
+ return { ok: false, error: `"${ref}" is not a branch or tag there, and fetching it as a commit failed (exit ${fetch.code})${lastLine(fetch.stderr) ? `: ${lastLine(fetch.stderr)}` : ""}` };
68
+ }
69
+ const checkout = await spawn(["git", "checkout", "--quiet", "FETCH_HEAD"], dir);
70
+ if (checkout.code !== 0) return { ok: false, error: `fetched ${ref} but could not check it out (exit ${checkout.code})${lastLine(checkout.stderr) ? `: ${lastLine(checkout.stderr)}` : ""}` };
71
+ return { ok: true, resolvedBy: "commit" };
72
+ }
@@ -0,0 +1,121 @@
1
+ /** What installing this item costs you in context, said before the yes.
2
+ *
3
+ * THE NUMBER IS TWO NUMBERS, and collapsing them would be the whole feature's undoing. rovecode's skills
4
+ * are progressive disclosure: `buildSkillsIndex` puts one line per skill in the system prompt — the name,
5
+ * the version and the clipped description — and the SKILL.md body enters context only when the model calls
6
+ * `skill_view`. Measured across the 19 skills that ship: the index line averages 79 tokens, the body
7
+ * averages 2,288. A single "costs ~2.3k tokens per turn" would be 29× the truth for a skill nobody opens,
8
+ * and a reader who checked once would never trust the line again.
9
+ *
10
+ * So: `perTurn` is what every request carries, `whenUsed` is what arrives if the model opens it.
11
+ *
12
+ * WHAT CANNOT BE KNOWN is said instead of guessed:
13
+ * - an MCP server publishes its tool schemas after it connects. Before that there is no number, and
14
+ * inventing one would spend this line's credibility on the day it shipped.
15
+ * - a plugin's entry module contributes tools whose schemas we would have to LOAD ITS CODE to read,
16
+ * which is exactly what a plan must not do. Its skills and commands directories are files, so those
17
+ * are measured.
18
+ *
19
+ * THE ESTIMATE IS SCALED, NOT CAVEATED. `countTokens` is gpt-tokenizer's o200k_base and Anthropic's
20
+ * tokenizer is not public, so for a Claude model the raw count is simply wrong — measured against
21
+ * Anthropic's own count_tokens endpoint over all 19 skill bodies that ship, it reads 1.41×–1.79× low
22
+ * (mean 1.59×). Rather than describe that in prose, the numbers are multiplied by `tokenScaleFor`, which
23
+ * holds a measured factor per model generation. An earlier draft of this file said "reads roughly a third
24
+ * low on Anthropic models"; that was already wrong for Claude 4.5, where the factor is 1.21×, and a
25
+ * sentence like it is wrong again every time a model ships.
26
+ *
27
+ * When no model is named the numbers are left unscaled and the line says so. When the provider's own
28
+ * tokenizer IS o200k — OpenAI — there is nothing to scale and the line says that instead. A model nobody
29
+ * has measured is never given a neighbour's factor.
30
+ */
31
+
32
+ import { tokenScaleFor, type TokenScale } from "../core/token-scale.ts";
33
+ import { countTokens } from "../core/usage.ts";
34
+ import { INDEX_PROMPT_LIMIT } from "../skills/tools.ts";
35
+ import type { MarketItem } from "./types.ts";
36
+
37
+ export interface ContextCost {
38
+ /** tokens added to EVERY request while this is installed */
39
+ perTurn: number;
40
+ /** tokens added only when the model opens it; absent when there is no such body */
41
+ whenUsed?: number;
42
+ /** the tokenizer the numbers came from — named because it is not the model's */
43
+ tokenizer: "o200k_base";
44
+ /** a part of the cost that cannot be known before installing, and why */
45
+ unknown?: string;
46
+ /** installing this would push the skill count past the index limit; see `INDEX_PROMPT_LIMIT` */
47
+ overIndexLimit?: boolean;
48
+ /** how wrong the estimate is for the model that will carry it, when a measurement exists for it */
49
+ scale?: TokenScale;
50
+ }
51
+
52
+ export interface ContextCostOptions {
53
+ /** how many skills are already installed, so the index-limit warning can be right */
54
+ installedSkills?: number;
55
+ /** the model that will actually carry this, so the estimate can be scaled by a MEASURED factor rather
56
+ * than described with a hand-written one. Omit it and the line says the number is unscaled. */
57
+ model?: { provider: string; model: string };
58
+ }
59
+
60
+ /** The system-prompt line `buildSkillsIndex` renders, rebuilt from catalog fields so the count describes
61
+ * what would actually be in the prompt rather than an approximation of it (skills/tools.ts
62
+ * renderIndexLine). The description is already clipped to 60 characters by the skill reader. */
63
+ const indexLine = (item: MarketItem): string =>
64
+ `- ${item.id}${item.version ? ` (v${item.version})` : ""}: ${item.description}`;
65
+
66
+ export function contextCostOf(item: MarketItem, opts: ContextCostOptions = {}): ContextCost | undefined {
67
+ const install = item.install;
68
+
69
+ if (install.kind === "mcp") {
70
+ // Deliberately no numbers. A server's tools are whatever it reports on connect.
71
+ return { perTurn: 0, tokenizer: "o200k_base",
72
+ unknown: "an MCP server's tools are only known once it connects, so its context cost cannot be measured before you install it" };
73
+ }
74
+
75
+ if (install.kind === "skill") {
76
+ const body = item.docs?.body;
77
+ const cost: ContextCost = { perTurn: countTokens(indexLine(item)), tokenizer: "o200k_base" };
78
+ if (opts.model !== undefined) cost.scale = tokenScaleFor(opts.model);
79
+ if (body !== undefined) cost.whenUsed = countTokens(body);
80
+ else cost.unknown = "the SKILL.md is not carried in the catalog, so only the index line can be measured here";
81
+ const installed = opts.installedSkills;
82
+ if (installed !== undefined && installed + 1 > INDEX_PROMPT_LIMIT) cost.overIndexLimit = true;
83
+ return cost;
84
+ }
85
+
86
+ // A plugin, and the answer is nothing measurable — for two separate reasons, both worth stating plainly
87
+ // rather than papering over with a number:
88
+ // its entry module registers tools whose schemas need the code LOADED to read, which a plan must not do;
89
+ // its commands and skills are files inside the repository, and the catalog carries the plugin's README,
90
+ // not those files — measuring them would mean cloning during a preview.
91
+ return { perTurn: 0, tokenizer: "o200k_base",
92
+ unknown: "a plugin's context cost cannot be measured from the catalog: its tools need the code loaded to read, and its commands and skills are files that are only fetched when you install it" };
93
+ }
94
+
95
+ const n = (t: number): string => (t >= 1000 ? `${(t / 1000).toFixed(1)}k` : String(t));
96
+
97
+ /** The plan's line(s). Returns [] when there is nothing worth saying. */
98
+ export function contextCostLines(c: ContextCost | undefined): string[] {
99
+ if (c === undefined) return [];
100
+ const lines: string[] = [];
101
+
102
+ if (c.perTurn > 0 || c.whenUsed !== undefined) {
103
+ // When a measurement exists for the model in play, the numbers are SCALED BY IT rather than described
104
+ // with a hand-written caveat. "Reads roughly a third low on Anthropic models" was wrong the moment
105
+ // token-scale.ts had two Anthropic generations in it: 1.59x on Claude 5 and 1.21x on 4.5. A sentence
106
+ // that has to be rewritten every time a model ships is a sentence that will be wrong between ships.
107
+ const k = c.scale?.measured === true ? c.scale.scale : 1;
108
+ const turn = `~${n(Math.round(c.perTurn * k))} tokens every turn`;
109
+ const used = c.whenUsed !== undefined ? `, ~${n(Math.round(c.whenUsed * k))} more when the model opens it` : "";
110
+ lines.push(`${turn}${used}`);
111
+ if (c.scale === undefined) lines.push(`counted with o200k_base, which is not every model's tokenizer — unscaled here because no model was named`);
112
+ else if (!c.scale.measured) lines.push(`counted with o200k_base — ${c.scale.note}`);
113
+ else if (k === 1) lines.push(`counted with o200k_base — ${c.scale.note}`);
114
+ else lines.push(`o200k_base scaled ${k}× for this model — ${c.scale.note}`);
115
+ }
116
+ if (c.overIndexLimit) {
117
+ lines.push(`past ${INDEX_PROMPT_LIMIT} skills the index leaves the prompt entirely and the model lists skills with a tool instead — this changes the cost of every skill you have, not just this one`);
118
+ }
119
+ if (c.unknown !== undefined) lines.push(c.unknown);
120
+ return lines;
121
+ }
@@ -0,0 +1,106 @@
1
+ /** What landed on disk, as one number — so "has this changed since I installed it?" has an answer.
2
+ *
3
+ * `--ref` pins what we ASK for; a digest is what we GOT. The two answer different questions and the second
4
+ * is the one that survives: a commit id says the remote pointed there at fetch time, a digest says the
5
+ * bytes on this machine are still the bytes that arrived. Nobody in this space signs anything, so a
6
+ * recorded digest is the honest ceiling — it detects drift, it does not prove provenance, and the wording
7
+ * everywhere says the former.
8
+ *
9
+ * Over a FOLDER, the hash covers the relative path and the content of every file, in a sorted order, so it
10
+ * is stable across platforms and independent of the order a directory happens to list. `.git` is excluded:
11
+ * it is fetch bookkeeping, it differs between a clone and a copy of the same tree, and including it would
12
+ * make every digest disagree with itself for no reason a person could act on.
13
+ *
14
+ * Line endings are NOT normalised. A file that arrives with CRLF and later has LF is genuinely different
15
+ * content, and on a repository that has been through a Windows checkout that difference is exactly the
16
+ * kind of thing someone would want reported rather than hidden. */
17
+
18
+ import { createHash } from "node:crypto";
19
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
20
+ import { join, relative, sep } from "node:path";
21
+
22
+ export interface Digest {
23
+ algo: "sha256";
24
+ /** hex */
25
+ value: string;
26
+ /** how many files went into it — a cheap sanity check when two digests differ */
27
+ files: number;
28
+ }
29
+
30
+ /** Every file under `dir`, relative and slash-separated, sorted. Excludes `.git`. */
31
+ function walk(dir: string): string[] {
32
+ const out: string[] = [];
33
+ const stack = [dir];
34
+ while (stack.length > 0) {
35
+ const here = stack.pop()!;
36
+ let names: string[];
37
+ try { names = readdirSync(here); } catch { continue; }
38
+ for (const name of names) {
39
+ if (name === ".git") continue;
40
+ const full = join(here, name);
41
+ let st;
42
+ try { st = statSync(full); } catch { continue; }
43
+ // a symlink is never followed: install refuses them, and following one here would hash something
44
+ // outside the folder we claim to be describing
45
+ if (st.isDirectory()) { stack.push(full); continue; }
46
+ if (st.isFile()) out.push(relative(dir, full).split(sep).join("/"));
47
+ }
48
+ }
49
+ return out.sort();
50
+ }
51
+
52
+ /** The digest of a file or a folder. Undefined when the path is not there — a missing thing has no
53
+ * digest, and pretending it has one of an empty folder would make "deleted" and "emptied" look alike. */
54
+ export function digestOf(path: string): Digest | undefined {
55
+ if (!existsSync(path)) return undefined;
56
+ const hash = createHash("sha256");
57
+ let files = 0;
58
+ try {
59
+ if (statSync(path).isFile()) {
60
+ hash.update(readFileSync(path));
61
+ files = 1;
62
+ } else {
63
+ for (const rel of walk(path)) {
64
+ // the PATH goes in too: moving a file's content to another name is a change
65
+ hash.update(rel);
66
+ hash.update("\0");
67
+ hash.update(readFileSync(join(path, rel)));
68
+ hash.update("\0");
69
+ files += 1;
70
+ }
71
+ }
72
+ } catch { return undefined; }
73
+ return { algo: "sha256", value: hash.digest("hex"), files };
74
+ }
75
+
76
+ export type VerifyState =
77
+ /** the bytes are what they were */
78
+ | { state: "unchanged"; digest: Digest }
79
+ /** it is still installed, and it is not what it was */
80
+ | { state: "changed"; recorded: Digest; now: Digest }
81
+ /** it was installed and is no longer there */
82
+ | { state: "missing"; recorded: Digest }
83
+ /** there is nothing recorded to compare against; not a failure */
84
+ | { state: "unrecorded"; now?: Digest }
85
+ /** the kind carries no digest by design (an MCP entry is a line in a shared file) */
86
+ | { state: "not-applicable"; why: string };
87
+
88
+ /** Compare what is on disk with what was recorded. Pure over its inputs apart from reading the path. */
89
+ export function verifyDigest(recorded: Digest | undefined, path: string | undefined): VerifyState {
90
+ if (path === undefined) return { state: "not-applicable", why: "this kind of install has no folder of its own to hash" };
91
+ const now = digestOf(path);
92
+ if (recorded === undefined) return now === undefined ? { state: "unrecorded" } : { state: "unrecorded", now };
93
+ if (now === undefined) return { state: "missing", recorded };
94
+ return now.value === recorded.value ? { state: "unchanged", digest: now } : { state: "changed", recorded, now };
95
+ }
96
+
97
+ /** One line for `market verify`, in the words the state deserves. */
98
+ export function verifyLine(id: string, v: VerifyState): string {
99
+ switch (v.state) {
100
+ case "unchanged": return `${id} unchanged (${v.digest.files} file${v.digest.files === 1 ? "" : "s"})`;
101
+ case "changed": return `${id} CHANGED since install — recorded ${v.recorded.value.slice(0, 12)} (${v.recorded.files} files), now ${v.now.value.slice(0, 12)} (${v.now.files} files)`;
102
+ case "missing": return `${id} gone from disk, but a record remains`;
103
+ case "unrecorded": return `${id} no digest recorded — installed before rovecode kept one, or by hand`;
104
+ case "not-applicable": return `${id} ${v.why}`;
105
+ }
106
+ }
@@ -0,0 +1,22 @@
1
+ /** The market's public face. Every surface — the CLI, the sextant's /market, the site's build step —
2
+ * imports from here and from nowhere deeper, so the internals can move without touching them.
3
+ *
4
+ * Importing this module pulls in `registry.ts` and `install.ts`, which reach the MCP and plugin modules;
5
+ * it is NOT free, so keep it off the boot path (cli/main.ts loads `market-cmd.ts` with a dynamic import
6
+ * inside `case "market"`, and the TUI should reach it the same way, on first use). `types.ts` alone is
7
+ * free — import that directly when all you need is a shape. */
8
+
9
+ export type {
10
+ MarketKind, MarketSource, MarketScope, MarketEnv, InstallSpec, MarketItem,
11
+ InstalledState, MarketRow, SourceStatus, MarketResult, InstallPlanView, InstallOutcome, ItemDocs,
12
+ } from "./types.ts";
13
+ export { LIMITS, parseQualifiedId, qualify, itemLine } from "./types.ts";
14
+
15
+ export type { RegistryDeps } from "./registry.ts";
16
+ export { searchMarket, findItem, allItems, itemFromCatalog, itemFromMcp, CATALOG_FILES, CATALOG_DIR, MCP_DOCS_FILE } from "./registry.ts";
17
+
18
+ export type { Resolution } from "./resolve.ts";
19
+ export { resolveTarget, resolveDirect } from "./resolve.ts";
20
+
21
+ export type { PlanOptions, RunDeps } from "./install.ts";
22
+ export { planInstall, runInstall, installedState, withInstalled, removeItem, skillDir } from "./install.ts";