Native grep only prints -- between non-adjacent match blocks when
-A/-B/-C context is requested. The grouped output path was inserting
-- on any line-number gap unconditionally, so `rtk grep -rn todo`
invented separators between every match that grep never emits.
Gate the insertion on has_context_flag() which checks for -A/-B/-C
and their long-form equivalents.
When context flags (-A/-B/-C) are used, grep prints -- between
non-adjacent match blocks. parse_match_line() returned None for
this separator, and both output paths silently dropped it, merging
distinct matches into one contiguous block.
Fixes#2795
Deserialize each compiler-message line into typed structs instead of
indexing serde_json::Value, mirroring filter_go_test_json. Route the
internal-compiler-error level into the errors bucket so an ICE is no longer
dropped.
Routing clippy json through the build filter reported a clean run as
"cargo clippy (N crates compiled)". Detect the clean case up front and emit
the same "cargo clippy: No issues found" the human path uses; errors and
warnings still route through the diagnostics summary.
cargo emits "\`crate\` generated N warnings" which ends in "warning", so the
ends_with("generated") check never matched it and the summary could inflate
the count. Use contains, matching the human-text skip elsewhere in the file.
The batch filter built the handler with a hardcoded "build" label. It is
unused today (only the free summary functions receive the label) but would
silently mislabel if the function ever called handler.format_summary. Pass
the real label through.
cargo uses last-flag-wins, so --message-format=json --message-format=human
builds in human format. Track the last occurrence instead of returning on
the first json match.
cargo install --message-format=json is effectively never used, and routing
its success through the build filter dropped the "Installed <crate>" line
(cargo prints it as plain text, not a json record). Keep install on its
dedicated filter which preserves that information.
The !is_empty() guard was always true (filter_cargo_build_labeled never
returns empty), making the last-5-lines fallback dead code and letting a
success-shaped line through on a false-positive compile-error detection.
Check for the "cargo test:" failure summary instead.
Native Windows has had full auto-rewrite support since v0.37.2 via the
`rtk hook claude` native binary command (no bash/jq/Unix shell). The
README still described the pre-v0.37.2 "CLAUDE.md fallback" behavior,
which is now inaccurate and a recurring source of confusion (#330).
- Rewrite the Windows section: native binary hook is the primary path,
WSL secondary; drop the "limited support / CLAUDE.md fallback" framing
- Add an upgrade note (re-run `rtk init -g` to migrate off rtk-rewrite.sh)
- Add a ripgrep prerequisite note (`rg` on PATH)
- Fix the install note and Supported AI Tools table (bash -> native binary)
Refs #330
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rtk gain --history panicked with "byte index 22 is not a char
boundary" when a tracked command contained non-ASCII text (Cyrillic,
CJK, emoji). The same byte-slicing pattern existed in the --failures
display (top commands, recent failures, timestamp prefix) and in the
session id column of rtk session, all reproduced as real panics.
Replace the ad-hoc byte-based truncations with the shared char-safe
core::utils::truncate() helper, and use .get(..n).unwrap_or() for the
timestamp and session id prefix slices so they fall back to the full
string instead of panicking. Output is byte-identical to the previous
behavior for pure-ASCII data.
Fixes#2787
contains("generated") could swallow a real diagnostic mentioning both
"warning" and "generated"; the rustc summary record ends with "generated",
so match that precisely.
The test set a shared RTK_TEE_DIR and read back the tee file, but with the
finding-1 tee call other parallel tests now write to the same dir and the
max_files cleanup could evict the file before the read. The overflow line and
true totals are already covered by test_filter_cargo_build_json_errors_capped,
and force_tee_hint has its own tests in core/tee.rs.
Detect --message-format=json (and the json-* variants, inline and
space-separated) in the args and route build/check to the batch
filter_cargo_build path instead of inferring json mode from output content.
Makes json routing an explicit decision and removes reliance on the
has_compile_errors invariant.
The rewrite path only needs a yes/no match, not the full compiled pipeline find_matching_filter forces on every not-in-RULES command (~10ms/call saved; selection still uses find_matching_filter in run_fallback).