rovecode 0.3.2 → 0.4.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +512 -0
- package/README.md +33 -45
- package/bin/rovecode.js +24 -0
- package/dist/cli/app-dybnr56b.js +2 -0
- package/dist/cli/ask-user-p8hq4xgj.js +2 -0
- package/dist/cli/auth-login-ewpgw5sm.js +2 -0
- package/dist/cli/auth-m8p9grty.js +2 -0
- package/dist/cli/bench-xv3ypwev.js +9 -0
- package/dist/cli/catalog-737wb2s0.js +2 -0
- package/dist/cli/cli-arhg40m0.js +2 -0
- package/dist/cli/client-cf2pxx8q.js +2 -0
- package/dist/cli/commands-3p7e4xxs.js +2 -0
- package/dist/cli/connect-3q93d7cb.js +2 -0
- package/dist/cli/context-cmd-eqxmxhzq.js +2 -0
- package/dist/cli/context-report-hbw9zfes.js +2 -0
- package/dist/cli/count-remote-mby98cd0.js +2 -0
- package/dist/cli/design-122y0axd.js +2 -0
- package/dist/cli/dispatch-b4egzvvh.js +2 -0
- package/dist/cli/doctor-x4jkv72e.js +3 -0
- package/dist/cli/executor-ftvg6tsy.js +2 -0
- package/dist/cli/export-pdgdhkch.js +2 -0
- package/dist/cli/files-cez9a96p.js +2 -0
- package/dist/cli/gauntlet-r3xxaszc.js +2 -0
- package/dist/cli/gauntlet-runner-r515m7kk.js +10 -0
- package/dist/cli/gauntlet-wave3-bnkjk2v2.js +5 -0
- package/dist/cli/gauntlet-wave4-acs9s60q.js +14 -0
- package/dist/cli/hashline-ewg5hbe3.js +2 -0
- package/dist/cli/http-n0kehsk8.js +5 -0
- package/dist/cli/index-z5qt1s76.js +2 -0
- package/dist/cli/install-80mp63kx.js +2 -0
- package/dist/cli/loop-12twjcat.js +2 -0
- package/dist/cli/main-01pv9206.js +4 -0
- package/dist/cli/main-0jys2ccn.js +3 -0
- package/dist/cli/main-1ztz6fkj.js +10 -0
- package/dist/cli/main-23q7cmww.js +9 -0
- package/dist/cli/main-2rzbexn2.js +3 -0
- package/dist/cli/main-2wyax8k9.js +9 -0
- package/dist/cli/main-2yeveeve.js +6 -0
- package/dist/cli/main-2z3dek0b.js +3 -0
- package/dist/cli/main-2zgsknth.js +3 -0
- package/dist/cli/main-45ejth3a.js +4 -0
- package/dist/cli/main-45rn3trk.js +22 -0
- package/dist/cli/main-4p4e2w7x.js +4 -0
- package/dist/cli/main-4y0tnfpa.js +16 -0
- package/dist/cli/main-5py0rkmc.js +4 -0
- package/dist/cli/main-6dtqmbt6.js +7 -0
- package/dist/cli/main-6h9x282m.js +4 -0
- package/dist/cli/main-6vjeds42.js +3 -0
- package/dist/cli/main-78gq4bt9.js +6 -0
- package/dist/cli/main-7jd5vh3x.js +4 -0
- package/dist/cli/main-7kt6r53y.js +4 -0
- package/dist/cli/main-8c1tbazx.js +58 -0
- package/dist/cli/main-9a9rnh47.js +19 -0
- package/dist/cli/main-9ht36z12.js +3 -0
- package/dist/cli/main-a2yfvcy9.js +7 -0
- package/dist/cli/main-a3f51n0x.js +5 -0
- package/dist/cli/main-b8zq261k.js +3 -0
- package/dist/cli/main-bxtvnf6d.js +13 -0
- package/dist/cli/main-edxc3yzt.js +4 -0
- package/dist/cli/main-evgz4mp5.js +21 -0
- package/dist/cli/main-f33fc5je.js +9 -0
- package/dist/cli/main-fvnpq46y.js +12 -0
- package/dist/cli/main-gbbty4d4.js +3 -0
- package/dist/cli/main-gth53dnt.js +25 -0
- package/dist/cli/main-hqbz10aw.js +9 -0
- package/dist/cli/main-hrrvcfan.js +38 -0
- package/dist/cli/main-hzwtsb2m.js +5 -0
- package/dist/cli/main-j7ttv0sd.js +34 -0
- package/dist/cli/main-jak598k9.js +5 -0
- package/dist/cli/main-kba6zeyd.js +6 -0
- package/dist/cli/main-kwwsz6rq.js +3 -0
- package/dist/cli/main-m8vm17zq.js +3 -0
- package/dist/cli/main-mg4f96e1.js +3 -0
- package/dist/cli/main-mg9b20ac.js +18 -0
- package/dist/cli/main-mgb9ccnx.js +3 -0
- package/dist/cli/main-mjt2p7aj.js +3 -0
- package/dist/cli/main-n6qrdbmy.js +3 -0
- package/dist/cli/main-na7wse0x.js +5 -0
- package/dist/cli/main-nqveez48.js +4 -0
- package/dist/cli/main-ntqef02r.js +10 -0
- package/dist/cli/main-nvc3yjay.js +136 -0
- package/dist/cli/main-p0cfn6nr.js +16 -0
- package/dist/cli/main-qj2djy17.js +19 -0
- package/dist/cli/main-qsevpgsv.js +3 -0
- package/dist/cli/main-qvarybsp.js +3 -0
- package/dist/cli/main-rebtt91r.js +5 -0
- package/dist/cli/main-rpg7h8mb.js +3 -0
- package/dist/cli/main-rsy72qmw.js +15 -0
- package/dist/cli/main-rvetps99.js +18 -0
- package/dist/cli/main-s4bb0jav.js +3 -0
- package/dist/cli/main-s9v8k74e.js +3 -0
- package/dist/cli/main-tjvwmscs.js +3 -0
- package/dist/cli/main-tkgarpjj.js +4 -0
- package/dist/cli/main-v8y60bb2.js +3 -0
- package/dist/cli/main-vhrrq337.js +3 -0
- package/dist/cli/main-vp2dfb7s.js +4 -0
- package/dist/cli/main-vqbr22sz.js +8 -0
- package/dist/cli/main-vxnwe5xx.js +18 -0
- package/dist/cli/main-wgph00xf.js +5 -0
- package/dist/cli/main-wk2csfnj.js +5 -0
- package/dist/cli/main-wm997zjx.js +3 -0
- package/dist/cli/main-wpkyraxh.js +3 -0
- package/dist/cli/main-wqt32p5x.js +4 -0
- package/dist/cli/main-x9ct6y1a.js +3 -0
- package/dist/cli/main-xfekqh9m.js +7 -0
- package/dist/cli/main-xt9zc3n6.js +7 -0
- package/dist/cli/main-xx2z3zh5.js +4 -0
- package/dist/cli/main-y5c82rxr.js +3 -0
- package/dist/cli/main-yrjt2sqt.js +14 -0
- package/dist/cli/main-ys6zj3yr.js +3 -0
- package/dist/cli/main-ywbxshqc.js +8 -0
- package/dist/cli/main-z13755t8.js +25 -0
- package/dist/cli/main-zc7pyrbj.js +4 -0
- package/dist/cli/main.js +279 -0
- package/dist/cli/market-cmd-bm5xvn9f.js +5 -0
- package/dist/cli/mcp-login-bthtfpt7.js +2 -0
- package/dist/cli/mcp-market-cmd-mbeshfyd.js +2 -0
- package/dist/cli/notify-54v5z9dz.js +2 -0
- package/dist/cli/oauth-g5gme95c.js +2 -0
- package/dist/cli/output-satndjap.js +16 -0
- package/dist/cli/profiles-sfhpbq3m.js +2 -0
- package/dist/cli/provider-config-hv3xtdt4.js +2 -0
- package/dist/cli/provider-kwzq6g84.js +2 -0
- package/dist/cli/registry-fh0hdnyn.js +2 -0
- package/dist/cli/registry-y1y8e94r.js +2 -0
- package/dist/cli/repl-t4z03mqq.js +11 -0
- package/dist/cli/resume-fqt4chg8.js +2 -0
- package/dist/cli/run-flags-rysbag9t.js +2 -0
- package/dist/cli/runtime-j19fjbsa.js +2 -0
- package/dist/cli/sandbox-config-g4qxd7y5.js +2 -0
- package/dist/cli/server-r0b6bksk.js +5 -0
- package/dist/cli/session-arg-txmn5g4x.js +2 -0
- package/dist/cli/session-ed250d9j.js +2 -0
- package/dist/cli/sessions-cmd-adw7svfn.js +7 -0
- package/dist/cli/settings-y9rzcqx8.js +2 -0
- package/dist/cli/setup-jmbr11j0.js +2 -0
- package/dist/cli/sextant-smoke-tcth0vea.js +5 -0
- package/dist/cli/skills-cmd-zbdy99v6.js +2 -0
- package/dist/cli/smoke-1bg937kx.js +8 -0
- package/dist/cli/start-chat-p01cdks3.js +12 -0
- package/dist/cli/stream-4wmyaypz.js +2 -0
- package/dist/cli/task-eg4s093s.js +2 -0
- package/dist/cli/tasks-12v9rr9k.js +2 -0
- package/dist/cli/thinking-a5ngvqyh.js +2 -0
- package/dist/cli/todo-1wxpcecx.js +2 -0
- package/dist/cli/tools-2ftsya7w.js +2 -0
- package/dist/cli/tools-x1tj4fxm.js +2 -0
- package/dist/cli/trust-cmd-hccxehzb.js +2 -0
- package/dist/cli/update-check-ygt3vd7m.js +2 -0
- package/dist/cli/update-cmd-v23qhr8c.js +2 -0
- package/dist/cli/voice-g1gtck92.js +2 -0
- package/dist/cli/webfetch-0nnrjgb5.js +2 -0
- package/dist/cli/websearch-f0vr2p7d.js +2 -0
- package/dist/cli/workspace-9rq1w4ta.js +2 -0
- package/dist/lib/index.js +62 -0
- package/dist/lib/models-index.json +1 -0
- package/dist/lib/plugins.js +6 -0
- package/dist/lib/providers.js +17 -0
- package/dist/lib/public-api.js +20 -0
- package/dist/rovecode.exe +4 -0
- package/package.json +38 -11
- 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/server/http.ts
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
/** Headless HTTP server (port #19): pattern-level port of opencode's client/server
|
|
2
|
-
* split (MIT, snapshot research/source_snapshots/opencode-2026).
|
|
3
|
-
*
|
|
4
|
-
* Patterns ported (citations against the snapshot):
|
|
5
|
-
* - client/server split: the TUI/CLI are HTTP clients of a headless server —
|
|
6
|
-
* packages/opencode/src/cli/cmd/serve.ts:6-24 (serve command → Server.listen),
|
|
7
|
-
* packages/sdk/js (client generated from the server's OpenAPI spec),
|
|
8
|
-
* packages/opencode/src/cli/cmd/tui.ts:11 (TUI imports @opencode-ai/sdk).
|
|
9
|
-
* - session surface: routes/instance/httpapi/groups/session.ts — root "/session"
|
|
10
|
-
* (:29), create POST (:203), prompt POST (:316), list GET (:111).
|
|
11
|
-
* - GET /doc serving the OpenAPI JSON: routes/instance/httpapi/server.ts:190
|
|
12
|
-
* (docRoute) + :188 (lazy spec build). We hand-author the object (openapi.ts).
|
|
13
|
-
* - SSE event streaming: routes/instance/httpapi/handlers/event.ts:69-85
|
|
14
|
-
* (text/event-stream response, no-cache headers).
|
|
15
|
-
* - loopback bind by default: cli/network.ts:12-15 (hostname default "127.0.0.1").
|
|
16
|
-
*
|
|
17
|
-
* NOT ported: opencode's implementation is Effect-based (server.ts imports
|
|
18
|
-
* effect / @effect/platform-node / effect/unstable/httpapi). ADR-001 rejects
|
|
19
|
-
* Effect idioms — this file is plain Bun.serve + the ONE agentLoop (ADR-003)
|
|
20
|
-
* reused via createRuntime. v1 approvals are policy-only: no interactive
|
|
21
|
-
* approver over HTTP; a permission rule with effect "prompt" fails the tool
|
|
22
|
-
* call at the registry seam (core/tools.ts:87-93). See APPROVALS_NOTE in /doc.
|
|
23
|
-
*
|
|
24
|
-
* Never-throw seam: route handlers are wrapped — an exception becomes a JSON
|
|
25
|
-
* 500; a mid-stream loop error becomes a final run_end error frame, never a
|
|
26
|
-
* socket reset or a crashed server. */
|
|
27
|
-
|
|
28
|
-
import { randomUUID } from "node:crypto";
|
|
29
|
-
import { join } from "node:path";
|
|
30
|
-
import { bootRuntime, type Runtime } from "../cli/runtime.ts";
|
|
31
|
-
import { noModelHint } from "../core/voice.ts";
|
|
32
|
-
import { SandboxConfigError } from "../core/sandbox-config.ts";
|
|
33
|
-
import { agentLoop, SteeringQueue } from "../core/loop.ts";
|
|
34
|
-
import { listSessions } from "../core/session.ts";
|
|
35
|
-
import type { ModelRef, RunEvent, StreamFn } from "../core/types.ts";
|
|
36
|
-
import { buildOpenApiDoc } from "./openapi.ts";
|
|
37
|
-
|
|
38
|
-
export const DEFAULT_PORT = 4100;
|
|
39
|
-
export const DEFAULT_HOSTNAME = "127.0.0.1";
|
|
40
|
-
/** request-body bound: prompt bodies over this fail with a clean JSON 413
|
|
41
|
-
* (checked against content-length before the body is read). Bun.serve's
|
|
42
|
-
* maxRequestBodySize is set to 2× this as a transport ceiling for clients
|
|
43
|
-
* that lie about / omit content-length (chunked): those are cut at the
|
|
44
|
-
* socket instead of ballooning RSS. */
|
|
45
|
-
export const MAX_BODY_BYTES = 1024 * 1024;
|
|
46
|
-
|
|
47
|
-
export interface ServerOptions {
|
|
48
|
-
/** TCP port; default 4100; 0 = ephemeral (tests) */
|
|
49
|
-
port?: number;
|
|
50
|
-
/** bind address; default 127.0.0.1 (loopback-only, opencode cli/network.ts:15) */
|
|
51
|
-
hostname?: string;
|
|
52
|
-
/** project root; sessions live in <cwd>/.rovecode/sessions */
|
|
53
|
-
cwd?: string;
|
|
54
|
-
/** injectable provider stream (tests); undefined = resolve from env; null = no stream */
|
|
55
|
-
stream?: StreamFn | null;
|
|
56
|
-
/** allow-all permission rules; default false = policy rules with prompt-effect
|
|
57
|
-
* gates, which FAIL over HTTP (no approver) — see APPROVALS_NOTE */
|
|
58
|
-
yolo?: boolean;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface RovecodeServer {
|
|
62
|
-
port: number;
|
|
63
|
-
hostname: string;
|
|
64
|
-
url: string;
|
|
65
|
-
/** closes the listener and in-flight SSE sockets, aborts every in-flight
|
|
66
|
-
* run's controller (port #21: the in-flight provider fetch and tool
|
|
67
|
-
* subprocesses die mid-turn), then closes every session runtime's MCP
|
|
68
|
-
* children. Returns without awaiting the aborted generators' final settle. */
|
|
69
|
-
stop(): Promise<void>;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
interface SessionEntry {
|
|
73
|
-
runtime: Runtime;
|
|
74
|
-
running: boolean;
|
|
75
|
-
/** the in-flight run's controller (port #21) — DELETE /session/:id/prompt and
|
|
76
|
-
* stop() abort it; null when idle. Cleared by the pump's settle, like `running`. */
|
|
77
|
-
abort: AbortController | null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function json(body: unknown, status = 200): Response {
|
|
81
|
-
return new Response(JSON.stringify(body), {
|
|
82
|
-
status,
|
|
83
|
-
headers: { "content-type": "application/json" },
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** SSE framing (bar): `event: <type>\ndata: <json>\n\n`. */
|
|
88
|
-
function frame(ev: RunEvent): string {
|
|
89
|
-
return `event: ${ev.type}\ndata: ${JSON.stringify(ev)}\n\n`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Pump loop events into an SSE response; the stream closes on run_end.
|
|
93
|
-
* Client disconnects abort the run's controller (port #21): the in-flight
|
|
94
|
-
* provider fetch dies and tool subprocesses are killed mid-turn, then the
|
|
95
|
-
* generator settles at its next suspension point. `running` is cleared ONLY
|
|
96
|
-
* from the pump's finally — when the generator has actually released the
|
|
97
|
-
* session — so the 409 one-run-per-session invariant holds across
|
|
98
|
-
* disconnects (MED-F1). */
|
|
99
|
-
function sseResponse(run: AsyncGenerator<RunEvent>, onSettled: () => void, abort: () => void): Response {
|
|
100
|
-
const enc = new TextEncoder();
|
|
101
|
-
let settled = false;
|
|
102
|
-
const settle = () => { if (!settled) { settled = true; onSettled(); } };
|
|
103
|
-
const stream = new ReadableStream<Uint8Array>({
|
|
104
|
-
async start(controller) {
|
|
105
|
-
try {
|
|
106
|
-
for await (const ev of run) {
|
|
107
|
-
controller.enqueue(enc.encode(frame(ev)));
|
|
108
|
-
if (ev.type === "run_end") break; // bar: stream closes on run_end
|
|
109
|
-
}
|
|
110
|
-
} catch (e) {
|
|
111
|
-
// never-throw seam: a loop/enqueue error becomes a terminal error frame
|
|
112
|
-
const end: RunEvent = { type: "run_end", status: "error", summary: e instanceof Error ? e.message : String(e) };
|
|
113
|
-
try { controller.enqueue(enc.encode(frame(end))); } catch { /* consumer gone */ }
|
|
114
|
-
} finally {
|
|
115
|
-
settle();
|
|
116
|
-
try { controller.close(); } catch { /* cancelled/closed already */ }
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
cancel() {
|
|
120
|
-
// client hung up mid-run: abort the run's controller (kills the in-flight
|
|
121
|
-
// fetch / tool subprocesses — port #21), then close the generator as the
|
|
122
|
-
// follow-through. Do NOT settle here: the pump's finally settles
|
|
123
|
-
// truthfully once the generator finishes; an eager settle let a second
|
|
124
|
-
// run share this session's store (MED-F1).
|
|
125
|
-
abort();
|
|
126
|
-
void Promise.resolve(run.return(undefined)).catch(() => {});
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
return new Response(stream, {
|
|
130
|
-
status: 200,
|
|
131
|
-
headers: {
|
|
132
|
-
// headers per opencode handlers/event.ts:78-83
|
|
133
|
-
"content-type": "text/event-stream",
|
|
134
|
-
"cache-control": "no-cache, no-transform",
|
|
135
|
-
"x-accel-buffering": "no",
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function bodyText(body: unknown): string | null {
|
|
141
|
-
if (body && typeof body === "object" && typeof (body as { text?: unknown }).text === "string") {
|
|
142
|
-
return (body as { text: string }).text;
|
|
143
|
-
}
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function bodyModel(body: unknown): ModelRef | null {
|
|
148
|
-
if (body && typeof body === "object" && (body as { model?: unknown }).model && typeof (body as { model?: unknown }).model === "object") {
|
|
149
|
-
const m = (body as { model: { provider?: unknown; model?: unknown } }).model;
|
|
150
|
-
if (typeof m.provider === "string" && typeof m.model === "string") return { provider: m.provider, model: m.model };
|
|
151
|
-
}
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function startServer(opts: ServerOptions = {}): RovecodeServer {
|
|
156
|
-
const hostname = opts.hostname ?? DEFAULT_HOSTNAME;
|
|
157
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
158
|
-
const sessionsRoot = join(cwd, ".rovecode", "sessions");
|
|
159
|
-
const yolo = opts.yolo ?? false;
|
|
160
|
-
const sessions = new Map<string, SessionEntry>();
|
|
161
|
-
|
|
162
|
-
const createSession = async (): Promise<Response> => {
|
|
163
|
-
const id = randomUUID();
|
|
164
|
-
// Reuse the ONE runtime construction every surface uses (cli/runtime.ts):
|
|
165
|
-
// same stores, same tools, same provider resolution. Injectable stream for tests.
|
|
166
|
-
let runtime: Runtime;
|
|
167
|
-
try {
|
|
168
|
-
runtime = await bootRuntime({ cwd, sessionId: id, stream: opts.stream });
|
|
169
|
-
} catch (e) {
|
|
170
|
-
// port #27: sandbox misconfig / unavailable configured rung → 503 with the
|
|
171
|
-
// one-line message (the server cwd cannot provide the requested executor)
|
|
172
|
-
if (e instanceof SandboxConfigError) return json({ error: e.message }, 503);
|
|
173
|
-
throw e; // never-throw seam below turns anything else into a JSON 500
|
|
174
|
-
}
|
|
175
|
-
sessions.set(id, { runtime, running: false, abort: null });
|
|
176
|
-
return json({ id }, 201);
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const prompt = async (id: string, req: Request): Promise<Response> => {
|
|
180
|
-
const entry = sessions.get(id);
|
|
181
|
-
if (!entry) return json({ error: `unknown session ${id}` }, 404);
|
|
182
|
-
// LOW-MED-F4: bound the request body BEFORE reading it (declared size), and
|
|
183
|
-
// the parsed text after — an unbounded body was a local RSS balloon.
|
|
184
|
-
const declared = Number(req.headers.get("content-length") ?? "0");
|
|
185
|
-
if (declared > MAX_BODY_BYTES) return json({ error: `request body too large (max ${MAX_BODY_BYTES} bytes)` }, 413);
|
|
186
|
-
let body: unknown;
|
|
187
|
-
try { body = await req.json(); } catch { return json({ error: "body must be JSON" }, 400); }
|
|
188
|
-
const text = bodyText(body);
|
|
189
|
-
if (text === null) return json({ error: 'body must be {"text": string}' }, 400);
|
|
190
|
-
if (text.length > MAX_BODY_BYTES) return json({ error: `text too large (max ${MAX_BODY_BYTES} chars)` }, 413);
|
|
191
|
-
if (entry.running) return json({ error: "a run is already in progress for this session" }, 409);
|
|
192
|
-
const rt = entry.runtime;
|
|
193
|
-
const stream = rt.stream;
|
|
194
|
-
// live: a provider added after boot (rovecode provider add / auth set) serves the next request
|
|
195
|
-
const noProvider = rt.noProviderReason();
|
|
196
|
-
if (!stream || noProvider !== null) return json({ error: noProvider ?? noModelHint("cli") }, 503);
|
|
197
|
-
const model: ModelRef = bodyModel(body) ?? { provider: rt.provider?.id ?? "mock", model: rt.defaultModel || "default" };
|
|
198
|
-
const def = rt.buildDef(model);
|
|
199
|
-
// no interactive ApprovalFn — buildCfg installs the port-#9 exec-policy wrapper:
|
|
200
|
-
// allow-listed argv auto-runs, forbidden is denied, prompt-classified fails closed
|
|
201
|
-
// as tool_call_failed/permission_denied (core/tools.ts:87-93)
|
|
202
|
-
const cfg = rt.buildCfg(yolo, undefined);
|
|
203
|
-
const ac = new AbortController(); // port #21: one controller per run
|
|
204
|
-
rt.tasks.bindRun(ac.signal); // port #26: DELETE / disconnect / stop() also cancel the run's background tasks
|
|
205
|
-
const run = agentLoop(def, text, {}, cfg, {
|
|
206
|
-
stream, registry: rt.registry, store: rt.store,
|
|
207
|
-
tools: rt.registry.list().map((t) => t.schema), guard: rt.guard, planReminder: rt.planReminder,
|
|
208
|
-
hooks: rt.hooks, // port #29: .rovecode/hooks.{ts,js} of the server cwd
|
|
209
|
-
cwd: rt.cwd, // session cwd reaches ToolContext (same gap as ACP HIGH-G1)
|
|
210
|
-
signal: ac.signal, // port #21: DELETE / disconnect / stop() kill in-flight work
|
|
211
|
-
}, rt.steering); // port #26: the session's queue — background-task notes land on the next prompt
|
|
212
|
-
entry.running = true;
|
|
213
|
-
entry.abort = ac;
|
|
214
|
-
return sseResponse(run, () => { entry.running = false; entry.abort = null; }, () => ac.abort());
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
/** DELETE /session/:id/prompt — cancel the in-flight run (port #21). Aborting
|
|
218
|
-
* the controller kills the provider fetch / tool subprocesses; the run's own
|
|
219
|
-
* SSE stream then ends with run_end status "stopped". `running` still clears
|
|
220
|
-
* only from the pump's settle, so the 409 invariant is untouched: the session
|
|
221
|
-
* frees when the generator has actually released it. opencode exposes the
|
|
222
|
-
* same operation as POST /session/:sessionID/abort → SessionPrompt.cancel
|
|
223
|
-
* (routes/instance/httpapi/groups/session.ts:91,253; handlers/session.ts:232). */
|
|
224
|
-
const cancelPrompt = (id: string): Response => {
|
|
225
|
-
const entry = sessions.get(id);
|
|
226
|
-
if (!entry) return json({ error: `unknown session ${id}` }, 404);
|
|
227
|
-
const live = entry.abort !== null;
|
|
228
|
-
entry.abort?.abort();
|
|
229
|
-
return json({ cancelled: live });
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
/** GET /session/:id/tasks — background-task status (port #26): the session runtime's
|
|
233
|
-
* TaskManager snapshot (TaskInfo[], oldest first). opencode exposes the same registry
|
|
234
|
-
* through its job service (packages/core/src/background-job.ts list/get). */
|
|
235
|
-
const listTasks = (id: string): Response => {
|
|
236
|
-
const entry = sessions.get(id);
|
|
237
|
-
if (!entry) return json({ error: `unknown session ${id}` }, 404);
|
|
238
|
-
return json(entry.runtime.tasks.list());
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
const route = async (req: Request): Promise<Response> => {
|
|
242
|
-
const path = new URL(req.url).pathname;
|
|
243
|
-
if (req.method === "POST" && path === "/session") return createSession();
|
|
244
|
-
const m = /^\/session\/([^/]+)\/prompt$/.exec(path);
|
|
245
|
-
if (req.method === "POST" && m) return prompt(m[1]!, req);
|
|
246
|
-
if (req.method === "DELETE" && m) return cancelPrompt(m[1]!);
|
|
247
|
-
const t = /^\/session\/([^/]+)\/tasks$/.exec(path);
|
|
248
|
-
if (req.method === "GET" && t) return listTasks(t[1]!);
|
|
249
|
-
if (req.method === "GET" && path === "/sessions") return json(listSessions(sessionsRoot));
|
|
250
|
-
if (req.method === "GET" && path === "/doc") return json(buildOpenApiDoc(api.url));
|
|
251
|
-
return json({ error: `no route for ${req.method} ${path}` }, 404);
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
const server = Bun.serve({
|
|
255
|
-
hostname,
|
|
256
|
-
port: opts.port ?? DEFAULT_PORT,
|
|
257
|
-
idleTimeout: 0, // SSE runs outlive Bun's default idle timeout
|
|
258
|
-
// transport ceiling (LOW-MED-F4): bodies without/with a lying content-length
|
|
259
|
-
// are cut here (socket close); declared oversizes get a clean 413 in prompt()
|
|
260
|
-
maxRequestBodySize: MAX_BODY_BYTES * 2,
|
|
261
|
-
async fetch(req) {
|
|
262
|
-
// never-throw seam: handler exceptions become JSON 500s, the server survives
|
|
263
|
-
try { return await route(req); }
|
|
264
|
-
catch (e) { return json({ error: e instanceof Error ? e.message : String(e) }, 500); }
|
|
265
|
-
},
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
const api: RovecodeServer = {
|
|
269
|
-
port: server.port ?? 0,
|
|
270
|
-
hostname,
|
|
271
|
-
url: `http://${hostname}:${server.port}`,
|
|
272
|
-
async stop() {
|
|
273
|
-
await server.stop(true);
|
|
274
|
-
// port #21: abort every in-flight run — the provider fetch and tool
|
|
275
|
-
// subprocesses die now instead of running on after the sockets closed.
|
|
276
|
-
for (const entry of sessions.values()) entry.abort?.abort();
|
|
277
|
-
for (const { runtime } of sessions.values()) runtime.tasks.cancelAll(); // port #26: background children die with the server, never after it
|
|
278
|
-
// MED-F3: reap MCP children — every POST /session spawns one set via
|
|
279
|
-
// createRuntime; without this an unauthenticated loopback port is an
|
|
280
|
-
// unbounded local spawn primitive that outlives the server.
|
|
281
|
-
const closing: Promise<unknown>[] = [];
|
|
282
|
-
for (const { runtime } of sessions.values()) {
|
|
283
|
-
runtime.bashJobs.dispose(); // #55: background shell jobs die with their session
|
|
284
|
-
closing.push(runtime.hooks.close()); // port #29: session_close per session runtime
|
|
285
|
-
if (runtime.mcp) closing.push(runtime.mcp.close().catch(() => {}));
|
|
286
|
-
}
|
|
287
|
-
await Promise.all(closing);
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
|
-
return api;
|
|
291
|
-
}
|
package/src/server/openapi.ts
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/** Hand-authored OpenAPI 3.1 document for the rovecode server surface (port #19).
|
|
2
|
-
* opencode serves its spec at GET /doc — packages/opencode/src/server/routes/
|
|
3
|
-
* instance/httpapi/server.ts:190 (route) + :188 (lazy OpenApi.fromApi(PublicApi))
|
|
4
|
-
* — and generates its client SDK from that spec (packages/sdk/js, @hey-api/openapi-ts).
|
|
5
|
-
* Their spec is derived from Effect httpapi endpoint schemas; ADR-001 rejects Effect
|
|
6
|
-
* idioms, and this surface is five routes, so the object is written by hand — no
|
|
7
|
-
* codegen dependency, the doc IS the source of truth for what the server exposes. */
|
|
8
|
-
|
|
9
|
-
/** Honesty note (bar requirement): served verbatim in the doc so HTTP clients know
|
|
10
|
-
* interactive approvals do not exist in v1. */
|
|
11
|
-
export const APPROVALS_NOTE =
|
|
12
|
-
"v1 approvals are policy-only: the server runs with rule-based permissions and has no " +
|
|
13
|
-
"interactive approver over HTTP. A tool call whose permission rule resolves to effect " +
|
|
14
|
-
"\"prompt\" is NOT paused for approval — it surfaces as a failed tool call " +
|
|
15
|
-
"(tool_call_failed, reason permission_denied, \"approval required but no approver " +
|
|
16
|
-
"connected\") and the run continues. Start the server with --yolo (allow-all rules) " +
|
|
17
|
-
"or provide allow rules to let gated tools run.";
|
|
18
|
-
|
|
19
|
-
/** RunEvent discriminator values (src/core/types.ts RunEvent union). Hand-listed:
|
|
20
|
-
* types are erased at runtime, and the doc is hand-authored by design. */
|
|
21
|
-
export const RUN_EVENT_TYPES = [
|
|
22
|
-
"run_start", "turn_start", "message_update", "reasoning_update",
|
|
23
|
-
"tool_execution_start", "tool_execution_update", "tool_execution_end",
|
|
24
|
-
"tool_call_failed", "compaction", "turn_end", "steer", "run_end",
|
|
25
|
-
] as const;
|
|
26
|
-
|
|
27
|
-
const errorResponse = (description: string) => ({
|
|
28
|
-
description,
|
|
29
|
-
content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } },
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
/** Build the OpenAPI 3.1 object. `serverUrl` is the actually-bound base URL. */
|
|
33
|
-
export function buildOpenApiDoc(serverUrl: string): Record<string, unknown> {
|
|
34
|
-
return {
|
|
35
|
-
openapi: "3.1.0",
|
|
36
|
-
info: {
|
|
37
|
-
title: "rovecode server",
|
|
38
|
-
version: "0.1.0",
|
|
39
|
-
description:
|
|
40
|
-
"Headless HTTP surface over the one rovecode agent loop (ADR-003). " +
|
|
41
|
-
"Five routes: create a session, prompt it (SSE stream of typed run events; " +
|
|
42
|
-
"DELETE the same path cancels the in-flight run mid-turn), " +
|
|
43
|
-
"list its background tasks, list sessions, and this document. " + APPROVALS_NOTE,
|
|
44
|
-
},
|
|
45
|
-
servers: [{ url: serverUrl }],
|
|
46
|
-
paths: {
|
|
47
|
-
"/session": {
|
|
48
|
-
post: {
|
|
49
|
-
operationId: "session.create",
|
|
50
|
-
summary: "Create a new session",
|
|
51
|
-
description: "Creates a session backed by the append-only JSONL session store and returns its id.",
|
|
52
|
-
responses: {
|
|
53
|
-
"201": {
|
|
54
|
-
description: "Session created",
|
|
55
|
-
content: {
|
|
56
|
-
"application/json": {
|
|
57
|
-
schema: {
|
|
58
|
-
type: "object",
|
|
59
|
-
required: ["id"],
|
|
60
|
-
properties: { id: { type: "string", description: "Session id (also the session directory name)" } },
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
"/session/{id}/prompt": {
|
|
69
|
-
post: {
|
|
70
|
-
operationId: "session.prompt",
|
|
71
|
-
summary: "Run the agent loop on a session and stream its events",
|
|
72
|
-
description:
|
|
73
|
-
"Runs one agent loop over the session with the given text as the goal. " +
|
|
74
|
-
"The response is a Server-Sent Events stream: each event is framed as " +
|
|
75
|
-
"`event: <RunEvent.type>` + `data: <RunEvent JSON>`, and the stream closes " +
|
|
76
|
-
"after the terminal run_end event. " + APPROVALS_NOTE,
|
|
77
|
-
parameters: [
|
|
78
|
-
{ name: "id", in: "path", required: true, schema: { type: "string" }, description: "Session id from POST /session" },
|
|
79
|
-
],
|
|
80
|
-
requestBody: {
|
|
81
|
-
required: true,
|
|
82
|
-
content: {
|
|
83
|
-
"application/json": {
|
|
84
|
-
schema: {
|
|
85
|
-
type: "object",
|
|
86
|
-
required: ["text"],
|
|
87
|
-
properties: {
|
|
88
|
-
text: { type: "string", description: "The user goal for this run" },
|
|
89
|
-
model: {
|
|
90
|
-
type: "object",
|
|
91
|
-
description: "Optional model override; defaults to the server's resolved provider/model",
|
|
92
|
-
required: ["provider", "model"],
|
|
93
|
-
properties: { provider: { type: "string" }, model: { type: "string" } },
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
responses: {
|
|
101
|
-
"200": {
|
|
102
|
-
description: "SSE stream of RunEvent frames; closes after run_end",
|
|
103
|
-
content: { "text/event-stream": { schema: { $ref: "#/components/schemas/RunEvent" } } },
|
|
104
|
-
},
|
|
105
|
-
"400": errorResponse("Body is not JSON or lacks a string `text`"),
|
|
106
|
-
"404": errorResponse("Unknown session id"),
|
|
107
|
-
"409": errorResponse("A run is already in progress for this session"),
|
|
108
|
-
"503": errorResponse("No provider configured — run `rovecode setup` (or rovecode provider add + rovecode auth set, or set ROVECODE_BASE_URL/ROVECODE_API_KEY)"),
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
delete: {
|
|
112
|
-
operationId: "session.cancel",
|
|
113
|
-
summary: "Cancel the in-flight run on a session",
|
|
114
|
-
description:
|
|
115
|
-
"Aborts the running prompt's AbortController: the in-flight provider fetch and " +
|
|
116
|
-
"tool subprocesses are killed mid-turn, and the run's SSE stream ends with a " +
|
|
117
|
-
"run_end event of status \"stopped\". The session stays busy (409 on new prompts) " +
|
|
118
|
-
"until that stream has actually settled. Idempotent: cancelling an idle session " +
|
|
119
|
-
"returns cancelled: false.",
|
|
120
|
-
parameters: [
|
|
121
|
-
{ name: "id", in: "path", required: true, schema: { type: "string" }, description: "Session id from POST /session" },
|
|
122
|
-
],
|
|
123
|
-
responses: {
|
|
124
|
-
"200": {
|
|
125
|
-
description: "Cancellation signalled (cancelled: true) or nothing was running (cancelled: false)",
|
|
126
|
-
content: {
|
|
127
|
-
"application/json": {
|
|
128
|
-
schema: {
|
|
129
|
-
type: "object",
|
|
130
|
-
required: ["cancelled"],
|
|
131
|
-
properties: { cancelled: { type: "boolean" } },
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
"404": errorResponse("Unknown session id"),
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
"/session/{id}/tasks": {
|
|
141
|
-
get: {
|
|
142
|
-
operationId: "session.tasks",
|
|
143
|
-
summary: "List the session's background subagent tasks",
|
|
144
|
-
description:
|
|
145
|
-
"Snapshot of the session's background tasks (port #26): child agent sessions started by " +
|
|
146
|
-
"the `task` tool, oldest first, with status queued|running|done|failed|cancelled, timing, " +
|
|
147
|
-
"the child's final text (done) or error (failed). Tasks are process-local and not durable " +
|
|
148
|
-
"across server restarts. Completion notes reach the model as steering on the session's next prompt.",
|
|
149
|
-
parameters: [
|
|
150
|
-
{ name: "id", in: "path", required: true, schema: { type: "string" }, description: "Session id from POST /session" },
|
|
151
|
-
],
|
|
152
|
-
responses: {
|
|
153
|
-
"200": {
|
|
154
|
-
description: "Task snapshots",
|
|
155
|
-
content: {
|
|
156
|
-
"application/json": {
|
|
157
|
-
schema: { type: "array", items: { $ref: "#/components/schemas/TaskInfo" } },
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
"404": errorResponse("Unknown session id"),
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
"/sessions": {
|
|
166
|
-
get: {
|
|
167
|
-
operationId: "session.list",
|
|
168
|
-
summary: "List sessions",
|
|
169
|
-
description: "Scans the session root and returns summaries, sorted by updatedAt descending. Corrupt or foreign directories are skipped, never errors.",
|
|
170
|
-
responses: {
|
|
171
|
-
"200": {
|
|
172
|
-
description: "Session summaries",
|
|
173
|
-
content: {
|
|
174
|
-
"application/json": {
|
|
175
|
-
schema: { type: "array", items: { $ref: "#/components/schemas/SessionSummary" } },
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
"/doc": {
|
|
183
|
-
get: {
|
|
184
|
-
operationId: "doc",
|
|
185
|
-
summary: "This OpenAPI 3.1 document",
|
|
186
|
-
description: "Returns the OpenAPI 3.1 JSON describing exactly this server surface.",
|
|
187
|
-
responses: {
|
|
188
|
-
"200": { description: "OpenAPI 3.1 document", content: { "application/json": { schema: { type: "object" } } } },
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
components: {
|
|
194
|
-
schemas: {
|
|
195
|
-
Error: {
|
|
196
|
-
type: "object",
|
|
197
|
-
required: ["error"],
|
|
198
|
-
properties: { error: { type: "string" } },
|
|
199
|
-
},
|
|
200
|
-
SessionSummary: {
|
|
201
|
-
type: "object",
|
|
202
|
-
required: ["id", "createdAt", "updatedAt", "entryCount", "preview"],
|
|
203
|
-
properties: {
|
|
204
|
-
id: { type: "string" },
|
|
205
|
-
createdAt: { type: "number" },
|
|
206
|
-
updatedAt: { type: "number" },
|
|
207
|
-
entryCount: { type: "number" },
|
|
208
|
-
preview: { type: "string", description: "First user-message text, single line, ≤80 chars" },
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
RunEvent: {
|
|
212
|
-
type: "object",
|
|
213
|
-
description:
|
|
214
|
-
"Typed agent-loop event (src/core/types.ts RunEvent union), discriminated by `type`. " +
|
|
215
|
-
"The SSE `event:` field always equals this `type` field.",
|
|
216
|
-
required: ["type"],
|
|
217
|
-
properties: {
|
|
218
|
-
type: { type: "string", enum: [...RUN_EVENT_TYPES] },
|
|
219
|
-
},
|
|
220
|
-
additionalProperties: true,
|
|
221
|
-
},
|
|
222
|
-
TaskInfo: {
|
|
223
|
-
type: "object",
|
|
224
|
-
description: "Background subagent task snapshot (src/core/tasks.ts TaskInfo).",
|
|
225
|
-
required: ["id", "label", "agent", "goal", "isolated", "depth", "status", "createdAt"],
|
|
226
|
-
properties: {
|
|
227
|
-
id: { type: "string", description: "Task id (t1, t2, …; scoped to the session)" },
|
|
228
|
-
label: { type: "string" },
|
|
229
|
-
agent: { type: "string", description: "Agent definition the child runs" },
|
|
230
|
-
goal: { type: "string", description: "Bounded preview of the child's goal (≤200 chars)" },
|
|
231
|
-
isolated: { type: "boolean", description: "Ran in a worktree copy; file changes merge back as a patch on success" },
|
|
232
|
-
depth: { type: "number", description: "Child depth (root-started tasks run at 1)" },
|
|
233
|
-
status: { type: "string", enum: ["queued", "running", "done", "failed", "cancelled"] },
|
|
234
|
-
createdAt: { type: "number" },
|
|
235
|
-
startedAt: { type: "number" },
|
|
236
|
-
finishedAt: { type: "number" },
|
|
237
|
-
summary: { type: "string", description: "The child's final text (status done), ≤4000 chars" },
|
|
238
|
-
error: { type: "string", description: "Failure reason (status failed) or \"cancelled\"" },
|
|
239
|
-
usage: { type: "object", properties: { input: { type: "number" }, output: { type: "number" } } },
|
|
240
|
-
patchLines: { type: "number", description: "Isolated children: line count of the merged-back patch" },
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
};
|
|
246
|
-
}
|
package/src/sextant/card-hits.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/** Click zones for the modal card (approval verdicts, question options, free text, skip).
|
|
2
|
-
*
|
|
3
|
-
* Why this exists: the card is the single most frequent interaction in the surface — every gated
|
|
4
|
-
* edit, every shell command, every ask_user question goes through it — and until now it answered
|
|
5
|
-
* only to the arrow keys. Clicking `allow` did nothing at all: keys.ts's onMouse walks the hit zones
|
|
6
|
-
* the drawers registered that frame, and nobody registered any for the card, so the click fell
|
|
7
|
-
* through to the "focus the panel under the pointer" fallback. That is the complaint "most things do
|
|
8
|
-
* not respond to clicks, it only works with the arrow keys", in its most-used place.
|
|
9
|
-
*
|
|
10
|
-
* Geometry, not painting: draw-messages.ts owns how the card looks, this file owns where its targets
|
|
11
|
-
* landed. The two are kept honest by deriving everything from the SAME exported helpers the painter
|
|
12
|
-
* uses (areas, cardShape, cardRows) rather than re-deriving row counts — a second copy of the layout
|
|
13
|
-
* arithmetic would drift the moment the card grew a row.
|
|
14
|
-
*
|
|
15
|
-
* Two subtleties the card forces:
|
|
16
|
-
* - The card is CLIPPED from the top when it does not fit (draw-messages keeps the tail so the
|
|
17
|
-
* buttons stay reachable), so a row's screen y is its index minus the hidden count, and a target
|
|
18
|
-
* scrolled off the top has no zone at all rather than a wrong one.
|
|
19
|
-
* - The approval verdicts share ONE row, laid out horizontally, so they need x ranges; the question
|
|
20
|
-
* card gives every option its own row.
|
|
21
|
-
*
|
|
22
|
-
* `confirm` is false for exactly one target, the free-text row: clicking it means "I want to type
|
|
23
|
-
* here", not "submit an empty answer". Every other target is a labelled button, and a click on a
|
|
24
|
-
* button is the decision — the same as clicking OK in any dialog. */
|
|
25
|
-
|
|
26
|
-
import { areas, cardRows, cardShape, questionRows, SKIP_LABEL, VERDICT_LABEL } from "./draw-messages.ts";
|
|
27
|
-
import { inner } from "./draw-util.ts";
|
|
28
|
-
import { strWidth } from "./screen.ts";
|
|
29
|
-
import type { Rect, SextantState, Theme } from "./types.ts";
|
|
30
|
-
|
|
31
|
-
export interface CardHit {
|
|
32
|
-
rect: Rect;
|
|
33
|
-
/** the value card.selected takes when this target is clicked */
|
|
34
|
-
index: number;
|
|
35
|
-
/** replay Enter after selecting (a button); false leaves the caret on the row (free text) */
|
|
36
|
-
confirm: boolean;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** button() in draw-messages renders a label as ` label `, and the verdict row separates them by two
|
|
40
|
-
* spaces at indent 2. */
|
|
41
|
-
const BUTTON_PAD = 2;
|
|
42
|
-
const BUTTON_GAP = 2;
|
|
43
|
-
const ROW_INDENT = 2;
|
|
44
|
-
|
|
45
|
-
/** The card's clickable targets in screen coordinates, or [] when no card is open, the panel is too
|
|
46
|
-
* small to draw one, or every target is clipped away. `rect` is the messages panel, as passed to
|
|
47
|
-
* drawMessages. */
|
|
48
|
-
export function cardHits(rect: Rect, s: SextantState, theme: Theme): CardHit[] {
|
|
49
|
-
const card = s.card;
|
|
50
|
-
if (card === null || card === undefined) return [];
|
|
51
|
-
if (rect.w < 4 || rect.h < 3) return []; // drawMessages paints nothing at all below this
|
|
52
|
-
const B = inner(rect);
|
|
53
|
-
const { cardH, msgH, maxDetail } = areas(B, s);
|
|
54
|
-
if (cardH <= 0) return [];
|
|
55
|
-
|
|
56
|
-
const all = cardRows(card, B.w, maxDetail, theme);
|
|
57
|
-
// when the card is taller than its slot the painter keeps the TAIL: rows [hidden..] are on screen
|
|
58
|
-
const hidden = all.length - cardH;
|
|
59
|
-
const yOf = (i: number): number | null => {
|
|
60
|
-
const v = i - hidden;
|
|
61
|
-
return v < 0 || v >= cardH ? null : B.y + msgH + v;
|
|
62
|
-
};
|
|
63
|
-
const out: CardHit[] = [];
|
|
64
|
-
|
|
65
|
-
if (card.kind === "approval") {
|
|
66
|
-
// the verdicts are the last row, so they survive clipping — that is why the painter keeps the tail
|
|
67
|
-
const y = yOf(all.length - 1);
|
|
68
|
-
if (y === null) return [];
|
|
69
|
-
let x = B.x + ROW_INDENT;
|
|
70
|
-
for (const [i, v] of card.verdicts.entries()) {
|
|
71
|
-
const w = strWidth(VERDICT_LABEL[v] ?? String(v)) + BUTTON_PAD;
|
|
72
|
-
if (x + w > B.x + B.w) break; // a verdict pushed past the right edge was never drawn
|
|
73
|
-
out.push({ rect: { x, y, w, h: 1 }, index: i, confirm: true });
|
|
74
|
-
x += w + BUTTON_GAP;
|
|
75
|
-
}
|
|
76
|
-
return out;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// question card: blank, q question rows, one row per option, [free text, wrapped], skip, hint.
|
|
80
|
-
// The row arithmetic comes from questionRows — the same helper the painter and the caret use — so
|
|
81
|
-
// the three cannot disagree; cardShape is still consulted for the clip.
|
|
82
|
-
const opts = card.prompt.options ?? [];
|
|
83
|
-
const { q, freeRows } = questionRows(card, B.w);
|
|
84
|
-
const shape = cardShape(card, B.w, maxDetail);
|
|
85
|
-
if (shape.total !== 1 + q + opts.length + freeRows + 2) return []; // the painter and the helper disagree: register nothing rather than wrong zones
|
|
86
|
-
const push = (rowIndex: number, index: number, w: number, confirm: boolean, h = 1): void => {
|
|
87
|
-
const y = yOf(rowIndex);
|
|
88
|
-
if (y !== null && w > 0) out.push({ rect: { x: B.x + ROW_INDENT, y, w, h }, index, confirm });
|
|
89
|
-
};
|
|
90
|
-
const full = Math.max(0, B.w - ROW_INDENT);
|
|
91
|
-
for (const [i, o] of opts.entries()) push(1 + q + i, i, Math.min(strWidth(o) + BUTTON_PAD, full), true);
|
|
92
|
-
// the free-text field is one zone across all its wrapped rows: select it, do not answer for the human.
|
|
93
|
-
// Rows clipped off the top shrink the zone from above (the first visible row is where it starts).
|
|
94
|
-
if (freeRows > 0) {
|
|
95
|
-
const first = 1 + q + opts.length;
|
|
96
|
-
const visibleFrom = Math.max(first, hidden);
|
|
97
|
-
const rows = first + freeRows - visibleFrom;
|
|
98
|
-
if (rows > 0) push(visibleFrom, opts.length, full, false, rows);
|
|
99
|
-
}
|
|
100
|
-
push(1 + q + opts.length + freeRows, opts.length + (freeRows > 0 ? 1 : 0), Math.min(strWidth(SKIP_LABEL) + BUTTON_PAD, full), true);
|
|
101
|
-
return out;
|
|
102
|
-
}
|