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/tui/pi-renderer.ts
DELETED
|
@@ -1,428 +0,0 @@
|
|
|
1
|
-
/** PiTuiRenderer — the Renderer seam implemented over the vendored pi-tui library.
|
|
2
|
-
*
|
|
3
|
-
* Wiring ported from upstream pi (earendil-works/pi, pinned 853a80d2):
|
|
4
|
-
* - chat layout / transcript splice-before-editor / loader-while-responding:
|
|
5
|
-
* packages/tui/test/chat-simple.ts (splice at children.length-1, editor last & focused)
|
|
6
|
-
* - CancellableLoader Escape-to-abort: packages/tui/src/components/cancellable-loader.ts
|
|
7
|
-
* Vendor quirk: TruncatedText has no setText (its text is private), so setStatus
|
|
8
|
-
* swaps the status-line instance in tui.children instead of mutating it.
|
|
9
|
-
*
|
|
10
|
-
* Only this module, overlays.ts (card bodies) and theme.ts may import from vendor/pi-tui.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
CancellableLoader,
|
|
15
|
-
CombinedAutocompleteProvider,
|
|
16
|
-
type Component,
|
|
17
|
-
Editor,
|
|
18
|
-
Key,
|
|
19
|
-
Markdown,
|
|
20
|
-
matchesKey,
|
|
21
|
-
ProcessTerminal,
|
|
22
|
-
type SelectItem,
|
|
23
|
-
SelectList,
|
|
24
|
-
type Terminal,
|
|
25
|
-
Text,
|
|
26
|
-
TruncatedText,
|
|
27
|
-
type TUI,
|
|
28
|
-
TuiMainScreen,
|
|
29
|
-
} from "../../vendor/pi-tui/src/index.ts";
|
|
30
|
-
import type {
|
|
31
|
-
ApprovalAnswer,
|
|
32
|
-
AssistantView,
|
|
33
|
-
PickItem,
|
|
34
|
-
QuestionAnswer,
|
|
35
|
-
QuestionPrompt,
|
|
36
|
-
Renderer,
|
|
37
|
-
RendererHooks,
|
|
38
|
-
RendererStartOptions,
|
|
39
|
-
SlashCommand,
|
|
40
|
-
StatusInfo,
|
|
41
|
-
} from "./renderer.ts";
|
|
42
|
-
import { ApprovalCard, FREE_TEXT, QuestionCard, SKIP_QUESTION } from "./overlays.ts";
|
|
43
|
-
import { modeLabelShort } from "../core/voice.ts";
|
|
44
|
-
import { expandMentions, mentionsIn, splitAttached } from "../sextant/mentions.ts";
|
|
45
|
-
import { existsSync } from "node:fs";
|
|
46
|
-
import { join } from "node:path";
|
|
47
|
-
import { rovecodeEditorTheme, rovecodeMarkdownTheme, rovecodeSelectListTheme, pal, st } from "./theme.ts";
|
|
48
|
-
|
|
49
|
-
/** Tool cards stay single-line: collapse whitespace and clip to ~120 columns. */
|
|
50
|
-
import { StagedTerminal } from "./staged-terminal.ts";
|
|
51
|
-
|
|
52
|
-
const CARD_MAX = 120;
|
|
53
|
-
function oneLine(text: string, max = CARD_MAX): string {
|
|
54
|
-
const flat = text.replace(/\s+/g, " ").trim();
|
|
55
|
-
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
interface ToolCard {
|
|
59
|
-
line: Text;
|
|
60
|
-
tool: string;
|
|
61
|
-
base: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// requestRender() from seeding must not leak a frame while the loading intro still owns stdout.
|
|
65
|
-
class PreparingTui extends TuiMainScreen {
|
|
66
|
-
private holding = true;
|
|
67
|
-
override requestRender(force = false): void { if (!this.holding) super.requestRender(force); }
|
|
68
|
-
reveal(): void { this.holding = false; this.start(); }
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface PiTuiRendererOptions {
|
|
72
|
-
/** Defaults to ProcessTerminal; tests inject a VirtualTerminal. */
|
|
73
|
-
terminal?: Terminal;
|
|
74
|
-
/** Working directory for file autocomplete; defaults to process.cwd(). */
|
|
75
|
-
cwd?: string;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export class PiTuiRenderer implements Renderer {
|
|
79
|
-
private readonly terminal: Terminal;
|
|
80
|
-
private readonly cwd: string;
|
|
81
|
-
private commands: SlashCommand[] = [];
|
|
82
|
-
private tui: TUI | null = null;
|
|
83
|
-
private editor: Editor | null = null;
|
|
84
|
-
private statusLine: TruncatedText | null = null;
|
|
85
|
-
private statusText = "";
|
|
86
|
-
private loader: CancellableLoader | null = null;
|
|
87
|
-
private hooks: RendererHooks | null = null;
|
|
88
|
-
private unsubscribeInput: (() => void) | null = null;
|
|
89
|
-
private readonly toolCards = new Map<string, ToolCard>();
|
|
90
|
-
/** cancel thunks for overlays awaiting an answer; drained on stop() */
|
|
91
|
-
private readonly pendingPickers = new Set<() => void>();
|
|
92
|
-
|
|
93
|
-
constructor(opts?: PiTuiRendererOptions) {
|
|
94
|
-
this.terminal = opts?.terminal ?? new ProcessTerminal();
|
|
95
|
-
this.cwd = opts?.cwd ?? process.cwd();
|
|
96
|
-
}
|
|
97
|
-
private ui(): TUI {
|
|
98
|
-
if (!this.tui) throw new Error("PiTuiRenderer: start() must be called first");
|
|
99
|
-
return this.tui;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private requireEditor(): Editor {
|
|
103
|
-
if (!this.editor) throw new Error("PiTuiRenderer: start() must be called first");
|
|
104
|
-
return this.editor;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Children order: header … transcript … [loader] … editor … status line.
|
|
108
|
-
* New transcript items land after existing ones: before the loader when busy,
|
|
109
|
-
* otherwise directly before the editor (chat-simple.ts pattern). */
|
|
110
|
-
private insertTranscript(component: Component): void {
|
|
111
|
-
// after stop() (e.g. a run's finally block racing user exit) mutations are no-ops
|
|
112
|
-
const tui = this.tui;
|
|
113
|
-
const anchor = this.loader ?? this.editor;
|
|
114
|
-
if (!tui || !anchor) return;
|
|
115
|
-
const idx = tui.children.indexOf(anchor);
|
|
116
|
-
tui.children.splice(idx < 0 ? tui.children.length : idx, 0, component);
|
|
117
|
-
tui.requestRender();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
start(hooks: RendererHooks, options?: RendererStartOptions): void | Promise<void> {
|
|
121
|
-
if (this.tui) return;
|
|
122
|
-
this.hooks = hooks;
|
|
123
|
-
const staged = options?.beforeReveal ? new StagedTerminal(this.terminal) : undefined;
|
|
124
|
-
const tui = staged ? new PreparingTui(staged) : new TuiMainScreen(this.terminal);
|
|
125
|
-
this.tui = tui;
|
|
126
|
-
|
|
127
|
-
// header banner
|
|
128
|
-
tui.addChild(new Text(st.dim("rovecode"), 1, 0));
|
|
129
|
-
|
|
130
|
-
// editor (kept just above the status line; transcript is spliced in before it)
|
|
131
|
-
const editor = new Editor(tui, rovecodeEditorTheme);
|
|
132
|
-
this.editor = editor;
|
|
133
|
-
editor.onSubmit = (value: string) => {
|
|
134
|
-
const text = value.trim();
|
|
135
|
-
if (!text) return;
|
|
136
|
-
// `@file` (sextant/mentions.ts): this editor's autocomplete offers files after `@`, so the mention must do
|
|
137
|
-
// something here too. No file list on this surface, so a mention is the exact cwd-relative path — what
|
|
138
|
-
// the autocomplete inserts. Every refusal and cap is said as a note, never swallowed.
|
|
139
|
-
const mentions = mentionsIn(text);
|
|
140
|
-
if (mentions.length === 0) { hooks.onSubmit(text); return; }
|
|
141
|
-
const r = expandMentions(text, { cwd: this.cwd, mentions, resolve: (m) => (existsSync(join(this.cwd, m)) ? m.replace(/\\/g, "/") : null) });
|
|
142
|
-
for (const n of r.notes) this.addSystemNote(n, "warn");
|
|
143
|
-
hooks.onSubmit(r.text);
|
|
144
|
-
};
|
|
145
|
-
editor.setAutocompleteProvider(new CombinedAutocompleteProvider(this.commands, this.cwd));
|
|
146
|
-
tui.addChild(editor);
|
|
147
|
-
|
|
148
|
-
// status line (always last)
|
|
149
|
-
const status = new TruncatedText(this.statusText, 1, 0);
|
|
150
|
-
this.statusLine = status;
|
|
151
|
-
tui.addChild(status);
|
|
152
|
-
|
|
153
|
-
tui.setFocus(editor);
|
|
154
|
-
|
|
155
|
-
// Input listeners run before the focused component (tui.ts handleTerminalInput),
|
|
156
|
-
// so Ctrl+C always exits and Escape reaches the loader while the editor keeps focus.
|
|
157
|
-
this.unsubscribeInput = tui.addInputListener((data) => {
|
|
158
|
-
if (matchesKey(data, Key.ctrl("c"))) {
|
|
159
|
-
hooks.onExit();
|
|
160
|
-
return { consume: true };
|
|
161
|
-
}
|
|
162
|
-
if (this.loader && !tui.hasOverlay() && matchesKey(data, Key.escape)) {
|
|
163
|
-
this.loader.handleInput(data); // abort → onAbort → hooks.onInterrupt()
|
|
164
|
-
return { consume: true };
|
|
165
|
-
}
|
|
166
|
-
return undefined;
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
options?.beforeFirstRender?.();
|
|
170
|
-
if (staged && tui instanceof PreparingTui && options?.beforeReveal) {
|
|
171
|
-
staged.prepare(() => tui.renderNow(true));
|
|
172
|
-
return options.beforeReveal().then(() => {
|
|
173
|
-
if (this.tui !== tui) return; // cancelled while the intro was visible
|
|
174
|
-
staged.prepare(() => tui.renderNow(true)); // latest terminal size, transcript and status
|
|
175
|
-
staged.reveal(() => tui.reveal(), options.onReveal);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
options?.onReveal?.();
|
|
179
|
-
tui.start();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
stop(): void {
|
|
183
|
-
const tui = this.tui;
|
|
184
|
-
if (!tui) return;
|
|
185
|
-
if (this.loader) {
|
|
186
|
-
this.loader.stop();
|
|
187
|
-
this.loader = null;
|
|
188
|
-
}
|
|
189
|
-
if (this.unsubscribeInput) {
|
|
190
|
-
this.unsubscribeInput();
|
|
191
|
-
this.unsubscribeInput = null;
|
|
192
|
-
}
|
|
193
|
-
// an overlay that never gets an answer must not pin the process (or a caller
|
|
194
|
-
// awaiting it) forever — a stopped UI cannot answer, so cancel them all
|
|
195
|
-
for (const cancel of this.pendingPickers) cancel();
|
|
196
|
-
this.pendingPickers.clear();
|
|
197
|
-
tui.stop();
|
|
198
|
-
this.tui = null;
|
|
199
|
-
this.editor = null;
|
|
200
|
-
this.statusLine = null;
|
|
201
|
-
this.hooks = null;
|
|
202
|
-
this.toolCards.clear();
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
setCommands(cmds: SlashCommand[]): void {
|
|
206
|
-
this.commands = cmds.slice();
|
|
207
|
-
if (this.editor) {
|
|
208
|
-
this.editor.setAutocompleteProvider(new CombinedAutocompleteProvider(this.commands, this.cwd));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
addUser(text: string): void {
|
|
213
|
-
// the typed line and one row per @file attached — the read blocks stay in the session, not on screen
|
|
214
|
-
const { text: typed, files } = splitAttached(text);
|
|
215
|
-
this.insertTranscript(new Text(st.dim("> ") + typed, 1, 0));
|
|
216
|
-
for (const f of files) this.insertTranscript(new Text(st.dim(` ▤ attached ${f}`), 1, 0));
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
addSystemNote(text: string, tone: "info" | "warn" | "error" = "info"): void {
|
|
220
|
-
const paint = tone === "warn" ? pal.warn : tone === "error" ? pal.err : pal.muted;
|
|
221
|
-
this.insertTranscript(new Text(paint(text), 1, 0));
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
beginAssistant(): AssistantView {
|
|
225
|
-
const tui = this.tui;
|
|
226
|
-
if (!tui) return { append: () => {}, done: () => {} };
|
|
227
|
-
const md = new Markdown("", 1, 1, rovecodeMarkdownTheme);
|
|
228
|
-
this.insertTranscript(md);
|
|
229
|
-
let buffer = "";
|
|
230
|
-
return {
|
|
231
|
-
append: (delta: string) => {
|
|
232
|
-
buffer += delta;
|
|
233
|
-
md.setText(buffer);
|
|
234
|
-
tui.requestRender();
|
|
235
|
-
},
|
|
236
|
-
done: () => {
|
|
237
|
-
/* buffer already flushed on each append */
|
|
238
|
-
},
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
toolStart(callId: string, tool: string, argsPreview: string): void {
|
|
243
|
-
const base = oneLine(`→ ${tool} ${argsPreview}`);
|
|
244
|
-
const line = new Text(st.dim(base), 1, 0);
|
|
245
|
-
this.toolCards.set(callId, { line, tool, base });
|
|
246
|
-
this.insertTranscript(line);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
toolUpdate(callId: string, note: string): void {
|
|
250
|
-
const card = this.toolCards.get(callId);
|
|
251
|
-
if (!card) return;
|
|
252
|
-
card.line.setText(st.dim(oneLine(`${card.base} · ${note}`)));
|
|
253
|
-
this.tui?.requestRender();
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
toolEnd(callId: string, ok: boolean, outputPreview: string, durationMs: number): void {
|
|
257
|
-
const card = this.toolCards.get(callId);
|
|
258
|
-
if (!card) return;
|
|
259
|
-
this.toolCards.delete(callId);
|
|
260
|
-
const paint = ok ? pal.ok : pal.err;
|
|
261
|
-
const verdict = ok ? "ok" : "FAIL";
|
|
262
|
-
card.line.setText(paint(oneLine(`← ${verdict} ${card.tool} (${durationMs}ms) ${outputPreview}`)));
|
|
263
|
-
this.tui?.requestRender();
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/** Show `component` as a centered overlay whose keys route to `list`; settles on select,
|
|
267
|
-
* cancel, or stop() (a stopped UI cannot answer — pendingPickers drains it to null). */
|
|
268
|
-
private pickWith(component: Component, list: SelectList, width: number): Promise<string | null> {
|
|
269
|
-
const tui = this.tui;
|
|
270
|
-
const editor = this.editor;
|
|
271
|
-
if (!tui || !editor) return Promise.resolve(null);
|
|
272
|
-
return new Promise<string | null>((resolve) => {
|
|
273
|
-
const handle = tui.showOverlay(component, { width, anchor: "center" });
|
|
274
|
-
let settled = false;
|
|
275
|
-
const finish = (answer: string | null): void => {
|
|
276
|
-
if (settled) return;
|
|
277
|
-
settled = true;
|
|
278
|
-
this.pendingPickers.delete(cancel);
|
|
279
|
-
handle.hide();
|
|
280
|
-
if (this.tui) { tui.setFocus(editor); tui.requestRender(); }
|
|
281
|
-
resolve(answer);
|
|
282
|
-
};
|
|
283
|
-
const cancel = () => finish(null);
|
|
284
|
-
this.pendingPickers.add(cancel);
|
|
285
|
-
list.onSelect = (item: SelectItem) => finish(item.value);
|
|
286
|
-
list.onCancel = () => finish(null);
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
pickOne(items: PickItem[], title?: string): Promise<string | null> {
|
|
291
|
-
if (!this.tui || items.length === 0) return Promise.resolve(null);
|
|
292
|
-
if (title) this.addSystemNote(title);
|
|
293
|
-
const list = new SelectList(
|
|
294
|
-
items.map((i) => ({ value: i.value, label: i.label, description: i.description })),
|
|
295
|
-
Math.min(items.length, 8),
|
|
296
|
-
rovecodeSelectListTheme,
|
|
297
|
-
);
|
|
298
|
-
return this.pickWith(list, list, 64);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
async askApproval(tool: string, argsPreview: string, detail?: string): Promise<ApprovalAnswer> {
|
|
302
|
-
this.addSystemNote(`approval needed: ${tool} ${argsPreview}`, "warn");
|
|
303
|
-
const items: PickItem[] = [
|
|
304
|
-
{ value: "once", label: "allow once", description: "run this call only" },
|
|
305
|
-
{ value: "always", label: "always", description: "allow this tool for the session" },
|
|
306
|
-
{ value: "deny", label: "deny", description: "reject this call" },
|
|
307
|
-
];
|
|
308
|
-
let picked: string | null;
|
|
309
|
-
if (detail) {
|
|
310
|
-
// port #24: the diff rides inside the overlay; same list, same keys as the plain path
|
|
311
|
-
const list = new SelectList(items, items.length, rovecodeSelectListTheme);
|
|
312
|
-
const card = new ApprovalCard(`approval needed: ${tool}`, detail.split("\n"), list, () => this.terminal.rows);
|
|
313
|
-
picked = await this.pickWith(card, list, Math.max(40, Math.min(this.terminal.columns - 4, 100)));
|
|
314
|
-
} else picked = await this.pickOne(items);
|
|
315
|
-
return picked === "once" || picked === "always" ? picked : "deny"; // null/cancel/stop → deny
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/** Port #33 question overlay, modal like approval (keys go to the card). Escape while a run is
|
|
319
|
-
* in flight (loader showing) INTERRUPTS the run — stopping beats letting the model proceed
|
|
320
|
-
* unanswered — and the run's abort signal then dismisses the card; Escape with no run (idle
|
|
321
|
-
* caller) declines → null; inside the free-text input Escape steps back to the options. */
|
|
322
|
-
askQuestion(q: QuestionPrompt, signal?: AbortSignal): Promise<QuestionAnswer | null> {
|
|
323
|
-
const tui = this.tui;
|
|
324
|
-
const editor = this.editor;
|
|
325
|
-
if (!tui || !editor || signal?.aborted) return Promise.resolve(null); // nobody to ask / run already gone
|
|
326
|
-
// concurrent-ask decision: ONE modal at a time — a second ask is a caller bug surfaced loudly, not queued
|
|
327
|
-
if (tui.hasOverlay()) return Promise.reject(new Error("a question or approval overlay is already open"));
|
|
328
|
-
const options = q.options ?? [];
|
|
329
|
-
const freeText = q.allowFreeText !== false;
|
|
330
|
-
const items: SelectItem[] = options.map((label, i) => ({ value: String(i), label }));
|
|
331
|
-
if (freeText) items.push({ value: FREE_TEXT, label: "type an answer…" });
|
|
332
|
-
items.push({ value: SKIP_QUESTION, label: "skip this question" }); // non-destructive decline → null; Escape on a busy run still stops the run
|
|
333
|
-
const list = new SelectList(items, Math.max(1, items.length), rovecodeSelectListTheme);
|
|
334
|
-
const card = new QuestionCard(q.question, list, options.length, freeText, () => this.terminal.rows, () => this.loader !== null);
|
|
335
|
-
this.addSystemNote(`question: ${oneLine(q.question)}`, "warn"); // transcript record, like approvals
|
|
336
|
-
return new Promise<QuestionAnswer | null>((resolve) => {
|
|
337
|
-
const handle = tui.showOverlay(card, { width: Math.max(40, Math.min(this.terminal.columns - 4, 100)), anchor: "center" });
|
|
338
|
-
let settled = false;
|
|
339
|
-
const finish = (answer: QuestionAnswer | null): void => {
|
|
340
|
-
if (settled) return;
|
|
341
|
-
settled = true;
|
|
342
|
-
this.pendingPickers.delete(cancel);
|
|
343
|
-
signal?.removeEventListener("abort", cancel);
|
|
344
|
-
handle.hide();
|
|
345
|
-
if (this.tui) { tui.setFocus(editor); tui.requestRender(); }
|
|
346
|
-
resolve(answer);
|
|
347
|
-
};
|
|
348
|
-
const cancel = () => finish(null);
|
|
349
|
-
this.pendingPickers.add(cancel);
|
|
350
|
-
signal?.addEventListener("abort", cancel, { once: true }); // the run's abort (port #21) dismisses the card
|
|
351
|
-
const escape = () => { if (this.loader) this.hooks?.onInterrupt(); else finish(null); };
|
|
352
|
-
list.onCancel = escape;
|
|
353
|
-
list.onSelect = (item: SelectItem) => {
|
|
354
|
-
if (item.value === SKIP_QUESTION) { finish(null); return; } // declined: the tool reports "user declined to answer"
|
|
355
|
-
if (item.value === FREE_TEXT) { card.setTyping(true); tui.requestRender(); return; }
|
|
356
|
-
const choice = Number(item.value);
|
|
357
|
-
finish({ choice, label: options[choice] });
|
|
358
|
-
};
|
|
359
|
-
card.input.onEscape = () => { if (options.length > 0) { card.setTyping(false); tui.requestRender(); } else escape(); };
|
|
360
|
-
card.input.onSubmit = (value: string) => { const text = value.trim(); if (text) finish({ text }); };
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
/** Remove every transcript item (keep header, loader, editor, status) — history replay. */
|
|
365
|
-
clearTranscript(): void {
|
|
366
|
-
const tui = this.tui;
|
|
367
|
-
const anchor = this.loader ?? this.editor;
|
|
368
|
-
if (!tui || !anchor) return;
|
|
369
|
-
const end = tui.children.indexOf(anchor);
|
|
370
|
-
if (end > 1) tui.children.splice(1, end - 1); // index 0 = header banner
|
|
371
|
-
this.toolCards.clear();
|
|
372
|
-
tui.requestRender();
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
prefillEditor(text: string): void {
|
|
376
|
-
const tui = this.tui;
|
|
377
|
-
const editor = this.editor;
|
|
378
|
-
if (!tui || !editor) return;
|
|
379
|
-
editor.setText(text);
|
|
380
|
-
tui.setFocus(editor);
|
|
381
|
-
tui.requestRender();
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
setBusy(busy: boolean, label?: string): void {
|
|
385
|
-
const tui = this.tui;
|
|
386
|
-
if (!tui) { this.loader = null; return; }
|
|
387
|
-
if (busy) {
|
|
388
|
-
const message = label ?? "thinking…";
|
|
389
|
-
if (this.loader) {
|
|
390
|
-
this.loader.setMessage(message);
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
const loader = new CancellableLoader(tui, (s) => pal.accent(s), (s) => st.dim(s), message);
|
|
394
|
-
loader.onAbort = () => { this.hooks?.onInterrupt(); };
|
|
395
|
-
this.loader = loader;
|
|
396
|
-
const anchor = this.editor;
|
|
397
|
-
const idx = anchor ? tui.children.indexOf(anchor) : -1;
|
|
398
|
-
tui.children.splice(idx < 0 ? tui.children.length : idx, 0, loader);
|
|
399
|
-
loader.start();
|
|
400
|
-
tui.requestRender();
|
|
401
|
-
} else {
|
|
402
|
-
const loader = this.loader;
|
|
403
|
-
if (!loader) return;
|
|
404
|
-
this.loader = null;
|
|
405
|
-
loader.stop();
|
|
406
|
-
const idx = tui.children.indexOf(loader);
|
|
407
|
-
if (idx >= 0) tui.children.splice(idx, 1);
|
|
408
|
-
tui.requestRender();
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
setStatus(info: StatusInfo): void {
|
|
413
|
-
const gate = modeLabelShort(info.yolo); // "ask first" | "auto" — the flags keep their names
|
|
414
|
-
const mode = info.mode ? `${info.mode} · ` : ""; // port #20 mode indicator
|
|
415
|
-
this.statusText = st.dim(
|
|
416
|
-
`${mode}${info.provider}/${info.model} · ${gate} · turns ${info.turns} · tokens ${info.tokensIn}/${info.tokensOut}${info.todos ? ` · ${info.todos}` : ""}`, // port #32 todo progress
|
|
417
|
-
);
|
|
418
|
-
const tui = this.tui;
|
|
419
|
-
if (!tui || !this.statusLine) return; // applied at start()
|
|
420
|
-
// vendor quirk: TruncatedText has no setText — swap the instance in place.
|
|
421
|
-
const next = new TruncatedText(this.statusText, 1, 0);
|
|
422
|
-
const idx = tui.children.indexOf(this.statusLine);
|
|
423
|
-
if (idx >= 0) tui.children.splice(idx, 1, next);
|
|
424
|
-
else tui.children.push(next);
|
|
425
|
-
this.statusLine = next;
|
|
426
|
-
tui.requestRender();
|
|
427
|
-
}
|
|
428
|
-
}
|