Skip to content

fix(plan): slice task commands by byte offsets - #861

Merged
wan9chi merged 5 commits into
voidzero-dev:mainfrom
magurotuna:fix/shell-span-byte-offsets
Oct 19, 2026
Merged

wan9chi merged 5 commits into
voidzero-dev:mainfrom
magurotuna:fix/shell-span-byte-offsets

Conversation

@magurotuna

Copy link
Copy Markdown
Member

Motivation

The vp run command panics before it runs a script that contains multi-byte UTF-8 characters, for example echo ああ. To display each command, the planner slices the script with the command spans from the brush-parser crate. These spans are character indices (SourcePosition::index), but the planner uses them as byte ranges. If an index falls inside a character, the slice panics. If an index falls on a character boundary, the planner displays a truncated command: it displays echo あああ as echo あ.

The brush project tracks this bug in reubeno/brush#1127. The fix in reubeno/brush#1144 is still open.

Fixes #719.

Changes

  • The vt_shell crate converts the character indices from the brush-parser crate to byte indices before it returns the command spans. Each conversion counts characters from the start of the script, which takes about 0.2 µs for a 150-byte script.
  • Add a unit test with 2-, 3-, and 4-byte characters, and add the non_ascii_commands fixture for plan snapshots.

magurotuna and others added 5 commits October 16, 2026 21:40
Command spans from the shell parser are sliced out of the script to
display each command. These cases put multi-byte UTF-8 characters before
span boundaries, where `vp run` currently panics or truncates the
displayed command (voidzero-dev#719).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
`brush_parser` reports source positions as character indices, but the
command spans were used as byte ranges into the script. A script with a
multi-byte UTF-8 character before a span boundary made `vp run` panic
before running it, or display a truncated command.

Convert the parser's character indices to byte indices before returning
the spans.

Fixes voidzero-dev#719

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The comment relied on an open brush PR that renames `index`. If a brush
release switches to byte offsets without the rename, the unit test for
multi-byte characters is what detects the double conversion.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@fengmk2
fengmk2 requested a review from wan9chi October 19, 2026 01:05
@wan9chi
wan9chi merged commit 32cf238 into voidzero-dev:main Oct 19, 2026
20 checks passed
cursor Bot added a commit to voidzero-dev/vite-plus that referenced this pull request Oct 21, 2026
Bumps vite-task from `9ba4cc9` to `8db455e`.

Changelog:
voidzero-dev/vite-task@9ba4cc9...8db455e#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed

## Breaking change adapted

fspy no longer reports a bitset of access modes on each path. Each
tracked operation is its own `PathAccess` (`Read`, `Write`, `ReadWrite`,
or `ReadDir`). `vp_command` combines the operations that touch the same
workspace-relative path into the existing `AccessMode` set, so the
JavaScript `run_command` result is unchanged.

## User-facing vite-task changes

- A mistyped task setting now fails with an error that names the field,
instead of `data did not match any variant of untagged enum
UserTaskDefinition` (voidzero-dev/vite-task#815).
- `vp run` no longer panics on scripts that contain non-ASCII
characters, and no longer cuts those commands off where it displays them
(voidzero-dev/vite-task#861).
- Reinstalling with another pnpm version no longer changes the cache
fingerprint of `node_modules/.modules.yaml`; only whether the file
exists is hashed (voidzero-dev/vite-task#850).
- Cached tasks on Linux and macOS no longer abort when a program passes
`-1` as a directory descriptor, and concurrent syscalls in tracked
programs no longer overflow the stack (voidzero-dev/vite-task#862,
voidzero-dev/vite-task#854).

Docs are unchanged. These are fixes to existing behavior, and the guides
do not describe the old error text or the `.modules.yaml` fingerprint.

## Validation

- `cargo check --workspace --all-features --all-targets --locked`
- `cargo clippy -p vp_command -p vite-plus-cli --all-targets
--all-features -- --deny warnings`
- `cargo test` for `vp_command`, `vp_error`, `vp_pm_cli`,
`vp_js_runtime`, `vp_migration`, `vp_shared`, `vp_static_config`,
`vite-plus-cli`, and `vp_global_cli`


<div><a
href="https://cursor.com/agents/bc-9c9cb178-3b56-4d68-9556-3028d946a3ec?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/automations/3a586a0e-cc2b-11f1-bec7-b2318963e0b6"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/view-automation-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/view-automation-light.png"><img
alt="View Automation" width="141" height="28"
src="https://cursor.com/assets/images/view-automation-dark.png"></picture></a>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Charles Wang <wan9chi@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vt_shell: command spans are character indices but sliced as bytes (plan.rs:185)

2 participants