Skip to content

Architecture

themarch/dev is a Turborepo + pnpm mono-repo with a strict separation of concerns.

packages/
├── core/ detect, apply, skills loader/runner, MCP path helpers
├── cli/ commander binary that wires core + skills + templates together
├── skills/ the @themarch/skills package, hosts the catalog/ folder
└── mcp-servers/ three MCP servers (postgres-local, skills, knowledge)
templates/ scaffolding inputs (saas-b2b, api-only, lib) — NOT workspace members
configs/ stack-aware .cursorrules and CLAUDE.md variants, MCP config templates
docs/ the documentation you're reading

@themarch/core/detect walks a target directory and produces a RepoSnapshot — a structured record of language, package manager, monorepo tool, frontend / backend frameworks, data layer, infrastructure markers, AI tooling, auth, async, and testing. The inferProfile function distills this into one of saas-b2b | api-only | lib | unknown.

The snapshot is pure data, so it’s deterministic, easy to test, and serialisable.

@themarch/core/apply provides:

  • renderTemplate(source, ctx) — Handlebars with case-conversion + pluralisation helpers.
  • copyDir(from, to, ctx, options) — recursive copy with template substitution in both file content and file paths.
  • mergeJson(base, patch, options) — deep-merge with per-key strategies (replace, shallow, deep, concat-unique).

All of it supports a dryRun mode so the CLI can preview changes before applying.

@themarch/core/skills:

  • loadSkill(path) — parse SKILL.md frontmatter (gray-matter + Zod validation).
  • loadCatalog(roots) — discover every skill folder under one or more roots.
  • runSkill(skill, options) — check requires against the snapshot, fill default inputs, render templates into the target directory, append a JSONL audit line under .themarch/skill-runs.jsonl.

@themarch/cli wires the above into six commands. Each command is a separate file under packages/cli/src/commands/. Common helpers live in src/util/. Global flags (--dry-run, --verbose, --no-prompt, --config) are inherited via Commander’s optsWithGlobals().

Detection > guessing. Every skill declares its requires against RepoSnapshot keys, so a skill that depends on Drizzle refuses to run on a Prisma codebase rather than silently failing halfway through. The composite skills (scaffold-feature, enhance-existing-repo) chain compatible skills only.

Running themarch enhance . twice produces the same result as running it once. The CLI never overwrites an existing file without confirmation. JSON merges (MCP configs, package.jsons) are content-stable: the same input produces byte-identical output.

Because the goal is compounding — every project benefits from every previous one. A monorepo lets us share @themarch/core between the CLI, the MCP servers, and the skills catalog without versioning friction. When clear necessity arises we’ll split, not before.