usm/cli-scan
The usm scan command reads usmconfig.json, scans the codebase, and generates .usm files for services, packages, data, and features.
Usage
# Scan with defaults (smart merge)
usm scan
# Overwrite all existing .usm files
usm scan --force
# Only extract routes, skip service/package detection
usm scan --routes
# Overwrite mechanical fields, preserve human edits
usm scan --merge overwriteWhy this exists
After init creates the config, scan detects the actual structure — services from package.json, routes from app/ directories, data from Prisma schemas — and writes .usm files. Smart-merge preserves human edits on re-scan.
How it works
Scan pipeline (codebase detection) (run-scan)
System pipeline behind usm scan: read config, detect structure, write and smart-merge .usm files.
- Get — usmconfig.json
- expects: valid: true
- Parse — package.json in matched service directories
- Parse — app/*/app directories for Next.js routes
- Generate — .usm/services/.usm, .usm/features/.usm, .usm/data/*.usm
- Update — .usm/system.usm index with new findings
Generate specs from the codebase (first-scan)
First scan: an adopter runs usm scan after init and gets .usm files for every detected service, route, and data source.
- Run — usm scan in the repo root after init created usmconfig.json
- Review — console output — services, routes, and data sources matched against expectations
- Inspect — generated .usm files in .usm/ for gaps or wrong detections
Re-scan after enriching specs (re-scan-after-edits)
A spec author re-runs usm scan after editing .usm files and confirms smart-merge kept their work.
- Edit — summaries, intent, decisions, contracts in .usm files
- Run — usm scan again
- Verify — human-edited fields survived the merge; only mechanical fields ($last_updated, paths) changed
Guarantees
scan-preserves-edits
Smart-merge preserves human-edited fields (summary, intent, decisions, flows, contracts, tests) on re-scan
Acceptance criteria:
- [ ] PRESERVE_FIELDS are kept if non-default
- [ ] UPDATE_FIELDS ($last_updated, paths, port, depends_on) are overwritten
- [ ] --force bypasses merge
Test specifications
scan-creates-files
Given:
- config_exists: true
When: first-scan
Then:
- assertion: .usm/services/*.usm files created for each matched app
- assertion: .usm/features/*.usm files created from route extraction
scan-smart-merge
Given:
- existing_usm_with_human_edits: true
When: re-scan-after-edits
Then:
- assertion: human-edited summary preserved
- assertion: mechanical fields like $last_updated updated
Implementation
- Primary: src/scan/structural.ts
- Test code status: none
See Also
- usm/cli-init