fix(editor): strip ANSI from rustyline prompt raw() so the cursor tracks on Windows#3461
Merged
amitksingh1490 merged 2 commits intoJun 6, 2026
Merged
Conversation
…cks on Windows rustyline's Windows console backend computes cursor columns from Prompt::raw() via calculate_position(), counting grapheme widths and unable to interpret ANSI escapes (it debug-asserts against the CSI introducer). Since tailcallhq#3399 (reedline -> rustyline) ForgePrompt::raw() has been built from nu_ansi_term-styled text, so every SGR byte was counted as a visible column and the cursor was pushed past the typed text (typing :version rendered as :v ersion). raw() now returns the ANSI-stripped form; styled() keeps the colors for display. Mirrors the existing Windows handling in forge_select/src/input.rs. Adds a regression test asserting raw() has no escape sequences. Co-authored-by: Claude Opus 4.8 <[email protected]>
amitksingh1490
approved these changes
Jun 6, 2026
KooshaPari
pushed a commit
to KooshaPari/forgecode
that referenced
this pull request
Jun 16, 2026
…tion, and loop commands (#20) * fix: pin reedline to 0.47.0 (tailcallhq#3398) Co-authored-by: ForgeCode <[email protected]> Co-authored-by: laststylebender <[email protected]> * chore(deps): update rust crate reedline to v0.48.0 (tailcallhq#3406) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Revert "chore(deps): update rust crate reedline to v0.48.0" (tailcallhq#3409) * fix(openai_responses): handle codex response completed/incomplete events (tailcallhq#3405) * chore(deps): update rust crate posthog-rs to v0.7.2 (tailcallhq#3410) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @ai-sdk/google-vertex to v4.0.140 (tailcallhq#3412) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.192 (tailcallhq#3413) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(provider): add model entries to provider.json and vertex.json (tailcallhq#3414) * chore(deps): update rust crate posthog-rs to v0.7.3 (tailcallhq#3415) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate aws-sdk-bedrockruntime to v1.132.0 (tailcallhq#3416) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix: apply Opus 4.7 API contract to Claude Opus 4.8 (tailcallhq#3418) Co-authored-by: ForgeCode <[email protected]> * refactor(editor): replace reedline with rustyline completer (tailcallhq#3399) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix(minimax): MiniMax M3 model support (tailcallhq#3434) Co-authored-by: ForgeCode <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix(gemini): strip propertyNames from tool schemas (tailcallhq#3426) Co-authored-by: Amit Singh <[email protected]> * fix(http): map invalid response status to openai error (tailcallhq#3439) * chore(deps): update aws-sdk-rust monorepo (tailcallhq#3420) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @ai-sdk/google-vertex to v4.0.142 (tailcallhq#3440) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.197 (tailcallhq#3444) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency tsx to v4.22.4 (tailcallhq#3427) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate chrono to v0.4.45 (tailcallhq#3445) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate diesel to v2.3.10 (tailcallhq#3446) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate unicode-segmentation to v1.13.3 (tailcallhq#3431) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate uuid to v1.23.2 (tailcallhq#3421) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @types/node to v24.13.0 (tailcallhq#3447) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust to 1.96 (tailcallhq#3419) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate ignore to v0.4.26 (tailcallhq#3453) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate google-cloud-auth to v1.12.0 (tailcallhq#3449) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate serial_test to v3.5.0 (tailcallhq#3423) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(deps): update rust crate posthog-rs to 0.9.0 (tailcallhq#3451) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(deps): update rust crate posthog-rs to 0.10.0 (tailcallhq#3455) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(provider): Ambient as a built-in verified-inference provider (tailcallhq#3389) Co-authored-by: Amit Singh <[email protected]> * chore(deps): update dependency @types/node to v24.13.1 (tailcallhq#3458) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Amit Singh <[email protected]> * build(deps): bump brace-expansion from 5.0.5 to 5.0.6 (tailcallhq#3359) Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(openai_responses): preserve 503 retryable errors in stream (tailcallhq#3460) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix(select): ignore key Release events so pickers do not close instantly on Windows (tailcallhq#3462) Co-authored-by: Claude Opus 4.8 <[email protected]> * fix(editor): strip ANSI from rustyline prompt raw() so the cursor tracks on Windows (tailcallhq#3461) Co-authored-by: Claude Opus 4.8 <[email protected]> Co-authored-by: Amit Singh <[email protected]> * chore(deps): update tokio-prost monorepo to v0.14.4 (tailcallhq#3467) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.198 (tailcallhq#3470) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate http to v1.4.2 (tailcallhq#3471) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate uuid to v1.23.3 (tailcallhq#3473) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @ai-sdk/google-vertex to v4.0.143 (tailcallhq#3475) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.199 (tailcallhq#3476) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(anthropic): support for claude mythos and fable models (tailcallhq#3474) * chore(deps): update rust crate regex to v1.12.4 (tailcallhq#3478) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.200 (tailcallhq#3481) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @types/node to v24.13.2 (tailcallhq#3483) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.201 (tailcallhq#3484) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate insta to v1.48.0 (tailcallhq#3486) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @ai-sdk/google-vertex to v4.0.144 (tailcallhq#3488) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.202 (tailcallhq#3489) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate rmcp to v1 [security] (tailcallhq#3277) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Amit Singh <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * build(deps): bump openssl from 0.10.78 to 0.10.80 (tailcallhq#3364) Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Amit Singh <[email protected]> * fix(config): config auto_install_vscode_extension option (tailcallhq#3485) Co-authored-by: laststylebender <[email protected]> * chore(deps): update rust crate aws-smithy-types to v1.5.0 (tailcallhq#3490) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate async-openai to 0.41.0 (tailcallhq#3078) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Amit Singh <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * feat(provider): add claude-fable-5 to vertex_ai_anthropic models (tailcallhq#3480) Co-authored-by: akhilapp <[email protected]> Co-authored-by: Amit Singh <[email protected]> * chore(deps): update rust crate google-cloud-auth to v1.13.0 (tailcallhq#3491) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(deps): update rust crate posthog-rs to 0.11.0 (tailcallhq#3487) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(forge_select): enter alternate screen to keep prompt visible (tailcallhq#3492) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix(zsh): pad _forge_reset to avoid zle clearing output (tailcallhq#3494) * chore(deps): update dependency @ai-sdk/google-vertex to v4.0.145 (tailcallhq#3495) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(deps): update rust crate posthog-rs to 0.12.0 (tailcallhq#3498) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ai to v6.0.204 (tailcallhq#3496) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update rust crate aws-sdk-bedrockruntime to v1.134.0 (tailcallhq#3499) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(provider): add missing fireworks models in provider.json (tailcallhq#3504) * fix(provider): add z.ai glm-5.2 model to provider.json (tailcallhq#3505) * chore(deps): update dependency ai to v6.0.205 (tailcallhq#3509) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix: show only direct conversation initiated by the user via the `:conversation` command (tailcallhq#3510) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * feat: add parent_id, source, FTS5, subagent hiding, and loop commands * fix(ui): apply user_initiated_conversations filter to SelectCommand::Conversation --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Amit Singh <[email protected]> Co-authored-by: ForgeCode <[email protected]> Co-authored-by: laststylebender <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Imamuzzaki Abu Salam <[email protected]> Co-authored-by: Pascal <[email protected]> Co-authored-by: Gregory <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: resrever <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]> Co-authored-by: Sandipsinh Dilipsinh Rathod <[email protected]> Co-authored-by: Akhil Appana <[email protected]> Co-authored-by: akhilapp <[email protected]> Co-authored-by: Tushar Mathur <[email protected]> Co-authored-by: Phenotype Agent <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Windows, typing in the interactive prompt desyncs the cursor. The input is received correctly, but rendered in the wrong columns — e.g. typing
:versionshows up as:v ersion(the command still parses fine; only the display/cursor is wrong). The cursor also starts a few columns to the right of the prompt.Reproduces in both Windows Terminal and
cmd.Root cause
rustyline's Windows console backend positions the cursor through the Win32 Console API and computes columns itself in
calculate_position(tty/windows.rs), counting grapheme widths. It cannot interpret ANSI escapes — it evendebug_assert!s that the measured string contains no\x1b[("content should not be styled directly").The prompt's contribution to the cursor is measured from
Prompt::raw()(edit.rs:calculate_position(prompt.raw(), …)). Since #3399 (reedline → rustyline),ForgePrompt'sraw()was built fromnu_ansi_term-painted (styled) text, so every SGR escape byte was counted as a visible column, pushing the cursor past the typed text.content should not be styled directly.Fix
raw()now returns the ANSI-stripped string (it's only used for measurement);styled()keeps the colors (and the right prompt) for display. This mirrors the existing Windows handling already noted inforge_select/src/input.rs.Adds a regression test asserting
render_prompt(…).rawcontains no escape sequences (whilestyledstill does).Testing
cargo test -p forge_main— new testtest_render_prompt_raw_has_no_ansi_escapespasses.raw()content is only ever measured).