rtk grep previously returned exit 0 for all failure modes (no match,
invalid regex, missing file) where rg returns non-zero. This broke
shell workflows relying on exit code semantics.
Now propagates rg exit codes: 1 (no match), 2 (error) and surfaces
stderr for error cases so users see why the command failed.
Fixes#162
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs when passing grep-idiom arguments to rtk grep:
1. Pattern alternation `\|` (BRE syntax) returns 0 results because rg
uses PCRE-style `|`, not BRE `\|`. Users coming from grep/awk muscle
memory naturally write `rtk grep "fn foo\|fn bar" src/` and get
empty output with no error.
Fix: translate `\|` → `|` in pattern before passing to rg.
2. `-r`/`--recursive` flag (grep idiom) silently breaks the search.
In rg, `-r` means `--replace` and requires an argument — passing it
alone causes rg to exit with an error. The `.or_else(|_| ...)` fallback
only catches IO errors (command not found), so the grep fallback never
triggers; stdout is empty and rtk reports "0 for '<pattern>'".
Fix: filter out `-r`/`--recursive` from extra_args before building
the rg command (rg is recursive by default, flag is a no-op).
Adds two regression tests documenting both behaviours.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: prevent UTF-8 panics on multi-byte characters (Thai, emoji, CJK)
Replace all byte-indexed string slicing (`&s[..n]`) with char-aware
operations across 10 locations in 7 files. Rust strings are UTF-8, so
byte slicing can land mid-character on Thai (3 bytes), emoji (4 bytes),
or CJK text and panic at runtime.
Fixes applied:
- git.rs: filter_log_output, format_status_output
- log_cmd.rs: error/warning message truncation (2 locations)
- env_cmd.rs: long value display, mask_value
- parser/mod.rs: truncate_output
- grep_cmd.rs: clean_line (pattern context + fallback truncation)
- wget_cmd.rs: compact_url, truncate_line, parse_error
Also adds safe_char_boundary() utility and 20 regression tests covering
Thai, emoji, and CJK input across all affected modules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: collect chars once in compact_url to avoid redundant iteration
Address review feedback: collect chars into Vec once instead of
calling .chars() multiple times. Also fixes byte-vs-char length check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove unused safe_char_boundary function and tests
Address review: function was defined but never called anywhere.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: convert remaining is_char_boundary to full .chars() approach
Address review: use consistent .chars() everywhere instead of
mixing byte-based is_char_boundary with char-based operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add support for passing additional ripgrep arguments to rtk grep
while preserving RTK's token-optimized output formatting.
Changes:
- src/main.rs: Add extra_args field to Grep command variant
- src/main.rs: Pass extra_args to grep_cmd::run()
- src/grep_cmd.rs: Add extra_args parameter to run() signature
- src/grep_cmd.rs: Inject extra_args into ripgrep command
- Unit test: test_extra_args_accepted verifies parameter exists
- Smoke tests: 2 assertions for -i and -A flags
Usage note: Extra args must come AFTER pattern and path:
✓ rtk grep "pattern" src/ -i
✗ rtk grep "pattern" -i (clap interprets -i as path)
This enables full ripgrep functionality (case-insensitive, context
lines, word boundaries, globs) while maintaining RTK's compact output.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add exec_time_ms column to SQLite schema and track execution time
for all rtk commands. Display time metrics in gain summary, daily/
weekly/monthly breakdowns, and JSON/CSV exports.
Changes:
- tracking.rs: Add exec_time_ms column, TimedExecution struct
- display_helpers.rs: Add format_duration() helper, update tables
- gain.rs: Display total/avg exec time in summary and by-command
- All command modules: Apply TimedExecution timer wrapper
- Exports: Include total_time_ms and avg_time_ms in JSON/CSV
Example output:
Total exec time: 24.6s (avg 34ms)
rtk cargo test 7 -86.1% 349ms avg
rtk git status 111 -84.1% 1ms avg
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add SQLite tracking for all commands (90-day history)
- Add rtk gain command with ASCII graph visualization
- Add config.rs for TOML configuration support
- Integrate tracking in all command modules
- Add CI/CD workflow for multi-platform releases (deb, rpm, win, mac)
- Add LICENSE file and improve .gitignore
Features:
- Strips leading/trailing whitespace
- Groups results by file with counts
- Truncates long lines (keeps match visible)
- Shows compact file paths
- -c flag for context-only (just the match)
- -l flag for max line length
Example: rtk grep "pattern" src/ -l 60
Total: 17 commands