Solarchsolarch
<- solarch.dev
// developer tools

Solarch CLI

The bridge between your codebase and the architecture you draw. Drift checking, bidirectional cloud sync, deterministic code generation and live binding — one binary, built for NestJS.

bash
npm install -g @solarch/clicd your-nestjs-reposolarch connect      # sign in + link projectsolarch diff --ci    # check drift in CI
Same diff engine as MCP & CI·ts-morph · AST-level·SARIF 2.1.0 + GitHub annotations·Node 20+

@solarch/cli reads your NestJS code at the compiler level with ts-morph, extracts the As-Is architecture graph, and compares it against the To-Be architecture you drew in Solarch. Run solarch diff --ci in a pull request and code that violates your architecture cannot merge. Generate deterministic scaffolds from the graph, fill the method bodies under contract, push code-side additions back to the canvas, and keep entities and DTOs in sync as you type. No AI in the parts that need to be reproducible — same graph in, byte-identical code out.

// what it does

scan — extract As-Is

Reads NestJS source at the compiler level (ts-morph) and builds the As-Is architecture graph — controllers, services, repositories, tables, DTOs and edges — straight from decorators.

diff — drift guard

Compares As-Is against the To-Be architecture. --ci emits GitHub annotations and exits 1 on error-level drift; --sarif feeds code-scanning; --to-be runs offline against a pulled graph.

pull / push — two-way sync

Pull the To-Be graph to .solarch/to-be.json; push code-side additions (nodes, edges, list-properties) atomically. Push is rejected on illegal edges, never deletes, and is idempotent.

generate — deterministic scaffold

The Constructor writes code from the cloud graph with no AI — same graph, byte-identical output. Method bodies arrive with @solarch:surgical markers; existing files are skipped unless --force.

fill — surgical body fill

Replaces NOT_IMPLEMENTED bodies with implementations honoring each region's contract (throws/deps/signature), then runs tsc + tests as gates. Only contract-passing fills are saved.

bind / watch — live binding

Bind an entity to a DTO so columns flow to typed, validated properties marked @solarch:bound. watch runs a chokidar daemon: re-runs bindings and prints incremental drift on every save.

// how it works

Your code and the diagram, always in step

Solarch keeps two graphs in step: the As-Is graph the CLI extracts from your code, and the To-Be graph you draw in the Solarch canvas. Every command is a move between those two graphs — scan reads code, diff compares, push and pull sync, generate writes the scaffold the diagram describes. The match cache in .solarch/map.json keeps node identity stable across renames so the comparison stays meaningful.

  • scan — extract the As-Is graph from NestJS source via ts-morph (controllers, services, repositories, tables, DTOs, edges).
  • diff — compare As-Is against the To-Be architecture; emit drift findings with severities.
  • pull / push — download the To-Be graph offline, or write code-side additions back to the cloud.
  • generate → status → fill — produce a deterministic scaffold, track fill rate, implement bodies under contract.
flow
Code ──scan──▶ As-Is graph ──diff──▶ drift report (blocks merge in CI)                                    └──push──▶ Solarch Cloud (missing nodes/edges + properties)Cloud ──pull──▶ .solarch/to-be.json (offline reference)Entity changed ──watch──▶ auto property sync to DTO (bind)

// drift guard in CI

Code that breaks the architecture cannot merge

solarch diff reconciles the scanned code against your To-Be graph and classifies each difference. With --ci it prints GitHub Actions annotations and exits 1 on any error-level finding, failing the job. --sarif emits SARIF 2.1.0 for GitHub code-scanning; --json is machine-readable; --to-be <file> runs fully offline against a pulled graph. Error findings — architecture present but missing in code, an unwired diagram connection, or a code connection that violates the Rules Matrix — block the merge.

  • DRIFT_NODE_MISSING_IN_CODE / DRIFT_EDGE_MISSING_IN_CODE — a commitment in the diagram was never wired up (error).
  • DRIFT_ILLEGAL_EDGE — a code connection violates the Rules Matrix legality (error).
  • DRIFT_NODE_NOT_IN_CLOUD / DRIFT_EDGE_NOT_IN_CLOUD — unapproved expansion in code (warn).
  • DRIFT_PROPERTY — column/field/method lists differ (info).
  • Exit codes: 0 = clean or warn/info only · 1 = error-level drift.
github actions
- name: Install Solarch CLI  run: npm install -g @solarch/cli- name: Login  run: solarch login --key "$SOLARCH_API_KEY"  env:    SOLARCH_API_KEY: ${{ secrets.SOLARCH_API_KEY }}- name: Drift check  run: solarch diff --ci

// from diagram to code

Generate deterministically, fill under contract

solarch generate turns the cloud graph into a code scaffold with the Constructor — no AI, so the same graph produces byte-identical output. Method bodies arrive with @solarch:surgical markers; existing files are skipped by default so hand-filled or AI-filled code is never overwritten (--force resets to a fresh scaffold). solarch status reads those markers and reports per-node fill rate, pending members with their job descriptions, contract violations, and marker loss. solarch fill replaces NOT_IMPLEMENTED bodies with implementations that honor each region's contract, then runs tsc and the project's tests as gates — only contract-passing fills are saved.

  • generate — Constructor output: deterministic, skips existing files, records markers in .solarch/generated.json.
  • status --ci — exit 1 if skeletons, contract violations, or marker losses remain.
  • fill --all / --region — per-region LLM → write → contract check → retry, then tsc + test gates.
  • fix-imports — deterministic import resolution (no AI, no tsc); the AI writes the body, the system owns imports.
bash
solarch generate                 # write the deterministic scaffoldsolarch status                   # 12/40 member(s) implemented (30%)solarch fill --all --with-tests  # fill bodies under contract, verifysolarch diff                     # confirm code matches the architecture

// two-way sync

Push code-side additions back to the canvas

solarch push fetches the current graph, builds a plan of nodes and edges to add and list-properties to update, then applies the additions in one atomic call. For list fields — Columns, Fields, Methods, Endpoints, Values — code is the source of truth; other cloud properties are preserved. Push is rejected entirely when illegal edges exist, and it never deletes (removing nodes is canvas-only, by design). Stale-revision conflicts auto-retry once; node-version conflicts prompt keep-cloud / write-code / skip.

  • pull — download the To-Be graph with its revision to .solarch/to-be.json for offline diff and reference.
  • push --yes — atomic adds with baseRevision; idempotent (a second push is a no-op via .solarch/map.json).
  • init — brownfield import: scan an existing repo, create a fresh project from it, write solarch.json.
  • No --prune flag: the CLI adds and updates, it does not delete from the cloud.

// live binding

Keep entities and DTOs in sync as you type

solarch bind <source> <target> defines a persistent binding in solarch.json and runs the first sync immediately — entity columns flow to DTO properties as typed fields with class-validator decorators. Added fields carry a // @solarch:bound marker, hand-written properties are left alone, and type conflicts are reported rather than overwritten. solarch watch runs a chokidar daemon that re-runs linked bindings and prints an incremental drift summary every time you save; --no-drift makes it binding-only.

bash
solarch bind "src/users/user.entity.ts#User" \             "src/users/create-user.dto.ts#CreateUserDto"solarch watch              # daemon: bindings + incremental drift on savesolarch watch --no-drift   # bindings only

// files & config

Credentials stay local, config travels with your code

Credentials are stored machine-wide in ~/.solarch/credentials (mode 600) and stay out of the repo. The project link lives in solarch.json — projectId, include/exclude globs, and bindings — and is meant to be committed. The CLI is the single source of truth the Solarch MCP server and VS Code extension consume via @solarch/cli/lib, so the diff engine behaves identically across CLI, MCP and editor. Requires Node 20+.

  • ~/.solarch/credentials — API key, mode 600, home dir (not committed).
  • solarch.json — projectId, include/exclude, bindings[] — commit this.
  • .solarch/map.json — code-node ↔ cloud-node match cache (commit it for stable matching after renames).
  • .solarch/to-be.json — pull output, regenerable (not committed).

// faq

What does solarch diff actually block in CI?

Error-level findings: architecture present in the diagram but missing in code (DRIFT_NODE_MISSING_IN_CODE / DRIFT_EDGE_MISSING_IN_CODE) and code connections that violate the Rules Matrix (DRIFT_ILLEGAL_EDGE). With --ci these exit 1 and fail the job. Unapproved expansions are warnings and property-list mismatches are info — neither fails the build.

Is the generated code written by an AI?

No. solarch generate uses the Constructor, which is deterministic — the same graph produces byte-identical output, no AI involved. AI only enters with solarch fill, which writes method bodies inside @solarch:surgical regions under a fixed contract (throws/deps/signature) and verifies them with tsc and the project's tests. Imports are resolved deterministically by fix-imports, not the model.

Will push or generate overwrite my work?

No. generate skips existing files by default so hand-filled or AI-filled code is never clobbered (use --force to reset to a fresh scaffold). push only adds nodes/edges and updates list-properties — it has no delete path, is rejected entirely if illegal edges exist, and is idempotent: a second push is a no-op.

Can I run drift checks offline?

Yes. solarch pull writes the To-Be graph (with its revision) to .solarch/to-be.json, and solarch diff --to-be .solarch/to-be.json runs the comparison without hitting the API. Rules-Matrix legality checks need a stored login when available; offline, those checks are skipped and noted.

Which frameworks and runtimes are supported?

The CLI targets NestJS codebases and scans src/**/*.ts at the compiler level via ts-morph. It requires Node 20 or newer. Commands like generate and fill require a Build+ plan, and fill needs an LLM key (DEEPSEEK_API_KEY or SOLARCH_FILL_API_KEY).

Put Solarch CLI to work

Architecture that's verified, not guessed.