CLI reference

Every flag, every subcommand, every output format. The complete @geoql/vue-doctor and @geoql/nuxt-doctor CLI surface.

The CLI surface is identical for @geoql/vue-doctor and @geoql/nuxt-doctor — the latter just adds Nuxt-specific context to the same engine. This page uses @geoql/vue-doctor for all examples; swap the package name as needed.

Synopsis

bash
npx -y @geoql/vue-doctor [flags]
npx -y @geoql/vue-doctor <subcommand> [flags]

Audit flags

These flags control the audit pass. They are the most-used subset.

flagdescriptiondefault
--root <path>project root to scancwd
--include <glob>extra include glob (repeatable)
--exclude <glob>extra exclude glob (repeatable)
--rule <id>:<level>override a single rule's severity (repeatable). level = error|warn|info|off
--preset <name>minimal | recommended | strict | allrecommended
--category <cat>only score rules in this category (repeatable)all
--dimension <dim>only score this dimension (repeatable); --dimension performance = perf-onlyall
--format <fmt>agent | pretty | json | json-compact | sarif | htmlagent
--output <path>write the report to a file (extension can imply format)stdout
--fixapply auto-fixes where the rule supports itoff
--fix-exclude <glob>never auto-fix files matching this glob (repeatable)
--no-lintskip the oxlint subprocess passoff
--respect-inline-disableshonor // vue-doctor-disable-next-line commentsoff
--diffscope the audit to files changed vs. HEAD (includes untracked)off
--stagedscope the audit to files in the git indexoff
--changed-files-from <ref>scope the audit to source files changed since <ref> (e.g. origin/main)off
--include-untrackedfold non-ignored untracked files into --staged / --changed-files-from scopeoff
--fulloverride the scope flags and audit everythingoff
--scoreprint the score in CI-friendly format even when format is jsonoff
--annotationsemit ::error file=…:: GitHub-style annotationsauto (in CI)
--threshold <n>override the score threshold (0–100)0
--fail-on <level>error | warn | none — when to exit non-zeroerror
--verbose / --quietadjust log leveldefault
--ci / --no-ciforce-enable or disable CI-only behavior (annotations, color)auto
--include-test-filesScore findings in test/story files too (reported but unscored by default)
--max-duration <seconds>soft time budget; on exhaustion, skip remaining passes and return partial results

Scoping by git changes

Three flags scope the audit to the files touched by a change set. They are mutually exclusive — passing more than one exits 2.

bash
# files changed vs HEAD in the working tree (untracked files included)
npx -y @geoql/vue-doctor --diff

# only what is staged in the git index (great for pre-commit hooks)
npx -y @geoql/vue-doctor --staged

# everything changed since a base ref — stacked branches, non-default PR bases
npx -y @geoql/vue-doctor --changed-files-from origin/main

--diff already unions non-ignored untracked files. For --staged and --changed-files-from, add --include-untracked to fold newly-created (non-ignored) files into the scope — useful when an agent writes a file and audits before staging it:

bash
npx -y @geoql/vue-doctor --staged --include-untracked

An unresolvable --changed-files-from ref exits 2. --full overrides every scope flag and audits the whole project.

Scoping by category or dimension

--category and --dimension narrow the audit to a subset of rules. Both are repeatable and compose (the scope is the union). They are orthogonal to --preset/--rule: the preset decides which rules are on, then the category/dimension scope keeps only the on-rules whose category falls in the requested set.

bash
# perf-only run — the most common case
npx -y @geoql/vue-doctor --dimension performance

# just security + the two perf categories
npx -y @geoql/vue-doctor --category security --dimension performance

# a single category
npx -y @geoql/vue-doctor --category reactivity

The six dimensions and the categories they cover:

dimensioncategories
performanceperformance, template-perf
correctnessreactivity, composition, template, sfc, vue-builtin, hydration
securitysecurity
maintainabilityai-slop, dead-code, build-quality, deps, structure, modules-deps
nuxtnitro, seo, cloudflare, server-routes, data-fetching
designdesign

An unknown --category or --dimension value exits 2. Scoping re-scores from the surviving findings, so the printed score reflects only the in-scope rules.

Time-budgeting with --max-duration

--max-duration <seconds> sets a soft deadline for the whole audit. When the budget is exhausted, doctor stops starting new passes (in cost order: dead-code → template → lint → sfc → project), keeps every finding already collected, and returns a partial result instead of being killed with nothing.

bash
# in CI, cap a slow monorepo scan at 90s
npx -y @geoql/vue-doctor --max-duration 90 --format json

The score stays a real number (√-decay over the findings that were collected) and the exit code still follows --threshold / --fail-on — a time-out never changes those. In json output the report gains:

jsonc
{
  "incomplete": true,
  "skippedCheckReasons": [
    {
      "kind": "time-budget-exhausted",
      "deadlineMs": 90000,
      "elapsedMs": 90420,
      "skippedPasses": ["dead-code", "project"],
    },
  ],
}

On a run that finishes within budget, incomplete is omitted (the JSON is byte-for-byte what you get today) and schemaVersion stays "1".

Test and story files

Findings in test, story, and fixture files (*.test.*, *.spec.*, *.stories.*, __tests__/, tests/, cypress/, e2e/, ...) are still reported — each carries "surface": "test" in the JSON output — but they are excluded from the score and the CI gate by default. Your test helpers shouldn't drag down your production health score.

Route files that merely happen to be named test (pages/test.vue, server/api/tests.get.ts) stay production surface.

Opt test findings back into the score with the flag or config:

bash
npx @geoql/vue-doctor --include-test-files
doctor.config.ts
export default defineConfig({
  includeTestFiles: true,
});

Subcommands

list-rules

Print the registered rule catalogue. Use --json or --json-compact to get a machine-readable form.

bash
npx -y @geoql/vue-doctor list-rules
npx -y @geoql/vue-doctor list-rules --category hydration --json

Filters:

flagdescription
--preset <name>restrict to rules enabled by the given preset
--category <cat>ai-slop | composition | performance | reactivity | hydration | data-fetching | server-routes
--source <src>oxlint | core
--severity <sev>error | warn | info

explain <ruleId>

Print the long-form description, the rationale, and the recommended fix for a single rule.

bash
npx -y @geoql/vue-doctor explain no-em-dash-in-str

The output is the same text that appears in the docs at /rules/vue and /rules/nuxt, but reachable from the terminal.

inspect [dir]

Print the detected project profile: framework versions, capabilities (auto-imports, Pinia, Vue Router), monorepo layout, and the rules that would be enabled under the active preset.

bash
npx -y @geoql/vue-doctor inspect
npx -y @geoql/vue-doctor inspect apps/web --json

Useful in CI to debug "why is rule X not firing on this project?".

The JSON report's projectInfo carries a frameworkDetected boolean (true when a Vue or Nuxt project is detected, false otherwise) so a consumer can tell a real audit apart from a scan that found no Vue/Nuxt project — without string-matching framework.

init

Generate a doctor.config.ts in the current directory. Interactive by default; pass --yes to accept defaults.

bash
npx -y @geoql/vue-doctor init --yes
npx -y @geoql/vue-doctor init --yes --config-format json

The init flow asks five questions (preset, output format, fail-on threshold, file scope, ignore globs) and writes a typed config that matches the config schema.

ci install

Scaffold a CI workflow that runs doctor on every push and pull request. It writes a workflow which uses the published geoql/doctor-action@v2 — it does not inline an npx run, so upgrades come for free from the action's floating major tag.

bash
# GitHub Actions (auto-detected) — writes .github/workflows/doctor.yml
npx -y @geoql/vue-doctor ci install

# preview without writing
npx -y @geoql/vue-doctor ci install --dry-run

# also scaffold a PR-review workflow; skip inline PR comments
npx -y @geoql/vue-doctor ci install --pr --no-comments
flagdescriptiondefault
--pralso scaffold a separate PR-review workflowoff
--no-commentsstrict gate only — omit the PR-comment inputscomments
--provider <name>github | gitlab | auto (GitLab writes a gate-only job)auto
-y, --yeswrite without promptingoff
--forceoverwrite an existing workflowoff
--dry-runprint the planned files, write nothingoff

The scaffolded workflow wires api-key to secrets.DOCTOR_API_KEY and sets push-project, so pushing scores to the dashboard only needs you to add the secret. framework is fixed to the CLI you ran (vue for vue-doctor, nuxt for nuxt-doctor). ci upgrade and ci config are intentionally not provided — the floating @v2 tag handles upgrades, and gate/scope/PR settings live on the audit flags and the action's with: block.

design [dir]

Runs a focused design-quality scan — accessibility, interaction states, forms, and production polish — powered by shadscan-vue. The design score is its own weighted 0-100 and never affects the health score.

bash
npx @geoql/vue-doctor design .
npx @geoql/vue-doctor design . --format json
npx @geoql/vue-doctor design . --fail-under 70
FlagWhat it does
--format <name>human (default), json, or agent
--fail-under <score>Exit 1 when the design score is below N

Dashboard push (the-doctor.report)

When you run doctor in CI, it can stream privacy-stripped findings to your the-doctor.report dashboard so the score, severity counts, and per-rule findings show up over time.

flagdescriptiondefault
--pushafter the audit, POST findings to the SaaS (negate with --no-push)off
--api-key <key>the-doctor.report API key (doc_…); pass via a secret, never inline
--push-project <slug>dashboard project slug (e.g. owner/repo); falls back to the directory nameaudited dir name
--push-workspace <path>sub-app label inside a monorepo project (e.g. apps/docs)none (single-app repo)
--push-url <url>SaaS endpoint for the pushhttps://app.the-doctor.report/api/v1/findings
bash
npx -y @geoql/vue-doctor \
  --push \
  --api-key "$DOCTOR_API_KEY" \
  --push-project "owner/repo"

Monorepos: one project, one score series per workspace

A repo that ships a Vue library and a Nuxt app has two codebases with two very different scores. Push them under the same --push-project slug and tag each with --push-workspace, and the dashboard keeps a separate score series, findings list, and leaderboard row per sub-app — instead of the two runs overwriting each other on every commit.

bash
# Vue library
npx -y @geoql/vue-doctor packages/my-lib \
  --push --api-key "$DOCTOR_API_KEY" \
  --push-project "owner/repo" --push-workspace "packages/my-lib"

# Nuxt docs app in the same repo
npx -y @geoql/nuxt-doctor apps/docs \
  --push --api-key "$DOCTOR_API_KEY" \
  --push-project "owner/repo" --push-workspace "apps/docs"

Output formats

formatbest forshape
agentlocal dev, CI logs (default)one-line summary + per-finding block
prettylocal dev, human readingboxed tables with rule descriptions
jsonprogrammatic consumptionfull AuditReport JSON
json-compacthigh-volume CIsingle-line JSON per finding
sarifGitHub code scanning, GitLab code qualitySARIF 2.1.0
htmlshareable report (emailable, PR comment)self-contained HTML

The format is auto-detected from the --output extension if you don't pass --format. .jsonjson, .sarifsarif, .htmlhtml, anything else → agent.

Exit codes

Stable across all subcommands:

codemeaning
0success — score above threshold, no findings at or above --fail-on
1at or above --fail-on threshold (or score below --threshold)
2invalid arguments, missing config, doctor crash, or I/O error

Environment variables

variableequivalent flagnotes
DOCTOR_NO_COLOR--no-colordisable ANSI in output
DOCTOR_PRESET--presetpicked up before the CLI flag
DOCTOR_FAIL_ON--fail-on
DOCTOR_FORMAT--format
DOCTOR_ROOT--root
CIauto-enables annotations when set
GITHUB_ACTIONSalso auto-enables annotations

The CLI flag always wins over the env var. The env var is useful for shell aliases and CI matrix defaults.