chowbea-axios
Commands

doctor

Detect and repair generated artifacts wrongly tracked in git.

doctor scans for generated artifacts that are wrongly tracked in git and, with --fix, untracks them while keeping the files on disk. The _internal/ cache (spec downloads, timestamps, hashes) is machine state that must never be committed — it churns on every fetch and triggers meaningless merge conflicts. In pinned-inputs mode, _generated/ is the same: it's deterministically regenerated from the committed pins, so tracking it causes churn. doctor finds both and repairs the damage.

Usage

chowbea-axios doctor [flags]

Requires a git repository. Non-git projects exit cleanly with a message.

What it does

  1. Detects if you're in a git repository
  2. Scans _internal/ for tracked files (always checked)
  3. Scans _generated/ for tracked files (only in pinned-inputs mode — non-pinned setups legitimately commit _generated/)
  4. Checks if .gitignore has the required ignore rules
  5. Reports problems, or (with --fix) untracks the artifacts and adds the gitignore rules
  6. Stages the .gitignore repair so you can commit it

Without --fix, doctor reports problems and exits non-zero — use it as a CI gate. With --fix, it untracks the files (git rm --cached, keeping them on disk) and ensures the ignore rules exist.

When to use it

  • After init — projects created before the auto-gitignore feature may still track _internal/
  • When merge conflicts appear in _internal/.api-cache.json or _internal/openapi.json
  • After migrating to pinned-inputs mode — _generated/ should stop being committed (see migration guide)
  • As a CI check — doctor (without --fix) exits non-zero when artifacts are tracked

Not useful outside git repos.

Flags

FlagShortDescriptionDefault
--config-cPath to api.config.tomlAuto-detected
--fix-Untrack artifacts and add gitignore rulesfalse
--quiet-qSuppress non-error outputfalse
--verbose-vShow detailed outputfalse

Examples

Check for problems (report-only)

chowbea-axios doctor
# 3 generated/cache artifact(s) are tracked in git — they churn on every regen and trigger merge conflicts.
#   tracked: src/api/_internal/.api-cache.json
#   tracked: src/api/_internal/openapi.json
#   tracked: src/api/_internal/openapi-normalized.json
# Missing .gitignore rule(s): '_internal/' — regenerable output may get re-committed.
# Run 'chowbea-axios doctor --fix' to untrack the cache and ignore it.

Exit code 1 — problems found. The cache files are in the index and will churn on the next fetch, and the gitignore rule is missing.

Note: doctor reports unhealthy even when nothing is tracked but the gitignore rule is missing — --fix adds the rule and stages .gitignore.

Repair (untrack and add gitignore)

chowbea-axios doctor --fix
# Added _internal/ to .gitignore
# Untracked src/api/_internal/ (files kept on disk)
# Repaired. Commit the staged changes to finish.

The gitignore rule is added first, then artifacts are removed from the index (git rm --cached) but stay on disk, and .gitignore is staged with the new rule. Commit to finish:

git commit -m "chore: stop tracking _internal cache"

Healthy setup

chowbea-axios doctor
# No tracked cache artifacts — generated output is conflict-safe.

Exit code 0. Nothing to fix.

Exit codes

CodeMeaning
0Healthy — no tracked artifacts, or --fix repaired everything
1Problems found (report-only mode), or regeneration failed

Report-only mode (doctor without --fix) that finds problems exits 1 so it can gate CI. Once --fix repairs them, it succeeds.

What gets checked

Always: _internal/

The cache folder holding:

  • openapi.json / openapi.yaml — downloaded spec
  • openapi-normalized.json — canonicalized form
  • .api-cache.json — hash + timestamp metadata

These change on every fetch and must never be committed. init gitignores them automatically, but older setups or manual clones may have tracked them.

In pinned-inputs mode only: _generated/

When both api_endpoint and spec_file are set (pinned mode), _generated/ is regenerated from the committed pins (openapi.json, chowbea.bus.json) — tracking it causes the same churn as _internal/. doctor --fix untracks it and adds the _generated/ ignore rule.

Non-pinned setups (no spec_file configured) legitimately commit _generated/ — CI has no pinned spec to regenerate from, so the generated files must be in the repo. doctor skips the _generated/ scan in that mode.

The ignore rules doctor adds are:

  • _internal/ with comment # chowbea-axios cache (timestamps, downloaded specs)
  • _generated/ with comment # chowbea-axios generated output (pinned-inputs mode — regenerate with \chowbea-axios generate`)` (only in pinned mode)

How it works

Under the hood, doctor:

  1. Runs git ls-files _internal/ to list tracked cache files
  2. In pinned mode, also runs git ls-files _generated/
  3. Checks if .gitignore contains _internal/ (and _generated/ in pinned mode)
  4. With --fix:
    • Runs git rm --cached _internal/ (and _generated/ if needed) — files stay on disk
    • Appends the ignore rules to .gitignore if missing
    • Runs git add .gitignore

The untracked files remain in your working tree — doctor --fix never deletes anything. You can still fetch and generate normally; they just won't be committed anymore.

Pinned-inputs mode detection

Pinned mode is when both api_endpoint and spec_file are configured. When that's true, doctor knows _generated/ is regenerable from the pins and should be gitignored. Otherwise, _generated/ is assumed to be legitimately committed (the "traditional" chowbea-axios setup) and doctor doesn't touch it.

See Pinned Inputs for the full picture.

Error cases

Not a git repository

chowbea-axios doctor
# Not a git repository — nothing to check.

Exit code 0. Nothing to do.

--fix fails to untrack

If git rm --cached fails (permissions, locked files, unusual git state), doctor errors and exits non-zero. The error message includes git's output. Fix the underlying issue and re-run.

  • init — auto-gitignores _internal/ and _generated/ (in pinned mode) from the start
  • resolve — resolves merge conflicts in _generated/
  • fetch — writes to _internal/ (the cache doctor checks)
  • generate — writes to _generated/
  • sync — the command that updates pinned inputs in pinned mode

CI integration

Use doctor (without --fix) as a CI gate:

# .github/workflows/ci.yml
- name: Check for tracked cache artifacts
  run: npx chowbea-axios doctor

Exits non-zero if someone accidentally committed _internal/ or (in pinned mode) _generated/. The PR goes red, and the commit message is clear: "stop tracking generated artifacts."

Workflow example

Repairing a tracked cache

# Discover the problem
chowbea-axios doctor
# 2 generated/cache artifact(s) are tracked in git...
# Missing .gitignore rule(s): '_internal/' — regenerable output may get re-committed.

# Fix it
chowbea-axios doctor --fix
# Added _internal/ to .gitignore
# Untracked src/api/_internal/ (files kept on disk)

# Commit the repair
git commit -m "chore: stop tracking _internal cache"

# Verify
chowbea-axios doctor
# No tracked cache artifacts — generated output is conflict-safe.

Migrating to pinned mode

After you've added the pinned-inputs keys to api.config.toml:

# Stop tracking _generated/ now that it's regenerable from pins
chowbea-axios doctor --fix
# Added _generated/ to .gitignore
# Untracked src/api/_generated/ (files kept on disk)

# Commit as part of the migration
git commit -m "chore: adopt pinned-inputs mode"

doctor --fix removes files from the index but keeps them on disk. If you later run git status, they'll appear as untracked (but gitignored) files. That's correct — they're ignored now, so git stops watching them. Don't manually delete them; fetch and generate still need them.

On this page