Generate _FEATURES.md files documenting what a web app does — screens, flows, states, behavioral invariants. Companion to tree-sitting, which surfaces code structure.
v0.3.0: Code-first architecture. The code IS the ground truth; screenshots are supplementary verification.
Prerequisites
- tree-sitting must be installed (structure is scanned at runtime)
- Claude API key available (via
api-credentialsskill orANTHROPIC_API_KEYenv var) - Optional: webctl for visual verification (not required for
--code-only)
Usage
# Code-only analysis (no browser needed):
python /mnt/skills/user/mapping-webapp/scripts/featuremap.py \
--app-url https://example.com --codebase /path/to/repo --code-only
Full pipeline (code analysis + selective visual verification):
python /mnt/skills/user/mapping-webapp/scripts/featuremap.py
--app-url https://example.com --codebase /path/to/repo
python /mnt/skills/user/mapping-webapp/scripts/featuremap.py
--app-url https://example.com --codebase . --incremental
### Options
| Flag | Default | Description |
|------|---------|-------------|
| `--app-url` | required | Base URL of the web app |
| `--codebase` | required | Path to repo root |
| `--output` | `<codebase>/_FEATURES.md` | Output path |
| `--max-pages` | `100` | Cap on pages to discover |
| `--code-only` | `false` | Skip all vision — code analysis only |
| `--verify-only` | `false` | Only run vision on already-analyzed pages |
| `--batch-size` | auto | Pages per batch (auto-detected from environment) |
| `--incremental` | `false` | Only re-process changed pages |
| `--viewport` | `1280x720` | Screenshot viewport (WxH) |
| `--routes` | none | Comma-separated routes or path to routes file |
| `--screenshots-dir` | `<codebase>/screenshots` | Where to store PNGs |
| `--model` | `claude-sonnet-5-5` (set in `scripts/featuremap.py`; that file is the source of truth) | Claude model for analysis/vision |
| `--dry-run` / `-n` | `false` | Discover only, print sitemap |
## Architecture: Code-First Pipeline
### Phase 1: DISCOVER
Discovers pages from **code structure**, not browser crawling:
- Scans for HTML files (static sites)
- Detects framework routing conventions (Next.js, SvelteKit, etc.)
- Scans the codebase for page references
- Supplements with `--routes` for manual seeding
No browser required for discovery.
### Phase 2: ANALYZE
Reads source code for each discovered page and uses Claude API (text, not vision) to generate behavioral descriptions:
- Finds relevant source files (HTML + referenced JS/CSS)
- Includes tree-sitting excerpts for code context
- Produces: what the user sees, interactions, invariants, code references
**Code-derived descriptions are usable standalone.** Vision is enrichment, not requirement.
### Phase 3: VERIFY (optional)
Selective visual verification for pages where it adds value:
- Skips error pages (404, 500), gated pages, redirects
- Captures screenshots + accessibility trees via webctl
- Sends to Claude vision API to verify/enrich code descriptions
- Falls back to code description if vision fails
Skipped entirely with `--code-only`. Run only this phase with `--verify-only`.
### Phase 4: ASSEMBLE
Compiles all descriptions into `_FEATURES.md`:
- Source badges indicate code-analyzed vs visually-verified
- Screenshot references only for verified pages
- Status summary with breakdown by source
## Environment-Adaptive Batching
The skill auto-detects the runtime environment and adjusts batch size:
| Environment | Batch Size | Notes |
|-------------|-----------|-------|
| Claude.ai container | 4 pages | Short bash timeouts |
| Claude Code on Web | 12 pages | Longer execution windows |
| Local CLI | Unbatched | Full control |
Override with `--batch-size N`.
Progress is checkpointed after each batch via `_FEATURES_MANIFEST.json`, so work survives if a conversation ends mid-pipeline.
## Incremental Mode
Each run stores page hashes and descriptions in `_FEATURES_MANIFEST.json`. With `--incremental`:
- Code analysis: skips pages with existing descriptions
- Visual verification: skips pages with unchanged screenshots
- Descriptions from previous runs are preserved and merged
## Auth / Gated Pages
Pages requiring authentication are detected during verification (redirect detection + text heuristics) and marked `GATED`. The skill generates step-by-step manual capture instructions in `GATED_PAGES.md`.
## Output Format
```markdown
# _FEATURES.md — App Name
Generated: 2026-03-22T12:00:00+0000
App URL: https://example.com
## Feature Inventory
### Status Summary
- **Documented:** 45 pages
- Code-analyzed: 40
- Visually verified: 5
- **Gated (auth required):** 2 pages
### Page Title (`/route`)
> *Derived from source code analysis*
**What the user sees:** Prose description from code analysis.
**Interactions:**
- Button "X" → does Y
**Invariants:**
- Rule 1
**Code:** `src/page.html` :1
---
Relationship to CLAUDE.md
_FEATURES.md is the behavioral source of truth. Structure is not persisted
alongside it — it is derived on demand:
tree-sitting→ structure, scanned at runtimemapping-webapp→_FEATURES.md(behavioral)- Merge the behavioral layer into CLAUDE.md architecture/concepts sections
Limitations
- Code analysis requires Claude API calls (tokens)
- Visual verification requires webctl + a running app instance
- SPAs with client-side routing may need
--routesflag - Auth-gated pages require human intervention for visual verification
- Code analysis quality depends on source code readability