UNPKG

@zapier/stubtree

Version:

CLI tool to generate ASCII tree of project structure with symbol stubs using universal-ctags

210 lines (153 loc) 6.42 kB
# stubtree Generate a bird's-eye view of your codebase with all the important symbols (functions, classes, methods) shown inline. Perfect for documentation, code reviews, or understanding new projects. ```bash $ stubtree --root ./src --lang ts src/ ├── index.ts │ ├── class FileProcessor │ │ ├── constructor(options: ProcessorOptions) │ │ ├── processDirectory(dirPath: string): Promise<TreeNode> │ │ └── shouldIgnoreFile(filePath: string): boolean ├── parser.ts │ ├── parseTags(input: string): Promise<Tag[]> │ └── interface Tag │ ├── name: string │ ├── path: string │ └── kind: string └── renderer.ts ├── renderTree(node: TreeNode, options?: RenderOptions): string └── formatSymbol(tag: Tag): string ``` ## What is stubtree? stubtree is a CLI tool that combines the power of ctags with a clean tree visualization to help you quickly understand any codebase. Unlike regular tree commands that only show files and folders, stubtree extracts and displays the actual code structure - classes, methods, functions, and more - giving you instant insight into how a project is organized. **Perfect for AI coding assistants:** Tools like Claude, GitHub Copilot, and Cursor can better understand your codebase when provided with stubtree's structured output, leading to more accurate suggestions and refactoring. ## Installation ```bash # Install globally npm install -g @zapier/stubtree # Or with yarn yarn global add @zapier/stubtree # Or use directly with npx npx @zapier/stubtree ``` ### Prerequisites stubtree requires `ctags`: ```bash # macOS brew install ctags # Ubuntu/Debian sudo apt-get install ctags ``` ## Getting Started ```bash # Scan current directory stubtree # Scan specific directory with TypeScript files stubtree --root ./src --lang ts,tsx # Limit depth for large projects stubtree --depth 3 # Export as JSON for processing stubtree --json > structure.json ``` ## Options - `--root <dir>` - Root directory to scan (default: current directory) - `--lang <globs>` - Comma-separated file extensions to include (e.g., `py,ts,tsx`) - `--depth <n>` - Maximum directory depth to traverse - `--json` - Output raw JSON instead of ASCII tree ### Examples #### TypeScript/JavaScript project ```bash stubtree --root ./src --lang ts,tsx,js,jsx ``` Output: ``` src/ ├── main.ts │ ├── init_app() -> void │ └── class Service │ ├── start() -> Promise<void> │ └── stop() -> Promise<void> └── utils/ └── io.ts ├── read(path: string) -> string └── write(path: string, data: string) -> void ``` #### Python project with depth limit ```bash stubtree --root ./myproject --lang py --depth 2 ``` #### JSON output ```bash stubtree --json > project-structure.json ``` ## Features - Fast parsing using ctags JSON output with advanced pattern extraction - Extracts function signatures, return types, and async modifiers - Shows class inheritance and property type annotations - Respects file order as encountered (no sorting) - Colorized output when outputting to TTY - Ignores common directories (.git, node_modules, etc.) and test files - Supports multiple programming languages through ctags - Smart filtering to show only relevant symbols (classes, functions, methods, not internal variables) ## How it Works ### Behind the Scenes stubtree combines the power of ctags with Node.js's streaming capabilities to efficiently parse and render your codebase: 1. **Symbol Extraction**: We spawn `ctags` as a child process with specific flags: ```bash ctags --output-format=json --fields=+neKStr --extras=+q --sort=no -R . ``` - `--output-format=json`: Outputs newline-delimited JSON, one symbol per line - `--fields=+neKStr`: Includes line numbers, end lines, kind info, scope, type refs, and roles - `--extras=+q`: Includes extra tag information like signatures - `--sort=no`: Preserves file discovery order - `-R`: Recursively scans directories 2. **Streaming JSON Parser**: Instead of loading all ctags output into memory, we use Node's `readline` interface to process the JSON stream line-by-line. Each line contains a symbol like: ```json {"name":"readFile","path":"/project/src/io.ts","kind":"function","signature":"(path: string): Promise<string>"} ``` 3. **Tree Building**: We build the tree structure in two passes: - First, we group all tags by their file paths - Then, we walk the actual filesystem to build the directory structure, attaching the relevant tags to each file node 4. **Smart Filtering**: - Language filtering happens at the tag parsing stage based on file extensions - Directory traversal respects `--depth` limits and ignores common non-source directories - Empty directories are automatically pruned from the output 5. **ASCII Rendering**: The tree renderer uses a recursive algorithm with careful prefix tracking: - `├──` for non-last items - `└──` for last items - `` for continuation lines - Tags are indented one level deeper than their containing file 6. **Color Support**: We detect TTY output using Node's `isatty()` and apply colors via chalk: - Blue for directories - Green for files - Gray for symbols ### Performance Optimizations - **Streaming**: We never load the entire ctags output into memory - **Lazy Directory Walking**: We only traverse directories that contain matching files - **Early Filtering**: Language filters are applied during tag parsing, not after - **Minimal Dependencies**: Just `commander` for CLI parsing and `chalk` for colors ## Performance stubtree is designed to be fast, typically scanning and rendering a project tree in under 1 second on a typical laptop. ## Limitations - Symbol information is limited to what ctags provides - No language-specific type inference beyond ctags capabilities - Requires ctags to be installed separately ## Development ```bash # Install dependencies npm install # Run in development mode npm run dev # Run tests npm test # Build npm run build # Lint npm run lint # Type check npm run typecheck ``` ### Known Issues - The tool gracefully handles broken symlinks and files that can't be accessed by skipping them during directory traversal ## License MIT