Skip to content

CLI commands

bash
npx dowsing <command> [options]

Common options

Available on most commands.

OptionDefaultDescription
--since <date>12 months agoStart of the git window. Anything git can parse.
--until <date>End of the git window
--complexity <type>locComplexity proxy: loc | cyclomatic | cognitive
--jsonfalseWrite JSON to stdout
--config <path>auto-detectedConfig file (dowsing.config.ts / .mts / .mjs / .js)
--refreshfalseIgnore the cache and re-analyse
--no-cacheNeither read nor write the cache

Analysis results are cached in .dowsing/cache, keyed by HEAD, working-tree state, and the options above. A cache hit is announced on stderr.

For a summary of this whole page — plus requirements, output shapes, exit codes, and caching — run dowsing --help.


analyze

Analyses the workspace, writes .dowsing/dowsing.json, and prints a summary.

bash
dowsing analyze [dir]
OptionDefaultDescription
--top <n>10Number of hotspots to display
--out <path>.dowsing/dowsing.jsonOutput path
--verify-churn [n]offVerify change frequency of the top N files (default 20) by AST
--min-degree <n>0.3Minimum coupling degree (percentages like 30 also accepted)
--min-shared <n>5Minimum shared commits for coupling

With --json the report goes to stdout and no file is written.


hotspots

Prints just the hotspot ranking.

bash
dowsing hotspots [dir] --top 15

coupling

Shows change coupling.

bash
dowsing coupling [dir] --hidden
OptionDefaultDescription
--hiddenfalseOnly hidden coupling (co-change with no dependency)
--filesfalseAlso show file-level coupling
--top <n>20Number of rows
--min-degree <n>0.3Minimum degree
--min-shared <n>5Minimum shared commits

Lower the threshold to catch what you are missing

Two very active packages have a large denominator, which drags the degree down. --min-degree 15 often surfaces real pairs.


why

Explains why two things change together.

bash
dowsing why <a> <b>

Each target can be a package name, a file path, or a directory — resolved in that order (package name → exact path → prefix match).

OptionDefaultDescription
--cwd <path>.Directory to analyse
--top <n>10Number of file pairs to show
--commits <n>10Number of representative commits
bash
dowsing why @acme/admin-web @acme/customer-web
dowsing why packages/ui src/api --since "6 months ago"

health

Shows Code Health and the smell breakdown.

bash
dowsing health [dir]
dowsing health --file src/foo.ts    # deductions for one file
OptionDefaultDescription
--file <path>Show the breakdown for one file only
--top <n>10Number of rows

knowledge

Shows ownership and bus factor.

bash
dowsing knowledge [dir] --top 15

Reports bus factor per package, the contributor list, and an off-boarding simulation showing what would be left unowned if the main developer left.


report

Generates a self-contained single-file HTML report. It makes no external requests and the data is embedded, so you can share the file as-is.

bash
dowsing report [dir] --out report.html

init

Appends a dowsing section to AGENTS.md, so that every agent working in this repository knows the tool exists — whatever host it runs on.

bash
dowsing init
dowsing init --dry-run
OptionDefaultDescription
--cwd <path>.Target directory
--file <path>AGENTS.mdFile to append to
--dry-runfalsePrint the section instead of writing it

Running it again updates that section rather than adding a second one.


check

Quality gate. Exits 1 on violation.

bash
dowsing check [dir] --min-file-health 3
OptionDescription
--min-file-health <n>Floor for file health
--min-package-health <n>Floor for package health
--max-hotspot <n>Ceiling for hotspot score (0–1)
--min-bus-factor <n>Floor for package bus factor
--max-hidden-coupling <n>Ceiling on hidden coupling count
--sarif <path>Emit SARIF for GitHub Code Scanning

It checks nothing by default

Only thresholds you name explicitly are enforced. Measure where you are first, then start from a level you can actually pass.


diff

Assesses whether changes since a base touched risky ground, and measures how complexity actually moved between the two revisions.

bash
dowsing diff <base>
dowsing diff origin/main --markdown
OptionDefaultDescription
--head <ref>HEADComparison target
--cwd <path>.Directory to analyse
--markdownfalseWrite PR-comment Markdown to stdout
--out <path>Write the Markdown to a file

Every changed .ts/.tsx file is read at both revisions and re-parsed, so the delta is independent of who made the change. See Measuring the effect.


Configuration file

Everything above can be fixed in dowsing.config.ts so that it does not have to be passed each time. CLI flags win over the file, which wins over the defaults.

ts
import { defineConfig } from "dowsing";

export default defineConfig({
  since: "12 months ago",
  complexity: "cognitive",
  coupling: { minDegree: 0.3, minShared: 5 },
  health: { thresholds: { cognitive: 15 }, weights: { "large-file": 1.5 } },
  check: { minFileHealth: 4, maxHiddenCoupling: 0 },
});

Lookup order is dowsing.config.ts.mts.mjs.js; --config <path> names one explicitly. TypeScript is read as-is (Node 22.18+ strips the types), so there is no build step.

An unknown key is an error, not a silently ignored line — a threshold you believe you set but which never took effect is worse than a startup failure.

Released under the MIT License