Skip to main content

CLI Commands

setup / init

Launches the interactive wizard. init is an alias for setup.

npx @rtorcato/repo-tooling setup # current directory
npx @rtorcato/repo-tooling setup -d ./my-app # specific directory
npx @rtorcato/repo-tooling setup --skip-install # skip npm/pnpm install

Add --preset <name> to skip the prompts entirely: library, web-app, node-api, nextjs-app, react-app, or swift-library. The Swift preset scaffolds a SwiftPM package rather than an npm one — see the Swift guide.

copy <name>

Copies a standalone config file into the current directory without running the full wizard.

npx @rtorcato/repo-tooling copy biome # → biome.json
npx @rtorcato/repo-tooling copy tsconfig # → tsconfig.json

Available presets: biome, tsconfig, bun, nx, changesets, release-please, oxlint, claude-skill, mcp-example, docusaurus-sync-changelog, docusaurus-theme-tokens, docusaurus-theme.

copy is for configs you must own rather than extend — Biome doesn't support configuration extension, and TypeScript configs resolve more reliably when local. Most other configs (ESLint, Prettier, Vitest, etc.) can be imported or extended directly — see the Configuration Reference for usage.

list / ls

Prints all available tooling configurations.

npx @rtorcato/repo-tooling list

doctor

Audits an existing project against the presets and reports drift.

npx @rtorcato/repo-tooling doctor # current dir
npx @rtorcato/repo-tooling doctor -d ./app # specific dir
npx @rtorcato/repo-tooling doctor --json # machine-readable output

Each row reports one of:

StatusMeaning
okConfig matches the preset (or required file present)
driftConfig exists but has diverged from the preset
missingConfig required but not found
not configuredOptional tool not present in the project

What gets checked

GroupChecks
EnvironmentNode version (vs. minimum + LTS patch level), engines.node field
Repo baselinepackage.json, .editorconfig, .nvmrc / .node-version, .vscode/extensions.json
Tooling presetsTypeScript, Biome, ESLint, Prettier, Vitest, Commitlint
AutomationHusky, lint-staged, verify script, semantic-release, knip
CI / supply chainGitHub Actions, coverage upload, Dependabot, CodeQL, GitLab CI
Build / docsTypeDoc, docs site (Docusaurus), size-limit
EcosystemBun runtime, Turborepo / Nx, Tailwind / PostCSS

After the per-row results, doctor prints a Next steps: footer listing the exact fix command to run for each non-ok item:

Next steps:
- Run `npx @rtorcato/repo-tooling fix engines` to align engines.node
- Run `npx @rtorcato/repo-tooling fix editorconfig` to scaffold EditorConfig
- Run `npx @rtorcato/repo-tooling fix dependabot` to scaffold Dependabot
- Run `npx @rtorcato/repo-tooling fix` to walk all findings interactively

Exits non-zero on drift or missing — useful as a CI gate.

fix [target]

Applies scaffolders for items doctor flagged. Without a target it walks every non-ok result, prompting per item; with a target it applies just that one.

npx @rtorcato/repo-tooling fix # walk all findings interactively
npx @rtorcato/repo-tooling fix dependabot # scaffold dependabot.yml + auto-merge workflow
npx @rtorcato/repo-tooling fix --yes # apply every recommended fix without prompts
npx @rtorcato/repo-tooling fix biome --dry-run # print what would change, write nothing
npx @rtorcato/repo-tooling fix biome --diff # show the exact diff before confirming

Flags

FlagBehaviour
-d, --directory <path>Target directory (defaults to cwd)
--yesAssume yes to every prompt, including drift overwrites
--dry-runPrint the files each fixer would write, without writing
--diffPrint a unified diff of each change before the confirm prompt

Drift policy

When a file exists but doesn't extend the preset, fix defaults the confirm prompt to No — your customisations are preserved unless you explicitly say yes (or pass --yes). The prompt always tells you which file is about to be overwritten.

Diff preview (--diff)

When you want to see exactly what would change before saying yes, pass --diff. For each output the fixer would touch, you'll see:

  • a create <path> header if the file is new (no diff body to show), or
  • a modify <path> header followed by a unified diff comparing the current file to what the fixer would write.
$ npx @rtorcato/repo-tooling fix biome --diff
🔧 biome — Biome is drift

modify biome.json
--- biome.json
+++ biome.json
@@ -1,3 +1,12 @@
-{
- "rules": { "noConsole": "error" }
-}
+{
+ "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
+ "extends": ["@rtorcato/repo-tooling/biome"],
+ …
+}
? ⚠️ Scaffold biome.json … — overwrite existing file? user customizations will be lost (y/N)

The diff:

  • is suppressed in --json mode (the structured output stream stays clean),
  • is suppressed for safe-add fixers (those never overwrite existing files),
  • honours NO_COLOR and the standard terminal-colour detection chalk uses,
  • works in both targeted (fix biome --diff) and walk-all (fix --diff) modes.

Implementation note: the preview is computed by shadow-running the fixer in a temp copy of your project directory — your real files are never touched until you confirm.

Available targets

doctor and list --json are the source of truth — run them for the exact set in the version you have; new targets are added regularly. The current set:

Core config

TargetScaffolds
package-jsonadds @rtorcato/repo-tooling to devDependencies
enginesengines.node in package.json (never overwrites)
tsconfigtsconfig.json
biomebiome.json
eslinteslint.config.mjs
prettierprettier.config.mjs
editorconfig.editorconfig
vscode-extensions.vscode/extensions.json (merge-friendly)
nvmrc.nvmrc pinned to Node 22
node-versionpoints CI at node-version-file: .nvmrc (one Node source of truth)

Testing & verify

TargetScaffolds
vitestvitest.config.ts (preserves existing vitest.setup.ts)
cypresscypress.config.ts + cypress/support + tests/e2e boilerplate
commitlintcommitlint.config.mjs
husky.husky/pre-commit, .husky/pre-push, package.json lint-staged (deep-merges)
verifyunified verify script (typecheck && lint && tests) in package.json
knipknip.json

Release

TargetScaffolds
semantic-releaserelease.config.mjs + plugins (skipped on private packages)
changesets.changeset/config.json (alternative to semantic-release)
release-pleaserelease-please-config.json + manifest + workflow (alternative)
attw@arethetypeswrong/cli + an attw script, wired into verify
publintpublint + a publint --strict script, wired into verify
badgesstatus-badge row (CI, npm, coverage, license) in README.md

CI & supply chain

TargetScaffolds
github-actions.github/workflows/ci.yml (+ codecov.yml; Vitest jobs upload coverage). A ci.yml that no longer matches the preset is left as-is unless the finding being fixed is the GitHub Actions drift itself — your edits are never silently reverted
gitlab-ci.gitlab-ci.yml (lint/typecheck/test/build mirrored from GitHub Actions)
dependabot.github/dependabot.yml (monthly, grouped: production-minor/dev-minor/major-updates) + the dependabot-automerge.yml workflow — see Dependabot strategy
renovaterenovate.json (alternative to Dependabot)
codeql.github/workflows/codeql.yml (security scanning)
github-settingsbranch protection + auto-merge + workflow permissions + a code-scanning branch ruleset (when CodeQL is on) via gh api (mutates the remote repo)
milestonescloses 100%-complete open milestones via gh api (mutates the remote repo). Never deletes or creates one — see milestone hygiene
codeowners.github/CODEOWNERS with commented examples
community-healthCONTRIBUTING.md, SECURITY.md, PR + issue templates
lockfilerecords current tool choices in the repo-tooling lockfile

Build, bundling & monorepo

TargetScaffolds
bunbunfig.toml + a Bun-typed tsconfig.json for Bun runtime/test users
rolluprollup.config.mjs re-exporting the shared library preset
rolldownrolldown.config.mjs re-exporting the shared library preset
size-limita size-limit budget (.size-limit.cjs/.json), plus the size-limit script and devDependency that run it
treeshake-checkapps/treeshake-check — esbuild + metafile bundle assertion
pnpm-workspacemerges the family-wide pnpm settings into pnpm-workspace.yaml (verifyDepsBeforeRun, minimumReleaseAgeExclude, esbuild's build approval) — never rewrites the file
turborepoturbo.json task pipeline (pnpm-workspace monorepos)
nxnx.json task orchestrator (alternative to Turborepo)
tailwindTailwind CSS v4 (postcss.config.mjs + src/styles/globals.css)
postcsspostcss.config.mjs with autoprefixer (non-Tailwind pipelines)

Docs

TargetScaffolds
typedoctypedoc.json + .github/workflows/docs.yml (GitHub Pages)
docs-sitea Docusaurus site under apps/docs (config/sidebars/tokens + Pages deploy) — see Docs site
brandbrand/ — banner, mobile-banner and social-card SVG sources + render.sh, and repoints a README still on root-level banner paths — see Brand assets

AI agents (opt-in)

TargetScaffolds
aiall AI agent files at once (AGENTS.md, CLAUDE.md, Cursor, Copilot, Claude skill, MCP example)
claude-skillthe Claude Code skill at .claude/skills/repo-tooling.md
cursor-rulesthe rules for Cursor at .cursor/rules/repo-tooling.mdc
copilot-instructionsthe rules block in .github/copilot-instructions.md
agents-mdthe rules block in AGENTS.md (universal)

Typical workflow

npx @rtorcato/repo-tooling doctor # see what's missing
npx @rtorcato/repo-tooling fix # walk the list, accept defaults
npx @rtorcato/repo-tooling doctor # confirm everything is now ok