@pyreon/cli 0.15.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,20 +12,49 @@ bun add -d @pyreon/cli
12
12
 
13
13
  ### `pyreon doctor`
14
14
 
15
- Scans your project for React patterns and auto-fixes them to Pyreon equivalents.
15
+ Project-wide health audit runs every check Pyreon ships across 5 categories
16
+ (`correctness`, `performance`, `architecture`, `testing`, `documentation`) and
17
+ returns a unified 0-100 score with per-category breakdown.
16
18
 
17
19
  ```bash
18
- pyreon doctor # human-readable output
19
- pyreon doctor --fix # auto-fix safe transforms
20
- pyreon doctor --json # structured JSON output for AI tools
21
- pyreon doctor --ci # exit code 1 on any error (for CI)
22
-
23
- # Test-environment audit (mock-vnode patterns the PR #197 bug class)
24
- pyreon doctor --audit-tests # appends test-audit with minRisk=medium
25
- pyreon doctor --audit-tests --audit-min-risk high # only HIGH-risk files
26
- pyreon doctor --json --audit-tests # audit emitted as a second JSON blob
20
+ pyreon doctor # default: 8 fast gates, ~2-5s, scored output
21
+ pyreon doctor --full # adds 2 slow gates (audit-types, bundle-budgets)
22
+ pyreon doctor --fix # auto-fix what we can (lint + react-patterns)
23
+ pyreon doctor --json # full DoctorReport as JSON
24
+ pyreon doctor --gha # GitHub Actions annotation format
25
+ pyreon doctor --ci # exit non-zero on error findings only
26
+ pyreon doctor --only lint,distribution # ONLY these gates
27
+ pyreon doctor --skip pyreon-patterns # exclude these gates
28
+ pyreon doctor --audit-min-risk high # tighten test-environment audit
27
29
  ```
28
30
 
31
+ #### Gates
32
+
33
+ | Gate | Category | Speed | What it catches |
34
+ | ----------------- | -------------- | ----- | ---------------------------------------------------------- |
35
+ | `react-patterns` | correctness | fast | useState/useEffect/className/React imports (auto-fixable) |
36
+ | `pyreon-patterns` | correctness | fast | Pyreon-specific anti-patterns (12 detector codes) |
37
+ | `lint` | varies | fast | All 66 `@pyreon/lint` rules |
38
+ | `distribution` | architecture | fast | `sideEffects` field, source-map exclusion in published pkg |
39
+ | `doc-claims` | documentation | fast | Numeric claims in docs match the source of truth |
40
+ | `audit-tests` | testing | fast | Mock-vnode test patterns (PR #197 bug class) |
41
+ | `islands-audit` | architecture | fast | Cross-file islands foot-guns (duplicate names, dead, ...) |
42
+ | `ssg-audit` | architecture | fast | `_404.tsx` placement, missing `getStaticPaths`, ... |
43
+ | `audit-types` | architecture | slow | Typed-but-unimplemented public-interface fields |
44
+ | `bundle-budgets` | performance | slow | Gzipped main-entry size > locked budget |
45
+
46
+ #### Score formula
47
+
48
+ - Per-finding penalty: `error=10, warning=3, info=1` points.
49
+ - Per-category subscore: `max(0, 100 - sum(penalties))` (saturates at 0).
50
+ - Overall score: mean of *included* category subscores (skipped categories drop out).
51
+ - Letter grades: A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 60, F otherwise.
52
+
53
+ #### Legacy flags (still work)
54
+
55
+ `--audit-tests`, `--check-islands`, `--check-ssg` are still accepted — they map
56
+ to `--only <gate>` shortcuts so existing CI scripts keep working.
57
+
29
58
  #### What it detects and suggests
30
59
 
31
60
  ```tsx
@@ -95,37 +124,47 @@ function Counter() {
95
124
  run: bunx @pyreon/cli doctor --ci
96
125
  ```
97
126
 
98
- #### JSON output format
127
+ #### JSON output format (`--json`)
99
128
 
100
129
  ```json
101
130
  {
102
- "passed": false,
103
- "files": [
131
+ "score": 92,
132
+ "grade": "A",
133
+ "categories": [
134
+ { "category": "correctness", "score": 87, "errors": 1, "warnings": 1, "infos": 0, "grade": "B", "included": true },
135
+ { "category": "performance", "score": 100, "errors": 0, "warnings": 0, "infos": 0, "grade": "A", "included": true },
136
+ { "category": "architecture", "score": 100, "errors": 0, "warnings": 0, "infos": 0, "grade": "A", "included": true },
137
+ { "category": "testing", "score": 100, "errors": 0, "warnings": 0, "infos": 0, "grade": "A", "included": true },
138
+ { "category": "documentation", "score": 100, "errors": 0, "warnings": 0, "infos": 0, "grade": "A", "included": true }
139
+ ],
140
+ "findings": [
104
141
  {
105
- "file": "src/App.tsx",
106
- "diagnostics": [
107
- {
108
- "code": "react-import",
109
- "line": 1,
110
- "message": "React import detected",
111
- "current": "import React from \"react\"",
112
- "suggested": "import { h } from \"@pyreon/core\"",
113
- "fixable": false
114
- }
115
- ],
116
- "fixed": false
142
+ "category": "correctness",
143
+ "severity": "error",
144
+ "code": "react-patterns/use-state-import",
145
+ "gate": "react-patterns",
146
+ "message": "useState imported from React. Use signal() from @pyreon/reactivity.",
147
+ "location": { "path": "/abs/src/App.tsx", "relPath": "src/App.tsx", "line": 1, "column": 9 },
148
+ "fix": "import { signal } from \"@pyreon/reactivity\""
117
149
  }
118
150
  ],
119
- "summary": {
120
- "filesScanned": 12,
121
- "filesWithIssues": 1,
122
- "totalErrors": 1,
123
- "totalFixable": 0,
124
- "totalFixed": 0
125
- }
151
+ "gates": [ /* one entry per gate, with meta.elapsedMs + meta.skipped */ ],
152
+ "totals": { "errors": 1, "warnings": 1, "infos": 0 },
153
+ "elapsedMs": 2300,
154
+ "timestamp": "2026-05-14T12:00:00.000Z"
126
155
  }
127
156
  ```
128
157
 
158
+ #### GitHub Actions annotations (`--gha`)
159
+
160
+ ```text
161
+ ::notice::pyreon doctor score: 92/100 (A) — 1 errors, 1 warnings, 0 info
162
+ ::error title=react-patterns/use-state-import,file=src/App.tsx,line=1,col=9::useState imported from React. — import { signal } from "@pyreon/reactivity"
163
+ ```
164
+
165
+ GitHub Actions parses these into inline PR annotations (clickable in the
166
+ "Files changed" tab).
167
+
129
168
  ### `pyreon context`
130
169
 
131
170
  Generates project context for AI tools.
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"6e84cb74-1","name":"context.ts"},{"uid":"6e84cb74-3","name":"doctor.ts"},{"uid":"6e84cb74-5","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"6e84cb74-1":{"renderedLength":1323,"gzipLength":627,"brotliLength":0,"metaUid":"6e84cb74-0"},"6e84cb74-3":{"renderedLength":5474,"gzipLength":1928,"brotliLength":0,"metaUid":"6e84cb74-2"},"6e84cb74-5":{"renderedLength":2212,"gzipLength":875,"brotliLength":0,"metaUid":"6e84cb74-4"}},"nodeMetas":{"6e84cb74-0":{"id":"/src/context.ts","moduleParts":{"index.js":"6e84cb74-1"},"imported":[{"uid":"6e84cb74-6"},{"uid":"6e84cb74-7"},{"uid":"6e84cb74-8"}],"importedBy":[{"uid":"6e84cb74-4"}]},"6e84cb74-2":{"id":"/src/doctor.ts","moduleParts":{"index.js":"6e84cb74-3"},"imported":[{"uid":"6e84cb74-6"},{"uid":"6e84cb74-7"},{"uid":"6e84cb74-8"}],"importedBy":[{"uid":"6e84cb74-4"}]},"6e84cb74-4":{"id":"/src/index.ts","moduleParts":{"index.js":"6e84cb74-5"},"imported":[{"uid":"6e84cb74-0"},{"uid":"6e84cb74-2"}],"importedBy":[],"isEntry":true},"6e84cb74-6":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"6e84cb74-0"},{"uid":"6e84cb74-2"}]},"6e84cb74-7":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"6e84cb74-0"},{"uid":"6e84cb74-2"}]},"6e84cb74-8":{"id":"@pyreon/compiler","moduleParts":{},"imported":[],"importedBy":[{"uid":"6e84cb74-0"},{"uid":"6e84cb74-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"d41728b9-1","name":"context.ts"},{"name":"doctor","children":[{"name":"gates","children":[{"uid":"d41728b9-3","name":"audit-types.ts"},{"uid":"d41728b9-5","name":"bundle-budgets.ts"},{"uid":"d41728b9-7","name":"distribution.ts"},{"uid":"d41728b9-9","name":"doc-claims.ts"},{"uid":"d41728b9-13","name":"react-patterns.ts"},{"uid":"d41728b9-15","name":"pyreon-patterns.ts"},{"uid":"d41728b9-17","name":"audit-tests.ts"},{"uid":"d41728b9-19","name":"islands-audit.ts"},{"uid":"d41728b9-21","name":"ssg-audit.ts"},{"uid":"d41728b9-23","name":"lint.ts"}]},{"name":"utils/walk.ts","uid":"d41728b9-11"},{"uid":"d41728b9-25","name":"score.ts"},{"uid":"d41728b9-27","name":"report.ts"},{"uid":"d41728b9-29","name":"orchestrator.ts"},{"name":"render","children":[{"uid":"d41728b9-31","name":"ansi.ts"},{"uid":"d41728b9-33","name":"text.ts"},{"uid":"d41728b9-35","name":"json.ts"},{"uid":"d41728b9-37","name":"gha.ts"}]}]},{"uid":"d41728b9-39","name":"doctor.ts"},{"uid":"d41728b9-41","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"d41728b9-1":{"renderedLength":1323,"gzipLength":627,"brotliLength":0,"metaUid":"d41728b9-0"},"d41728b9-3":{"renderedLength":3182,"gzipLength":1501,"brotliLength":0,"metaUid":"d41728b9-2"},"d41728b9-5":{"renderedLength":4737,"gzipLength":1972,"brotliLength":0,"metaUid":"d41728b9-4"},"d41728b9-7":{"renderedLength":4730,"gzipLength":1941,"brotliLength":0,"metaUid":"d41728b9-6"},"d41728b9-9":{"renderedLength":5261,"gzipLength":1912,"brotliLength":0,"metaUid":"d41728b9-8"},"d41728b9-11":{"renderedLength":1336,"gzipLength":717,"brotliLength":0,"metaUid":"d41728b9-10"},"d41728b9-13":{"renderedLength":2574,"gzipLength":1018,"brotliLength":0,"metaUid":"d41728b9-12"},"d41728b9-15":{"renderedLength":1404,"gzipLength":732,"brotliLength":0,"metaUid":"d41728b9-14"},"d41728b9-17":{"renderedLength":1824,"gzipLength":908,"brotliLength":0,"metaUid":"d41728b9-16"},"d41728b9-19":{"renderedLength":1436,"gzipLength":691,"brotliLength":0,"metaUid":"d41728b9-18"},"d41728b9-21":{"renderedLength":1218,"gzipLength":669,"brotliLength":0,"metaUid":"d41728b9-20"},"d41728b9-23":{"renderedLength":2573,"gzipLength":1113,"brotliLength":0,"metaUid":"d41728b9-22"},"d41728b9-25":{"renderedLength":1987,"gzipLength":871,"brotliLength":0,"metaUid":"d41728b9-24"},"d41728b9-27":{"renderedLength":1661,"gzipLength":842,"brotliLength":0,"metaUid":"d41728b9-26"},"d41728b9-29":{"renderedLength":3847,"gzipLength":1571,"brotliLength":0,"metaUid":"d41728b9-28"},"d41728b9-31":{"renderedLength":2087,"gzipLength":1071,"brotliLength":0,"metaUid":"d41728b9-30"},"d41728b9-33":{"renderedLength":4212,"gzipLength":1584,"brotliLength":0,"metaUid":"d41728b9-32"},"d41728b9-35":{"renderedLength":113,"gzipLength":115,"brotliLength":0,"metaUid":"d41728b9-34"},"d41728b9-37":{"renderedLength":951,"gzipLength":486,"brotliLength":0,"metaUid":"d41728b9-36"},"d41728b9-39":{"renderedLength":2210,"gzipLength":1048,"brotliLength":0,"metaUid":"d41728b9-38"},"d41728b9-41":{"renderedLength":4281,"gzipLength":1560,"brotliLength":0,"metaUid":"d41728b9-40"}},"nodeMetas":{"d41728b9-0":{"id":"/src/context.ts","moduleParts":{"index.js":"d41728b9-1"},"imported":[{"uid":"d41728b9-42"},{"uid":"d41728b9-43"},{"uid":"d41728b9-44"}],"importedBy":[{"uid":"d41728b9-40"}]},"d41728b9-2":{"id":"/src/doctor/gates/audit-types.ts","moduleParts":{"index.js":"d41728b9-3"},"imported":[{"uid":"d41728b9-47"},{"uid":"d41728b9-43"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-4":{"id":"/src/doctor/gates/bundle-budgets.ts","moduleParts":{"index.js":"d41728b9-5"},"imported":[{"uid":"d41728b9-47"},{"uid":"d41728b9-43"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-6":{"id":"/src/doctor/gates/distribution.ts","moduleParts":{"index.js":"d41728b9-7"},"imported":[{"uid":"d41728b9-47"},{"uid":"d41728b9-42"},{"uid":"d41728b9-43"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-8":{"id":"/src/doctor/gates/doc-claims.ts","moduleParts":{"index.js":"d41728b9-9"},"imported":[{"uid":"d41728b9-42"},{"uid":"d41728b9-43"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-10":{"id":"/src/doctor/utils/walk.ts","moduleParts":{"index.js":"d41728b9-11"},"imported":[{"uid":"d41728b9-42"},{"uid":"d41728b9-43"}],"importedBy":[{"uid":"d41728b9-12"},{"uid":"d41728b9-14"}]},"d41728b9-12":{"id":"/src/doctor/gates/react-patterns.ts","moduleParts":{"index.js":"d41728b9-13"},"imported":[{"uid":"d41728b9-42"},{"uid":"d41728b9-43"},{"uid":"d41728b9-44"},{"uid":"d41728b9-10"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-14":{"id":"/src/doctor/gates/pyreon-patterns.ts","moduleParts":{"index.js":"d41728b9-15"},"imported":[{"uid":"d41728b9-42"},{"uid":"d41728b9-43"},{"uid":"d41728b9-44"},{"uid":"d41728b9-10"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-16":{"id":"/src/doctor/gates/audit-tests.ts","moduleParts":{"index.js":"d41728b9-17"},"imported":[{"uid":"d41728b9-44"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-18":{"id":"/src/doctor/gates/islands-audit.ts","moduleParts":{"index.js":"d41728b9-19"},"imported":[{"uid":"d41728b9-44"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-20":{"id":"/src/doctor/gates/ssg-audit.ts","moduleParts":{"index.js":"d41728b9-21"},"imported":[{"uid":"d41728b9-44"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-22":{"id":"/src/doctor/gates/lint.ts","moduleParts":{"index.js":"d41728b9-23"},"imported":[{"uid":"d41728b9-43"},{"uid":"d41728b9-48"}],"importedBy":[{"uid":"d41728b9-46"}]},"d41728b9-24":{"id":"/src/doctor/score.ts","moduleParts":{"index.js":"d41728b9-25"},"imported":[],"importedBy":[{"uid":"d41728b9-26"}]},"d41728b9-26":{"id":"/src/doctor/report.ts","moduleParts":{"index.js":"d41728b9-27"},"imported":[{"uid":"d41728b9-24"}],"importedBy":[{"uid":"d41728b9-28"}]},"d41728b9-28":{"id":"/src/doctor/orchestrator.ts","moduleParts":{"index.js":"d41728b9-29"},"imported":[{"uid":"d41728b9-46"},{"uid":"d41728b9-26"}],"importedBy":[{"uid":"d41728b9-38"}]},"d41728b9-30":{"id":"/src/doctor/render/ansi.ts","moduleParts":{"index.js":"d41728b9-31"},"imported":[],"importedBy":[{"uid":"d41728b9-45"},{"uid":"d41728b9-32"}]},"d41728b9-32":{"id":"/src/doctor/render/text.ts","moduleParts":{"index.js":"d41728b9-33"},"imported":[{"uid":"d41728b9-30"}],"importedBy":[{"uid":"d41728b9-45"}]},"d41728b9-34":{"id":"/src/doctor/render/json.ts","moduleParts":{"index.js":"d41728b9-35"},"imported":[],"importedBy":[{"uid":"d41728b9-45"}]},"d41728b9-36":{"id":"/src/doctor/render/gha.ts","moduleParts":{"index.js":"d41728b9-37"},"imported":[],"importedBy":[{"uid":"d41728b9-45"}]},"d41728b9-38":{"id":"/src/doctor.ts","moduleParts":{"index.js":"d41728b9-39"},"imported":[{"uid":"d41728b9-28"},{"uid":"d41728b9-45"}],"importedBy":[{"uid":"d41728b9-40"}]},"d41728b9-40":{"id":"/src/index.ts","moduleParts":{"index.js":"d41728b9-41"},"imported":[{"uid":"d41728b9-0"},{"uid":"d41728b9-38"}],"importedBy":[],"isEntry":true},"d41728b9-42":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"d41728b9-0"},{"uid":"d41728b9-6"},{"uid":"d41728b9-8"},{"uid":"d41728b9-12"},{"uid":"d41728b9-14"},{"uid":"d41728b9-10"}]},"d41728b9-43":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"d41728b9-0"},{"uid":"d41728b9-2"},{"uid":"d41728b9-4"},{"uid":"d41728b9-6"},{"uid":"d41728b9-8"},{"uid":"d41728b9-12"},{"uid":"d41728b9-14"},{"uid":"d41728b9-22"},{"uid":"d41728b9-10"}]},"d41728b9-44":{"id":"@pyreon/compiler","moduleParts":{},"imported":[],"importedBy":[{"uid":"d41728b9-0"},{"uid":"d41728b9-12"},{"uid":"d41728b9-14"},{"uid":"d41728b9-16"},{"uid":"d41728b9-18"},{"uid":"d41728b9-20"}]},"d41728b9-45":{"id":"/src/doctor/render/index.ts","moduleParts":{},"imported":[{"uid":"d41728b9-32"},{"uid":"d41728b9-34"},{"uid":"d41728b9-36"},{"uid":"d41728b9-30"}],"importedBy":[{"uid":"d41728b9-38"}]},"d41728b9-46":{"id":"/src/doctor/gates/index.ts","moduleParts":{},"imported":[{"uid":"d41728b9-2"},{"uid":"d41728b9-4"},{"uid":"d41728b9-6"},{"uid":"d41728b9-8"},{"uid":"d41728b9-12"},{"uid":"d41728b9-14"},{"uid":"d41728b9-16"},{"uid":"d41728b9-18"},{"uid":"d41728b9-20"},{"uid":"d41728b9-22"}],"importedBy":[{"uid":"d41728b9-28"}]},"d41728b9-47":{"id":"node:child_process","moduleParts":{},"imported":[],"importedBy":[{"uid":"d41728b9-2"},{"uid":"d41728b9-4"},{"uid":"d41728b9-6"}]},"d41728b9-48":{"id":"@pyreon/lint","moduleParts":{},"imported":[],"importedBy":[{"uid":"d41728b9-22"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;