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.
- package/README.md +57 -72
- package/THIRD_PARTY_NOTICES.md +0 -44
- package/bin/rovecode.ts +21 -0
- package/package.json +16 -38
- package/src/account/keys.ts +97 -0
- package/src/account/login.ts +158 -0
- package/src/account/provision.ts +47 -0
- package/src/account/store.ts +63 -0
- package/src/acp/server.ts +373 -0
- package/src/cli/account-cmd.ts +116 -0
- package/src/cli/connect.ts +244 -0
- package/src/cli/context-cmd.ts +199 -0
- package/src/cli/dispatch.ts +109 -0
- package/src/cli/doctor.ts +324 -0
- package/src/cli/export.ts +278 -0
- package/src/cli/help.ts +240 -0
- package/src/cli/is-tui-invocation.ts +8 -0
- package/src/cli/main.ts +599 -0
- package/src/cli/market-cmd.ts +658 -0
- package/src/cli/mcp-market-cmd.ts +299 -0
- package/src/cli/output.ts +382 -0
- package/src/cli/repl.ts +172 -0
- package/src/cli/resume.ts +32 -0
- package/src/cli/run-limits.ts +78 -0
- package/src/cli/runtime.ts +792 -0
- package/src/cli/setup.ts +187 -0
- package/src/cli/update-cmd.ts +78 -0
- package/src/cli/workflow-cmd.ts +100 -0
- package/src/coding/checkpoints.ts +270 -0
- package/src/coding/diff.ts +136 -0
- package/src/coding/files.ts +339 -0
- package/src/coding/hashline.ts +319 -0
- package/src/coding/lsp.ts +406 -0
- package/src/coding/repomap-cache.ts +99 -0
- package/src/coding/repomap-files.ts +110 -0
- package/src/coding/repomap.ts +392 -0
- package/src/core/compaction.ts +399 -0
- package/src/core/config.ts +289 -0
- package/src/core/context-report.ts +228 -0
- package/src/core/context.ts +60 -0
- package/src/core/count-remote.ts +107 -0
- package/src/core/execpolicy-rules.ts +196 -0
- package/src/core/execpolicy.ts +385 -0
- package/src/core/executor.ts +397 -0
- package/src/core/guardrails.ts +400 -0
- package/src/core/hooks.ts +398 -0
- package/src/core/images.ts +230 -0
- package/src/core/intro.ts +236 -0
- package/src/core/loop.ts +621 -0
- package/src/core/modes.ts +372 -0
- package/src/core/orchestrator.ts +207 -0
- package/src/core/reflection.ts +165 -0
- package/src/core/sandbox-config.ts +167 -0
- package/src/core/session-images.ts +73 -0
- package/src/core/session.ts +398 -0
- package/src/core/settings.ts +98 -0
- package/src/core/stuck-detector.ts +273 -0
- package/src/core/tasks.ts +374 -0
- package/src/core/token-scale.ts +108 -0
- package/src/core/tool-output-budget.ts +166 -0
- package/src/core/tools.ts +288 -0
- package/src/core/types.ts +330 -0
- package/src/core/update-check.ts +171 -0
- package/src/core/update.ts +158 -0
- package/src/core/usage.ts +204 -0
- package/src/core/validate.ts +121 -0
- package/src/core/verify-gate.ts +159 -0
- package/src/core/verify.ts +237 -0
- package/src/core/voice.ts +158 -0
- package/src/core/win-job.ts +183 -0
- package/src/design/audit.ts +797 -0
- package/src/design/direction.ts +190 -0
- package/src/design/rules.ts +157 -0
- package/src/eval/bench.ts +150 -0
- package/src/eval/gauntlet-runner.ts +218 -0
- package/src/eval/gauntlet.ts +226 -0
- package/src/eval/grader.ts +186 -0
- package/src/eval/record.ts +202 -0
- package/src/eval/redact.ts +141 -0
- package/src/eval/replay.ts +147 -0
- package/src/eval/trajectory.ts +373 -0
- package/src/index.ts +17 -0
- package/src/market/catalogs/mcp-docs.json +111 -0
- package/src/market/catalogs/plugins.json +111 -0
- package/src/market/catalogs/skills.json +478 -0
- package/src/market/clone.ts +72 -0
- package/src/market/context-cost.ts +121 -0
- package/src/market/digest.ts +106 -0
- package/src/market/index.ts +22 -0
- package/src/market/install.ts +578 -0
- package/src/market/manifest.ts +187 -0
- package/src/market/prereq.ts +145 -0
- package/src/market/registry.ts +363 -0
- package/src/market/resolve.ts +111 -0
- package/src/market/types.ts +236 -0
- package/src/market/validate.ts +227 -0
- package/src/mcp/client.ts +431 -0
- package/src/mcp/config.ts +239 -0
- package/src/mcp/local-package.ts +211 -0
- package/src/mcp/market-catalog.ts +84 -0
- package/src/mcp/market-install.ts +289 -0
- package/src/mcp/market.ts +0 -0
- package/src/mcp/tools.ts +131 -0
- package/src/mcp/trust.ts +49 -0
- package/src/memory/blocks.ts +175 -0
- package/src/memory/recall.ts +355 -0
- package/src/memory/store.ts +105 -0
- package/src/memory/tools.ts +99 -0
- package/src/plugins/cli.ts +123 -0
- package/src/plugins/discover.ts +108 -0
- package/src/plugins/index.ts +50 -0
- package/src/plugins/init.ts +140 -0
- package/src/plugins/install.ts +184 -0
- package/src/plugins/load.ts +149 -0
- package/src/plugins/manifest.ts +106 -0
- package/src/plugins/state.ts +83 -0
- package/src/providers/auth.ts +293 -0
- package/src/providers/cache.ts +223 -0
- package/src/providers/catalog-local.ts +160 -0
- package/src/providers/catalog.ts +408 -0
- package/src/providers/middleware-context.ts +86 -0
- package/src/providers/middleware.ts +373 -0
- package/src/providers/profile-glm53.ts +111 -0
- package/src/providers/profile-sonnet5-persona.ts +65 -0
- package/src/providers/profile-sonnet5-voice.ts +23 -0
- package/src/providers/profiles.ts +156 -0
- package/src/providers/provider-config.ts +311 -0
- package/src/providers/registry.ts +302 -0
- package/src/providers/response-validation.ts +80 -0
- package/src/providers/retry.ts +234 -0
- package/src/providers/router.ts +294 -0
- package/src/providers/sse.ts +26 -0
- package/src/providers/stream-errors.ts +117 -0
- package/src/providers/stream.ts +569 -0
- package/src/providers/thinking.ts +189 -0
- package/src/providers/wire-messages.ts +129 -0
- package/src/sdk/client.ts +225 -0
- package/src/sdk/index.ts +3 -0
- package/src/server/dashboard.ts +144 -0
- package/src/server/http.ts +343 -0
- package/src/server/openapi.ts +246 -0
- package/src/sextant/card-hits.ts +102 -0
- package/src/sextant/card-keys.ts +55 -0
- package/src/sextant/context-source.ts +157 -0
- package/src/sextant/draw-agents.ts +273 -0
- package/src/sextant/draw-code.ts +388 -0
- package/src/sextant/draw-context.ts +222 -0
- package/src/sextant/draw-frame.ts +164 -0
- package/src/sextant/draw-market.ts +573 -0
- package/src/sextant/draw-messages.ts +386 -0
- package/src/sextant/draw-pet.ts +230 -0
- package/src/sextant/draw-plan.ts +159 -0
- package/src/sextant/draw-tabs.ts +85 -0
- package/src/sextant/draw-util.ts +65 -0
- package/src/sextant/engine.ts +230 -0
- package/src/sextant/frame-hits.ts +25 -0
- package/src/sextant/frame.ts +101 -0
- package/src/sextant/git-status.ts +197 -0
- package/src/sextant/grid.ts +59 -0
- package/src/sextant/input.ts +119 -0
- package/src/sextant/keys.ts +488 -0
- package/src/sextant/layout.ts +86 -0
- package/src/sextant/local-commands.ts +156 -0
- package/src/sextant/market-source.ts +287 -0
- package/src/sextant/mentions.ts +141 -0
- package/src/sextant/message-hits.ts +26 -0
- package/src/sextant/model.ts +387 -0
- package/src/sextant/overlays.ts +451 -0
- package/src/sextant/panel-hits.ts +38 -0
- package/src/sextant/pet.ts +399 -0
- package/src/sextant/screen.ts +324 -0
- package/src/sextant/scroll-hits.ts +66 -0
- package/src/sextant/scrollbar.ts +82 -0
- package/src/sextant/selection.ts +123 -0
- package/src/sextant/sextant-bridge.ts +174 -0
- package/src/sextant/sextant-cards.ts +142 -0
- package/src/sextant/sextant-diff-base.ts +63 -0
- package/src/sextant/sextant-files.ts +154 -0
- package/src/sextant/sextant-frame-loop.ts +314 -0
- package/src/sextant/sextant-renderer.ts +478 -0
- package/src/sextant/sextant-repo.ts +131 -0
- package/src/sextant/theme.ts +66 -0
- package/src/sextant/tool-rows.ts +189 -0
- package/src/sextant/types.ts +473 -0
- package/src/skills/index.ts +306 -0
- package/src/skills/tools.ts +69 -0
- package/src/skills/versioned.ts +227 -0
- package/src/telemetry/otel.ts +353 -0
- package/src/telemetry/otlp.ts +68 -0
- package/src/tools/ask-user.ts +156 -0
- package/src/tools/design.ts +151 -0
- package/src/tools/evalcell.ts +338 -0
- package/src/tools/html-text.ts +139 -0
- package/src/tools/provider.ts +149 -0
- package/src/tools/task.ts +216 -0
- package/src/tools/todo.ts +320 -0
- package/src/tools/webfetch.ts +331 -0
- package/src/tui/app.ts +608 -0
- package/src/tui/attach.ts +127 -0
- package/src/tui/checkpoints-cmd.ts +70 -0
- package/src/tui/clipboard-image.ts +81 -0
- package/src/tui/commands.ts +277 -0
- package/src/tui/cost.ts +108 -0
- package/src/tui/info-cmd.ts +144 -0
- package/src/tui/mcp-cmd.ts +128 -0
- package/src/tui/modes-cmd.ts +45 -0
- package/src/tui/overlays.ts +97 -0
- package/src/tui/pi-renderer.ts +424 -0
- package/src/tui/providers-cmd.ts +366 -0
- package/src/tui/renderer.ts +101 -0
- package/src/tui/replay-marker.ts +29 -0
- package/src/tui/session-cmd.ts +146 -0
- package/src/tui/sextant-attach.ts +68 -0
- package/src/tui/sextant-io.ts +184 -0
- package/src/tui/sextant-smoke.ts +110 -0
- package/src/tui/smoke.ts +72 -0
- package/src/tui/theme.ts +59 -0
- package/src/tui/todo-label.ts +7 -0
- package/src/workflow/engine.ts +266 -0
- package/tsconfig.json +30 -0
- package/vendor/pi-tui/LICENSE +21 -0
- package/vendor/pi-tui/PATCHES.md +12 -0
- package/vendor/pi-tui/PROVENANCE.md +12 -0
- package/vendor/pi-tui/README.upstream.md +854 -0
- package/vendor/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/vendor/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/vendor/pi-tui/src/alt-screen-search.ts +158 -0
- package/vendor/pi-tui/src/autocomplete.ts +827 -0
- package/vendor/pi-tui/src/components/alt-screen-flash.ts +52 -0
- package/vendor/pi-tui/src/components/box.ts +138 -0
- package/vendor/pi-tui/src/components/cancellable-loader.ts +41 -0
- package/vendor/pi-tui/src/components/editor.ts +2364 -0
- package/vendor/pi-tui/src/components/h-stack.ts +45 -0
- package/vendor/pi-tui/src/components/image.ts +128 -0
- package/vendor/pi-tui/src/components/input.ts +448 -0
- package/vendor/pi-tui/src/components/loader.ts +93 -0
- package/vendor/pi-tui/src/components/markdown.ts +1016 -0
- package/vendor/pi-tui/src/components/scroll-view.ts +217 -0
- package/vendor/pi-tui/src/components/select-list.ts +230 -0
- package/vendor/pi-tui/src/components/settings-list.ts +277 -0
- package/vendor/pi-tui/src/components/spacer.ts +29 -0
- package/vendor/pi-tui/src/components/stack.ts +155 -0
- package/vendor/pi-tui/src/components/text.ts +108 -0
- package/vendor/pi-tui/src/components/truncated-text.ts +66 -0
- package/vendor/pi-tui/src/components/v-stack.ts +34 -0
- package/vendor/pi-tui/src/editor-component.ts +75 -0
- package/vendor/pi-tui/src/fuzzy.ts +138 -0
- package/vendor/pi-tui/src/index.ts +149 -0
- package/vendor/pi-tui/src/keybindings.ts +321 -0
- package/vendor/pi-tui/src/keys.ts +1402 -0
- package/vendor/pi-tui/src/kill-ring.ts +47 -0
- package/vendor/pi-tui/src/latex.ts +1381 -0
- package/vendor/pi-tui/src/layout-node.ts +52 -0
- package/vendor/pi-tui/src/layout.ts +411 -0
- package/vendor/pi-tui/src/native-modifiers.ts +60 -0
- package/vendor/pi-tui/src/native-module-path.ts +32 -0
- package/vendor/pi-tui/src/stdin-buffer.ts +445 -0
- package/vendor/pi-tui/src/terminal-colors.ts +74 -0
- package/vendor/pi-tui/src/terminal-image.ts +701 -0
- package/vendor/pi-tui/src/terminal.ts +554 -0
- package/vendor/pi-tui/src/tui-alt-screen.ts +1379 -0
- package/vendor/pi-tui/src/tui-main-screen.ts +655 -0
- package/vendor/pi-tui/src/tui.ts +1264 -0
- package/vendor/pi-tui/src/undo-stack.ts +29 -0
- package/vendor/pi-tui/src/utils.ts +1327 -0
- package/vendor/pi-tui/src/word-navigation.ts +118 -0
- package/vendor/pi-tui/test/test-themes.ts +39 -0
- package/vendor/pi-tui/test/virtual-terminal.ts +219 -0
- package/CHANGELOG.md +0 -527
- package/bin/rovecode.js +0 -24
- package/dist/cli/app-j6gn14w3.js +0 -2
- package/dist/cli/ask-user-cwstt8fz.js +0 -2
- package/dist/cli/auth-login-9bbp9915.js +0 -2
- package/dist/cli/auth-m8p9grty.js +0 -2
- package/dist/cli/bench-16zqdms5.js +0 -9
- package/dist/cli/catalog-1xchffa4.js +0 -2
- package/dist/cli/cli-1n1zb64f.js +0 -2
- package/dist/cli/client-2t9gjkck.js +0 -2
- package/dist/cli/commands-exafvm2b.js +0 -2
- package/dist/cli/connect-6zde0kn3.js +0 -2
- package/dist/cli/context-cmd-5t43wgqt.js +0 -2
- package/dist/cli/context-report-kt01pw8y.js +0 -2
- package/dist/cli/count-remote-ap7x3vh6.js +0 -2
- package/dist/cli/design-ne5zszyh.js +0 -2
- package/dist/cli/dispatch-2r5myxye.js +0 -2
- package/dist/cli/doctor-ws4fh4tn.js +0 -3
- package/dist/cli/executor-bdrjn634.js +0 -2
- package/dist/cli/export-1mxb9g5p.js +0 -2
- package/dist/cli/files-g104xghh.js +0 -2
- package/dist/cli/gauntlet-07xrjpj7.js +0 -2
- package/dist/cli/gauntlet-runner-xvy64436.js +0 -10
- package/dist/cli/gauntlet-wave3-jm91yt5w.js +0 -5
- package/dist/cli/gauntlet-wave4-r13py7p1.js +0 -14
- package/dist/cli/hashline-znvrat11.js +0 -2
- package/dist/cli/http-xafw6fsh.js +0 -143
- package/dist/cli/index-1sgjm25y.js +0 -2
- package/dist/cli/init-g2m0tn4m.js +0 -51
- package/dist/cli/install-avaqjjqq.js +0 -2
- package/dist/cli/loop-mmpfft01.js +0 -2
- package/dist/cli/main-0904f6ps.js +0 -5
- package/dist/cli/main-0ab9fc26.js +0 -9
- package/dist/cli/main-0jys2ccn.js +0 -3
- package/dist/cli/main-0mtcdbs7.js +0 -3
- package/dist/cli/main-0z1w2zsg.js +0 -3
- package/dist/cli/main-1dchs7xv.js +0 -18
- package/dist/cli/main-1ereejm1.js +0 -3
- package/dist/cli/main-1k1kw6b5.js +0 -3
- package/dist/cli/main-27y4sm2k.js +0 -38
- package/dist/cli/main-2wwjex5j.js +0 -58
- package/dist/cli/main-2yeveeve.js +0 -6
- package/dist/cli/main-2yfck9b5.js +0 -3
- package/dist/cli/main-2zmzgkwh.js +0 -3
- package/dist/cli/main-351pz3z7.js +0 -7
- package/dist/cli/main-3gjqfh7a.js +0 -6
- package/dist/cli/main-3nf3kgve.js +0 -3
- package/dist/cli/main-3pjrb2hd.js +0 -3
- package/dist/cli/main-3rxcvgna.js +0 -19
- package/dist/cli/main-4b3jgy66.js +0 -19
- package/dist/cli/main-4wndhjdc.js +0 -7
- package/dist/cli/main-4xcmvxnk.js +0 -3
- package/dist/cli/main-5tbz0wbz.js +0 -4
- package/dist/cli/main-5ywnwthm.js +0 -3
- package/dist/cli/main-6b62vkz0.js +0 -14
- package/dist/cli/main-6dnk69vp.js +0 -3
- package/dist/cli/main-6genrmhs.js +0 -136
- package/dist/cli/main-73g7eff4.js +0 -15
- package/dist/cli/main-7c5thhjd.js +0 -5
- package/dist/cli/main-7rn6bqje.js +0 -3
- package/dist/cli/main-80haw7qk.js +0 -4
- package/dist/cli/main-875s60s2.js +0 -4
- package/dist/cli/main-8kjxbpw4.js +0 -8
- package/dist/cli/main-90ds1z4e.js +0 -10
- package/dist/cli/main-9etavkew.js +0 -3
- package/dist/cli/main-a9njrkk1.js +0 -3
- package/dist/cli/main-aecrjq2d.js +0 -12
- package/dist/cli/main-ck9asesq.js +0 -9
- package/dist/cli/main-cta9racd.js +0 -4
- package/dist/cli/main-ddv7j2ag.js +0 -3
- package/dist/cli/main-dfreez27.js +0 -10
- package/dist/cli/main-f7rw7des.js +0 -3
- package/dist/cli/main-ggcn7rd7.js +0 -5
- package/dist/cli/main-gzkmycnv.js +0 -3
- package/dist/cli/main-hq51jg8v.js +0 -18
- package/dist/cli/main-jft389w9.js +0 -8
- package/dist/cli/main-k1eqkg83.js +0 -3
- package/dist/cli/main-k2y8a2aw.js +0 -9
- package/dist/cli/main-kcpbykxz.js +0 -4
- package/dist/cli/main-kd488vje.js +0 -22
- package/dist/cli/main-kh32yvgk.js +0 -5
- package/dist/cli/main-kqxnqjnv.js +0 -25
- package/dist/cli/main-kyn0xnsg.js +0 -3
- package/dist/cli/main-m1kk6fp5.js +0 -21
- package/dist/cli/main-mv40pcr2.js +0 -4
- package/dist/cli/main-n0t3973w.js +0 -3
- package/dist/cli/main-nqveez48.js +0 -4
- package/dist/cli/main-pknhvrmj.js +0 -3
- package/dist/cli/main-pn1w7a7j.js +0 -3
- package/dist/cli/main-prxxs70n.js +0 -4
- package/dist/cli/main-q3vsesf9.js +0 -3
- package/dist/cli/main-qsevpgsv.js +0 -3
- package/dist/cli/main-rdgdw24b.js +0 -25
- package/dist/cli/main-rfth4tbm.js +0 -16
- package/dist/cli/main-rg0wn0xf.js +0 -5
- package/dist/cli/main-sdmxhtv8.js +0 -4
- package/dist/cli/main-skbp13js.js +0 -18
- package/dist/cli/main-t4xnd213.js +0 -7
- package/dist/cli/main-vqak588n.js +0 -4
- package/dist/cli/main-w2n1303f.js +0 -9
- package/dist/cli/main-wbrdspr2.js +0 -5
- package/dist/cli/main-wsrg79c1.js +0 -7
- package/dist/cli/main-x4r0fne4.js +0 -5
- package/dist/cli/main-xea2f3tn.js +0 -6
- package/dist/cli/main-xg704a3c.js +0 -3
- package/dist/cli/main-xvnrabfp.js +0 -16
- package/dist/cli/main-xy53xf0r.js +0 -4
- package/dist/cli/main-y1fqy60y.js +0 -3
- package/dist/cli/main-yn8cd281.js +0 -34
- package/dist/cli/main-yr0ksc0h.js +0 -4
- package/dist/cli/main-z2ex2vyf.js +0 -4
- package/dist/cli/main-z3aayzvq.js +0 -3
- package/dist/cli/main-zaqh35jg.js +0 -3
- package/dist/cli/main-zc2e8e46.js +0 -4
- package/dist/cli/main-zzrfw6cf.js +0 -13
- package/dist/cli/main.js +0 -280
- package/dist/cli/market-cmd-e14kmx9n.js +0 -5
- package/dist/cli/mcp-login-wq7ktdek.js +0 -2
- package/dist/cli/mcp-market-cmd-9mg3jecy.js +0 -2
- package/dist/cli/notify-b7qc0cjb.js +0 -2
- package/dist/cli/oauth-z8whcgfx.js +0 -2
- package/dist/cli/output-b3ewj3ps.js +0 -16
- package/dist/cli/profiles-6mr5he5e.js +0 -2
- package/dist/cli/provider-config-g7j42q8x.js +0 -2
- package/dist/cli/provider-jr1y8vvm.js +0 -2
- package/dist/cli/registry-s8yk86g0.js +0 -2
- package/dist/cli/registry-t6p8d4mn.js +0 -2
- package/dist/cli/repl-bajwe1mh.js +0 -11
- package/dist/cli/resume-rwn9nz7y.js +0 -2
- package/dist/cli/run-flags-nah7ndpt.js +0 -2
- package/dist/cli/runtime-n7gafzhb.js +0 -2
- package/dist/cli/sandbox-config-emdy18x4.js +0 -2
- package/dist/cli/server-b0nvs2bn.js +0 -5
- package/dist/cli/session-arg-y75wd4kj.js +0 -2
- package/dist/cli/session-j62evmjq.js +0 -2
- package/dist/cli/sessions-cmd-tsnwz0ns.js +0 -7
- package/dist/cli/settings-df10wfez.js +0 -2
- package/dist/cli/setup-jzvv72fg.js +0 -2
- package/dist/cli/sextant-smoke-37m81ke6.js +0 -5
- package/dist/cli/skills-cmd-gjxnxnhx.js +0 -2
- package/dist/cli/smoke-p7748apt.js +0 -8
- package/dist/cli/start-chat-s4st3mm0.js +0 -12
- package/dist/cli/stream-gmeyewds.js +0 -2
- package/dist/cli/task-gh0kkp3n.js +0 -2
- package/dist/cli/tasks-z1kfpe8e.js +0 -2
- package/dist/cli/thinking-0eqkrz6t.js +0 -2
- package/dist/cli/todo-5brcrt9m.js +0 -2
- package/dist/cli/tools-7pzm0vj9.js +0 -2
- package/dist/cli/tools-s635p6s8.js +0 -2
- package/dist/cli/trust-cmd-cjav8zgm.js +0 -2
- package/dist/cli/update-check-pt31bm2f.js +0 -2
- package/dist/cli/update-cmd-tk131s9t.js +0 -2
- package/dist/cli/voice-56nabd8d.js +0 -2
- package/dist/cli/webfetch-xd8q596m.js +0 -2
- package/dist/cli/websearch-5hkf98k1.js +0 -2
- package/dist/cli/workflow-cmd-cy3cvzjp.js +0 -4
- package/dist/cli/workspace-q10g5z3e.js +0 -2
- package/dist/lib/index.js +0 -62
- package/dist/lib/models-index.json +0 -1
- package/dist/lib/plugins.js +0 -55
- package/dist/lib/providers.js +0 -17
- package/dist/lib/public-api.js +0 -20
- package/dist/lib/sdk.js +0 -360
- /package/{dist/cli → src/providers}/models-index.json +0 -0
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ OpenHands) — every port traces to file:line in a snapshotted source and lands
|
|
|
8
8
|
fresh-context critic verifies it against a pre-written bar (ledger: `PORTS.md`, kept outside this
|
|
9
9
|
repository for now).
|
|
10
10
|
|
|
11
|
-

|
|
12
12
|
|
|
13
13
|
## Status (2026-09-04, post wave 4)
|
|
14
14
|
|
|
@@ -38,22 +38,18 @@ repository for now).
|
|
|
38
38
|
- **run budgets** — `--max-turns` / `--max-seconds`, so a spiral ends in a result instead of an outside kill
|
|
39
39
|
- a decided **wire-failure policy** (`docs/wire-failures.md`): what is retried, what is never retried after
|
|
40
40
|
text has arrived, and the wait announced while it happens
|
|
41
|
-
- the **site** ([
|
|
41
|
+
- the **site** ([its own repo](https://github.com/9Code-Labs/rovecode-site), 15 languages, prerendered, [live](http://64.177.43.110/)) and the CI/CD workflows
|
|
42
42
|
that build and ship it
|
|
43
43
|
- **sextant** gained mouse and scrollbar dragging, the page tab strip, the notices history and prompt suggestions
|
|
44
44
|
- **startup** is lazy: `rovecode --help` no longer boots the TUI, the loop, the runtime or the plugin scanner
|
|
45
45
|
|
|
46
46
|
## Install
|
|
47
47
|
|
|
48
|
-
Requires [Bun](https://bun.sh) ≥ 1.3.14
|
|
48
|
+
Requires [Bun](https://bun.sh) ≥ 1.3.14 (the CLI entry is TypeScript, executed by bun — node cannot run it).
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
# from
|
|
52
|
-
|
|
53
|
-
rovecode --version
|
|
54
|
-
|
|
55
|
-
# from source (this repository is the bundle's AGPL source)
|
|
56
|
-
git clone https://github.com/9Code-Labs/rovecode-community.git && cd rovecode-community && bun install
|
|
51
|
+
# from source
|
|
52
|
+
git clone https://github.com/9Code-Labs/rovecode.git && cd rovecode && bun install
|
|
57
53
|
bun run src/cli/main.ts --help # or: bun link → `rovecode` on PATH
|
|
58
54
|
bun run build:cli # optional: pre-bundle (TUI cold start ~230 ms → ~80 ms); re-run after git pull
|
|
59
55
|
|
|
@@ -61,24 +57,18 @@ bun run build:cli # optional: pre-bundle (TUI cold start ~
|
|
|
61
57
|
bun run build # scripts/build.ts → dist/rovecode(.exe) + smoke
|
|
62
58
|
dist/rovecode.exe --version
|
|
63
59
|
|
|
64
|
-
# from
|
|
65
|
-
npm
|
|
60
|
+
# from an npm tarball (npm pack) — global install shims to bun via the shebang
|
|
61
|
+
npm install -g ./rovecode-0.3.1.tgz
|
|
66
62
|
```
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
restart. A compiled binary does not replace itself yet and says where the new artifact is. Rovecode does tell you when that is worth doing: the
|
|
77
|
-
TUI's startup card carries `update available: 0.3.2 → 0.4.0 · <release url>` when a newer release exists. The check
|
|
78
|
-
(`src/core/update-check.ts`) asks GitHub once every six hours (cached per release repo in `~/.rovecode/update-check-<repo>.json`), never
|
|
79
|
-
blocks the start and never throws. The repository is public, so the check works anonymously; `GITHUB_TOKEN`,
|
|
80
|
-
`GH_TOKEN` or a `gh auth login` only raise the rate limit. When the check could not look,
|
|
81
|
-
the card prints nothing rather than a guess. Only a real newer release produces a line
|
|
64
|
+
Not yet published to the npm registry (name availability unverified). Releases are cut on
|
|
65
|
+
[GitHub Releases](https://github.com/9Code-Labs/rovecode/releases) — v0.3.1 is the current one — and there is no
|
|
66
|
+
self-update: `git pull` and rebuild, or reinstall the binary. Rovecode does tell you when that is worth doing: the
|
|
67
|
+
TUI's startup card carries `update available: 0.3.0 → 0.4.0 · <release url>` when a newer release exists. The check
|
|
68
|
+
(`src/core/update-check.ts`) asks GitHub once every six hours (cached in `~/.rovecode/update-check.json`), never
|
|
69
|
+
blocks the start and never throws. The repository is private, so it needs `GITHUB_TOKEN`, `GH_TOKEN` or a
|
|
70
|
+
`gh auth login`; without one the result is "unknown — the release repository is private and no token is set",
|
|
71
|
+
never "up to date", and the card prints nothing rather than a guess. Only a real newer release produces a line
|
|
82
72
|
on the card — `rovecode --version` prints the version to stdout alone (so a script can still read it) and, on
|
|
83
73
|
stderr, whatever the last check found. It reads the cache and never opens a socket: a courtesy line must not
|
|
84
74
|
make the one command scripts call to identify a build wait on the network.
|
|
@@ -121,9 +111,9 @@ rovecode --accept-edits # middle tier: writes INSIDE this folder stop as
|
|
|
121
111
|
# session. network and writes outside it still ask (/accept-edits ·
|
|
122
112
|
# ROVECODE_ACCEPT_EDITS=1 · or the `all edits` button on a write approval
|
|
123
113
|
# card)
|
|
124
|
-
# The same file takes "bell": false —
|
|
125
|
-
#
|
|
126
|
-
#
|
|
114
|
+
# The same file takes "bell": false — the sextant rings the terminal bell
|
|
115
|
+
# (BEL) when a run ends or a card needs you, so a tabbed-away terminal
|
|
116
|
+
# can flash or chime; off with that key (user or project scope).
|
|
127
117
|
@src/auth.ts why does this fail # @file attaches the file to the message as a `read` would return it —
|
|
128
118
|
# contents + edit anchors, no tool round-trip. Capped and said: 400 lines
|
|
129
119
|
# per file (the footer names the offset to continue), 8 files, ~60k chars
|
|
@@ -143,6 +133,8 @@ rovecode gauntlet # adversarial eval suite (offline, deterministic
|
|
|
143
133
|
rovecode gauntlet --live # 9 of those tasks against the configured REAL model, through the real prompt
|
|
144
134
|
# (--model provider/model, --effort …): the before/after instrument for prompt
|
|
145
135
|
# work
|
|
136
|
+
bun scripts/eval-offline.ts # eval gate: trajectory JSONL + patch/test grading + offline replay + stuck
|
|
137
|
+
# detection + secrets redaction, no network (~150 ms; docs/eval.md)
|
|
146
138
|
rovecode bench # cross-harness micro-benchmarks
|
|
147
139
|
rovecode tools # registered tool listing
|
|
148
140
|
rovecode auth set <provider> # store an API key (prompted on the terminal, never echoed); auth list / auth
|
|
@@ -154,10 +146,7 @@ rovecode models # just list them (* = current); alias for `model l
|
|
|
154
146
|
rovecode model use <provider/model> # persist the default model directly (--project pins it to this repo)
|
|
155
147
|
rovecode model show # the model, its protocol, and the exact thinking field each --effort level
|
|
156
148
|
# sends
|
|
157
|
-
rovecode
|
|
158
|
-
rovecode sessions rename|delete|fork|search # name, remove (with its checkpoints), copy or search sessions —
|
|
159
|
-
# ids are exact or a unique prefix; ambiguous/unknown → exit 2, nothing touched
|
|
160
|
-
rovecode trace <id|prefix> # replay a session's JSONL tree
|
|
149
|
+
rovecode trace <session-id> # replay a session's JSONL tree
|
|
161
150
|
rovecode acp # Agent Client Protocol v1 over stdio (Zed/JetBrains)
|
|
162
151
|
rovecode serve # headless HTTP + SSE server (ROVECODE_PORT, loopback-only)
|
|
163
152
|
```
|
|
@@ -382,10 +371,6 @@ mcp/ acp/ server/ tui/ sextant/ surfaces over the same loop (no second loop
|
|
|
382
371
|
eval/ scripted-provider gauntlet + deterministic benches
|
|
383
372
|
```
|
|
384
373
|
|
|
385
|
-
## Supported extension API
|
|
386
|
-
|
|
387
|
-
Distributed integrations should import only `rovecode/extensions`, `rovecode/plugins`, or `rovecode/providers`; deep `src/` imports are internal. See [API stability](docs/api-stability.md), [extension interfaces](docs/extensions.md), the [authentication boundary](docs/authentication-boundary.md), and the [open-core architecture](docs/open-core-architecture.md). Public code is mechanically prevented from importing private overlays or hosted product-auth/control-plane contracts. Generic local provider and MCP authentication remain part of the usable open-source core.
|
|
388
|
-
|
|
389
374
|
## Configuration
|
|
390
375
|
|
|
391
376
|
Defaults < project config chunks (harvested, capped) < env < CLI flags.
|
|
@@ -395,15 +380,6 @@ Defaults < project config chunks (harvested, capped) < env < CLI flags.
|
|
|
395
380
|
- `.rovecode/mcp.json` (+ harvested `.mcp.json`, + `~/.rovecode/mcp.json` for you) — MCP servers; `rovecode mcp add`
|
|
396
381
|
writes them. PROJECT files are gated: until you approve them (`rovecode mcp show` to review,
|
|
397
382
|
`rovecode mcp trust` to approve) their servers stay off, and any edit asks again (`docs/mcp-market.md`)
|
|
398
|
-
- **Project trust** (`src/core/trust.ts`, 2026-09-07) — the same gate, one store (`~/.rovecode/plugins.json`, path →
|
|
399
|
-
sha256), now covers EVERY project file that could make rovecode run or import something: `.rovecode/hooks.ts`
|
|
400
|
-
(imported in-process at boot — the worst of them), `.rovecode/sandbox.json` (the rung and the docker image every
|
|
401
|
-
bash command runs in), `.rovecode/settings.json` when it carries a command-bearing key (`verify`, `lsp`,
|
|
402
|
-
`notify_command`), and the MCP files. A cloned repository's copies contribute NOTHING until `rovecode trust`:
|
|
403
|
-
`rovecode trust show` lists each file with what it WOULD do (the keys and their values, the rung and image, the
|
|
404
|
-
server commands), `rovecode trust [--yes]` approves them as they are now, `rovecode trust untrust` withdraws; an
|
|
405
|
-
edit asks again. Your own `~/.rovecode` files never ask. `verify: false` is a refusal, not a command, and is honoured
|
|
406
|
-
from any file. `.rovecode/commands/*.md` and `agents/*.md` are prompt text, not executables — out of this gate's scope
|
|
407
383
|
- `.rovecode/modes.json` — per-mode model config (TUI-scoped; see limitations)
|
|
408
384
|
- `.rovecode/sandbox.json` — `{"rung": "direct"|"wsl"|"docker", "dockerImage"?: "…"}` selects where `bash` runs (#27);
|
|
409
385
|
`ROVECODE_SANDBOX=<rung>` / `ROVECODE_SANDBOX_IMAGE=<image>` override it; default `direct`
|
|
@@ -417,15 +393,8 @@ Defaults < project config chunks (harvested, capped) < env < CLI flags.
|
|
|
417
393
|
give once; the project file wins key by key. Three keys: `"permission": "ask" | "accept-edits" | "auto"` (written
|
|
418
394
|
by `/yolo --save` and `/accept-edits --save [--project]`; ladder: CLI flag > `ROVECODE_PERMISSION` > project >
|
|
419
395
|
user > ask), `"effort": "auto" | "off" | "low" | "medium" | "high"` (the thinking dial, `/effort --save`), and
|
|
420
|
-
`"bell": false` — both TUIs
|
|
421
|
-
|
|
422
|
-
hears (a terminal that never reports focus reads as watched and stays silent). `"notify": "auto" | "bell" | "osc9" |
|
|
423
|
-
"osc777"` picks the signal (auto = an OSC 9 desktop toast on Ghostty, iTerm2, kitty, Warp and WezTerm, the BEL
|
|
424
|
-
everywhere else; Windows Terminal turns the bell into a flash, a chime or a taskbar badge per profile);
|
|
425
|
-
`"notify_when": "always"` brings back a signal on every run; `"notify_command": ["notify-send","rovecode"]` (a JSON
|
|
426
|
-
string array, or whitespace-split words) runs a desktop hook under the same gate with a JSON payload as its last
|
|
427
|
-
argument, never through a shell — from the project file it applies only once that file is trusted, from the user file
|
|
428
|
-
always. `ROVECODE_NOTIFY[=off]`, `ROVECODE_NOTIFY_WHEN` and `ROVECODE_NOTIFY_COMMAND` override the files. Fourth key: `"verify": "bun run check"`
|
|
396
|
+
`"bell": false` — both TUIs ring the terminal bell (BEL) when a run ends and when an approval or question card
|
|
397
|
+
opens, so a terminal you tabbed away from can flash or chime; this turns it off. Fourth key: `"verify": "bun run check"`
|
|
429
398
|
(or a list, run in order; or `false`) — the check the loop runs after the agent's last edit before its reply counts
|
|
430
399
|
as done. Without the key rovecode infers one only where both the name and the shape are recognised: a
|
|
431
400
|
`package.json` `check` script (unless its body names deploy/publish/push/docker/curl and the like), or a
|
|
@@ -511,14 +480,6 @@ Environment knobs (`rovecode help env` is the full reference; this list is the c
|
|
|
511
480
|
`ROVECODE_STREAM` — streaming is ON by default for both protocols; `off`/`json`/`0`/`false`/`none` fall back
|
|
512
481
|
to the one-shot JSON adapters (a proxy with no SSE route); `sse` selects the raw OpenAI-compatible SSE
|
|
513
482
|
adapter for `rovecode run` — still streaming, but without the text-tool-call middleware wrap;
|
|
514
|
-
`ROVECODE_OPENAI_WIRE=responses|chat` — which OpenAI wire a request takes (`src/providers/wire-select.ts`, per call).
|
|
515
|
-
Unset: a stored ChatGPT login (`rovecode auth login openai`) always takes `/responses` (its token is accepted by the
|
|
516
|
-
Codex backend only, with `originator: rovecode`); provider `openai` takes `/responses` for models the catalog does not
|
|
517
|
-
mark non-reasoning (gpt-5, o3, unknown ids) and `/chat/completions` for the gpt-4o class; every other provider stays
|
|
518
|
-
on `/chat/completions`, byte-identical to before. Selection is static — a `/responses` 404 is an error turn, never a
|
|
519
|
-
re-issue. Not done yet on `/responses`: reasoning items are not replayed to the model on the next turn (each turn
|
|
520
|
-
reasons afresh; reasoning text still streams live) — that needs a reasoning message part across the store, export
|
|
521
|
-
and the other wires;
|
|
522
483
|
`ROVECODE_HOME` — credentials + user-scope commands dir (default `~/.rovecode`)
|
|
523
484
|
- `ROVECODE_TUI=sextant|classic` — force the TUI surface (#44; sextant still needs a TTY of at least 40×12,
|
|
524
485
|
`--classic` wins); `ROVECODE_THEME=night|ember|contrast` — the sextant palette at boot (`/theme` switches it
|
|
@@ -654,14 +615,14 @@ tokens, cache hits, and catalog-priced spend.
|
|
|
654
615
|
`const rc = createClient({ cwd })`, `const s = await rc.session.create()`, and
|
|
655
616
|
`for await (const ev of s.prompt({ text })) …` streams every `RunEvent` plus `agent_tree_update`
|
|
656
617
|
frames for live subagent trees. One client = one engine: the SDK boots the same runtime the CLI
|
|
657
|
-
boots (no second loop), and `stream: mockStream(…)` makes it testable with no provider.
|
|
618
|
+
boots (no second loop), and `stream: mockStream(…)` makes it testable with no provider. A
|
|
619
|
+
`remote` transport against `rovecode serve` is planned on the same types. New in 0.4.0; the
|
|
620
|
+
surface is `0.x` — expect evolution, pinned by `test/unit/sdk-client.test.ts`.
|
|
658
621
|
- **Workflows** (`rovecode workflow run <file.ts>`, `src/workflow/engine.ts`): a file that
|
|
659
622
|
`export default defineWorkflow({ name, steps })` — a DAG of `agent` steps (run through the
|
|
660
623
|
TaskManager, so they appear in `serve`'s `/ui` agent tree) and `gate` steps (human approval),
|
|
661
624
|
with per-step retry, a token budget, and a JSONL checkpoint in `.rovecode/workflows/` that
|
|
662
625
|
`--resume <runId>` continues after a crash. `rovecode workflow list` shows known runs.
|
|
663
|
-
- **Mission control** (`rovecode serve` → `GET /ui` + `GET /events`): a zero-build dark dashboard
|
|
664
|
-
over a global SSE bus — sessions, every run's live event stream, and the per-session agent tree.
|
|
665
626
|
- **Plugins** (`src/plugins`, `docs/plugins.md`): a folder with a `plugin.json` that bundles the things below —
|
|
666
627
|
an in-process entry module (tools + hooks), `commands/*.md`, `skills/**/SKILL.md`, MCP servers — so one
|
|
667
628
|
`rovecode plugin add <folder|git-url>` installs all of it and `rovecode plugin list` shows all of it. User scope
|
|
@@ -696,10 +657,8 @@ tokens, cache hits, and catalog-priced spend.
|
|
|
696
657
|
tools arrive lazily through `mcp_list`/`mcp_call` under the same policy pipeline. A server a **repository** brings
|
|
697
658
|
with it is listed but never connected until you trust it: `mcp show` prints every configured file and what it would
|
|
698
659
|
run, `mcp trust` records the project files' content digest in your home (`--yes` to skip the prompt; an edit to
|
|
699
|
-
either file asks again) and `mcp untrust` revokes it. User-scope servers need no gate.
|
|
700
|
-
|
|
701
|
-
settings keys in one step (see Project trust above).
|
|
702
|
-
- **Market** (`src/market`, [`docs/mcp-market.md`](docs/mcp-market.md)): one shelf over all three — `rovecode market search|info|docs|
|
|
660
|
+
either file asks again) and `mcp untrust` revokes it. User-scope servers need no gate.
|
|
661
|
+
- **Market** (`src/market`, `docs/market.md`): one shelf over all three — `rovecode market search|info|docs|
|
|
703
662
|
install|remove|list|update|sources|verify|validate` (each with `--json`) and `/market` in the TUI find MCP
|
|
704
663
|
servers, skills and plugins
|
|
705
664
|
and install any of them with one command. A single argument resolves five shapes (bare id, `kind:id`, a git URL,
|
|
@@ -719,6 +678,34 @@ tokens, cache hits, and catalog-priced spend.
|
|
|
719
678
|
`.rovecode/design.json`) and `design_audit`, which counts template patterns in source and reports them as
|
|
720
679
|
*slop* only while nothing is recorded, or as *deviation* from what the project chose. `ROVECODE_DESIGN=off`
|
|
721
680
|
drops the section for runs with no UI in them.
|
|
681
|
+
- **Site** ([9Code-Labs/rovecode-site](https://github.com/9Code-Labs/rovecode-site), `docs/deploy.md`):
|
|
682
|
+
the landing page, the docs and the market — Vite + React, prerendered once per language, no runtime.
|
|
683
|
+
It moved out of this repository on 2026-09-06 and builds without reading anything outside itself.
|
|
684
|
+
What stays here is the content it renders: `bun run publish:site` regenerates `docs.json`,
|
|
685
|
+
`market.json` and `facts.json` from `docs/*.md`, `src/market/catalogs/`, `src/mcp/market-catalog.ts`
|
|
686
|
+
and `plugins/`, and pushes them there. Deploying is `bun run deploy` in that repo. Live at
|
|
687
|
+
[64.177.43.110](http://64.177.43.110/) until there is a domain.
|
|
688
|
+
|
|
689
|
+
## License & notices
|
|
690
|
+
|
|
691
|
+
Rovecode is free software under the GNU Affero General Public License v3.0 — see `LICENSE`.
|
|
692
|
+
Copyright (C) 2026 9Code Labs. You may use, study, modify and redistribute it; every copy and every
|
|
693
|
+
derivative must keep this license and its copyright notices, and if you run a modified rovecode as a
|
|
694
|
+
network service you must offer its complete source to the users of that service.
|
|
695
|
+
|
|
696
|
+
Third-party attributions (Apache-2.0 NOTICE entries + MIT credits): `THIRD_PARTY_NOTICES.md`
|
|
697
|
+
(shipped in the npm tarball). No code from crush (FSL), claw-code, nanocoder, iflow, or the Claude
|
|
698
|
+
Agent SDK.
|
|
699
|
+
|
|
700
|
+
## What wave 3 added (`PORTS.md` §Wave-3)
|
|
701
|
+
|
|
702
|
+
Landed, not planned. Ports #21–#39: mid-turn cancellation, first-class grep/glob/ls tools,
|
|
703
|
+
retry-with-backoff, approval diff previews, compaction v2, background subagents, sandbox rung config,
|
|
704
|
+
reflection retries, hooks v2, custom slash commands, web fetch, todo/ask_user tools, image input,
|
|
705
|
+
JSON/NDJSON output modes, session export, OTel spans.
|
|
706
|
+
|
|
707
|
+
### Not built
|
|
708
|
+
|
|
722
709
|
- **#47 external agentic-CLI lanes** — the one wave-4 row that was never implemented here. Measured
|
|
723
710
|
2026-09-06 rather than assumed: `claude -p` and `opencode run` already work through the `bash` tool
|
|
724
711
|
today, in print mode, without a TTY. What makes a lane a real feature rather than a shortcut is the
|
|
@@ -732,7 +719,5 @@ tokens, cache hits, and catalog-priced spend.
|
|
|
732
719
|
and name the account it spends from. (`opencode` also writes `.opencode/` and `docs/` into the working
|
|
733
720
|
directory even when it fails, and on Windows a nested shell layer ate the backslashes of an absolute
|
|
734
721
|
path and produced a file literally named `C:UsersberkaycikAppData…banana.txt`.)
|
|
735
|
-
- **Publishing**:
|
|
736
|
-
`prepack` hook; the repo itself stays the AGPL source. `npm install -g rovecode@beta` for the beta
|
|
737
|
-
channel, `rovecode` for the latest stable cut.
|
|
722
|
+
- **Publishing**: no npm package; the binary is built locally (see Known limitations)
|
|
738
723
|
- **Linux/macOS CI**: POSIX paths are exercised in tests, but only Windows is gated
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -48,22 +48,6 @@ Source: https://github.com/openai/codex, © 2025 OpenAI. Snapshot
|
|
|
48
48
|
`codex-rs/utils/cli/src/sandbox_mode_cli_arg.rs:14-25`), and an explicitly requested but
|
|
49
49
|
unprovidable tier as a hard error (`codex-rs/sandboxing/src/manager.rs:203-222`
|
|
50
50
|
SandboxTransformError). Here `.rovecode/sandbox.json` < `ROVECODE_SANDBOX`; rungs direct/wsl/docker only.
|
|
51
|
-
- **OpenAI Responses wire (aion port #75, 2026-09-07)** — `src/providers/responses.ts` follows AT PATTERN
|
|
52
|
-
LEVEL (no code copied) the event set a Responses client consumes and the `event:` + `data:` pairing
|
|
53
|
-
(`codex-rs/codex-api/src/sse/responses.rs:357-518`, fixtures :843-845), the ChatGPT Codex base URL
|
|
54
|
-
(`codex-rs/model-provider-info/src/lib.rs:40`) and an `originator` header on every request
|
|
55
|
-
(`codex-rs/core/src/client.rs:688`; the value here is `rovecode`). The request shape, the output-slot
|
|
56
|
-
state machine and the `chatgpt-account-id` / `OpenAI-Beta` headers follow earendil-works/pi (MIT,
|
|
57
|
-
credited in the module header). Not ported: codex's error taxonomy, websocket and zstd transports.
|
|
58
|
-
- **TUI notifications (aion port #79, 2026-09-07)** — `src/tui/notify-seq.ts` and `src/tui/notify.ts` follow AT
|
|
59
|
-
PATTERN LEVEL (no code copied) codex's terminal-notification design: the `auto` backend chooser and its
|
|
60
|
-
terminal list (`codex-rs/tui/src/notifications/mod.rs`), the tmux DCS passthrough with doubled ESC and its
|
|
61
|
-
test vectors (`codex-rs/tui/src/notifications/osc9.rs`), the env markers per terminal
|
|
62
|
-
(`codex-rs/terminal-detection/src/lib.rs`), the unfocused | always gate with focus starting true and the
|
|
63
|
-
warn-once-then-disable write path (`codex-rs/tui/src/tui.rs`), the event set (`codex-rs/tui/src/chatwidget/
|
|
64
|
-
notifications.rs`) and the `notify` argv hook with the payload as the last argument and nulled stdio
|
|
65
|
-
(`codex-rs/hooks/src/legacy_notify.rs`). Deviations: focus reporting stays on under Windows, and the hook obeys
|
|
66
|
-
the focus gate. OSC 777, the control-byte scrub, the argv parser and the trust gate are rovecode's own.
|
|
67
51
|
|
|
68
52
|
## cline (Apache-2.0)
|
|
69
53
|
|
|
@@ -194,34 +178,6 @@ every surface and fails closed at execute time instead. Snapshot
|
|
|
194
178
|
`research/source_snapshots/google-gemini-gemini-cli` @ 0bd1d43. The tool contract (option labels,
|
|
195
179
|
typed answer, dismissed question = error) follows opencode (MIT, credited in the module header).
|
|
196
180
|
|
|
197
|
-
### Port #81 — workspace roots (`--add-dir`)
|
|
198
|
-
`src/core/workspace.ts` follows AT PATTERN LEVEL (no code copied) opencode's external-directory
|
|
199
|
-
handling (`external-directory.ts` and `fs-util.ts` `contains()`: an added directory is a peer of the
|
|
200
|
-
cwd, and containment is decided on canonical paths, not on string prefixes) and gemini-cli's
|
|
201
|
-
`isPathWithinRoot`. Snapshots `research/source_snapshots/opencode-2026` @ ebece6e and
|
|
202
|
-
`research/source_snapshots/google-gemini-gemini-cli` @ 0bd1d43. What is not followed: neither project
|
|
203
|
-
puts the boundary in the permission ladder as its own action — rovecode evaluates `file.external` at
|
|
204
|
-
dispatch so the refusal is a card a person can answer, and so an "always" is remembered per directory.
|
|
205
|
-
|
|
206
|
-
### Port #57/#76 — MCP prompts, resources, status and OAuth
|
|
207
|
-
`src/mcp/prompts-resources.ts` follows AT PATTERN LEVEL (no code copied) gemini-cli's
|
|
208
|
-
`list-mcp-resources.ts` / `read-mcp-resource.ts`: server-scoped listing, text content returned
|
|
209
|
-
verbatim, binary content summarized rather than inlined. `src/mcp/status.ts` follows its `/mcp`
|
|
210
|
-
per-server status rows (state, tool and prompt counts, the remedy line). `src/mcp/oauth.ts` follows
|
|
211
|
-
`packages/core/src/mcp/oauth-provider.ts:399-405` — start the loopback callback server FIRST so the
|
|
212
|
-
redirect URI names a port that is already listening, rather than racing the browser. Snapshot
|
|
213
|
-
`research/source_snapshots/google-gemini-gemini-cli` @ 0bd1d43.
|
|
214
|
-
|
|
215
|
-
The provider-class shape over the SDK's own seam was additionally read from opencode's
|
|
216
|
-
`packages/opencode/src/mcp/oauth-provider.ts` (MIT); its FIXED callback port is deliberately not
|
|
217
|
-
followed — rovecode allocates an ephemeral one, so two logins cannot collide and a stuck listener
|
|
218
|
-
cannot block the next attempt.
|
|
219
|
-
|
|
220
|
-
MCP OAuth itself is done through `@modelcontextprotocol/sdk`'s `OAuthClientProvider` seam (MIT —
|
|
221
|
-
dependency, API usage, not a port): the SDK performs discovery, dynamic client registration, PKCE and
|
|
222
|
-
refresh; rovecode supplies persistence (`~/.rovecode/credentials.json`, 0600), the loopback redirect
|
|
223
|
-
and the `rovecode mcp login` command.
|
|
224
|
-
|
|
225
181
|
## Zed Industries — agent-client-protocol (Apache-2.0)
|
|
226
182
|
|
|
227
183
|
- **ACP endpoint (port #15)** — `src/acp/server.ts` speaks ACP v1 via the official SDK
|
package/bin/rovecode.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
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/package.json
CHANGED
|
@@ -1,33 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rovecode",
|
|
3
|
-
"version": "0.4.0
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"author": "9Code Labs",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "
|
|
8
|
+
"url": "https://github.com/9Code-Labs/rovecode.git"
|
|
9
9
|
},
|
|
10
|
-
"homepage": "https://github.com/9Code-Labs/rovecode
|
|
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).
|
|
10
|
+
"homepage": "https://github.com/9Code-Labs/rovecode",
|
|
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
12
|
"type": "module",
|
|
13
|
-
"module": "
|
|
13
|
+
"module": "src/index.ts",
|
|
14
14
|
"exports": {
|
|
15
|
-
".": "./
|
|
16
|
-
"./
|
|
17
|
-
"./
|
|
18
|
-
"
|
|
19
|
-
"./sdk": "./dist/lib/sdk.js",
|
|
20
|
-
"./package.json": "./package.json"
|
|
15
|
+
".": "./src/index.ts",
|
|
16
|
+
"./sdk": "./src/sdk/index.ts",
|
|
17
|
+
"./package.json": "./package.json",
|
|
18
|
+
"./*": "./*"
|
|
21
19
|
},
|
|
22
20
|
"bin": {
|
|
23
|
-
"rovecode": "bin/rovecode.
|
|
21
|
+
"rovecode": "bin/rovecode.ts"
|
|
24
22
|
},
|
|
25
23
|
"files": [
|
|
26
24
|
"bin",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"LICENSE",
|
|
25
|
+
"src",
|
|
26
|
+
"vendor",
|
|
27
|
+
"tsconfig.json",
|
|
31
28
|
"THIRD_PARTY_NOTICES.md"
|
|
32
29
|
],
|
|
33
30
|
"engines": {
|
|
@@ -35,12 +32,7 @@
|
|
|
35
32
|
},
|
|
36
33
|
"scripts": {
|
|
37
34
|
"build": "bun run scripts/build.ts",
|
|
38
|
-
"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
|
|
39
|
-
"build:npm": "bun run build:npm:cli && bun run build:npm:lib && bun run smoke:npm",
|
|
40
|
-
"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')\"",
|
|
41
|
-
"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 build --target=bun --minify --packages=external src/sdk/index.ts --outfile dist/lib/sdk.js && bun -e \"require('node:fs').copyFileSync('src/providers/models-index.json', 'dist/lib/models-index.json')\"",
|
|
42
|
-
"smoke:npm": "bun dist/cli/main.js --version && bun dist/cli/main.js smoke-tui --sextant",
|
|
43
|
-
"prepack": "bun run build:npm",
|
|
35
|
+
"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 run smoke:cli && bun run smoke:dist",
|
|
44
36
|
"smoke:cli": "bun dist/cli/main.js --version",
|
|
45
37
|
"smoke:dist": "bun dist/cli/main.js smoke-tui --sextant",
|
|
46
38
|
"test": "bun test",
|
|
@@ -48,14 +40,8 @@
|
|
|
48
40
|
"typecheck": "tsc --noEmit",
|
|
49
41
|
"check": "node scripts/build-model-index.mjs --check && tsc --noEmit && bun test",
|
|
50
42
|
"smoke": "bun src/cli/main.ts smoke-tui --sextant",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"check:product-boundary": "node scripts/check-product-boundary.mjs",
|
|
54
|
-
"check:links": "node scripts/check-doc-links.mjs",
|
|
55
|
-
"ci": "bun run check:boundary && bun run check:product-boundary && bun run check:links && bun run typecheck && bun test && bun run build:cli",
|
|
56
|
-
"release:check": "bun run ci && bun run build:npm && npm pack --dry-run",
|
|
57
|
-
"release:stage": "bun run scripts/stage-release.ts",
|
|
58
|
-
"quality:offline": "bun run scripts/harness-quality.ts"
|
|
43
|
+
"publish:site": "bash scripts/publish-site-data.sh",
|
|
44
|
+
"build:model-index": "node scripts/build-model-index.mjs"
|
|
59
45
|
},
|
|
60
46
|
"dependencies": {
|
|
61
47
|
"@ast-grep/napi": "^0.45.3",
|
|
@@ -72,13 +58,5 @@
|
|
|
72
58
|
"@types/bun": "latest",
|
|
73
59
|
"@xterm/headless": "6.0.0",
|
|
74
60
|
"typescript": "^5.9.3"
|
|
75
|
-
},
|
|
76
|
-
"bugs": {
|
|
77
|
-
"url": "https://github.com/9Code-Labs/rovecode-community/issues"
|
|
78
|
-
},
|
|
79
|
-
"publishConfig": {
|
|
80
|
-
"access": "public",
|
|
81
|
-
"provenance": true,
|
|
82
|
-
"tag": "beta"
|
|
83
61
|
}
|
|
84
62
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** The CLI's proof-of-possession key (Ed25519, node:crypto only — no dependencies).
|
|
2
|
+
*
|
|
3
|
+
* `rovecode login` generates one keypair per machine and sends only the PUBLIC JWK with the device/code
|
|
4
|
+
* request; the server binds the issued `rc_live_…` token to that key's thumbprint. Every authed call then
|
|
5
|
+
* carries a compact-JWS proof (DPoP-style) in the `dpop` header, so a stolen token alone answers 401.
|
|
6
|
+
*
|
|
7
|
+
* The private key lives in ~/.rovecode/account-key.json (mode 0600) and never crosses the wire. */
|
|
8
|
+
|
|
9
|
+
import { createHash, createPrivateKey, createPublicKey, generateKeyPairSync, randomBytes, sign as edSign, type KeyObject } from "node:crypto";
|
|
10
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { rovecodeHome } from "../providers/auth.ts";
|
|
13
|
+
|
|
14
|
+
export interface PopJwk {
|
|
15
|
+
kty: "OKP";
|
|
16
|
+
crv: "Ed25519";
|
|
17
|
+
x: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AccountKey {
|
|
21
|
+
privateKey: KeyObject;
|
|
22
|
+
publicJwk: PopJwk;
|
|
23
|
+
/** RFC 7638 thumbprint of publicJwk — what the server binds the token to */
|
|
24
|
+
jkt: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const b64url = (buf: Buffer): string => buf.toString("base64url");
|
|
28
|
+
|
|
29
|
+
export function keyPath(): string {
|
|
30
|
+
return join(rovecodeHome(), "account-key.json");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function thumbprint(publicJwk: PopJwk): string {
|
|
34
|
+
return b64url(createHash("sha256").update(`{"crv":"${publicJwk.crv}","kty":"${publicJwk.kty}","x":"${publicJwk.x}"}`).digest());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function createAccountKey(): AccountKey {
|
|
38
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
39
|
+
const jwk = publicKey.export({ format: "jwk" });
|
|
40
|
+
const publicJwk: PopJwk = { kty: "OKP", crv: "Ed25519", x: jwk.x! };
|
|
41
|
+
return { privateKey, publicJwk, jkt: thumbprint(publicJwk) };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** load the machine's key, generating and persisting it on first use (or after a corrupt file) */
|
|
45
|
+
export function loadOrCreateAccountKey(path: string = keyPath()): AccountKey {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(readFileSync(path, "utf8")) as { privateJwk?: unknown; publicJwk?: unknown };
|
|
48
|
+
const privateKey = createPrivateKey({ key: parsed.privateJwk as never, format: "jwk" });
|
|
49
|
+
const publicKey = createPublicKey({ key: parsed.publicJwk as never, format: "jwk" });
|
|
50
|
+
const jwk = publicKey.export({ format: "jwk" });
|
|
51
|
+
if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) throw new Error("not an Ed25519 key");
|
|
52
|
+
const publicJwk: PopJwk = { kty: "OKP", crv: "Ed25519", x: jwk.x };
|
|
53
|
+
return { privateKey, publicJwk, jkt: thumbprint(publicJwk) };
|
|
54
|
+
} catch {
|
|
55
|
+
const key = createAccountKey();
|
|
56
|
+
saveAccountKey(key, path);
|
|
57
|
+
return key;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function saveAccountKey(key: AccountKey, path: string): void {
|
|
62
|
+
mkdirSync(rovecodeHome(), { recursive: true, mode: 0o700 });
|
|
63
|
+
const privateJwk = key.privateKey.export({ format: "jwk" });
|
|
64
|
+
writeFileSync(path, JSON.stringify({ privateJwk, publicJwk: key.publicJwk }, null, 2) + "\n", { mode: 0o600 });
|
|
65
|
+
try {
|
|
66
|
+
chmodSync(path, 0o600);
|
|
67
|
+
} catch {
|
|
68
|
+
/* best-effort, same Windows caveat as account/store.ts */
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface ProofClaims {
|
|
73
|
+
htm: string;
|
|
74
|
+
htu: string;
|
|
75
|
+
/** seconds since epoch */
|
|
76
|
+
iat: number;
|
|
77
|
+
jti?: string;
|
|
78
|
+
/** the access token the request carries — its sha256 goes in as ath */
|
|
79
|
+
accessToken?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** sign a compact JWS (`dpop+jwt`) for one request. jti defaults to 128 random bits. */
|
|
83
|
+
export function signProof(key: AccountKey, claims: ProofClaims): string {
|
|
84
|
+
const header = b64url(Buffer.from(JSON.stringify({ typ: "dpop+jwt", alg: "EdDSA", jwk: key.publicJwk })));
|
|
85
|
+
const payload: Record<string, unknown> = {
|
|
86
|
+
jti: claims.jti ?? b64url(randomBytes(16)),
|
|
87
|
+
htm: claims.htm,
|
|
88
|
+
htu: claims.htu,
|
|
89
|
+
iat: claims.iat,
|
|
90
|
+
};
|
|
91
|
+
if (claims.accessToken !== undefined) {
|
|
92
|
+
payload.ath = b64url(createHash("sha256").update(claims.accessToken).digest());
|
|
93
|
+
}
|
|
94
|
+
const body = b64url(Buffer.from(JSON.stringify(payload)));
|
|
95
|
+
const sig = b64url(edSign(null, Buffer.from(`${header}.${body}`), key.privateKey));
|
|
96
|
+
return `${header}.${body}.${sig}`;
|
|
97
|
+
}
|