context-lens-tui
v0.1.0
Published
See exactly which files an AI coding agent's context window would include, exclude, or pin, and why, scored live in your terminal.
Maintainers
Readme
Context Lens
A terminal tool that adds a visibility and control layer on top of an AI coding agent's repo context. AI coding tools compress and prioritize files before feeding them to the model, but the process is opaque, you can't see what got included, what got dropped, or why. Context Lens surfaces that decision live in your terminal and lets you override it.
What it shows
- Token budget bar — tokens used vs. total budget, at the top, updated on every rescan.
- One row per candidate file — relative path, relevance score (0-100), token count, and a status:
INCLUDED/EXCLUDED/PINNED. - Exclusion reasons — every excluded file says why:
Below relevance threshold,Token budget exceeded,No task-relevant symbols found, orManually excluded. - Manual overrides — pin a file (force-include, bypassing scoring) or exclude one (force-drop), persisted to a small JSON file in the target directory so it survives between runs.
- Symbol-level drill-down — for JS/TS files, expand a row to see which specific function or class matched the task, with its own score and line range.
Install and run
npm install
npm run compile
# one-shot: prints the snapshot and exits
node out/cli.js <workspace-dir> --task "add password reset flow" --print
# interactive terminal UI
node out/cli.js <workspace-dir> --task "add password reset flow"Or, once published:
npx context-lens-tui <workspace-dir> --task "add password reset flow"Interactive keybindings
| Key | Action |
|---|---|
| up / down or j / k | Move selection |
| enter | Expand/collapse a file's symbol matches |
| p | Pin selected file to context |
| x | Exclude selected file from context |
| c | Clear a manual override |
| r | Rescan the workspace |
| q / Ctrl-C | Quit |
Flags
| Flag | Default | Meaning |
|---|---|---|
| --task "<description>" | (required for real scoring) | What the agent is working on; files are scored against this text. |
| --budget N | 8000 | Total mock token budget for the context window. |
| --threshold N | 15 | Minimum score (0-100) to be eligible for inclusion. |
| --max-files N | 500 | Cap on files scanned per run. |
| --print | off | Print the snapshot once and exit, instead of the interactive UI. |
Excluded from scanning by default: node_modules, .git, out, dist, build, .vscode-test, plus binary/lockfile extensions (.png, .jpg, .svg, .woff, .lock, and similar).
Mock vs. real: the integration boundary
Superbrain's real context engine isn't exposed for this tool to hook into, so v1 ships with a self-contained mock scoring layer that makes it fully demoable against any local directory, with no external dependency.
src/scan.ts (computeContext) is the only implementation today. It:
- Walks the target directory (plain
fs, respecting the ignore list above and--max-files). - Tokenizes each file and the task description, and scores relevance with TF-IDF (term frequency in the file × inverse document frequency across the scanned set), normalized to 0-100 against the top score in the workspace.
- Estimates tokens per file as
content.length / 4, a standard rough approximation, not a real tokenizer. - Walks the ranked list applying pins, exclusions, the relevance threshold, and the token budget in order, attaching an exclusion reason at whichever step drops a file.
- For the highest-scoring JS/TS files, parses each into functions and classes (
src/symbolExtractor.ts) and scores those symbols individually against the task, so a file row can expand into the specific matches that justify its score.
This is the entire integration point. To wire up Superbrain's real context engine, write a function with the same signature as computeContext in src/scan.ts that pulls actual relevance scores, real token counts, and real inclusion/exclusion decisions from Superbrain's internals instead of computing them locally, and swap the one import in src/cli.ts / src/app.ts. Nothing in render.ts, app.ts's rendering, or overrides.ts needs to change, since they only depend on the ContextSnapshot / ContextItem shape (src/types.ts), not on how it was produced.
Project layout
src/
types.ts shared types: ContextItem, ContextSnapshot, Overrides, ScanOptions
symbolExtractor.ts AST-based function/class extraction (Babel)
scan.ts directory scan + TF-IDF scoring + symbol matching
overrides.ts JSON-file pin/exclude persistence
render.ts plain-text snapshot renderer, used by --print
app.ts blessed interactive terminal UI
cli.ts entry point, arg parsingKnown limitations (v1)
- Token counts are a character-based estimate, not a real tokenizer.
- Relevance scoring is a local TF-IDF over the scanned directory, not the agent's actual reasoning about what it needs.
- Symbol extraction covers JS/TS/JSX/TSX only; other languages score at whole-file granularity.
- Symbol scoring runs on the top-ranked files only (
SYMBOL_MATCH_BUDGETinscan.ts), to keep rescans fast on large repos.
Credits
src/symbolExtractor.ts adapts the AST-based function/class extraction from QuackStack's src/lib/chunker.ts, walking a Babel AST to pull out FunctionDeclaration, ClassDeclaration, and named ArrowFunctionExpression nodes. QuackStack uses this to chunk code for embedding generation; here it's repurposed to identify which symbol inside a file actually matched the task, surfaced as expandable rows under each file.
