@cngx/doctor
v0.2.0
Published
Deterministic project-wiring scanner for cngx consumer apps: the whole-project checks ESLint's per-file scope cannot see, as an npx-able CI gate.
Maintainers
Readme
@cngx/doctor
A deterministic project-wiring scanner for apps that consume @cngx/*. It
catches the mistakes ESLint's per-file scope cannot see - the ones that need a
whole-project view - and exits non-zero when an error-severity finding trips, so
a consumer CI job can gate on it directly.
Usage
npx @cngx/doctor [projectDir] [--json]projectDir defaults to the current directory. Default output is human-readable;
--json emits the machine contract. --help and --version do what they say,
and an unknown flag is warned about on stderr rather than silently ignored. The
exit code follows lint semantics: 0 when clean or when only warn-severity
findings exist (they are still reported in the output), non-zero when any
error-severity finding exists - wire it straight into a CI step:
- run: npx @cngx/doctorEach finding is an object:
{
"id": "toaster-without-withtoasts",
"message": "why it is wrong",
"fixHint": "how to fix it",
"severity": "error",
"file": "src/app.ts"
}file is present only when the finding points at a specific source; --json
emits the array of these objects.
Checks
toaster-without-withtoasts- aCngxToaster/CngxAlerter/CngxBanner(or the*Onbridges) is used but the matchingprovideFeedback(withToasts()/withAlerts()/withBanners())root opt-in is missing, so the feedback surface has no host to render into.track-b-css-not-imported- a cngx directive whose visual theming lives in the Track-B stylesheet is imported, but no app style entry wires@cngx/themes/cngx.css- neither an@importin a global stylesheet nor a direct listing in a buildstylesarray - so it renders unstyled. Style entries resolve fromangular.json, from Nxproject.jsonfiles (root,apps/*,libs/*), and from the conventionalsrc/styles.*defaults.floating-fallback-missing-@floating-ui/domis installed butprovideFloatingFallback()is never called, so browsers without CSS Anchor Positioning get no positioning fallback.
Charter
The doctor owns exactly one class of defect: silent wiring failures. A wiring mistake it catches produces no throw and logs nothing - the app just renders wrong or does nothing, with no signal to the developer. The doctor makes that silence loud.
It deliberately does not cover throw-based errors. When a required provider is
genuinely missing at runtime, Angular's dependency injector already throws and
Angular's ErrorHandler already surfaces it; that path is loud on its own and is
out of scope here. The check set stays small and silent-wiring-only on purpose -
adding checks outside that charter is a separate decision, not a drop-in.
One known detection bound: symbol usage is read from named runtime imports
(import { CngxToaster } from '@cngx/...'). A namespace import
(import * as feedback from '@cngx/...') is not matched - the miss direction is
a skipped finding, never a false positive.
