Skip to content

tools: add top-level symbol outline to read_file auto-preview #487

@esengine

Description

@esengine

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:

  1. read_file foo.ts → auto-preview, no idea where things are
  2. search_content "^export function" path:foo.ts → get line numbers
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions