7.2 KiB
.understandignore Design Spec
Overview
Add user-configurable file exclusion via .understandignore files, using .gitignore syntax. This makes analysis faster by skipping irrelevant files (vendor code, generated output, test fixtures) without modifying hardcoded defaults.
Goals
- Let users exclude files/directories from analysis via
.understandignore - Use
.gitignoresyntax (familiar, no learning curve) - Keep hardcoded defaults as built-in —
.understandignoreadds patterns on top - Allow
!negation to force-include files excluded by defaults - Auto-generate a commented-out starter file on first run (deterministic code, not LLM)
- Pause before analysis to let user review the ignore file
Non-Goals
- Replacing
.gitignore— this is analysis-specific - Per-directory
.understandignorefiles (project root and.understand-anything/only) - GUI for editing ignore patterns
IgnoreFilter Module
New file: packages/core/src/ignore-filter.ts
Uses the ignore npm package for gitignore-compatible pattern matching.
API
export interface IgnoreFilter {
isIgnored(relativePath: string): boolean;
}
export function createIgnoreFilter(projectRoot: string): IgnoreFilter;
Behavior
createIgnoreFilter loads patterns in this order (later entries can override earlier ones):
- Hardcoded defaults — the existing exclusion patterns from project-scanner (node_modules/, .git/, dist/, build/, bin/, obj/, *.lock, *.min.js, etc.)
.understand-anything/.understandignore— project-level, lives alongside the output.understandignoreat project root — alternative location for visibility
Patterns merge additively. ! negation in user files can override hardcoded defaults (e.g., !dist/ force-includes dist/).
Hardcoded Default Patterns
These are the built-in defaults (matching current project-scanner behavior, plus bin/obj for .NET):
# Dependency directories
node_modules/
.git/
vendor/
venv/
.venv/
__pycache__/
# Build output
dist/
build/
out/
coverage/
.next/
.cache/
.turbo/
target/
bin/
obj/
# Lock files
*.lock
package-lock.json
yarn.lock
pnpm-lock.yaml
# Binary/asset files
*.png
*.jpg
*.jpeg
*.gif
*.svg
*.ico
*.woff
*.woff2
*.ttf
*.eot
*.mp3
*.mp4
*.pdf
*.zip
*.tar
*.gz
# Generated files
*.min.js
*.min.css
*.map
*.generated.*
# IDE/editor
.idea/
.vscode/
# Misc
LICENSE
.gitignore
.editorconfig
.prettierrc
.eslintrc*
*.log
Starter File Generator
New file: packages/core/src/ignore-generator.ts
API
export function generateStarterIgnoreFile(projectRoot: string): string;
Behavior
- Deterministic code — scans the project directory for common patterns
- Returns the file content as a string (caller writes it to disk)
- All suggestions are commented out — user must uncomment to activate
- Header comment explains the file, syntax, and built-in defaults
Detection Logic
| If exists | Suggest |
|---|---|
__tests__/ or *.test.* files |
# __tests__/, # *.test.*, # *.spec.* |
fixtures/ or testdata/ |
# fixtures/, # testdata/ |
test/ or tests/ |
# test/, # tests/ |
.storybook/ |
# .storybook/ |
docs/ |
# docs/ |
examples/ |
# examples/ |
scripts/ |
# scripts/ |
migrations/ |
# migrations/ |
*.snap files |
# *.snap |
bin/ (non-.NET, i.e. shell scripts) |
# bin/ |
obj/ |
# obj/ |
Generated File Format
# .understandignore — patterns for files/dirs to exclude from analysis
# Syntax: same as .gitignore (globs, # comments, ! negation, trailing / for dirs)
# Lines below are suggestions — uncomment to activate.
# Use ! prefix to force-include something excluded by defaults.
#
# Built-in defaults (always excluded unless negated):
# node_modules/, .git/, dist/, build/, bin/, obj/, *.lock, *.min.js, etc.
#
# --- Suggested exclusions (uncomment to activate) ---
# Test files
# __tests__/
# *.test.*
# *.spec.*
# Test data
# fixtures/
# testdata/
# Documentation
# docs/
# ... (more suggestions based on detection)
Only generated if .understand-anything/.understandignore doesn't already exist.
Skill Integration
Phase 0.5: Ignore Setup (new phase in SKILL.md)
Added between Pre-flight (Phase 0) and SCAN (Phase 1):
- Check if
.understand-anything/.understandignoreexists - If not, run
generateStarterIgnoreFile(projectRoot)and write the result to.understand-anything/.understandignore - Report to user:
- First run: "Generated
.understand-anything/.understandignorewith suggested exclusions. Please review it and uncomment any patterns you'd like to exclude. When ready, confirm to continue." - Subsequent runs: "Found
.understand-anything/.understandignore. Review it if needed, then confirm to continue."
- First run: "Generated
- Wait for user confirmation before proceeding
Phase 1: SCAN changes
The project-scanner agent's scan script is updated to:
- Collect files via
git ls-files(or fallback) - Apply agent's hardcoded pattern filter (Layer 1 — existing behavior)
- Apply
IgnoreFilterfrom core (Layer 2 — user patterns) - Add
filteredByIgnorecount to scan output - Report: "Scanned {totalFiles} files ({filteredByIgnore} excluded by .understandignore)"
Two-layer filtering:
- Layer 1: Agent's hardcoded patterns in the prompt (fast, coarse filter)
- Layer 2:
IgnoreFilterfrom core (deterministic code, user-configurable)
Project Scanner Agent Update
Changes to understand-anything-plugin/agents/project-scanner.md:
- After the file list is built and Layer 1 filtering is applied, the agent runs a Node.js script that imports
createIgnoreFilterfrom@understand-anything/coreand filters the remaining paths - The scan result JSON includes a new
filteredByIgnore: numberfield - Existing hardcoded exclusion patterns in the agent prompt remain for backward compatibility
Testing
packages/core/src/__tests__/ignore-filter.test.ts
- Parses basic glob patterns (
*.log,dist/) - Handles
#comments and blank lines - Handles
!negation (force-include) - Handles
**/recursive matching - Handles trailing
/for directory-only patterns - Merges defaults + user patterns correctly
!in user file overrides hardcoded defaults- Returns
falsefor paths not matching any pattern
packages/core/src/__tests__/ignore-generator.test.ts
- Generates starter file with header comment
- Detects existing directories and suggests relevant patterns
- All suggestions are commented out (prefixed with
#) - Doesn't overwrite existing file
- Includes bin/obj suggestions when relevant
File Structure
| File | Purpose |
|---|---|
packages/core/src/ignore-filter.ts |
Parse .understandignore, merge with defaults, filter paths |
packages/core/src/ignore-generator.ts |
Generate starter file by scanning project structure |
packages/core/src/__tests__/ignore-filter.test.ts |
Filter logic tests |
packages/core/src/__tests__/ignore-generator.test.ts |
Generator tests |
agents/project-scanner.md |
Add Layer 2 filtering via IgnoreFilter |
skills/understand/SKILL.md |
Add Phase 0.5 (generate + pause for review) |
packages/core/package.json |
Add ignore npm dependency |