Architecture overview¶
nsc is layered around a framework-free "brain". The brain — schema parsing
and the normalized command-model — knows nothing about Typer, Rich, or httpx.
The CLI layer consumes the brain; a future TUI could too without changing the
brain.
nsc/
├── schema/ # OpenAPI fetching, hashing, parsing
├── model/ # Normalized command-model (data only, framework-free)
├── builder/ # Schema → CommandModel
├── cli/ # Typer application; walks the model, registers commands
├── http/ # Thin httpx wrapper: auth, retries, audit
├── output/ # Formatters (table/json/jsonl/yaml/csv) + error envelope
├── config/ # Pydantic config models + ruamel.yaml writer
├── cache/ # On-disk cache for generated CommandModels
├── auth/ # Login verification helpers (verify probe, token rotate)
├── aliases/ # Curated alias resolver (ls/get/rm/search)
├── completion/ # Dynamic shell-completion: providers + cache probe + Typer callbacks
├── skill/ # Bundle-path helper for the portable SKILL.md
└── schemas/bundled/ # Versioned NetBox OpenAPI snapshots (offline fallback)
The hard rule¶
nsc/model/ imports nothing from nsc/cli/, nsc/http/, or any framework.
If you need to add a dependency to model/, you're solving the wrong problem.
Data flow at runtime¶
nscstartup → resolve profile (CLI flags > env > config > adhoc).- Resolve schema source (
--schemaoverride > fresh cache within the TTL policy > live fetch > stale cache > bundled fallback). - Hash + parse → build the command-model (or load cached).
- Hand model to Typer; register commands dynamically.
- Dispatch.
http/executes (or shows dry-run).output/renders.
Where to read next¶
- Schema loading — fetch, hash, fallback chain.
- Command generation — how
operationIdbecomes a verb. - HTTP client — auth, retries, audit log.
- Caching — disk layout, invalidation.
For the full design rationale, see the specs in docs/superpowers/specs/ (in
the repo, not in this site — the planning artifacts are local-only).