Skip to content

Token efficiency improvements and .c++ extension fix - #5

Open
andreasjansson wants to merge 7 commits into
mainfrom
fix-cpp-extension
Open

Token efficiency improvements and .c++ extension fix#5
andreasjansson wants to merge 7 commits into
mainfrom
fix-cpp-extension

Conversation

@andreasjansson

@andreasjansson andreasjansson commented Mar 30, 2026

Copy link
Copy Markdown
Owner

Changes

fix: recognize .c++ and .h++ file extensions as C++

Files with the .c++ extension (used extensively in codebases like Cloudflare's edgeworker with 577 C++ implementation files) were falling through to "plaintext" and being completely skipped by leta. This made them invisible to grep, graph, show, refs, and all other commands.

docs: recommend leta files before leta graph for exploring projects

Updated the skill and README to use a files-first workflow:

  • Start with leta files to understand project size and structure
  • Only use leta graph if the project has fewer than ~500 source files
  • For larger projects, use targeted leta calls or leta grep instead

feat: make leta graph output more token-efficient

Two changes to reduce token usage in graph output:

  1. Relative paths: when a callee is in the same directory as its caller, show ./filename instead of the full path
  2. Compact default: omit [Kind] and (signature) by default; use --include-signature to show the verbose format

Before:

crates/core/flags/defs.rs:1537 [Method] update (fn(&self, v: FlagValue) -> Result<()>)
├── crates/core/flags/mod.rs:294 [Function] unwrap_value (fn unwrap_value(self) -> OsString)
└── crates/core/flags/defs.rs:7602 [Function] human_readable_usize (pub(super) fn ...)

After:

crates/core/flags/defs.rs:1537 update
├── ./mod.rs:294 unwrap_value
└── ./defs.rs:7602 human_readable_usize

feat: detect rust-toolchain.toml mismatch and suggest fix

When rust-analyzer fails to start and the workspace has a rust-toolchain.toml or rust-toolchain file pinning to a toolchain that doesn't have rust-analyzer installed, leta now shows an actionable error message:

This project pins to Rust toolchain '1.91' (via rust-toolchain.toml),
which doesn't have rust-analyzer installed.

To fix, run:
  rustup component add rust-analyzer --toolchain 1.91

Previously this showed the generic "install rust-analyzer" message, which was confusing since rust-analyzer was already installed for the default toolchain.

fix: don't cache empty symbol results from LSP

When a language server isn't fully ready (e.g. rust-analyzer still indexing a large workspace), documentSymbol may return empty results. Previously these were cached permanently in the LMDB symbol cache (keyed by file path + mtime), making symbols invisible on all subsequent runs — even after the server finished indexing, and even across daemon restarts.

Now empty symbol results are never cached. The cost of re-fetching for genuinely empty files is negligible.

Files with the .c++ extension (used extensively in some codebases like
edgeworker) were falling through to "plaintext" and being completely
skipped by leta, making 577+ implementation files invisible to grep,
graph, and all other commands.
Update the skill and README to use a files-first workflow:
- Start with `leta files` to understand project size and structure
- Only use `leta graph` if the project has fewer than ~500 source files
- For larger projects, use targeted `leta calls` or `leta grep` instead
Two changes to reduce token usage in graph output:

1. Relative paths: when a callee is in the same directory as its caller,
   show `./filename` instead of the full path.

2. Compact default: by default, omit [Kind] and (signature) from each
   node. Use `--include-signature` to show the full format.

Corpus tests updated with `--include-signature` flag and regenerated
expected output for the new relative path format.
@andreasjansson andreasjansson changed the title fix: recognize .c++ and .h++ file extensions as C++ Token efficiency improvements and .c++ extension fix Mar 30, 2026
When rust-analyzer fails to start and the workspace has a
rust-toolchain.toml or rust-toolchain file, suggest installing
rust-analyzer for that specific toolchain:

  This project pins to Rust toolchain '1.91' (via rust-toolchain.toml),
  which doesn't have rust-analyzer installed.

  To fix, run:
    rustup component add rust-analyzer --toolchain 1.91
Three related fixes for large workspaces (e.g. astral-sh/uv with 64 crates):

1. Increase wait_for_indexing timeouts from 30s to 300s and CLI read
   timeout from 120s to 600s. Large Rust workspaces can take minutes
   for rust-analyzer to index.

2. Treat quiescent+error as indexing done. When rust-analyzer fails to
   load a workspace (e.g. missing cargo in pinned toolchain), it sends
   serverStatus with quiescent=true, health='error'. Previously this
   was ignored, causing wait_for_indexing to block for the full timeout.
   Now we unblock immediately and log a warning with the error message.

3. Show progress on stderr while waiting for daemon response. After 5s
   with no response, print 'Analyzing... (N symbols discovered)' every
   5s by polling the daemon's describe-session endpoint on a separate
   connection. Progress is cancelled as soon as the first response byte
   arrives, ensuring it never appears after stdout output.

Also adds optional analyzing lines to all corpus tests to handle the
progress output, and fixes two pre-existing test issues (Rust refs_basic
content was accidentally wiped, grep_case_sensitive_no_match needed
updating for newer rust-analyzer).
Two new filters to prevent build artifacts from appearing in leta output:

1. .gitignore: If a .gitignore exists in the workspace root, all paths
   it matches are excluded from both grep/graph (enumerate_source_files)
   and files (walk_directory/streaming). This catches .wrangler,
   public/app.js, and any other build output that users already gitignore.

2. Minified file detection: Files with any line longer than 5000 chars
   (checked in the first 32KB) are skipped during symbol collection.
   This catches minified JS/CSS bundles that might not be gitignored.

The gitignore support uses the ignore crate (same as ripgrep) and is
built into leta-fs as shared utilities: build_gitignore(), is_gitignored(),
and is_minified().
@andreasjansson
andreasjansson force-pushed the fix-cpp-extension branch 2 times, most recently from 97d5a18 to 1b54deb Compare March 31, 2026 11:11
…lippy

Replace three optional variables per test with a single one (cctr's
optional string greedily matches multiple lines). Also fix a clippy
collapsible_if warning in session.rs.
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.

1 participant