Repository navigation
fix(cli): show clap error for flag-only invocations + rebrand fallback msg - #4
Merged
Merged
Conversation
…k msg
Reproduction (fresh v0.1.2 install, both macOS and Ubuntu):
$ contextcrawler -v
[rtk: No such file or directory (os error 2)]
`-v` is defined as a global verbosity-count flag, but parsing it without
a subcommand fails. The clap-error fallback path in `run_fallback`
(main.rs:1231) then treated `args[0]` as a binary to exec — so it
ran `Command::new("-v")`, hit ENOENT, and wrapped the error in the
stale `[rtk: ...]` brand string.
Two fixes:
1. Add a leading-dash guard in `run_fallback`: if `args[0].starts_with('-')`,
call `parse_error.exit()` instead of trying to exec the flag.
Sibling to the existing `RTK_META_COMMANDS` guard for the same reason —
"this clearly isn't a passthrough target, show the parse error."
2. Rebrand the two `eprintln!("[rtk: {}]", e)` formats in `run_fallback`
to `[contextcrawler: ...]`. These fire when a real passthrough
command-not-found happens (e.g. `contextcrawler nonexistent-tool`),
and the brand prefix should match the binary name.
After:
$ contextcrawler -v
error: 'contextcrawler' requires a subcommand but one was not provided
[subcommands: ls, tree, read, ...]
Usage: contextcrawler [OPTIONS] <COMMAND>
For more information, try '--help'.
Verified: `cargo build` clean; smoke-tested `-v` and `-nosuchflag` —
both surface clap's proper parse error.
Independent of PR #1/#2/#3. Branched off develop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thehoff
added a commit
that referenced
this pull request
May 24, 2026
…157) The read filter is the #4 absolute leaker per the v0.1.10 audit (1838 runs, 2.5M leaked, 87.3% saved). The existing symmetric head/tail cap works for medium files but degrades on large files where the relevant content sits in the middle. Add `contextcrawler read <file> --intent "<terms>"`. When provided AND the file is > 5KB AND the splitter finds ≥ 3 sections AND at least one section scores above zero, the output becomes: <metadata banner> <head bookend> (omitted on files < 60 lines, byte-capped at 1KB) <top-scoring sections, in original document order> <omission count> <tail bookend> (same gating as head) Otherwise falls through to the existing render path — no regression on small files, no regression when intent omitted. Section splitters covered in v1: - Markdown (.md, .markdown) split on heading lines, skip fenced code - Rust (Language::Rust) top-level item starts (fn, impl, struct, enum, trait, mod, type, const, static), with vis/async/unsafe handled - TOML / Cargo.lock split on lines starting with [ - Unknown paragraph split on blank-line runs Scoring is lexical: per-term occurrence count in body plus heading hits weighted 5×. Stopword list is short and conservative; tokenisation is case-insensitive, alphanumeric + underscore only. No stemming, no LLM — preserves the zero-async, fast-startup posture. Live result on Cargo.lock (this repo, 2316-line / 14K-token file): contextcrawler read Cargo.lock → 0% saved contextcrawler read Cargo.lock --intent "rusqlite chrono" → 96.1% saved Tests added (13 new, total 2681 / 2681 pass): - tokenize_drops_stopwords_and_lowercases - tokenize_handles_punctuation - tokenize_only_stopwords_yields_empty - markdown_splitter_finds_sections - markdown_splitter_ignores_headings_in_fenced_code - rust_splitter_handles_visibility_and_qualifiers - rust_splitter_does_not_split_inner_fns - toml_splitter_array_of_tables - extract_returns_none_for_small_input - extract_returns_none_when_no_section_matches - extract_keeps_matching_section_and_drops_others - extract_preserves_head_and_tail_bookends - extract_achieves_meaningful_reduction Closes #157. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thehoff
added a commit
that referenced
this pull request
May 24, 2026
…157) The read filter is the #4 absolute leaker per the v0.1.10 audit (1838 runs, 2.5M leaked, 87.3% saved). The existing symmetric head/tail cap works for medium files but degrades on large files where the relevant content sits in the middle. Add `contextcrawler read <file> --intent "<terms>"`. When provided AND the file is > 5KB AND the splitter finds ≥ 3 sections AND at least one section scores above zero, the output becomes: <metadata banner> <head bookend> (omitted on files < 60 lines, byte-capped at 1KB) <top-scoring sections, in original document order> <omission count> <tail bookend> (same gating as head) Otherwise falls through to the existing render path — no regression on small files, no regression when intent omitted. Section splitters covered in v1: - Markdown (.md, .markdown) split on heading lines, skip fenced code - Rust (Language::Rust) top-level item starts (fn, impl, struct, enum, trait, mod, type, const, static), with vis/async/unsafe handled - TOML / Cargo.lock split on lines starting with [ - Unknown paragraph split on blank-line runs Scoring is lexical: per-term occurrence count in body plus heading hits weighted 5×. Stopword list is short and conservative; tokenisation is case-insensitive, alphanumeric + underscore only. No stemming, no LLM — preserves the zero-async, fast-startup posture. Live result on Cargo.lock (this repo, 2316-line / 14K-token file): contextcrawler read Cargo.lock → 0% saved contextcrawler read Cargo.lock --intent "rusqlite chrono" → 96.1% saved Tests added (13 new, total 2681 / 2681 pass): - tokenize_drops_stopwords_and_lowercases - tokenize_handles_punctuation - tokenize_only_stopwords_yields_empty - markdown_splitter_finds_sections - markdown_splitter_ignores_headings_in_fenced_code - rust_splitter_handles_visibility_and_qualifiers - rust_splitter_does_not_split_inner_fns - toml_splitter_array_of_tables - extract_returns_none_for_small_input - extract_returns_none_when_no_section_matches - extract_keeps_matching_section_and_drops_others - extract_preserves_head_and_tail_bookends - extract_achieves_meaningful_reduction Closes #157. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Found via Framework devel-test. `contextcrawler -v` failed with a confusing brand-mismatched OS error:
```
$ contextcrawler -v
[rtk: No such file or directory (os error 2)]
```
Root cause: `run_fallback` (`src/main.rs:1231`) catches clap parse failures and tries to exec `args[0]` as a passthrough binary. When `args[0]` is a flag like `-v`, it called `Command::new("-v")`, hit ENOENT, and wrapped the error in the stale `[rtk: …]` brand string.
Fixes
After
```
$ contextcrawler -v
error: 'contextcrawler' requires a subcommand but one was not provided
[subcommands: ls, tree, read, ...]
Usage: contextcrawler [OPTIONS]
For more information, try '--help'.
```
Test plan
Independence
Branched off `develop`. Touches only `src/main.rs` (9 lines). No conflicts with PR #1/#2/#3.
🤖 Generated with Claude Code