rovecode 0.3.3 → 0.4.0-beta.3
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/CHANGELOG.md +527 -0
- package/README.md +46 -48
- package/bin/rovecode.js +24 -0
- package/dist/cli/app-j6gn14w3.js +2 -0
- package/dist/cli/ask-user-cwstt8fz.js +2 -0
- package/dist/cli/auth-login-9bbp9915.js +2 -0
- package/dist/cli/auth-m8p9grty.js +2 -0
- package/dist/cli/bench-16zqdms5.js +9 -0
- package/dist/cli/catalog-1xchffa4.js +2 -0
- package/dist/cli/cli-1n1zb64f.js +2 -0
- package/dist/cli/client-2t9gjkck.js +2 -0
- package/dist/cli/commands-exafvm2b.js +2 -0
- package/dist/cli/connect-6zde0kn3.js +2 -0
- package/dist/cli/context-cmd-5t43wgqt.js +2 -0
- package/dist/cli/context-report-kt01pw8y.js +2 -0
- package/dist/cli/count-remote-ap7x3vh6.js +2 -0
- package/dist/cli/design-ne5zszyh.js +2 -0
- package/dist/cli/dispatch-2r5myxye.js +2 -0
- package/dist/cli/doctor-ws4fh4tn.js +3 -0
- package/dist/cli/executor-bdrjn634.js +2 -0
- package/dist/cli/export-1mxb9g5p.js +2 -0
- package/dist/cli/files-g104xghh.js +2 -0
- package/dist/cli/gauntlet-07xrjpj7.js +2 -0
- package/dist/cli/gauntlet-runner-xvy64436.js +10 -0
- package/dist/cli/gauntlet-wave3-jm91yt5w.js +5 -0
- package/dist/cli/gauntlet-wave4-r13py7p1.js +14 -0
- package/dist/cli/hashline-znvrat11.js +2 -0
- package/dist/cli/http-xafw6fsh.js +143 -0
- package/dist/cli/index-1sgjm25y.js +2 -0
- package/dist/cli/init-g2m0tn4m.js +51 -0
- package/dist/cli/install-avaqjjqq.js +2 -0
- package/dist/cli/loop-mmpfft01.js +2 -0
- package/dist/cli/main-0904f6ps.js +5 -0
- package/dist/cli/main-0ab9fc26.js +9 -0
- package/dist/cli/main-0jys2ccn.js +3 -0
- package/dist/cli/main-0mtcdbs7.js +3 -0
- package/dist/cli/main-0z1w2zsg.js +3 -0
- package/dist/cli/main-1dchs7xv.js +18 -0
- package/dist/cli/main-1ereejm1.js +3 -0
- package/dist/cli/main-1k1kw6b5.js +3 -0
- package/dist/cli/main-27y4sm2k.js +38 -0
- package/dist/cli/main-2wwjex5j.js +58 -0
- package/dist/cli/main-2yeveeve.js +6 -0
- package/dist/cli/main-2yfck9b5.js +3 -0
- package/dist/cli/main-2zmzgkwh.js +3 -0
- package/dist/cli/main-351pz3z7.js +7 -0
- package/dist/cli/main-3gjqfh7a.js +6 -0
- package/dist/cli/main-3nf3kgve.js +3 -0
- package/dist/cli/main-3pjrb2hd.js +3 -0
- package/dist/cli/main-3rxcvgna.js +19 -0
- package/dist/cli/main-4b3jgy66.js +19 -0
- package/dist/cli/main-4wndhjdc.js +7 -0
- package/dist/cli/main-4xcmvxnk.js +3 -0
- package/dist/cli/main-5tbz0wbz.js +4 -0
- package/dist/cli/main-5ywnwthm.js +3 -0
- package/dist/cli/main-6b62vkz0.js +14 -0
- package/dist/cli/main-6dnk69vp.js +3 -0
- package/dist/cli/main-6genrmhs.js +136 -0
- package/dist/cli/main-73g7eff4.js +15 -0
- package/dist/cli/main-7c5thhjd.js +5 -0
- package/dist/cli/main-7rn6bqje.js +3 -0
- package/dist/cli/main-80haw7qk.js +4 -0
- package/dist/cli/main-875s60s2.js +4 -0
- package/dist/cli/main-8kjxbpw4.js +8 -0
- package/dist/cli/main-90ds1z4e.js +10 -0
- package/dist/cli/main-9etavkew.js +3 -0
- package/dist/cli/main-a9njrkk1.js +3 -0
- package/dist/cli/main-aecrjq2d.js +12 -0
- package/dist/cli/main-ck9asesq.js +9 -0
- package/dist/cli/main-cta9racd.js +4 -0
- package/dist/cli/main-ddv7j2ag.js +3 -0
- package/dist/cli/main-dfreez27.js +10 -0
- package/dist/cli/main-f7rw7des.js +3 -0
- package/dist/cli/main-ggcn7rd7.js +5 -0
- package/dist/cli/main-gzkmycnv.js +3 -0
- package/dist/cli/main-hq51jg8v.js +18 -0
- package/dist/cli/main-jft389w9.js +8 -0
- package/dist/cli/main-k1eqkg83.js +3 -0
- package/dist/cli/main-k2y8a2aw.js +9 -0
- package/dist/cli/main-kcpbykxz.js +4 -0
- package/dist/cli/main-kd488vje.js +22 -0
- package/dist/cli/main-kh32yvgk.js +5 -0
- package/dist/cli/main-kqxnqjnv.js +25 -0
- package/dist/cli/main-kyn0xnsg.js +3 -0
- package/dist/cli/main-m1kk6fp5.js +21 -0
- package/dist/cli/main-mv40pcr2.js +4 -0
- package/dist/cli/main-n0t3973w.js +3 -0
- package/dist/cli/main-nqveez48.js +4 -0
- package/dist/cli/main-pknhvrmj.js +3 -0
- package/dist/cli/main-pn1w7a7j.js +3 -0
- package/dist/cli/main-prxxs70n.js +4 -0
- package/dist/cli/main-q3vsesf9.js +3 -0
- package/dist/cli/main-qsevpgsv.js +3 -0
- package/dist/cli/main-rdgdw24b.js +25 -0
- package/dist/cli/main-rfth4tbm.js +16 -0
- package/dist/cli/main-rg0wn0xf.js +5 -0
- package/dist/cli/main-sdmxhtv8.js +4 -0
- package/dist/cli/main-skbp13js.js +18 -0
- package/dist/cli/main-t4xnd213.js +7 -0
- package/dist/cli/main-vqak588n.js +4 -0
- package/dist/cli/main-w2n1303f.js +9 -0
- package/dist/cli/main-wbrdspr2.js +5 -0
- package/dist/cli/main-wsrg79c1.js +7 -0
- package/dist/cli/main-x4r0fne4.js +5 -0
- package/dist/cli/main-xea2f3tn.js +6 -0
- package/dist/cli/main-xg704a3c.js +3 -0
- package/dist/cli/main-xvnrabfp.js +16 -0
- package/dist/cli/main-xy53xf0r.js +4 -0
- package/dist/cli/main-y1fqy60y.js +3 -0
- package/dist/cli/main-yn8cd281.js +34 -0
- package/dist/cli/main-yr0ksc0h.js +4 -0
- package/dist/cli/main-z2ex2vyf.js +4 -0
- package/dist/cli/main-z3aayzvq.js +3 -0
- package/dist/cli/main-zaqh35jg.js +3 -0
- package/dist/cli/main-zc2e8e46.js +4 -0
- package/dist/cli/main-zzrfw6cf.js +13 -0
- package/dist/cli/main.js +280 -0
- package/dist/cli/market-cmd-e14kmx9n.js +5 -0
- package/dist/cli/mcp-login-wq7ktdek.js +2 -0
- package/dist/cli/mcp-market-cmd-9mg3jecy.js +2 -0
- package/dist/cli/notify-b7qc0cjb.js +2 -0
- package/dist/cli/oauth-z8whcgfx.js +2 -0
- package/dist/cli/output-b3ewj3ps.js +16 -0
- package/dist/cli/profiles-6mr5he5e.js +2 -0
- package/dist/cli/provider-config-g7j42q8x.js +2 -0
- package/dist/cli/provider-jr1y8vvm.js +2 -0
- package/dist/cli/registry-s8yk86g0.js +2 -0
- package/dist/cli/registry-t6p8d4mn.js +2 -0
- package/dist/cli/repl-bajwe1mh.js +11 -0
- package/dist/cli/resume-rwn9nz7y.js +2 -0
- package/dist/cli/run-flags-nah7ndpt.js +2 -0
- package/dist/cli/runtime-n7gafzhb.js +2 -0
- package/dist/cli/sandbox-config-emdy18x4.js +2 -0
- package/dist/cli/server-b0nvs2bn.js +5 -0
- package/dist/cli/session-arg-y75wd4kj.js +2 -0
- package/dist/cli/session-j62evmjq.js +2 -0
- package/dist/cli/sessions-cmd-tsnwz0ns.js +7 -0
- package/dist/cli/settings-df10wfez.js +2 -0
- package/dist/cli/setup-jzvv72fg.js +2 -0
- package/dist/cli/sextant-smoke-37m81ke6.js +5 -0
- package/dist/cli/skills-cmd-gjxnxnhx.js +2 -0
- package/dist/cli/smoke-p7748apt.js +8 -0
- package/dist/cli/start-chat-s4st3mm0.js +12 -0
- package/dist/cli/stream-gmeyewds.js +2 -0
- package/dist/cli/task-gh0kkp3n.js +2 -0
- package/dist/cli/tasks-z1kfpe8e.js +2 -0
- package/dist/cli/thinking-0eqkrz6t.js +2 -0
- package/dist/cli/todo-5brcrt9m.js +2 -0
- package/dist/cli/tools-7pzm0vj9.js +2 -0
- package/dist/cli/tools-s635p6s8.js +2 -0
- package/dist/cli/trust-cmd-cjav8zgm.js +2 -0
- package/dist/cli/update-check-pt31bm2f.js +2 -0
- package/dist/cli/update-cmd-tk131s9t.js +2 -0
- package/dist/cli/voice-56nabd8d.js +2 -0
- package/dist/cli/webfetch-xd8q596m.js +2 -0
- package/dist/cli/websearch-5hkf98k1.js +2 -0
- package/dist/cli/workflow-cmd-cy3cvzjp.js +4 -0
- package/dist/cli/workspace-q10g5z3e.js +2 -0
- package/dist/lib/index.js +62 -0
- package/dist/lib/models-index.json +1 -0
- package/dist/lib/plugins.js +55 -0
- package/dist/lib/providers.js +17 -0
- package/dist/lib/public-api.js +20 -0
- package/dist/lib/sdk.js +360 -0
- package/package.json +84 -72
- package/bin/rovecode.ts +0 -21
- package/src/acp/server.ts +0 -374
- package/src/cli/auth-login.ts +0 -122
- package/src/cli/connect.ts +0 -244
- package/src/cli/context-cmd.ts +0 -199
- package/src/cli/dispatch.ts +0 -82
- package/src/cli/doctor.ts +0 -362
- package/src/cli/export.ts +0 -276
- package/src/cli/help.ts +0 -293
- package/src/cli/is-tui-invocation.ts +0 -8
- package/src/cli/main.ts +0 -583
- package/src/cli/market-cmd.ts +0 -658
- package/src/cli/mcp-login.ts +0 -141
- package/src/cli/mcp-market-cmd.ts +0 -302
- package/src/cli/output.ts +0 -382
- package/src/cli/repl.ts +0 -250
- package/src/cli/repomap-root.ts +0 -14
- package/src/cli/resume.ts +0 -57
- package/src/cli/run-flags.ts +0 -43
- package/src/cli/run-limits.ts +0 -78
- package/src/cli/runtime.ts +0 -931
- package/src/cli/session-arg.ts +0 -30
- package/src/cli/sessions-cmd.ts +0 -145
- package/src/cli/setup.ts +0 -153
- package/src/cli/skills-cmd.ts +0 -194
- package/src/cli/start-chat.ts +0 -65
- package/src/cli/trust-cmd.ts +0 -52
- package/src/coding/bash.ts +0 -148
- package/src/coding/checkpoints.ts +0 -327
- package/src/coding/diff.ts +0 -138
- package/src/coding/files.ts +0 -341
- package/src/coding/hashline.ts +0 -274
- package/src/coding/lsp-gate.ts +0 -254
- package/src/coding/lsp-servers.ts +0 -147
- package/src/coding/lsp.ts +0 -283
- package/src/coding/repomap-cache.ts +0 -99
- package/src/coding/repomap-files.ts +0 -192
- package/src/coding/repomap.ts +0 -481
- package/src/core/agents.ts +0 -255
- package/src/core/compaction.ts +0 -259
- package/src/core/config.ts +0 -289
- package/src/core/context-report.ts +0 -228
- package/src/core/context.ts +0 -60
- package/src/core/count-remote.ts +0 -107
- package/src/core/execpolicy-rules.ts +0 -196
- package/src/core/execpolicy.ts +0 -385
- package/src/core/executor.ts +0 -454
- package/src/core/guardrails.ts +0 -400
- package/src/core/hooks.ts +0 -411
- package/src/core/images.ts +0 -230
- package/src/core/intro.ts +0 -266
- package/src/core/loop.ts +0 -567
- package/src/core/modes.ts +0 -372
- package/src/core/orchestrator.ts +0 -245
- package/src/core/proc-group.ts +0 -48
- package/src/core/project-trust.ts +0 -98
- package/src/core/reflection.ts +0 -165
- package/src/core/sandbox-config.ts +0 -186
- package/src/core/session-id.ts +0 -24
- package/src/core/session-images.ts +0 -73
- package/src/core/session-ops.ts +0 -183
- package/src/core/session-text.ts +0 -29
- package/src/core/session.ts +0 -469
- package/src/core/settings.ts +0 -170
- package/src/core/tasks.ts +0 -646
- package/src/core/token-scale.ts +0 -108
- package/src/core/tools.ts +0 -309
- package/src/core/trust.ts +0 -104
- package/src/core/types.ts +0 -330
- package/src/core/update-check.ts +0 -171
- package/src/core/usage.ts +0 -204
- package/src/core/validate.ts +0 -121
- package/src/core/verify-gate.ts +0 -159
- package/src/core/verify.ts +0 -236
- package/src/core/voice.ts +0 -158
- package/src/core/win-job.ts +0 -183
- package/src/core/workspace.ts +0 -184
- package/src/design/audit.ts +0 -797
- package/src/design/direction.ts +0 -190
- package/src/design/rules.ts +0 -157
- package/src/eval/bench.ts +0 -150
- package/src/eval/gauntlet-runner.ts +0 -215
- package/src/eval/gauntlet-support.ts +0 -84
- package/src/eval/gauntlet-wave3.ts +0 -269
- package/src/eval/gauntlet-wave4.ts +0 -217
- package/src/eval/gauntlet.ts +0 -253
- package/src/index.ts +0 -17
- package/src/lanes/agy.ts +0 -95
- package/src/lanes/approval.ts +0 -24
- package/src/lanes/claude.ts +0 -129
- package/src/lanes/codex.ts +0 -127
- package/src/lanes/events.ts +0 -130
- package/src/lanes/job.ts +0 -142
- package/src/lanes/opencode.ts +0 -122
- package/src/lanes/process.ts +0 -184
- package/src/lanes/progress.ts +0 -183
- package/src/lanes/registry.ts +0 -178
- package/src/lanes/runner.ts +0 -124
- package/src/lanes/types.ts +0 -112
- package/src/market/catalogs/mcp-docs.json +0 -111
- package/src/market/catalogs/plugins.json +0 -111
- package/src/market/catalogs/skills.json +0 -478
- package/src/market/clone.ts +0 -72
- package/src/market/context-cost.ts +0 -121
- package/src/market/digest.ts +0 -106
- package/src/market/index.ts +0 -22
- package/src/market/install.ts +0 -578
- package/src/market/manifest.ts +0 -187
- package/src/market/prereq.ts +0 -145
- package/src/market/registry.ts +0 -363
- package/src/market/resolve.ts +0 -111
- package/src/market/types.ts +0 -236
- package/src/market/validate.ts +0 -227
- package/src/mcp/client.ts +0 -449
- package/src/mcp/config.ts +0 -252
- package/src/mcp/local-package.ts +0 -211
- package/src/mcp/market-catalog.ts +0 -84
- package/src/mcp/market-install.ts +0 -289
- package/src/mcp/market.ts +0 -362
- package/src/mcp/oauth.ts +0 -251
- package/src/mcp/prompts-resources.ts +0 -249
- package/src/mcp/shared.ts +0 -149
- package/src/mcp/status.ts +0 -67
- package/src/mcp/tools.ts +0 -275
- package/src/mcp/transport.ts +0 -122
- package/src/mcp/trust.ts +0 -25
- package/src/memory/blocks.ts +0 -278
- package/src/memory/recall.ts +0 -355
- package/src/memory/scope.ts +0 -182
- package/src/memory/store.ts +0 -105
- package/src/memory/tools.ts +0 -99
- package/src/plugins/cli.ts +0 -119
- package/src/plugins/discover.ts +0 -108
- package/src/plugins/index.ts +0 -50
- package/src/plugins/install.ts +0 -184
- package/src/plugins/load.ts +0 -124
- package/src/plugins/manifest.ts +0 -92
- package/src/plugins/state.ts +0 -83
- package/src/providers/auth.ts +0 -408
- package/src/providers/cache.ts +0 -223
- package/src/providers/catalog-local.ts +0 -160
- package/src/providers/catalog.ts +0 -421
- package/src/providers/middleware-context.ts +0 -86
- package/src/providers/middleware.ts +0 -373
- package/src/providers/model-list.ts +0 -23
- package/src/providers/oauth/common.ts +0 -105
- package/src/providers/oauth/device-code.ts +0 -107
- package/src/providers/oauth/github-copilot.ts +0 -146
- package/src/providers/oauth/loopback.ts +0 -158
- package/src/providers/oauth/openai.ts +0 -163
- package/src/providers/oauth/openrouter.ts +0 -89
- package/src/providers/oauth/pkce.ts +0 -45
- package/src/providers/oauth/registry.ts +0 -39
- package/src/providers/oauth/seam.ts +0 -89
- package/src/providers/profile-glm53.ts +0 -111
- package/src/providers/profile-sonnet5-persona.ts +0 -65
- package/src/providers/profile-sonnet5-voice.ts +0 -23
- package/src/providers/profiles.ts +0 -156
- package/src/providers/provider-config.ts +0 -311
- package/src/providers/registry.ts +0 -333
- package/src/providers/responses.ts +0 -209
- package/src/providers/retry.ts +0 -234
- package/src/providers/router.ts +0 -294
- package/src/providers/sse.ts +0 -26
- package/src/providers/stream-errors.ts +0 -117
- package/src/providers/stream.ts +0 -566
- package/src/providers/thinking.ts +0 -189
- package/src/providers/wire-messages.ts +0 -129
- package/src/providers/wire-responses.ts +0 -79
- package/src/providers/wire-select.ts +0 -53
- package/src/server/http.ts +0 -291
- package/src/server/openapi.ts +0 -246
- package/src/sextant/card-hits.ts +0 -102
- package/src/sextant/card-keys.ts +0 -55
- package/src/sextant/context-source.ts +0 -157
- package/src/sextant/crew-cards.ts +0 -350
- package/src/sextant/draw-agents.ts +0 -273
- package/src/sextant/draw-code.ts +0 -388
- package/src/sextant/draw-context.ts +0 -222
- package/src/sextant/draw-frame.ts +0 -164
- package/src/sextant/draw-market.ts +0 -573
- package/src/sextant/draw-messages.ts +0 -386
- package/src/sextant/draw-pet.ts +0 -230
- package/src/sextant/draw-plan.ts +0 -187
- package/src/sextant/draw-tabs.ts +0 -85
- package/src/sextant/draw-util.ts +0 -65
- package/src/sextant/draw-wizard.ts +0 -378
- package/src/sextant/engine.ts +0 -230
- package/src/sextant/frame-hits.ts +0 -25
- package/src/sextant/frame.ts +0 -101
- package/src/sextant/git-status.ts +0 -197
- package/src/sextant/grid.ts +0 -59
- package/src/sextant/input.ts +0 -119
- package/src/sextant/keys.ts +0 -521
- package/src/sextant/layout.ts +0 -86
- package/src/sextant/local-commands.ts +0 -169
- package/src/sextant/market-source.ts +0 -287
- package/src/sextant/mentions.ts +0 -200
- package/src/sextant/message-hits.ts +0 -26
- package/src/sextant/model.ts +0 -387
- package/src/sextant/overlays.ts +0 -456
- package/src/sextant/panel-hits.ts +0 -38
- package/src/sextant/pet.ts +0 -399
- package/src/sextant/screen.ts +0 -324
- package/src/sextant/scroll-hits.ts +0 -66
- package/src/sextant/scrollbar.ts +0 -82
- package/src/sextant/sextant-bridge.ts +0 -174
- package/src/sextant/sextant-cards.ts +0 -142
- package/src/sextant/sextant-diff-base.ts +0 -63
- package/src/sextant/sextant-files.ts +0 -154
- package/src/sextant/sextant-frame-loop.ts +0 -335
- package/src/sextant/sextant-renderer.ts +0 -574
- package/src/sextant/sextant-repo.ts +0 -140
- package/src/sextant/theme.ts +0 -66
- package/src/sextant/tool-rows.ts +0 -189
- package/src/sextant/types.ts +0 -493
- package/src/skills/index.ts +0 -387
- package/src/skills/pack.ts +0 -220
- package/src/skills/spec.ts +0 -162
- package/src/skills/tools.ts +0 -69
- package/src/skills/versioned.ts +0 -227
- package/src/telemetry/otel-export.ts +0 -122
- package/src/telemetry/otel-lanes.ts +0 -89
- package/src/telemetry/otel-logs.ts +0 -131
- package/src/telemetry/otel-metrics.ts +0 -136
- package/src/telemetry/otel.ts +0 -397
- package/src/telemetry/otlp.ts +0 -76
- package/src/tools/ask-user.ts +0 -156
- package/src/tools/bash-bg.ts +0 -94
- package/src/tools/bash-jobs.ts +0 -237
- package/src/tools/design.ts +0 -151
- package/src/tools/evalcell.ts +0 -338
- package/src/tools/html-text.ts +0 -139
- package/src/tools/provider.ts +0 -149
- package/src/tools/task.ts +0 -250
- package/src/tools/todo.ts +0 -320
- package/src/tools/webfetch.ts +0 -332
- package/src/tools/websearch.ts +0 -359
- package/src/tui/agents-cmd.ts +0 -41
- package/src/tui/app.ts +0 -749
- package/src/tui/attach.ts +0 -127
- package/src/tui/boot-notes.ts +0 -41
- package/src/tui/builtin-prompts.ts +0 -59
- package/src/tui/checkpoints-cmd.ts +0 -70
- package/src/tui/clipboard-image.ts +0 -81
- package/src/tui/clipboard.ts +0 -78
- package/src/tui/commands.ts +0 -283
- package/src/tui/config-view.ts +0 -53
- package/src/tui/context-cmds.ts +0 -282
- package/src/tui/cost.ts +0 -108
- package/src/tui/crash-guard.ts +0 -173
- package/src/tui/focus-terminal.ts +0 -34
- package/src/tui/git-cmds.ts +0 -273
- package/src/tui/git-plain.ts +0 -58
- package/src/tui/info-cmd.ts +0 -150
- package/src/tui/input-plain.ts +0 -76
- package/src/tui/mcp-cmd.ts +0 -128
- package/src/tui/memory-note.ts +0 -77
- package/src/tui/modes-cmd.ts +0 -45
- package/src/tui/notify-seq.ts +0 -100
- package/src/tui/notify.ts +0 -318
- package/src/tui/overlays.ts +0 -97
- package/src/tui/pi-renderer.ts +0 -428
- package/src/tui/providers-cmd.ts +0 -377
- package/src/tui/reasoning-view.ts +0 -56
- package/src/tui/renderer.ts +0 -128
- package/src/tui/replay-marker.ts +0 -29
- package/src/tui/session-cmd.ts +0 -148
- package/src/tui/session-manage.ts +0 -95
- package/src/tui/sextant-attach.ts +0 -102
- package/src/tui/sextant-io.ts +0 -202
- package/src/tui/sextant-smoke.ts +0 -110
- package/src/tui/shell-cmd.ts +0 -158
- package/src/tui/smoke.ts +0 -72
- package/src/tui/staged-terminal.ts +0 -50
- package/src/tui/startup.ts +0 -12
- package/src/tui/theme.ts +0 -59
- package/src/tui/todo-label.ts +0 -7
- package/src/tui/trust-card.ts +0 -107
- package/src/tui/tui-commands.ts +0 -87
- package/tsconfig.json +0 -30
- package/vendor/pi-tui/LICENSE +0 -21
- package/vendor/pi-tui/PATCHES.md +0 -12
- package/vendor/pi-tui/PROVENANCE.md +0 -12
- package/vendor/pi-tui/README.upstream.md +0 -854
- 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 +0 -158
- package/vendor/pi-tui/src/autocomplete.ts +0 -827
- package/vendor/pi-tui/src/components/alt-screen-flash.ts +0 -52
- package/vendor/pi-tui/src/components/box.ts +0 -138
- package/vendor/pi-tui/src/components/cancellable-loader.ts +0 -41
- package/vendor/pi-tui/src/components/editor.ts +0 -2364
- package/vendor/pi-tui/src/components/h-stack.ts +0 -45
- package/vendor/pi-tui/src/components/image.ts +0 -128
- package/vendor/pi-tui/src/components/input.ts +0 -448
- package/vendor/pi-tui/src/components/loader.ts +0 -93
- package/vendor/pi-tui/src/components/markdown.ts +0 -1016
- package/vendor/pi-tui/src/components/scroll-view.ts +0 -217
- package/vendor/pi-tui/src/components/select-list.ts +0 -230
- package/vendor/pi-tui/src/components/settings-list.ts +0 -277
- package/vendor/pi-tui/src/components/spacer.ts +0 -29
- package/vendor/pi-tui/src/components/stack.ts +0 -155
- package/vendor/pi-tui/src/components/text.ts +0 -108
- package/vendor/pi-tui/src/components/truncated-text.ts +0 -66
- package/vendor/pi-tui/src/components/v-stack.ts +0 -34
- package/vendor/pi-tui/src/editor-component.ts +0 -75
- package/vendor/pi-tui/src/fuzzy.ts +0 -138
- package/vendor/pi-tui/src/index.ts +0 -149
- package/vendor/pi-tui/src/keybindings.ts +0 -321
- package/vendor/pi-tui/src/keys.ts +0 -1402
- package/vendor/pi-tui/src/kill-ring.ts +0 -47
- package/vendor/pi-tui/src/latex.ts +0 -1381
- package/vendor/pi-tui/src/layout-node.ts +0 -52
- package/vendor/pi-tui/src/layout.ts +0 -411
- package/vendor/pi-tui/src/native-modifiers.ts +0 -60
- package/vendor/pi-tui/src/native-module-path.ts +0 -32
- package/vendor/pi-tui/src/stdin-buffer.ts +0 -445
- package/vendor/pi-tui/src/terminal-colors.ts +0 -74
- package/vendor/pi-tui/src/terminal-image.ts +0 -701
- package/vendor/pi-tui/src/terminal.ts +0 -554
- package/vendor/pi-tui/src/tui-alt-screen.ts +0 -1379
- package/vendor/pi-tui/src/tui-main-screen.ts +0 -655
- package/vendor/pi-tui/src/tui.ts +0 -1264
- package/vendor/pi-tui/src/undo-stack.ts +0 -29
- package/vendor/pi-tui/src/utils.ts +0 -1327
- package/vendor/pi-tui/src/word-navigation.ts +0 -118
- package/vendor/pi-tui/test/test-themes.ts +0 -39
- package/vendor/pi-tui/test/virtual-terminal.ts +0 -219
- /package/{src/providers → dist/cli}/models-index.json +0 -0
package/src/coding/lsp-gate.ts
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/** LSP diagnostics gate (PORT #13; server table PORT #73, both ported from the Nimbus harness): discovery + the bounded
|
|
2
|
-
* post-edit note over the coding/lsp.ts LspClient, the per-root default gates, the write-tool wrapper, and the
|
|
3
|
-
* boot-time "this is NOT running here" line. Moved out of lsp.ts (which keeps the wire only) when the ONE built-in
|
|
4
|
-
* server became a table (coding/lsp-servers.ts, knob `lsp`): after a successful edit/write the touched file's
|
|
5
|
-
* lower-cased extension is looked up (miss → "" — no probe, no spawn); each DISTINCT argv is probed ONCE per root —
|
|
6
|
-
* argv[0] holding a path separator → existsSync (relative to the root), else Bun.which over PATH (+ PATHEXT) — and a
|
|
7
|
-
* miss turns THAT argv off for the process (never re-probed; the other servers are untouched); a hit spawns exactly
|
|
8
|
-
* the configured argv (no implicit `--stdio`); extensions sharing an argv share ONE server per root; the note label
|
|
9
|
-
* is the configured argv[0]'s basename minus extension, sanitised to [A-Za-z0-9._-] (`typescript-language-server`
|
|
10
|
-
* by default, so core/reflection.ts parses the note unchanged). The table is resolved lazily on the first note().
|
|
11
|
-
* Every #13 guarantee holds: ≤2 s hard deadline per note, wedged/dead never retried, per-root LRU-4, garbage/laggy
|
|
12
|
-
* frames survive; diagnostics ONLY — no goto/refs/hover/completion.
|
|
13
|
-
*
|
|
14
|
-
* Beside the verify gate (core/verify-gate.ts), not under it: this runs per edit, costs at most 2 s, feeds the
|
|
15
|
-
* model the error it just made, and is on wherever a server already exists (a probe miss is free). The verify
|
|
16
|
-
* gate runs the project's own command once at the end and is off by default because it costs 3–170 s. Its knob is
|
|
17
|
-
* ROVECODE_VERIFY; this one's is the `lsp` table (ROVECODE_LSP / settings `lsp`; `off` disables).
|
|
18
|
-
*
|
|
19
|
-
* Degradation is NAMED, never silent to the person: the tool result stays clean when no server is there (the model
|
|
20
|
-
* has nothing to act on), and lspAvailabilityNote says once, at boot and in `rovecode doctor`, which extensions are
|
|
21
|
-
* not being checked and why — the built-in TS entry when the project has a tsconfig.json, any configured entry
|
|
22
|
-
* whose binary is missing. Nothing is installed on anyone's behalf.
|
|
23
|
-
*
|
|
24
|
-
* Pattern source (MIT, pattern level, no code copied): opencode packages/opencode/src/lsp/lsp.ts:213 / :254-255
|
|
25
|
-
* (a file's extension selects the server), :221-227 / :259 (a broken server key is remembered, never retried),
|
|
26
|
-
* :360 (swallow-all gate errors), server.ts:125 (which-probe, then spawn); the hand-rolled reader is oh-my-pi's
|
|
27
|
-
* shape (credited in lsp.ts). The `cmd` / `serverName` test hooks keep their #13 meaning for the BUILT-IN entry only
|
|
28
|
-
* (cmd bypasses its probe, serverName swaps its probe target). */
|
|
29
|
-
|
|
30
|
-
import { existsSync } from "node:fs";
|
|
31
|
-
import { extname, isAbsolute, join, resolve } from "node:path";
|
|
32
|
-
import type { Tool, ToolOutput } from "../core/types.ts";
|
|
33
|
-
import { loadSettings } from "../core/settings.ts";
|
|
34
|
-
import { LspClient, formatGateNote, type Diagnostic } from "./lsp.ts";
|
|
35
|
-
import { DEFAULT_SERVER_ARGV, LSP_ENV, lspTableProblem, lspTableValue, resolveServerTable, type Env } from "./lsp-servers.ts";
|
|
36
|
-
|
|
37
|
-
// ---------- gate: discovery + bounded note ----------
|
|
38
|
-
|
|
39
|
-
export interface GateOptions {
|
|
40
|
-
root?: string; // workspace root (default process.cwd())
|
|
41
|
-
/** the resolved server table (tests); default resolveServerTable over env + the project settings, read on the first note() */
|
|
42
|
-
servers?: ReadonlyMap<string, readonly string[]>;
|
|
43
|
-
/** the env map the table is read from (tests); default process.env */
|
|
44
|
-
env?: Env;
|
|
45
|
-
/** the project settings `lsp` value (tests); default: `.rovecode/settings.json` at the root, key `lsp`, if the settings layer knows it */
|
|
46
|
-
settingsValue?: string;
|
|
47
|
-
serverName?: string; // the built-in entry's probe target (default "typescript-language-server") — tests
|
|
48
|
-
cmd?: string[]; // the built-in entry's explicit argv — bypasses its probe (tests)
|
|
49
|
-
/** the PATH probe (tests count calls); default Bun.which */
|
|
50
|
-
which?: (name: string) => string | null;
|
|
51
|
-
settleMs?: number; // diagnostics settle window, clamped ≤2000
|
|
52
|
-
hardDeadlineMs?: number; // absolute cap per note() call, clamped ≤2000 (default 2000)
|
|
53
|
-
initTimeoutMs?: number; // background initialize cap before kill (default 8000)
|
|
54
|
-
debounceMs?: number;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface LspGate {
|
|
58
|
-
/** "" when feature off / no errors / timed out; otherwise "\n\nlsp-gate ..." */
|
|
59
|
-
note(absPath: string): Promise<string>;
|
|
60
|
-
dispose(): void;
|
|
61
|
-
/** the most recently constructed client — null before the first spawn or when every probe missed */
|
|
62
|
-
readonly client: LspClient | null;
|
|
63
|
-
/** every client this root spawned, one per distinct argv (probe misses excluded) */
|
|
64
|
-
clients(): LspClient[];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const DEFAULT_KEY = DEFAULT_SERVER_ARGV.join("\0");
|
|
68
|
-
|
|
69
|
-
/** the project settings `lsp` value at `root`, or undefined — core/settings.ts decides whether the key exists at all
|
|
70
|
-
* (a key it does not sanitize is invisible here, and ROVECODE_LSP still works); a missing or corrupt file is undefined */
|
|
71
|
-
export function settingsLspValue(root: string): string | undefined {
|
|
72
|
-
try {
|
|
73
|
-
const v = (loadSettings(root) as { lsp?: unknown }).lsp;
|
|
74
|
-
return typeof v === "string" ? v : undefined;
|
|
75
|
-
} catch { return undefined; }
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** the note's `lsp-gate (<label>)`: argv[0]'s basename minus its extension, sanitised to [A-Za-z0-9._-] */
|
|
79
|
-
export function serverLabel(argv0: string): string {
|
|
80
|
-
const base = argv0.split(/[\\/]/).pop() ?? "";
|
|
81
|
-
const stem = base.replace(/\.[^.]+$/, "") || base;
|
|
82
|
-
const clean = stem.replace(/[^A-Za-z0-9._-]/g, "");
|
|
83
|
-
return clean === "" ? "lsp" : clean;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** ONE probe per distinct argv per root (opencode server.ts:125 which-then-spawn): argv[0] with a path separator must
|
|
87
|
-
* exist — resolved against the root; a bare name is looked up on PATH (+ PATHEXT). null = off for the process. */
|
|
88
|
-
function probe(argv: readonly string[], root: string, which: (name: string) => string | null): string[] | null {
|
|
89
|
-
const head = argv[0];
|
|
90
|
-
if (head === undefined || head === "") return null;
|
|
91
|
-
const bin = /[\\/]/.test(head) ? (existsSync(resolve(root, head)) ? resolve(root, head) : null) : which(head);
|
|
92
|
-
return bin === null ? null : [bin, ...argv.slice(1)];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** the table a root sees: an injected one, else env + this root's settings value */
|
|
96
|
-
function tableFor(root: string, opts: GateOptions): ReadonlyMap<string, readonly string[]> {
|
|
97
|
-
return opts.servers ?? resolveServerTable({ env: opts.env ?? process.env, settings: opts.settingsValue ?? settingsLspValue(root) });
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function createLspGate(opts: GateOptions = {}): LspGate {
|
|
101
|
-
const root = opts.root ?? process.cwd();
|
|
102
|
-
const hard = Math.min(opts.hardDeadlineMs ?? 2000, 2000);
|
|
103
|
-
const which = opts.which ?? ((name: string): string | null => Bun.which(name));
|
|
104
|
-
const clientOpts = {
|
|
105
|
-
...(opts.settleMs !== undefined ? { settleMs: opts.settleMs } : {}),
|
|
106
|
-
...(opts.initTimeoutMs !== undefined ? { initTimeoutMs: opts.initTimeoutMs } : {}),
|
|
107
|
-
...(opts.debounceMs !== undefined ? { debounceMs: opts.debounceMs } : {}),
|
|
108
|
-
};
|
|
109
|
-
let table: ReadonlyMap<string, readonly string[]> | undefined; // resolved on the first note()
|
|
110
|
-
const clients = new Map<string, LspClient | null>(); // argv key → client; absent = unprobed, null = probe miss (off, never re-probed)
|
|
111
|
-
let last: LspClient | null = null;
|
|
112
|
-
const clientFor = (argv: readonly string[]): { client: LspClient | null; label: string } => {
|
|
113
|
-
const key = argv.join("\0");
|
|
114
|
-
const builtIn = key === DEFAULT_KEY;
|
|
115
|
-
const label = builtIn && opts.serverName !== undefined ? opts.serverName : serverLabel(argv[0] ?? "");
|
|
116
|
-
let client = clients.get(key);
|
|
117
|
-
if (client === undefined) {
|
|
118
|
-
const cmd = builtIn && opts.cmd !== undefined
|
|
119
|
-
? opts.cmd
|
|
120
|
-
: probe(builtIn && opts.serverName !== undefined ? [opts.serverName, ...argv.slice(1)] : argv, root, which);
|
|
121
|
-
client = cmd === null ? null : new LspClient({ cmd, root, ...clientOpts });
|
|
122
|
-
clients.set(key, client);
|
|
123
|
-
if (client !== null) last = client;
|
|
124
|
-
}
|
|
125
|
-
return { client, label };
|
|
126
|
-
};
|
|
127
|
-
return {
|
|
128
|
-
get client(): LspClient | null { return last; },
|
|
129
|
-
clients(): LspClient[] { return [...clients.values()].filter((c): c is LspClient => c !== null); },
|
|
130
|
-
async note(absPath: string): Promise<string> {
|
|
131
|
-
table ??= tableFor(root, opts);
|
|
132
|
-
const argv = table.get(extname(absPath).toLowerCase());
|
|
133
|
-
if (argv === undefined) return ""; // not a gated extension (or every server off): no probe, no spawn
|
|
134
|
-
const { client, label } = clientFor(argv);
|
|
135
|
-
if (client === null || client.state === "dead") return ""; // absent/broken → silently off (said once at boot instead)
|
|
136
|
-
// hard deadline: a cold or wedged server can never block the loop; the swallowed touch
|
|
137
|
-
// continues (or gets killed by initTimeout) in the background (opencode lsp.ts:360).
|
|
138
|
-
// The deadline timer is cleared when touch settles first — a stray ref'd timer would
|
|
139
|
-
// hold the host's event loop open for up to 2s after every edit.
|
|
140
|
-
const c = client;
|
|
141
|
-
const diags = await new Promise<Diagnostic[] | null>((resolve) => {
|
|
142
|
-
const t = setTimeout(() => resolve(null), hard);
|
|
143
|
-
c.touch(absPath).then(
|
|
144
|
-
(d) => { clearTimeout(t); resolve(d); },
|
|
145
|
-
() => { clearTimeout(t); resolve(null); },
|
|
146
|
-
);
|
|
147
|
-
});
|
|
148
|
-
return diags === null ? "" : formatGateNote(absPath, diags, label);
|
|
149
|
-
},
|
|
150
|
-
dispose(): void { for (const c of clients.values()) c?.kill(); },
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// ---------- the absence, said once ----------
|
|
155
|
-
|
|
156
|
-
/** Startup lines for every server the gate CANNOT run here, or null when there is nothing to say.
|
|
157
|
-
*
|
|
158
|
-
* The gate is silent by design when a server is missing (the note above is "" and the edit succeeds as it
|
|
159
|
-
* should) — and that silence let everyone credit a diagnostics loop that was not running: on the machine this
|
|
160
|
-
* was written on, typescript-language-server was not on PATH and no edit had ever been type-checked. Silence is
|
|
161
|
-
* right for the TOOL RESULT (the model has nothing to act on); it is wrong for the person, who was promised the
|
|
162
|
-
* loop. So the absence is said once, at boot, next to the other "this is off" notes, and in `rovecode doctor`.
|
|
163
|
-
* The built-in TS entry is only reported for a TypeScript project (a tsconfig.json at the root): elsewhere
|
|
164
|
-
* nothing was promised. A CONFIGURED entry was promised by whoever wrote it, so a missing binary is always
|
|
165
|
-
* named, with the extensions it was meant to cover. `off` and `ext=off` are choices, not absences: nothing. */
|
|
166
|
-
export function lspAvailabilityNotes(root: string, which: (name: string) => string | null = (n) => Bun.which(n), serverName = "typescript-language-server", opts: Pick<GateOptions, "env" | "settingsValue" | "servers"> = {}): string[] {
|
|
167
|
-
const notes: string[] = [];
|
|
168
|
-
// a malformed table is a problem string, never silence: the gate applies the valid entries and skips the rest, so
|
|
169
|
-
// the person is told here which entry was ignored and where it was written (the settings layer keeps it as written)
|
|
170
|
-
if (opts.servers === undefined) {
|
|
171
|
-
const raw = lspTableValue({ env: opts.env ?? process.env, settings: opts.settingsValue ?? settingsLspValue(root) });
|
|
172
|
-
const problem = lspTableProblem(raw.value);
|
|
173
|
-
if (problem !== null) notes.push(`lsp: the \`lsp\` table (${raw.source === "env" ? LSP_ENV : ".rovecode/settings.json lsp"}) has a problem — ${problem}; that entry is ignored, the rest of the table applies`);
|
|
174
|
-
}
|
|
175
|
-
const table = tableFor(root, opts);
|
|
176
|
-
const byArgv = new Map<string, { argv: readonly string[]; exts: string[] }>();
|
|
177
|
-
for (const [ext, argv] of table) {
|
|
178
|
-
const key = argv.join("\0");
|
|
179
|
-
const e = byArgv.get(key);
|
|
180
|
-
if (e) e.exts.push(ext); else byArgv.set(key, { argv, exts: [ext] });
|
|
181
|
-
}
|
|
182
|
-
for (const [key, { argv, exts }] of byArgv) {
|
|
183
|
-
if (key === DEFAULT_KEY) {
|
|
184
|
-
if (!existsSync(join(root, "tsconfig.json"))) continue;
|
|
185
|
-
if (which(serverName) !== null) continue;
|
|
186
|
-
notes.push(`lsp: ${serverName} is not on PATH — edits and writes are NOT type-checked, and the model gets no diagnostics after them (npm i -g typescript-language-server typescript)`);
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
if (probe(argv, root, which) !== null) continue;
|
|
190
|
-
const head = argv[0] ?? "";
|
|
191
|
-
const where = /[\\/]/.test(head) ? `is not at ${resolve(root, head)}` : "is not on PATH";
|
|
192
|
-
notes.push(`lsp: ${head} (${exts.sort().join(", ")}) ${where} — edits to those files are NOT checked (the \`lsp\` setting names it; fix the path or install it)`);
|
|
193
|
-
}
|
|
194
|
-
return notes;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/** the notes above as ONE string or null — the shape cli/runtime.ts (a plugin warning) and cli/doctor.ts (one row
|
|
198
|
-
* detail, which strips the leading "lsp: ") consume: the first line keeps its prefix, the rest are indented under it */
|
|
199
|
-
export function lspAvailabilityNote(root: string, which: (name: string) => string | null = (n) => Bun.which(n), serverName = "typescript-language-server"): string | null {
|
|
200
|
-
const notes = lspAvailabilityNotes(root, which, serverName);
|
|
201
|
-
return notes.length === 0 ? null : notes.map((n, i) => (i === 0 ? n : ` ${n.replace(/^lsp: /, "")}`)).join("\n");
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// ---------- default gates (one per root) + tool wiring ----------
|
|
205
|
-
|
|
206
|
-
/** acp/http build per-session runtimes with per-caller cwds, so a single module-level gate
|
|
207
|
-
* bound the FIRST caller's root for the process lifetime and later sessions diagnosed
|
|
208
|
-
* against the wrong project (wrong tsconfig/paths). Keyed by resolved root; bounded LRU,
|
|
209
|
-
* since every live entry owns a server process. */
|
|
210
|
-
const MAX_DEFAULT_GATES = 4;
|
|
211
|
-
const defaultGates = new Map<string, LspGate>(); // insertion order doubles as LRU order
|
|
212
|
-
|
|
213
|
-
/** Post-edit hook for hashline's lint-gate point: await and append to successful tool output.
|
|
214
|
-
* `opts` (test hook) applies only when the root's gate is first constructed. */
|
|
215
|
-
export function lspGateNote(absPath: string, root?: string, opts?: Omit<GateOptions, "root">): Promise<string> {
|
|
216
|
-
const key = resolve(root ?? process.cwd());
|
|
217
|
-
let gate = defaultGates.get(key);
|
|
218
|
-
if (gate !== undefined) {
|
|
219
|
-
defaultGates.delete(key); // refresh LRU position
|
|
220
|
-
} else {
|
|
221
|
-
gate = createLspGate({ ...opts, root: key });
|
|
222
|
-
if (defaultGates.size >= MAX_DEFAULT_GATES) {
|
|
223
|
-
for (const [k, g] of defaultGates) { defaultGates.delete(k); g.dispose(); break; } // evict oldest
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
defaultGates.set(key, gate);
|
|
227
|
-
return gate.note(absPath);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/** dispose every default gate and forget it (test hook); returns them so exits can be awaited */
|
|
231
|
-
export function disposeDefaultGates(): LspGate[] {
|
|
232
|
-
const gates = [...defaultGates.values()];
|
|
233
|
-
defaultGates.clear();
|
|
234
|
-
for (const g of gates) g.dispose();
|
|
235
|
-
return gates;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/** Zero-touch alternative: wrap a write-kind tool (hashline editTool/writeTool) so every
|
|
239
|
-
* successful execution gets the diagnostics gate note appended to its output. */
|
|
240
|
-
export function withLspGate(tool: Tool, gate: (absPath: string) => Promise<string> = lspGateNote): Tool {
|
|
241
|
-
if (tool.kind !== "write") return tool;
|
|
242
|
-
return {
|
|
243
|
-
...tool,
|
|
244
|
-
async execute(args: unknown, ctx): Promise<ToolOutput> {
|
|
245
|
-
const out = await tool.execute(args, ctx);
|
|
246
|
-
const rel = (args as { path?: unknown }).path;
|
|
247
|
-
if (!out.ok || typeof rel !== "string") return out;
|
|
248
|
-
const abs = isAbsolute(rel) ? rel : join(ctx.cwd, rel);
|
|
249
|
-
if (!existsSync(abs)) return out;
|
|
250
|
-
const note = await gate(abs);
|
|
251
|
-
return note === "" ? out : { ...out, output: out.output + note };
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/** LSP server table (ported from the Nimbus harness, PORT #73): the `lsp` knob — `ext[,ext…]=argv[;…]` — merged over
|
|
2
|
-
* the built-in typescript-language-server entry. Pure: no probe, no spawn, no I/O — coding/lsp-gate.ts consumes the
|
|
3
|
-
* resolved table after a successful edit, coding/lsp.ts takes the languageId for didOpen.
|
|
4
|
-
*
|
|
5
|
-
* Where the value comes from (rovecode has one env prefix and one settings file, not Nimbus's layered reader):
|
|
6
|
-
* ROVECODE_LSP when defined — even "" (a defined-empty value means the defaults) — else the project
|
|
7
|
-
* `.rovecode/settings.json` key `lsp`, handed in by the caller (resolveServerTable never reads a file), else blank.
|
|
8
|
-
*
|
|
9
|
-
* Grammar (ONE string, flat like every other knob): entries separated by `;`; each entry is one or more extensions
|
|
10
|
-
* (`py`, `.PY`, `.py,.pyi` normalise to `.py`, `.pyi`) then `=` then the server argv — whitespace-split, double
|
|
11
|
-
* quotes group a path with spaces, NO implicit `--stdio`; `ext=off` disables that extension; the bare value `off`
|
|
12
|
-
* disables every server; blank = the defaults. Entries MERGE over DEFAULT_SERVERS (unset = the #13 behaviour byte
|
|
13
|
-
* for byte; `.py=pyright-langserver --stdio` adds Python without restating TS). A malformed value is a problem
|
|
14
|
-
* string (lspTableProblem), never silence: the settings layer should refuse it; an env value is read at gate time,
|
|
15
|
-
* where its malformed entries are skipped and the valid ones apply — the gate has no error channel.
|
|
16
|
-
*
|
|
17
|
-
* Pattern source: opencode packages/opencode/src/lsp/lsp.ts:151-181 (the config table overlays the built-in server
|
|
18
|
-
* set by name; a disabled entry deletes it), :213 / :254-255 (a file's extension selects the server), :221-227 /
|
|
19
|
-
* :259 (a broken server is remembered and never retried), server.ts:125 (which-probe before spawn) — MIT, pattern
|
|
20
|
-
* level, no code copied. Deliberate deviations: entries map extension → argv 1:1 instead of named servers carrying
|
|
21
|
-
* extension lists; no root-marker walk (every gate is keyed on the cwd root); no auto-install (network is out).
|
|
22
|
-
* LANGUAGE_IDS is hand-typed from the LSP specification's language-identifier list. */
|
|
23
|
-
|
|
24
|
-
/** a plain environment map (process.env, or an injected one in tests) */
|
|
25
|
-
export type Env = Readonly<Record<string, string | undefined>>;
|
|
26
|
-
|
|
27
|
-
/** the env spelling of the knob */
|
|
28
|
-
export const LSP_ENV = "ROVECODE_LSP";
|
|
29
|
-
|
|
30
|
-
/** the built-in entry: #13's TS/JS extensions → typescript-language-server over stdio */
|
|
31
|
-
export const DEFAULT_SERVER_ARGV: readonly string[] = ["typescript-language-server", "--stdio"];
|
|
32
|
-
const DEFAULT_EXTENSIONS: readonly string[] = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
33
|
-
export const DEFAULT_SERVERS: ReadonlyMap<string, readonly string[]> = new Map(DEFAULT_EXTENSIONS.map((e) => [e, DEFAULT_SERVER_ARGV]));
|
|
34
|
-
/** the knob's documented default: the built-in table written in the knob's own grammar (parses back to DEFAULT_SERVERS) */
|
|
35
|
-
export const DEFAULT_LSP_TABLE = `${DEFAULT_EXTENSIONS.join(",")}=${DEFAULT_SERVER_ARGV.join(" ")}`;
|
|
36
|
-
|
|
37
|
-
/** didOpen `languageId` per extension — the LSP specification's language identifiers, hand-typed (the TS/JS eight are
|
|
38
|
-
* #13's); anything else → the bare extension (most identifiers equal it), no extension → plaintext */
|
|
39
|
-
export const LANGUAGE_IDS: Readonly<Record<string, string>> = {
|
|
40
|
-
".ts": "typescript", ".mts": "typescript", ".cts": "typescript", ".tsx": "typescriptreact",
|
|
41
|
-
".js": "javascript", ".mjs": "javascript", ".cjs": "javascript", ".jsx": "javascriptreact",
|
|
42
|
-
".py": "python", ".pyi": "python", ".go": "go", ".rs": "rust", ".rb": "ruby", ".java": "java", ".kt": "kotlin",
|
|
43
|
-
".c": "c", ".h": "c", ".cpp": "cpp", ".cc": "cpp", ".cxx": "cpp", ".hpp": "cpp", ".hh": "cpp", ".cs": "csharp",
|
|
44
|
-
".php": "php", ".swift": "swift", ".scala": "scala", ".lua": "lua", ".pl": "perl", ".r": "r", ".dart": "dart",
|
|
45
|
-
".ex": "elixir", ".exs": "elixir", ".erl": "erlang", ".fs": "fsharp", ".clj": "clojure", ".hs": "haskell",
|
|
46
|
-
".sh": "shellscript", ".bash": "shellscript", ".ps1": "powershell", ".sql": "sql", ".html": "html", ".htm": "html",
|
|
47
|
-
".css": "css", ".scss": "scss", ".less": "less", ".json": "json", ".yaml": "yaml", ".yml": "yaml", ".xml": "xml",
|
|
48
|
-
".md": "markdown", ".tex": "latex", ".vue": "vue", ".toml": "toml",
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export function languageIdFor(ext: string): string {
|
|
52
|
-
const e = ext.toLowerCase();
|
|
53
|
-
const bare = e.startsWith(".") ? e.slice(1) : e;
|
|
54
|
-
return LANGUAGE_IDS[e] ?? (bare === "" ? "plaintext" : bare);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface ParsedServerTable {
|
|
58
|
-
/** normalised extension → argv, or null for `ext=off` */
|
|
59
|
-
table: Map<string, string[] | null>;
|
|
60
|
-
/** the bare value `off`: every server disabled */
|
|
61
|
-
off: boolean;
|
|
62
|
-
/** every problem, one line each — empty for a valid value */
|
|
63
|
-
problems: string[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** `py`, `.PY`, ` .Py ` → ".py"; null when the text is not an extension (letters, digits, `_`, `+`, `-`) */
|
|
67
|
-
export function normalizeExt(raw: string): string | null {
|
|
68
|
-
const s = raw.trim().toLowerCase().replace(/^\./, "");
|
|
69
|
-
return /^[a-z0-9_+-]+$/.test(s) ? `.${s}` : null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** whitespace split with double-quote grouping (`"C:\Program Files\x\srv.exe" --stdio` → two tokens); null = unbalanced quote */
|
|
73
|
-
export function tokenizeArgv(text: string): string[] | null {
|
|
74
|
-
const out: string[] = [];
|
|
75
|
-
let cur = "", quoted = false, open = false;
|
|
76
|
-
for (const ch of text) {
|
|
77
|
-
if (ch === '"') { quoted = !quoted; open = true; continue; }
|
|
78
|
-
if (!quoted && /\s/.test(ch)) { if (open) out.push(cur); cur = ""; open = false; continue; }
|
|
79
|
-
cur += ch; open = true;
|
|
80
|
-
}
|
|
81
|
-
if (quoted) return null;
|
|
82
|
-
if (open) out.push(cur);
|
|
83
|
-
return out;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** Parse one knob value (header grammar). Never throws; every problem is collected. */
|
|
87
|
-
export function parseServerTable(text: string): ParsedServerTable {
|
|
88
|
-
const out: ParsedServerTable = { table: new Map(), off: false, problems: [] };
|
|
89
|
-
const value = text.trim();
|
|
90
|
-
if (value === "") return out;
|
|
91
|
-
if (value.toLowerCase() === "off") { out.off = true; return out; }
|
|
92
|
-
for (const rawEntry of value.split(";")) {
|
|
93
|
-
const entry = rawEntry.trim();
|
|
94
|
-
if (entry === "") continue; // a trailing `;`
|
|
95
|
-
const eq = entry.indexOf("=");
|
|
96
|
-
if (eq < 0) { out.problems.push(`entry "${entry}" has no "=" (ext[,ext]=argv, ext=off, or the bare value off)`); continue; }
|
|
97
|
-
const exts: string[] = [];
|
|
98
|
-
for (const raw of entry.slice(0, eq).split(",")) {
|
|
99
|
-
const ext = normalizeExt(raw);
|
|
100
|
-
if (ext === null) { out.problems.push(`entry "${entry}": "${raw.trim()}" is not a file extension (letters, digits, _ + -)`); continue; }
|
|
101
|
-
if (out.table.has(ext) || exts.includes(ext)) { out.problems.push(`entry "${entry}": ${ext} is listed twice`); continue; }
|
|
102
|
-
exts.push(ext);
|
|
103
|
-
}
|
|
104
|
-
const rhs = entry.slice(eq + 1).trim();
|
|
105
|
-
let argv: string[] | null = null;
|
|
106
|
-
if (rhs.toLowerCase() !== "off") {
|
|
107
|
-
const tokens = tokenizeArgv(rhs);
|
|
108
|
-
if (tokens === null) { out.problems.push(`entry "${entry}": unbalanced double quote in the argv`); continue; }
|
|
109
|
-
if (tokens.length === 0) { out.problems.push(`entry "${entry}": empty argv (ext=argv, or ext=off to disable)`); continue; }
|
|
110
|
-
argv = tokens;
|
|
111
|
-
}
|
|
112
|
-
for (const ext of exts) out.table.set(ext, argv);
|
|
113
|
-
}
|
|
114
|
-
return out;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** The settings-layer validator: every problem joined, or null when the value parses. */
|
|
118
|
-
export function lspTableProblem(text: string): string | null {
|
|
119
|
-
const { problems } = parseServerTable(text);
|
|
120
|
-
return problems.length === 0 ? null : problems.join("; ");
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** where a table value comes from: the env map (ROVECODE_LSP wins when defined, even "") and the project
|
|
124
|
-
* settings value the caller read (`lsp` key), if any */
|
|
125
|
-
export interface LspSource {
|
|
126
|
-
env?: Env;
|
|
127
|
-
settings?: string | undefined;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/** the raw knob value the gate will parse, and where it came from — for the surfaces ("lsp (settings): …") */
|
|
131
|
-
export function lspTableValue(src: LspSource = {}): { value: string; source: "env" | "settings" | "default" } {
|
|
132
|
-
const env = (src.env ?? process.env)[LSP_ENV];
|
|
133
|
-
if (env !== undefined) return { value: env, source: "env" };
|
|
134
|
-
if (src.settings !== undefined) return { value: src.settings, source: "settings" };
|
|
135
|
-
return { value: "", source: "default" };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** The effective table for a gate: DEFAULT_SERVERS with the knob's entries merged over it (`ext=off` deletes);
|
|
139
|
-
* the bare `off` → an empty map (zero probes). */
|
|
140
|
-
export function resolveServerTable(src: LspSource = {}): Map<string, string[]> {
|
|
141
|
-
const parsed = parseServerTable(lspTableValue(src).value);
|
|
142
|
-
if (parsed.off) return new Map();
|
|
143
|
-
const out = new Map<string, string[]>();
|
|
144
|
-
for (const [ext, argv] of DEFAULT_SERVERS) out.set(ext, [...argv]);
|
|
145
|
-
for (const [ext, argv] of parsed.table) { if (argv === null) out.delete(ext); else out.set(ext, argv); }
|
|
146
|
-
return out;
|
|
147
|
-
}
|