Problem
read_file already has the right primitive (head / tail / range + auto-preview at >200 lines, src/tools/filesystem.ts:107). The auto-preview returns the first 80 lines + last 40 lines + an "N lines omitted" marker, telling the caller to re-call with a range.
The gap: on a real 3500+ line file, the head/tail slice doesn't cover the full export list. The caller sees import blocks at the top and the last 40 lines of JSX at the bottom, but has no idea where function AppInner is defined, where handleSubmit lives, etc. They have to follow up with search_content "^export function" (or worse, guess a range) — every single time.
That round-trip is exactly the failure mode the auto-preview was designed to prevent.
Proposal
When auto-preview fires (file > 200 lines), append a symbol outline between the head slice and the omitted-marker:
[outline: 14 top-level exports]
L311 export function AppInner
L1820 export const handleSubmit
L2640 export type AppState
...
Implementation:
- Cheap regex pass over the full file:
^export\s+(async\s+)?(function|class|const|interface|type|enum)\s+(\w+) → (line, kind, name).
- Cap at ~30 entries; if more, list the first 25 + tail 5 with
[… N more …] between.
- Skip when the file is already short (<= 200 lines) — full content is already visible.
- TypeScript-leaning is fine; for non-
.ts files fall back to ^(def|class|fn|func|pub fn)\s+ style heuristics, or just skip the outline.
Why this matters
This is the single highest-leverage change to the file-exploration loop. Most "read big file" sessions today look like:
read_file foo.ts → auto-preview, no idea where things are
search_content "^export function" path:foo.ts → get line numbers
read_file foo.ts range:"X-Y" → finally read the relevant section
After this issue: step 1 already contains step 2's answer. The whole shape collapses to two calls.
Out of scope
- Mid-file (non-export) symbols. Outline is for navigation, not full structure.
- Language-aware parsing. Regex is intentionally cheap; we're not booting up a TS compiler for a file preview.
Problem
read_filealready has the right primitive (head/tail/range+ auto-preview at >200 lines,src/tools/filesystem.ts:107). The auto-preview returns the first 80 lines + last 40 lines + an "N lines omitted" marker, telling the caller to re-call with arange.The gap: on a real 3500+ line file, the head/tail slice doesn't cover the full export list. The caller sees
importblocks at the top and the last 40 lines of JSX at the bottom, but has no idea wherefunction AppInneris defined, wherehandleSubmitlives, etc. They have to follow up withsearch_content "^export function"(or worse, guess a range) — every single time.That round-trip is exactly the failure mode the auto-preview was designed to prevent.
Proposal
When auto-preview fires (file > 200 lines), append a symbol outline between the head slice and the omitted-marker:
Implementation:
^export\s+(async\s+)?(function|class|const|interface|type|enum)\s+(\w+)→(line, kind, name).[… N more …]between..tsfiles fall back to^(def|class|fn|func|pub fn)\s+style heuristics, or just skip the outline.Why this matters
This is the single highest-leverage change to the file-exploration loop. Most "read big file" sessions today look like:
read_file foo.ts→ auto-preview, no idea where things aresearch_content "^export function" path:foo.ts→ get line numbersread_file foo.ts range:"X-Y"→ finally read the relevant sectionAfter this issue: step 1 already contains step 2's answer. The whole shape collapses to two calls.
Out of scope