Architecture
bin/cli.js # Commander entry; exports buildProgram() so docs generators can introspect itsrc/ index.js # Setup orchestration: run / apply / saveProfile / listProfiles select.js # Shared selection resolution (flag > defaults > prompt) + catalog checkbox builder runtime.js # Option normalization (CI / yes / json / dry-run) profile.js # Profile load / merge / save / discovery manifest.js # ~/.dxai + ./.dxai manifest helpers (installs recorded by id) inspect.js # list, status, doctor (incl. --handshake) handshake.js # Spawns stdio MCP servers, verifies JSON-RPC initialize update.js # dxai update (remote registry refresh + validation) auto-update.js # TTL-based background catalog refresh on setup runs cleanup.js # cleanup / reset — manifest-aware, supports -y/--json/--dry-run rollback.js # dxai rollback — restore files from .bak.<ts> snapshots mcp-cmd.js # Fast-path dxai add / remove config-writer.js # File writers + dry-run previews (JSON/TOML/Claude CLI), backups config-remover.js # Scan + remove helpers (shared with cleanup/status/remove) detect.js # OS, prerequisite, agent detection; AGENT_DEFINITIONS + MCP dialects detect-project.js # Stack / tooling / git inference (shell-free, Windows-safe) net.js # fetch with per-attempt timeout + retry/backoff (shared) fs-atomic.js # Atomic writes (temp + rename), optional 0600 mode branding.js # Banner, colors, message helpers registry/ validate.js # Validation for untrusted registry data (commands, repo/path, ids) loader.js # cache > bundled JSON resolution; remote fetch mcp-servers.js # Catalog re-export + per-agent config derivation from `transport` skills.js # Skills catalog re-export automation-tools.js # Automation tools catalog re-export stacks.js # Tech stacks, Cursor rules, commands, instruction-file templates data/ # Bundled JSON catalogs (MCP servers, skills, automation tools)test/ # node:test suite (run `npm test` for the current count)scripts/ run-tests.mjs # Portable test runner (Node 18–22, Windows-safe) catalog-health.mjs # Weekly pin/URL drift checker (drives the GitHub issue bot) docs/ # Docs generators + drift check.github/workflows/ # ci.yml (tests + lint + docs-check), docs.yml, catalog-health.ymlLoading is synchronous: registry data is resolved at module import via loadRegistry(name), which prefers ~/.dxai/cache/<name>.json (written by dxai update / the auto-refresh) and falls back to the bundled JSON shipped in src/registry/data/.
Two design decisions do most of the work:
- Transport derivation. A catalog server declares its
transportonce; per-agent config blocks (JSON dialects, Codex TOML,claude mcp addargv) are derived fromAGENT_DEFINITIONS. Adding a new agent definition makes every transport-based server support it instantly. - Manifest-first state. Every write is recorded, so
list/status/doctor/cleanup/rollbackoperate on what dxai actually did rather than guessing.