85 Commits

Author SHA1 Message Date
Florian BRUNIAUX 70c37867e7 feat: add hook audit mode for verifiable rewrite metrics (#151)
Add opt-in audit logging to the RTK rewrite hook and a new `rtk hook-audit`
command to analyze the collected metrics. This provides verifiable data on
hook reliability (rewrite rate, skip reasons, top commands) instead of
relying on anecdotal claims.

- Add `_rtk_audit_log()` function to rtk-rewrite.sh (opt-in via RTK_HOOK_AUDIT=1)
- Log each invocation: timestamp | action | original_cmd | rewritten_cmd
- Actions: rewrite, skip:already_rtk, skip:heredoc, skip:no_match, skip:no_deps, skip:empty
- New `src/hook_audit_cmd.rs` module with log parser and stats display
- New `rtk hook-audit --since N` subcommand (default: last 7 days)
- 8 Rust unit tests + 7 hook bash tests for audit mode
- Make HOOK var overridable in test suite for repo-local testing

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 22:05:28 +01:00
Florian BRUNIAUX a08a62b4e3 feat: tee raw output to file for LLM re-read without re-run (#134)
* feat: tee raw output to file for LLM re-read without re-run (#86)

When RTK filters command output, LLM agents lose failure details
(stack traces, assertions) and re-run the same command 2-3x. The tee
feature saves raw output to ~/.local/share/rtk/tee/ on failure and
prints a one-line hint so the agent can read the file instead.

- Add src/tee.rs: core module with tee_raw(), tee_and_hint(), rotation
- Add TeeConfig to config.rs: enabled, mode, max_files, max_file_size
- Integrate in 7 modules: cargo, runner, vitest, pytest, lint, tsc, go
- Default: failures only, skip <500 chars, 20 file rotation, 1MB cap
- Env overrides: RTK_TEE=0 (disable), RTK_TEE_DIR (custom directory)
- 14 unit tests, 352 total tests passing, zero regressions

Closes #86

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add tee.rs to ARCHITECTURE.md module count (47 modules)

CI validate-docs requires main.rs module count == ARCHITECTURE.md count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 20:03:03 +01:00
heAdz0r 606b86ed43 feat(gain): colored dashboard with efficiency meter and impact bars (#129)
* feat(gain): add colored dashboard with efficiency meter and impact bars

Upgrade `rtk gain` output with rich terminal visualization:
- Colored percentage cells (green ≥70%, yellow ≥40%, red <40%)
- Efficiency meter: ASCII progress bar with savings percentage
- Impact bars: proportional block charts per command
- Styled section headers (bold green)
- Command names in bright cyan
- History tier indicators (▲/■/•)
- Dynamic column widths for clean table alignment
- KPI-style key-value layout for summary metrics

All visual features are TTY-aware via std::io::IsTerminal — output
degrades gracefully to plain text when piped or redirected.

No new dependencies (uses existing `colored` crate).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add dashboard visualization screenshot

Shows colored terminal output of `rtk gain -p` with:
- Project-scoped token savings header
- Efficiency meter with color gradient
- Per-command table with colored Avg% and Impact bars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:50:24 +01:00
heAdz0r 356c0d61a3 refactor(init): add upsert_rtk_block for idempotent CLAUDE.md management (#123)
Replace naive append-or-skip logic in run_claude_md_mode with
upsert_rtk_block() that handles all 4 cases:
- Added: no existing block → append
- Updated: stale block → replace in-place
- Unchanged: current block → no-op
- Malformed: opening marker without closing → warn safely

Includes 4 unit tests covering each case.
2026-02-15 15:15:08 +01:00
igor 68fd570f2b feat(cargo): add cargo nextest support with failures-only output (#107)
Add token-optimized filtering for `cargo nextest` output: strip
compilation noise, PASS lines, and post-summary recaps; show only
failure details and a compact summary. Extract flush_failure_block
helper to DRY up failure block collection (was repeated 4 times).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:14:28 +01:00
Florian BRUNIAUX 4cae6b6c9a feat(python): add lint dispatcher + universal format command (#100)
* feat(cargo): aggregate test output into single line (#83)

Problem: `cargo test` shows 24+ summary lines even when all pass.
An LLM only needs to know IF something failed, not 24x "ok".

Before (24 lines):
```
✓ test result: ok. 2 passed; 0 failed; ...
✓ test result: ok. 0 passed; 0 failed; ...
... (x24)
```

After (1 line):
```
✓ cargo test: 137 passed (24 suites, 1.45s)
```

Changes:
- Add AggregatedTestResult struct with regex parsing
- Merge multiple test summaries when all pass
- Format: "N passed, M ignored, P filtered out (X suites, Ys)"
- Fallback to original behavior if parsing fails
- Failures still show full details (no aggregation)

Tests: 6 new + 1 modified, covering all cases:
- Multi-suite aggregation
- Single suite (singular "suite")
- Zero tests
- With ignored/filtered out
- Failures → no aggregation (detail preserved)
- Regex fallback

Closes #83

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add Python and Go support (#88)

* feat(cargo): aggregate test output into single line (#83)

Problem: `cargo test` shows 24+ summary lines even when all pass.
An LLM only needs to know IF something failed, not 24x "ok".

Before (24 lines):
```
✓ test result: ok. 2 passed; 0 failed; ...
✓ test result: ok. 0 passed; 0 failed; ...
... (x24)
```

After (1 line):
```
✓ cargo test: 137 passed (24 suites, 1.45s)
```

Changes:
- Add AggregatedTestResult struct with regex parsing
- Merge multiple test summaries when all pass
- Format: "N passed, M ignored, P filtered out (X suites, Ys)"
- Fallback to original behavior if parsing fails
- Failures still show full details (no aggregation)

Tests: 6 new + 1 modified, covering all cases:
- Multi-suite aggregation
- Single suite (singular "suite")
- Zero tests
- With ignored/filtered out
- Failures → no aggregation (detail preserved)
- Regex fallback

Closes #83

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add Python and Go language support

Implements comprehensive support for Python and Go development tooling
with 70-90% token reduction across all commands.

Python commands (3):
- rtk ruff: Linter/formatter with JSON (check) and text (format) parsing (80%+)
- rtk pytest: Test runner with state machine text parser (90%+)
- rtk pip: Package manager with auto-detect uv (70-85%)

Go commands (4):
- rtk go test: NDJSON streaming parser for interleaved test events (90%+)
- rtk go build: Text filter showing errors only (80%)
- rtk go vet: Text filter for issues (75%)
- rtk golangci-lint: JSON parser grouped by rule (85%)

Architecture:
- Standalone Python commands (mirror lint/prettier pattern)
- Go sub-enum (mirror git/cargo pattern)
- 5 new modules: ruff_cmd, pytest_cmd, pip_cmd, go_cmd, golangci_cmd
- Hook integration in rtk-rewrite.sh for transparent rewrites
- Comprehensive tests (47 new tests, all passing)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(benchmark): add Python and Go commands

Add benchmark sections for Python (ruff, pytest, pip) and Go (go test/build/vet, golangci-lint) to validate >80% token savings in CI pipeline.

Sections conditionally execute based on project markers (pyproject.toml, go.mod) and tool availability.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: make install-local.sh self-contained (#89)

- Build from source automatically instead of requiring a pre-built binary
- Default install dir to ~/.cargo/bin
- Skip rebuild when binary is up to date
- Warn if install dir is not in PATH

* chore(master): release 0.15.0 (#90)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(vitest): robust JSON extraction for pnpm/dotenv prefixes (#92)

* fix(vitest): robust JSON extraction for pnpm/dotenv prefixes

Problem: RTK's vitest parser forces --reporter=json but pnpm/dotenv prepend
non-JSON text to stdout (banners, env messages), causing 100% Tier 1 failure
and useless 500-char passthrough.

Solution:
- Add extract_json_object() to parser/mod.rs (shared utility)
- Algorithm: find "numTotalTests" or first standalone {, brace-balance forward
- VitestParser now tries direct parse → extract+parse → regex → passthrough
- Replace hardcoded Command::new("pnpm") with package_manager_exec("vitest")
- Delete orphan doc comment on line 203

Impact:
- Before: 100% Tier 3 passthrough with pnpm workflows
- After: Tier 1 success with prefixes, maintains 99.5% token savings

Tests:
- 6 tests for extract_json_object (clean, pnpm, dotenv, nested, no-json, strings)
- 3 tests for VitestParser with prefixes
- All 277 tests pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore(benchmark): add vitest, pnpm, and gh commands

Add benchmarks for recently implemented commands:
- vitest run (PR #92 - JSON extraction fix)
- pnpm list/outdated (PR #6)
- gh pr list/run list (existing gh support)

These commands are now tested in CI to ensure token savings are maintained.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: improve CI reliability and hook coverage (#95)

* feat(cargo): aggregate test output into single line (#83)

Problem: `cargo test` shows 24+ summary lines even when all pass.
An LLM only needs to know IF something failed, not 24x "ok".

Before (24 lines):
```
✓ test result: ok. 2 passed; 0 failed; ...
✓ test result: ok. 0 passed; 0 failed; ...
... (x24)
```

After (1 line):
```
✓ cargo test: 137 passed (24 suites, 1.45s)
```

Changes:
- Add AggregatedTestResult struct with regex parsing
- Merge multiple test summaries when all pass
- Format: "N passed, M ignored, P filtered out (X suites, Ys)"
- Fallback to original behavior if parsing fails
- Failures still show full details (no aggregation)

Tests: 6 new + 1 modified, covering all cases:
- Multi-suite aggregation
- Single suite (singular "suite")
- Zero tests
- With ignored/filtered out
- Failures → no aggregation (detail preserved)
- Regex fallback

Closes #83

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(ci): prevent Python/Go benchmark sections from being silently skipped

**Problem:**
Python and Go benchmark sections were silently skipped in CI because
the RTK repository doesn't contain pyproject.toml or go.mod files.
The sections only ran when these project files existed.

**Solution:**
1. Create temporary fixtures with minimal project structure:
   - Python: pyproject.toml + sample.py + test_sample.py
   - Go: go.mod + main.go + main_test.go
2. Resolve RTK to absolute path to work after cd into temp dirs
3. Install required tools in CI workflow:
   - Python: ruff, pytest
   - Go: stable version + golangci-lint

**Impact:**
- Python/Go sections now appear in CI benchmark output
- Self-contained fixtures ensure consistent benchmarking
- No dependency on RTK project structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(hooks): add missing RTK command rewrites

Add 8 missing command rewrites to rtk-rewrite.sh and rtk-suggest.sh:
- cargo check/install/fmt
- tree, find, diff
- head → rtk read (with --max-lines transformation)
- wget

Fixes BSD sed compatibility for head transformation by using literal
spaces instead of \s+ (which doesn't work on macOS).

Impact: ~18.2K tokens saved on previously missed commands discovered
by `rtk discover`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore(master): release 0.15.1 (#96)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat(python): add lint dispatcher + universal format command

Phase 1: Enhanced rtk lint
- Add pylint JSON2 parser (80-85% token savings)
- Add mypy text parser (75-80% token savings)
- Smart dispatcher: Python tools (pip) vs JS tools (npm)
- Reuse ruff_cmd JSON parser for rtk lint ruff

Phase 2: New rtk format command
- Universal formatter: black/ruff/prettier
- Auto-detect from pyproject.toml/package.json
- Implement black output parser (70-85% savings)
- Reuse existing prettier/ruff formatters

Phase 3: Hook integration
- Auto-rewrite: pylint → rtk lint pylint
- Auto-rewrite: mypy → rtk lint mypy
- Auto-rewrite: black --check → rtk format black

Files changed:
- src/lint_cmd.rs: +454 lines (pylint/mypy parsers, dispatcher)
- src/format_cmd.rs: +386 lines (NEW - universal formatter)
- src/ruff_cmd.rs: Export filter functions as pub
- src/prettier_cmd.rs: Export filter_prettier_output as pub
- src/main.rs: Add Commands::Format + routing
- hooks/rtk-rewrite.sh: Add Python tool rewrite rules

Testing: 10 new unit tests, all 313 tests passing
Impact: 80-90% token savings on Python workflows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Michael Coen <mhcoen@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-14 14:22:48 +01:00
Christian C. Berclaz 04e6bb032c fix(git): fix for issue #82
Returns "Not a git repository" when git status is executed in a
non-repo folder
2026-02-14 10:27:51 +01:00
polamin 155e26423d fix: prevent UTF-8 panics on multi-byte characters (#93)
* 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>
2026-02-13 18:03:32 +01:00
Florian BRUNIAUX e5adba8b21 fix(vitest): robust JSON extraction for pnpm/dotenv prefixes (#92)
* fix(vitest): robust JSON extraction for pnpm/dotenv prefixes

Problem: RTK's vitest parser forces --reporter=json but pnpm/dotenv prepend
non-JSON text to stdout (banners, env messages), causing 100% Tier 1 failure
and useless 500-char passthrough.

Solution:
- Add extract_json_object() to parser/mod.rs (shared utility)
- Algorithm: find "numTotalTests" or first standalone {, brace-balance forward
- VitestParser now tries direct parse → extract+parse → regex → passthrough
- Replace hardcoded Command::new("pnpm") with package_manager_exec("vitest")
- Delete orphan doc comment on line 203

Impact:
- Before: 100% Tier 3 passthrough with pnpm workflows
- After: Tier 1 success with prefixes, maintains 99.5% token savings

Tests:
- 6 tests for extract_json_object (clean, pnpm, dotenv, nested, no-json, strings)
- 3 tests for VitestParser with prefixes
- All 277 tests pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore(benchmark): add vitest, pnpm, and gh commands

Add benchmarks for recently implemented commands:
- vitest run (PR #92 - JSON extraction fix)
- pnpm list/outdated (PR #6)
- gh pr list/run list (existing gh support)

These commands are now tested in CI to ensure token savings are maintained.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 23:11:24 +01:00
Florian BRUNIAUX a005bb15c0 feat: add Python and Go support (#88)
* feat(cargo): aggregate test output into single line (#83)

Problem: `cargo test` shows 24+ summary lines even when all pass.
An LLM only needs to know IF something failed, not 24x "ok".

Before (24 lines):
```
✓ test result: ok. 2 passed; 0 failed; ...
✓ test result: ok. 0 passed; 0 failed; ...
... (x24)
```

After (1 line):
```
✓ cargo test: 137 passed (24 suites, 1.45s)
```

Changes:
- Add AggregatedTestResult struct with regex parsing
- Merge multiple test summaries when all pass
- Format: "N passed, M ignored, P filtered out (X suites, Ys)"
- Fallback to original behavior if parsing fails
- Failures still show full details (no aggregation)

Tests: 6 new + 1 modified, covering all cases:
- Multi-suite aggregation
- Single suite (singular "suite")
- Zero tests
- With ignored/filtered out
- Failures → no aggregation (detail preserved)
- Regex fallback

Closes #83

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add Python and Go language support

Implements comprehensive support for Python and Go development tooling
with 70-90% token reduction across all commands.

Python commands (3):
- rtk ruff: Linter/formatter with JSON (check) and text (format) parsing (80%+)
- rtk pytest: Test runner with state machine text parser (90%+)
- rtk pip: Package manager with auto-detect uv (70-85%)

Go commands (4):
- rtk go test: NDJSON streaming parser for interleaved test events (90%+)
- rtk go build: Text filter showing errors only (80%)
- rtk go vet: Text filter for issues (75%)
- rtk golangci-lint: JSON parser grouped by rule (85%)

Architecture:
- Standalone Python commands (mirror lint/prettier pattern)
- Go sub-enum (mirror git/cargo pattern)
- 5 new modules: ruff_cmd, pytest_cmd, pip_cmd, go_cmd, golangci_cmd
- Hook integration in rtk-rewrite.sh for transparent rewrites
- Comprehensive tests (47 new tests, all passing)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(benchmark): add Python and Go commands

Add benchmark sections for Python (ruff, pytest, pip) and Go (go test/build/vet, golangci-lint) to validate >80% token savings in CI pipeline.

Sections conditionally execute based on project markers (pyproject.toml, go.mod) and tool availability.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 21:51:10 +01:00
Florian BRUNIAUX 06b10491f9 feat(cargo): aggregate test output into single line (#83) (#85)
Problem: `cargo test` shows 24+ summary lines even when all pass.
An LLM only needs to know IF something failed, not 24x "ok".

Before (24 lines):
```
✓ test result: ok. 2 passed; 0 failed; ...
✓ test result: ok. 0 passed; 0 failed; ...
... (x24)
```

After (1 line):
```
✓ cargo test: 137 passed (24 suites, 1.45s)
```

Changes:
- Add AggregatedTestResult struct with regex parsing
- Merge multiple test summaries when all pass
- Format: "N passed, M ignored, P filtered out (X suites, Ys)"
- Fallback to original behavior if parsing fails
- Failures still show full details (no aggregation)

Tests: 6 new + 1 modified, covering all cases:
- Multi-suite aggregation
- Single suite (singular "suite")
- Zero tests
- With ignored/filtered out
- Failures → no aggregation (detail preserved)
- Regex fallback

Closes #83

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 20:36:13 +01:00
Joan Bordeau 93364b5457 feat(sqlite): add custom sqlite db location 2026-02-10 21:42:46 +01:00
Florian BRUNIAUX 645a773a65 feat(cargo): add cargo install filtering with 80-90% token reduction
Strip dep compilation, downloading, locking noise from cargo install output.
Keep only installed/replaced/error lines with compact summary format.

Closes #69

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:36:14 +01:00
Florian BRUNIAUX 848a63dfac feat(init): auto-patch settings.json for frictionless hook installation
## Summary

Eliminates manual settings.json setup friction by automating hook
registration with safety (backup, atomic writes, idempotency).

## Changes

### Core Features
- **Auto-patch**: Default `rtk init -g` prompts to patch settings.json [y/N]
- **CLI flags**: `--auto-patch` (no prompt), `--no-patch` (manual), `--uninstall` (full cleanup)
- **Safety**: Automatic backup to `settings.json.bak` before modification
- **Idempotency**: Detects existing hook, skips modification
- **Status check**: `rtk init --show` now displays settings.json registration

### Implementation
- New types: `PatchMode` (Ask/Auto/Skip), `PatchResult` (tracking outcomes)
- New functions in `src/init.rs`:
  - `hook_already_present()` - Detects RTK hook via substring match
  - `insert_hook_entry()` - Deep-merges hook using idiomatic `entry()` API
  - `atomic_write()` - Crash-safe writes with tempfile
  - `patch_settings_json()` - Main orchestrator
  - `uninstall()` - Complete cleanup (hook, RTK.md, settings.json)
- Modified functions: `run()`, `run_default_mode()`, `run_hook_only_mode()`, `show_config()`

### Code Quality Improvements
- Refactored `insert_hook_entry()` to use Rust `entry()` API (no manual unwraps)
- Simplified `hook_already_present()` with iterator chains (3x shorter)
- Improved error messages with file paths and actionable hints
- Fixed string allocation (to_str() vs to_string())

### Dependencies
- Added `preserve_order` feature to `serde_json` (key order preservation)
- Moved `tempfile` to production dependencies (atomic writes)

### Documentation
- **README.md**: Updated Quick Install, added Installation Flags, Uninstalling, Troubleshooting, What Are Hooks sections
- **INSTALL.md**: Updated Recommended Setup, added Common User Flows, Uninstalling sections
- **CHANGELOG.md**: Documented new feature under Unreleased

### Testing
- 11 new unit tests for hook detection, insertion, atomic writes, cleanup
- All 249 tests passing
- Smoke tested: install, idempotency, show, uninstall

## User Impact

**Before**: Users had to manually copy JSON snippet to settings.json
**After**: Single command with prompt, automatic backup, clean uninstall

## Breaking Changes

None. Backwards compatible - manual setup still works via `--no-patch`.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-07 16:12:40 +01:00
Florian BRUNIAUX 38fc860c31 refactor(init): eliminate DRY violations and improve error handling
## Code Quality Improvements

**Extracted helper functions:**
- `prepare_hook_paths()`: Prepare hook directory and paths (DRY)
- `ensure_hook_installed()`: Idempotent hook installation with chmod
- `write_if_changed()`: Generic file write with idempotence

**Before (duplicated):**
- Hook path logic repeated in default_mode + hook_only_mode
- Hook write logic repeated (lost idempotence in hook-only)
- RTK.md write logic duplicated

**After (DRY):**
- Single source of truth for each operation
- Consistent idempotence across all modes
- Reusable helpers for future file operations

## Error Handling Enhancements

**Improved error context:**
- `.with_context(|| format!("Failed to write hook to {}", path))`
- All fs operations now include the path that failed
- Migration warnings include line numbers and actionable steps

**Better Windows messaging:**
- Clear explanation of platform limitations
- Explicit fallback behavior

## API Improvements

**Idiomatic Rust:**
- `&PathBuf` → `&Path` for all function parameters
- Pattern match tuple instead of if/else chain
- `anyhow::bail!` for Windows hook-only error

## Impact

- **Maintainability**: Single place to update hook/file logic
- **Debuggability**: Error messages show exact paths
- **Robustness**: Consistent idempotence prevents conflicts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-07 15:28:24 +01:00
Florian BRUNIAUX 9620f66cd6 feat(init): refactor to hook-first with slim RTK.md
## Changes

**New default mode (hook + RTK.md):**
- Embed hook script in binary (include_str!)
- Write hook + chmod +x with guards (rtk/jq check before set -e)
- Write slim RTK.md (10 lines: meta commands only)
- Add @RTK.md reference to CLAUDE.md
- Print settings.json instructions (no auto-patch)

**Migration:**
- Auto-detect old <!-- rtk-instructions --> block
- Remove 137-line block, preserve user content
- Replace with @RTK.md reference

**New CLI flags:**
- `--claude-md`: Legacy mode (full injection)
- `--hook-only`: Hook only, no RTK.md
- Default (no flags): Hook + RTK.md (recommended)

**Enhanced --show:**
- Detect hook executable status (Unix)
- Detect hook guards (rtk/jq)
- Detect @RTK.md vs old block
- Show slim vs legacy mode

**Files added:**
- hooks/rtk-rewrite.sh (embedded, with guards)
- hooks/rtk-awareness.md (slim RTK.md content)

**Token savings:**
~2000 tokens → ~10 tokens in context (99.5% reduction)
Hook rewrites commands transparently (0 tokens overhead)

**Tests:** 9 new tests, all passing (236 total)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-07 15:11:24 +01:00
Florian BRUNIAUX d5f8a94604 fix(discover): add cargo check support, wire RtkStatus::Passthrough, enhance rtk init
## Discover Registry Fixes
- Add `check` to cargo pattern (registry.rs:52)
- Add `("check", 80.0)` savings to cargo rule
- Wire `RtkStatus::Passthrough` for `cargo fmt` (0% savings, passthrough mode)
- Add `status: RtkStatus` field to `Classification::Supported`
- Extract status from subcommand rules in classify_command()
- Fix UTF-8 truncation bug in report.rs truncate_str() (panic on multi-byte chars)

## Tests (7 new)
- test_classify_cargo_check()
- test_classify_cargo_check_all_targets()
- test_classify_cargo_fmt_passthrough() → status = Passthrough
- test_classify_cargo_clippy_savings()
- test_patterns_rules_length_match() → assert PATTERNS.len() == RULES.len()
- test_registry_covers_all_cargo_subcommands() → coupling test
- test_registry_covers_all_git_subcommands() → coupling test

## RTK Init Rewrite
- Rewrite template in English with 32+ commands grouped by workflow
- Add version marker `<!-- rtk-instructions v2 -->` for idempotency
- Fix idempotency detection: use marker instead of French text
- Add tests:
  - test_init_mentions_all_top_level_commands() → 15 key commands
  - test_init_has_version_marker()

## Documentation
- CLAUDE.md: dual format (raw + rtk) for all dev commands
- CLAUDE.md: pre-commit gate uses rtk
- ~/.claude/CLAUDE.md: add Cargo section (80-90% savings)

## Verification
✅ 229 tests pass (7 new)
✅ 88 smoke tests pass
✅ cargo fmt + clippy clean
✅ All coupling tests enforce registry/Commands alignment

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:28:13 +01:00
Florian BRUNIAUX 60d2d252ef fix: P0 crashes + cargo check + dedup utilities + discover status
Phase 1: Fix P0 crashes (3 bugs)
- Add external_subcommand fallback for cargo/docker/kubectl
- Fixes crashes on unsupported subcommands (e.g., cargo fmt, docker build)
- All passthroughs now route gracefully instead of Clap parse errors

Phase 2: cargo check handler + refactor (-40 lines)
- Add dedicated cargo check handler (most frequently used missing command)
- Extract run_cargo_filtered() to eliminate 90 lines of duplication
- Fix filter_cargo_build() to handle "Checking" prefix (not just "Compiling")
- Normalize exit code propagation in run_test()

Phase 3: Utility deduplication (-60 lines)
- Fix utils::truncate() Unicode handling (char-aware, not byte-based)
- Remove 5 duplicated utility functions across modules:
  - 3x truncate() → use crate::utils::truncate
  - 1x strip_ansi() → use crate::utils::strip_ansi
- Replace ~60 lines of inline package manager detection with utils::package_manager_exec()
- Clean: lint_cmd, prettier_cmd, playwright_cmd now use shared utils

Phase 4: Discover reporting improvements
- Add RtkStatus enum (Existing/Passthrough/NotSupported)
- Show status column in discover report to distinguish handler types
- Prevents future misleading "build 9 git subcommands" false analyses

Cleanup:
- Remove 2 unused imports (parser::ParseError, std::collections::HashMap)
- Reduce clippy warnings from 23 to 19

Testing:
- 220 tests pass
- 88 smoke tests pass
- All manual verification complete

Net: +10 lines, -3 P0 bugs, -5 duplications, +1 feature, +1 enum

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 10:37:50 +01:00
Florian BRUNIAUX 40e7eadbaf fix(git): accept native git flags in add command (including -A)
Problem:
- `rtk git add -A` failed with "unexpected argument '-A' found"
- Git flags like -A, -p, --all were rejected by Clap parser
- Only filenames could be passed to `git add`

Solution:
- Add `allow_hyphen_values = true` to Add command args (following PR #5 pattern)
- Change Add enum variant from `Add { files }` to `Add` (unified with other git commands)
- Modify run_add() to accept args slice and pass all arguments to git
- Add exit code propagation for consistency with other git commands

Impact:
- All native git add flags now work: -A, -p, --all, --update, etc.
- Maintains RTK compact output format ("ok ✓ 2 files changed, ...")
- Preserves backward compatibility (no args defaults to ".")

Testing:
- Manual: `rtk git add -A` works correctly
- All existing tests pass (154 passed)
- Smoke tests unchanged (git add not included in test-all.sh)

Fixes: Argument parsing error for git add with native flags

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 15:54:20 +01:00
patrick szymkowiak 3df8ce5525 Merge pull request #57 from FlorianBruniaux/fix/rtk-tsc-show-all-errors
fix(tsc): show every TypeScript error instead of collapsing by code
2026-02-04 18:23:45 +01:00
Florian BRUNIAUX 67e8de8732 fix(tsc): show every TypeScript error instead of collapsing by code
The previous implementation grouped errors by error code within each
file, showing only the first message when multiple errors shared the
same code (e.g. TS2322). This hid critical debugging information and
forced users to bypass rtk entirely.

Changes:
- Show each error individually with line number and full message
- Capture and display tsc continuation/context lines
- Increase message truncation from 60 to 120 chars
- Remove artificial limits (was: 3 codes/file, 10 files max)
- Compact top-codes summary to a single line

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 18:12:46 +01:00
patrick szymkowiak a5d0fd19fd Merge pull request #55 from LivioGama/fix/rtk-init-global-path
Fix rtk init global path
2026-02-03 17:40:11 +01:00
Patrick szymkowiak ea7cdb7a3b fix(ls): compact output (-72% tokens) + fix discover panic
- ls: rewrite to strip permissions/owner/group/dates, show only
  names with dir/ suffix and human sizes. Properly handle flag
  ordering (path -l), -lh, multi-paths, --all.
- discover: remove orphan diff pattern that caused index out of
  bounds panic (PATTERNS had 22 entries vs RULES 21)
- benchmark: add 8 ls test cases
- test-all: add 5 ls smoke tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:05:01 +01:00
Patrick szymkowiak ffe0d2e037 chore: cleanup diff references, fix docker ps, widen diff truncation
- Remove rtk diff from docs, tests, discover registry (command exists
  but was over-promoted)
- docker ps: include container ID in compact output
- diff_cmd: widen truncation from 35 to 70 chars per side

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:38:56 +01:00
Patrick szymkowiak fcc14624f8 fix(find): rewrite with ignore crate + fix json stdin + benchmark pipeline
- find: replace fd/find subprocess with ignore::WalkBuilder for native
  .gitignore support, fix "." pattern, fix --max file counting
- json: add stdin support via "-" path (same pattern as read)
- benchmark: one-line-per-test format with icons for CI logs,
  local debug files only when not in CI, remove md upload/PR steps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:38:17 +01:00
Florian BRUNIAUX b13d92c9ea fix(docs): escape HTML tags in rustdoc comments
Fixes 6 rustdoc warnings:
- Escape <action>, <detail>, <hash>, <branch>, <stats> tags
- Use backticks for [RTK:PASSTHROUGH] marker

All rustdoc warnings now resolved.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 11:33:40 +01:00
Florian BRUNIAUX 521eb1b9bc docs(tracking): complete API documentation + rustdoc comments
Add comprehensive documentation for tracking.rs public APIs:

**New Files:**
- docs/tracking.md (12 pages)
  - Architecture & data flow
  - All public APIs (12 methods, 7 types)
  - Usage examples (basic, CI/CD, dashboards, Rust lib)
  - JSON/CSV export schemas
  - Database schema & migrations
  - Integration examples (GitHub Actions, Python, Rust)
  - Security, performance, troubleshooting

- claudedocs/TRACKING_DOCUMENTATION.md
  - Documentation summary & metrics

**Updated Files:**
- src/tracking.rs
  - Module-level docs (//!)
  - Comprehensive doc comments (///) for all public APIs
  - Examples with error handling
  - Deprecation notices for legacy functions

- README.md
  - Pointer to docs/tracking.md after rtk gain section

**Coverage:**
- 7 public structs documented
- 12 public methods documented
- 3 utility functions documented
- 20+ code examples
- 3 integration examples (CI/CD, dashboards, Rust lib)
- JSON/CSV/SQL schemas

**Testing:**
- All 6 tracking tests still pass
- 100% coverage maintained

Closes gap: CLI was documented, but public APIs were not.
Now fully documented for external integration (CI/CD, dashboards, Rust lib usage).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 11:22:20 +01:00
Florian BRUNIAUX 7975624d0a feat: audit phase 3 + tracking validation + rtk learn
## Audit Tracking Phase 3 (Steps 0-6)
- Systematic tracking integration across all command modules
- TimedExecution pattern enforcement (9 files)
- Passthrough timing support for interactive commands
- Exit code preservation for CI/CD reliability

## Tracking Validation Tests
- 6 unit tests in src/tracking.rs (was 0)
  - estimate_tokens, args_display, DB round-trip
  - Passthrough non-dilution, TimedExecution timing
- 2 UTF-8 tests for gh_cmd truncate() (emoji support)
- scripts/test-tracking.sh: end-to-end smoke tests (9 checks)

## rtk learn (CLI Correction Detector)
- New module: src/learn/ (detector, report, orchestration)
- Analyzes Claude Code JSONL sessions for CLI error patterns
- Auto-generates .claude/rules/cli-corrections.md
- 18 new tests (detector: 15, report: 3)
- Commands: rtk learn [--write-rules] [--since N] [--format json]

## Provider Extensions
- ExtractedCommand: +output_content, +is_error, +sequence_index
- Backward compatible with existing discover::run()
- 3 new provider tests (capture, error flag, sequence)

## Test Results
✓ 201 unit tests passed (183 existing + 18 new)
✓ 9 tracking smoke tests passed
✓ cargo fmt + clippy clean
✓ No deprecation warnings

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 10:05:06 +01:00
Livio Gamassia c58bd95062 Fix global init path and append behavior 2026-02-03 08:30:54 +00:00
Florian BRUNIAUX 060c38b3c1 feat(read): add stdin support via "-" path
Add ability to read from stdin using the special path "-", following
Unix conventions. Also fixes a pre-existing bug in git.rs push output.

Changes:
- src/main.rs: Check for Path::new("-") and route to run_stdin()
- src/read.rs: Add run_stdin() function for stdin processing
- src/read.rs: Use Language::Unknown for stdin (no file extension)
- src/git.rs: Fix unused format! result in push command
- Unit test: test_stdin_support_signature verifies function exists
- Smoke tests: 1 assertion for stdin pipe

Usage:
  echo "code" | rtk read -
  cat file.txt | rtk read - --level aggressive
  somecommand | rtk read - -n

Note: Stdin detection requires explicit "-" path to avoid hanging.
No automatic stdin detection is performed.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 23:33:45 +01:00
Florian BRUNIAUX a240d1a1ee feat(grep): add extra args passthrough (-i, -A/-B/-C, etc.)
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>
2026-02-02 23:19:43 +01:00
Florian BRUNIAUX 614ff5c13f feat(pnpm): add fallback passthrough for unsupported subcommands
Add external_subcommand variant to PnpmCommands enum to handle
unsupported pnpm operations by passing them through directly.

Changes:
- src/pnpm_cmd.rs: Add run_passthrough() function with OsString support
- src/pnpm_cmd.rs: Add OsString import
- src/main.rs: Add PnpmCommands::Other variant with external_subcommand
- src/main.rs: Add match arm for pnpm passthrough
- Unit test: test_run_passthrough_accepts_args verifies signature
- Smoke tests: Conditional test for pnpm help if pnpm is available

This maintains compatibility with all pnpm commands while preserving
RTK's token-optimized versions for list/outdated/install.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 22:21:03 +01:00
Florian BRUNIAUX 32bbd02534 feat(git): add fallback passthrough for unsupported subcommands
Add external_subcommand variant to GitCommands enum to handle
unsupported git operations (tag, remote, rev-parse, etc.) by
passing them through directly to git.

Changes:
- src/git.rs: Add run_passthrough() function with OsString support
- src/main.rs: Add GitCommands::Other variant with external_subcommand
- src/main.rs: Add OsString import and match arm for passthrough
- Unit test: test_run_passthrough_accepts_args verifies signature
- Smoke tests: 3 new assertions for tag, remote, rev-parse

This preserves all git functionality while maintaining RTK's
token-optimized commands for supported operations.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 21:58:09 +01:00
Florian BRUNIAUX 278cc5700b feat: add rtk tree + fix rtk ls + audit phase 1-2
⚠️ MERGE AFTER: Résoudre issues Patrick (curl, benchmark, bypass)

## Changes

### 1. rtk tree - NEW COMMAND ✨
- Proxy vers `tree` natif avec filtrage token-optimized
- Filtre ligne summary ("X directories, Y files")
- Support complet flags natifs (-L, -d, -a, etc.)
- Message installation si tree absent
- Tests: 5/5 passing

Files:
- src/tree.rs (new, 159 lines)
- src/main.rs (add Tree command)

### 2. rtk ls - FIX 🐛
- Fix: ne force plus `-la` par défaut
- Comportement: passthrough pur vers ls natif
- Permet `rtk ls` simple sans flags forcés

Files:
- src/ls.rs (remove default -la)

### 3. Tests - UPDATE ✅
- Fix 3 tests obsolètes rtk ls (--depth, -f tree)
- Add 4 tests rtk tree
- Results: 75 PASS, 0 FAIL, 1 SKIP (98.7%)

Files:
- scripts/test-all.sh

## Audit Phase 1-2 (local docs)

Inventaire complet + analyse paramètres (40+ commandes):
- claudedocs/COMMAND_AUDIT.md
- claudedocs/PARAMETER_ANALYSIS.md
- claudedocs/rtk-tree-implementation.md
- claudedocs/PATRICK_FEEDBACK.md

15+ gaps critiques identifiés (grep -i, git fallback, etc.)

## Issues Patrick à résoudre AVANT merge

1. curl global à remettre
2. Benchmark.sh à exécuter
3. Souci de token à investiguer
4. Erreur PR/bypass des commandes
5. Commandes cassées à identifier

## Test

```bash
# Tree
rtk tree -L 2 src/
rtk tree -d -L 1 .

# Ls (nouveau comportement)
rtk ls          # Simple listing
rtk ls -la      # Detailed
rtk ls -lh      # Human readable

# Tests
bash scripts/test-all.sh  # 75 PASS ✅
cargo test tree::tests    # 5 PASS ✅
```

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 21:01:19 +01:00
Florian BRUNIAUX 2df4a348ab docs: add suggest hook pattern + fix discover issues URL
Changes:
- Fix discover issues URL: FlorianBruniaux → rtk-ai upstream repo
- Document suggest hook pattern as non-intrusive alternative to auto-rewrite
- Add rtk-suggest.sh template with systemMessage strategy
- Provide comparison table and setup instructions

The suggest hook emits system reminders instead of rewriting commands,
giving Claude Code explicit visibility into rtk alternatives while
preserving user control over execution decisions.

Use cases:
- Learning rtk patterns with visibility into rewrite logic
- Auditing command choices without forced adoption
- Debugging workflows requiring exact command preservation
- User preference for explicit control over transparency

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 17:03:19 +01:00
Florian BRUNIAUX a27bce82f0 fix: allow git status to accept native flags
Previously, `rtk git status` was the only git subcommand that rejected
all arguments. This fix aligns it with other git subcommands (diff, log,
show, etc.) by accepting native git flags.

Changes:
- Extract format_status_output() as pure testable function
- Add args variant to Clap Status command with trailing_var_arg
- Modify run_status() to accept args parameter
- Passthrough mode: if user provides flags (--short, -s, --porcelain),
  forward directly to git without RTK formatting
- Default mode: no flags = RTK compact formatting (unchanged behavior)
- Add 5 unit tests for format_status_output (clean, modified, untracked,
  mixed, truncation)
- Add 4 smoke tests for flag passthrough (--short, -s, --porcelain)

Test results:
- 151 unit tests passed (5 new)
- 69 smoke tests passed (4 new for status flags)

Fixes the issue where commands like `rtk git status --short` were
rejected with "unexpected argument" error.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 16:42:06 +01:00
Florian BRUNIAUX cf26ad477b feat: migrate vitest, playwright, pnpm to OutputParser trait
Complete Phase 4 module migrations - refactor to use unified parser infrastructure:

**Modules Migrated:**
1. vitest_cmd.rs → VitestParser : OutputParser<Output=TestResult>
2. playwright_cmd.rs → PlaywrightParser : OutputParser<Output=TestResult>
3. pnpm_cmd.rs → PnpmListParser + PnpmOutdatedParser : OutputParser<Output=DependencyState>

**Architecture:**
- All modules now use three-tier fallback (Full/Degraded/Passthrough)
- Leverage TokenFormatter trait for Compact/Verbose/Ultra modes
- Canonical types (TestResult, DependencyState) replace ad-hoc structures
- Consistent error handling with emit_degradation_warning/emit_passthrough_warning

**Benefits:**
- 41 lines removed (762 insertions, 803 deletions)
- Unified formatting across all test runners
- Observable parsing tiers in verbose mode
- Better maintainability with shared infrastructure
- Foundation for future module migrations

**Testing:**
- 10 new tests added (4 vitest, 3 playwright, 3 pnpm)
- All migrated modules pass their test suites
- JSON Tier 1 parsing validated
- Regex Tier 2 fallback validated
- Passthrough Tier 3 safety validated

**Next Steps:**
- Migrate remaining modules (lint_cmd, tsc_cmd, gh_cmd, prisma_cmd)
- Add observability (track parse_tier in tracking.db)
- Performance benchmarking of new architecture

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 08:44:11 +01:00
Florian BRUNIAUX edab4e142e feat: add parser infrastructure with three-tier fallback system
Implement Phase 3 of maintainability plan - unified parser architecture:

**Core Components:**
- parser/mod.rs: OutputParser trait + ParseResult enum (Full/Degraded/Passthrough)
- parser/error.rs: ParseError types with thiserror (JSON, Pattern, Partial, etc.)
- parser/types.rs: Canonical types (TestResult, LintResult, DependencyState, BuildOutput)
- parser/formatter.rs: TokenFormatter trait with Compact/Verbose/Ultra modes
- parser/README.md: Complete usage guide and migration examples

**Three-Tier Fallback System:**
1. Tier 1 (Full): Complete JSON parsing with structured data
2. Tier 2 (Degraded): Partial regex extraction with warnings
3. Tier 3 (Passthrough): Truncated raw output with [RTK:PASSTHROUGH] marker

**Benefits:**
- Never returns false data silently (fixes prisma_cmd issue)
- Graceful degradation on tool version changes
- Unified interface across all tool types
- Observable degradation with [RTK:DEGRADED] warnings
- Foundation for Phase 4 module migrations

**Dependencies:**
- Added thiserror 1.0 for structured error types

**Testing:**
- 3 unit tests for ParseResult tier system
- Tests pass: tier(), is_ok(), map(), warnings()

Next: Phase 4 - Migrate existing modules to use parser trait

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 08:43:19 +01:00
Florian BRUNIAUX 50ba21e2e5 feat: add JSON parsing with safe fallbacks for vitest, playwright, pnpm
Implement "Structured Output First" strategy with graceful degradation:

Phase 1 (Quick Wins):
- vitest: Add --reporter=json flag
- playwright: Add --reporter=json flag
- pnpm list/outdated: Add --json/--format json flags

Phase 2 (Safe Fallbacks):
- All modules: JSON parsing with [RTK:DEGRADED] fallback to regex
- Prevents silent failures and false data returns
- Three-tier fallback: JSON → Regex → Truncated passthrough

Impact:
- Eliminates 75% of maintenance risk from output format changes
- Provides structured data parsing for better token compression
- Maintains backward compatibility with existing regex parsers

Token savings maintained while improving reliability and future-proofing
against tool version changes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 08:43:19 +01:00
Florian BRUNIAUX 1d857914d6 feat: add local LLM analysis, filter improvements, and testing scripts
Add smart code analysis with local LLM integration (rtk smart command),
improve filter.rs formatting and readability, and add comprehensive
testing utilities.

Key changes:
- local_llm.rs: Ultra-compact code summaries for LLM contexts
- filter.rs: Better formatting, enhanced comment/docstring detection
- main.rs: Integrate smart command routing
- config.rs: Code formatting improvements
- .gitignore: Exclude claudedocs/ directory
- scripts/rtk-economics.sh: Token savings analysis
- scripts/test-all.sh: Comprehensive test runner
- scripts/test-aristote.sh: Project-specific test suite

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 08:43:19 +01:00
Florian BRUNIAUX 2a1e1a8ef3 feat: add execution time tracking to rtk gain analytics
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>
2026-02-02 00:14:06 +01:00
Florian BRUNIAUX 2176369467 fix: convert rtk ls from reimplementation to native proxy
BREAKING CHANGE: Removes --depth, --format (tree/flat/json) flags

Before: `rtk ls` was a reimplementation using WalkBuilder that didn't
support native ls flags like -l, -a, -h, -R.

After: `rtk ls` proxies to native ls, supporting all flags:
- `rtk ls -la` works
- `rtk ls -alh` works
- `rtk ls -R src/` works
- Default: `-la` when no args

Token optimization: filters "total X" line from output.

This aligns with rtk philosophy: proxy and filter, don't reimplement.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 21:22:17 +01:00
patrick szymkowiak c9c64cfd30 Merge pull request #36 from FlorianBruniaux/feat/git-show
feat: discover command, auto-rewrite hook, git show
2026-02-01 20:07:12 +01:00
Florian BRUNIAUX 4bb0130695 fix: forward args in rtk git push/pull to support -u, remote, branch
rtk git push and rtk git pull now accept trailing arguments and forward
them to git. Fixes the auto-rewrite hook failing on commands like
`git push -u origin feat/branch`.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:38:02 +01:00
Florian BRUNIAUX ff1c7598c2 feat: add discover command, auto-rewrite hook, and git show support
- New `rtk discover` command scans Claude Code JSONL session history to
  identify missed RTK savings and suggest unhandled commands for issues.
  Modular architecture: registry (RegexSet classification), provider
  (SessionProvider trait + ClaudeProvider), report (text/json formatting).

- New PreToolUse auto-rewrite hook transparently intercepts Bash commands
  and rewrites them to rtk equivalents before execution, ensuring 100%
  adoption across all conversations including subagents.

- New `rtk git show` command with compact output: one-line commit summary
  + stat + compacted diff (reuses compact_diff from git diff).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:31:34 +01:00
Florian BRUNIAUX 2d66726206 Add TDD skill, fix 3 failing tests, add 17 diff_cmd tests
- Fix test_analyze_logs: use normalizable paths instead of distinct IPs
- Fix test_filter_outdated: match real pnpm outdated output format
- Fix test_filter_ansi_colors: add missing Tests line for stats parsing
- Add .claude/skills/rtk-tdd/ with Red-Green-Refactor workflow
- Add testing-patterns.md reference with untested modules backlog
- Update CLAUDE.md Testing Strategy with TDD mandate and pre-commit gate
- Add 17 tests to diff_cmd.rs (similarity, truncate, compute_diff, condense)
- Test suite: 102/105 → 122/122

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 14:20:25 +01:00
Florian BRUNIAUX 314accbfd9 feat: curl with auto-JSON detection
- Execute curl -s, auto-detect JSON responses
- JSON output piped through filter_json_string() for schema view
- Non-JSON output truncated to 30 lines with byte count

New module: src/curl_cmd.rs with 4 unit tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:39:55 +01:00
Florian BRUNIAUX 49b3cf293d feat: npm/npx routing, pnpm build/typecheck, --skip-env flag
- npm run: filter boilerplate (> script, npm WARN, progress)
- npx: intelligent routing to specialized filters
  (tsc, eslint, prisma, next, prettier, playwright)
- pnpm build: delegates to next_cmd filter
- pnpm typecheck: delegates to tsc_cmd filter
- --skip-env global flag: propagates SKIP_ENV_VALIDATION=1

New module: src/npm_cmd.rs with 2 unit tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:39:03 +01:00
Florian BRUNIAUX 517a93d0e4 feat: gh pr create/merge/diff/comment/edit + gh api
- gh pr create: capture URL + number, "ok created #N url"
- gh pr merge: "ok merged #N" confirmation
- gh pr diff: reuse compact_diff() for condensed output
- gh pr comment/edit: generic "ok {action} #N" confirmations
- gh api: auto-detect JSON, pipe through filter_json_string()

5 new tests in gh_cmd.rs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:37:17 +01:00
Florian BRUNIAUX bc31da8ad9 feat: git branch, fetch, stash, worktree commands
- git branch: compact listing (current/local/remote-only)
- git fetch: "ok fetched (N new refs)" confirmation
- git stash: list/show/pop/apply/drop with compact output
- git worktree: compact listing with home dir abbreviation

4 new tests in git.rs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:36:44 +01:00