pyreon

@pyreon/cli provides command-line tools for Pyreon projects: a project-wide health audit (doctor) and project context inspection for AI tools (context).

@pyreon/clistable

Installation

npm install @pyreon/cli
bun add @pyreon/cli
pnpm add @pyreon/cli
yarn add @pyreon/cli

Overview

doctor

pyreon doctor is a project-wide health audit. It runs a set of independent gates in parallel, aggregates every finding into a unified report, and computes a 0-100 health score with a letter grade and a per-category bar chart (modeled after react.doctor).

pyreon doctor

By default it runs the 11 fast gates (~1-2s wall-clock on a warm cache). The 2 slow gates are opt-in via --full.

  pyreon doctor · project health audit

  Score:  92/100   Grade: A

  Per category:

  correctness    █████████░░░  87 · 1E 1W
  performance    ████████████ 100 · clean
  architecture   ████████████ 100 · clean
  testing        ████████████ 100 · clean
  documentation  ████████████ 100 · clean

  Top findings (2 of 2):

  ✖ useState imported from React. Use signal() from @pyreon/reactivity.
     src/App.tsx:1:9
     fix: import { signal } from "@pyreon/reactivity"

  ⚠ className → class (HTML standard attribute).
     src/App.tsx:3:18

  1 error · 1 warning · 8 gates · 1.4s

Gates

Each gate emits findings with a category, a severity (error / warning / info), and a stable <gate>/<rule> code. The default category drives where the gate's findings land in the score breakdown.

GateSpeedCategoryWhat it checks
react-patternsfastcorrectness"Coming from React" mistakes — useState, useEffect, className, htmlFor, onChange on inputs, .value writes, React imports.
pyreon-patternsfastcorrectness"Using Pyreon wrong" mistakes — <For> missing by, destructured props, signal-write-as-call, and more. Codes a @pyreon/lint rule fully owns (e.g. process-dev-gate, raw addEventListener) are deferred to the lint gate (not double-reported); kept codes honor .pyreonlintrc.json exemptPaths.
lintfastcorrectnessAll configured @pyreon/lint rules across the project (reads your .pyreonlintrc.json).
distributionfastarchitecturePublished-package hygiene — sideEffects declared, source maps shipped (not excluded via !lib/**/*.map).
doc-claimsfastdocumentationNumeric claims in human-written docs match the source of truth (hook count, doc-page count). Skipped automatically in non-Pyreon projects.
islands-auditfastarchitectureCross-file islands detectors — duplicate name, never+registry, registry mismatch, nested island, dead island.
ssg-auditfastarchitectureSSG-config consistency — _404.tsx placement, missing getStaticPaths (only for mode: 'ssg' apps — SPA/SSR/ISR never prerender), non-literal revalidate exports.
content-auditfastarchitecture@pyreon/zero-content content — broken internal links, missing frontmatter titles, orphaned .md files. Validated per-config (two apps that both mount /docs don't cross-contaminate).
audit-testsfasttestingThe mock-vnode anti-pattern — tests that build { type, props, children } literals instead of going through real h().
check-dedupfastarchitectureDuplicate dependency versions in the lockfile.
audit-leak-classesfastbest-practices (advisory)The 5 memory-leak classes. Advisory — false-positive-prone, so findings are VISIBLE but excluded from the grade + --ci.
audit-typesslowarchitectureTyped-but-unimplemented public fields (zero non-type refs in the owning package). Requires --full.
bundle-budgetsslowperformanceEach published package's gzipped main-entry size stays within its locked budget. Requires --full.

The two slow gates only run with --full; otherwise they appear in the report's skipped footer with the reason enable with --full. A gate that throws is isolated into a single <gate>/gate-failed error finding rather than crashing the whole run.

Score

The score is a simple mean of the included category subscores (a category with no contributing gate is excluded from the mean rather than counted as a misleading 100).

Per-finding penalty by severity:

  • error — 10 points

  • warning — 3 points

  • info — 1 point

Each category subscore is 100 - clamp(sum of penalties, 0, 100), so 10 errors saturate a category to 0, 33 warnings cost 1 point, and so on. "Fix one error, gain 10 points (capped at 100)" is predictable by design.

Letter grades:

GradeScore
A90-100
B80-89
C70-79
D60-69
Fbelow 60

Flags

FlagEffect
--fullInclude the slow gates (audit-types, bundle-budgets).
--fixAuto-fix where possible (lint + react-patterns findings with auto-fixers).
--only <gates>Run ONLY the listed comma-separated gates. Takes precedence over --full.
--skip <gates>Exclude the listed comma-separated gates (applied after --only).
--format text|json|ghaOutput format (default: text).
--jsonShortcut for --format=json — emits the full DoctorReport.
--ghaShortcut for --format=gha — GitHub Actions annotation lines for inline PR notes.
--ciExit non-zero on error findings only (warnings/infos don't fail the build).
--audit-min-risk high|medium|lowMinimum risk floor for the audit-tests gate (default: medium).

Valid gate names for --only / --skip: react-patterns, pyreon-patterns, lint, distribution, doc-claims, islands-audit, ssg-audit, content-audit, audit-tests, check-dedup, audit-leak-classes, audit-types, bundle-budgets.

pyreon doctor                                  # 11 fast gates + score
pyreon doctor --full                           # add audit-types + bundle-budgets
pyreon doctor --only lint,react-patterns       # run a focused subset
pyreon doctor --skip doc-claims                # everything except doc-claims
pyreon doctor --fix                            # auto-fix lint + react-patterns
pyreon doctor --ci                             # CI gate — exit non-zero on errors
pyreon doctor --json                           # full report for AI agents / dashboards
pyreon doctor --gha                            # GitHub Actions inline annotations

Without --ci, pyreon doctor is informational — it prints the report and always exits 0 (so it never breaks an interactive run). Use --ci to gate a build: it exits non-zero only on error findings (advisory best-practices errors are excluded — opinionated rules never fail CI).

Legacy flags

The pre-v2 single-purpose flags still work — they map to --only <gate> shortcuts so existing CI scripts keep functioning unchanged:

Legacy flagEquivalent
--audit-tests--only audit-tests
--check-islands--only islands-audit
--check-ssg--only ssg-audit
--check-content--only content-audit
pyreon doctor --check-islands                          # == --only islands-audit
pyreon doctor --audit-tests --audit-min-risk high      # filtered test-env audit
pyreon doctor --check-ssg --json                       # SSG audit, machine-readable

The islands-audit gate is the same scanner as the MCP audit_islands tool, flagging: duplicate-name (two island() calls with the same name — only the first hydrates), never-with-registry-entry (hydrate: 'never' paired with a manual registry entry), registry-mismatch (hydrateIslands({ X }) where X has no matching island()), nested-island (an island() whose loader-target file also contains an island()), and dead-island (an island() no other source imports).

The audit-tests gate scans every *.test.{ts,tsx} for the mock-vnode anti-pattern that caused PR #197's silent metadata drop, classifying files HIGH / MEDIUM / LOW. Three context-aware skips (helper-def vs binding discrimination, type-guard call-arg skip, template-string fixture mask) keep the false-positive rate low.

context

The context command inspects your project structure and writes a machine-readable summary (.pyreon/context.json) designed for AI coding assistants.

  • Lists detected routes, components, and islands

  • Outputs JSON that can be piped into an LLM prompt or MCP server

  • Used internally by @pyreon/mcp to provide project-aware assistance

pyreon context                       # writes .pyreon/context.json
pyreon context --out path/to/ctx.json   # custom output path
@pyreon/cli