laxy-verify 0.1.2 → 1.0.1

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.
Files changed (46) hide show
  1. package/README.md +150 -163
  2. package/dist/badge.d.ts +1 -0
  3. package/dist/badge.js +14 -0
  4. package/dist/build.d.ts +11 -0
  5. package/dist/build.js +67 -0
  6. package/dist/cli.js +283 -93
  7. package/dist/comment.d.ts +20 -0
  8. package/dist/comment.js +89 -0
  9. package/dist/config.d.ts +30 -12
  10. package/dist/config.js +148 -47
  11. package/dist/detect.d.ts +10 -0
  12. package/dist/detect.js +133 -0
  13. package/dist/github.d.ts +8 -0
  14. package/dist/github.js +14 -0
  15. package/dist/grade.d.ts +37 -0
  16. package/dist/grade.js +64 -0
  17. package/dist/init.d.ts +1 -0
  18. package/dist/init.js +121 -0
  19. package/dist/lighthouse.d.ts +7 -0
  20. package/dist/lighthouse.js +130 -0
  21. package/dist/serve.d.ts +12 -0
  22. package/dist/serve.js +126 -0
  23. package/dist/status.d.ts +6 -0
  24. package/dist/status.js +36 -0
  25. package/package.json +29 -44
  26. package/action.yml +0 -97
  27. package/dist/build-runner.d.ts +0 -22
  28. package/dist/build-runner.js +0 -156
  29. package/dist/build-runner.js.map +0 -1
  30. package/dist/cli.js.map +0 -1
  31. package/dist/config.js.map +0 -1
  32. package/dist/dev-server.d.ts +0 -8
  33. package/dist/dev-server.js +0 -81
  34. package/dist/dev-server.js.map +0 -1
  35. package/dist/lighthouse-runner.d.ts +0 -10
  36. package/dist/lighthouse-runner.js +0 -119
  37. package/dist/lighthouse-runner.js.map +0 -1
  38. package/dist/project-runtime.d.ts +0 -32
  39. package/dist/project-runtime.js +0 -99
  40. package/dist/project-runtime.js.map +0 -1
  41. package/dist/reporter.d.ts +0 -21
  42. package/dist/reporter.js +0 -100
  43. package/dist/reporter.js.map +0 -1
  44. package/dist/verification.d.ts +0 -42
  45. package/dist/verification.js +0 -105
  46. package/dist/verification.js.map +0 -1
package/README.md CHANGED
@@ -1,163 +1,150 @@
1
- # laxy-verify
2
-
3
- Frontend quality gate for any project. Checks your build and runs a Lighthouse audit outputs a Silver/Bronze/Unverified grade.
4
-
5
- ```bash
6
- npx laxy-verify .
7
- ```
8
-
9
- ```
10
- Laxy Verify — ✅ Silver
11
- ========================================
12
-
13
- Build: PASS (12.3s)
14
-
15
- Lighthouse Scores:
16
- Performance: 87 / 70 ✓
17
- Accessibility: 92 / 85 ✓
18
- SEO: 88 / 80 ✓
19
- Best Practices: 90 / 80 ✓
20
-
21
- Grade: Silver
22
- ```
23
-
24
- > Want Gold? Gold requires E2E tests on top of build + Lighthouse. Run full verification at [laxy.dev](https://laxy.dev).
25
-
26
- ---
27
-
28
- ## Install
29
-
30
- ```bash
31
- # Run once (no install needed)
32
- npx laxy-verify .
33
-
34
- # Or install globally
35
- npm install -g laxy-verify
36
- laxy-verify .
37
- ```
38
-
39
- ---
40
-
41
- ## Usage
42
-
43
- ```bash
44
- laxy-verify [dir] [options]
45
-
46
- Arguments:
47
- dir Project directory (default: current directory)
48
-
49
- Options:
50
- --format <type> Output format: console, json, md (default: console)
51
- --ci CI mode: relaxed thresholds, 3 Lighthouse runs
52
- --skip-lighthouse Build check only, skip Lighthouse
53
- --runs <number> Number of Lighthouse runs
54
- --port <number> Dev server port (default: 3000)
55
- ```
56
-
57
- ### Examples
58
-
59
- ```bash
60
- # Check current directory
61
- npx laxy-verify .
62
-
63
- # Build check only (fast)
64
- npx laxy-verify . --skip-lighthouse
65
-
66
- # CI mode with JSON output
67
- npx laxy-verify . --ci --format json
68
-
69
- # Markdown output (for PR comments)
70
- npx laxy-verify . --format md
71
- ```
72
-
73
- ---
74
-
75
- ## Exit Codes
76
-
77
- | Code | Meaning |
78
- |------|---------|
79
- | `0` | Silver or Gold — all checks passed |
80
- | `1` | Bronze — build passed, Lighthouse failed (soft fail) |
81
- | `2` | Unverified — build failed |
82
- | `3` | Config error — no package.json, no build script |
83
-
84
- ---
85
-
86
- ## Grades
87
-
88
- | Grade | Condition |
89
- |-------|-----------|
90
- | Silver | Build passed + all Lighthouse thresholds met |
91
- | 🔨 Bronze | Build passed, Lighthouse failed or skipped |
92
- | ⚠️ Unverified | Build failed |
93
-
94
- > 🏆 **Gold** requires E2E tests. Use [Laxy](https://laxy.dev) for full Gold verification.
95
-
96
- ---
97
-
98
- ## GitHub Action
99
-
100
- Add this to `.github/workflows/verify.yml`:
101
-
102
- ```yaml
103
- name: Laxy Verify
104
-
105
- on:
106
- pull_request:
107
-
108
- jobs:
109
- verify:
110
- runs-on: ubuntu-latest
111
- steps:
112
- - uses: actions/checkout@v4
113
- - uses: psungmin24/laxy-verify@v1
114
- with:
115
- format: md
116
- ```
117
-
118
- On every PR, laxy-verify will:
119
- 1. Run `npm run build`
120
- 2. Start your dev server and run Lighthouse
121
- 3. Post a comment with the grade and scores
122
-
123
- ### Action Inputs
124
-
125
- | Input | Default | Description |
126
- |-------|---------|-------------|
127
- | `node-version` | `20` | Node.js version |
128
- | `skip-lighthouse` | `false` | Build check only |
129
- | `format` | `md` | Output format |
130
-
131
- ---
132
-
133
- ## Configuration
134
-
135
- Create `.laxy.yml` in your project root to customize thresholds:
136
-
137
- ```yaml
138
- thresholds:
139
- performance: 70
140
- accessibility: 85
141
- seo: 80
142
- bestPractices: 80
143
-
144
- port: 3000
145
- runs: 1
146
- ```
147
-
148
- ---
149
-
150
- ## Supported Frameworks
151
-
152
- Automatically detects and runs the right build command:
153
-
154
- - **Next.js** — `next build`
155
- - **Vite** — `vite build`
156
- - **Create React App** — `react-scripts build`
157
- - **Custom** — reads `scripts.build` from `package.json`
158
-
159
- ---
160
-
161
- ## License
162
-
163
- MIT
1
+ # laxy-verify
2
+
3
+ Frontend quality gate for AI-generated code. Build + Lighthouse verification with grade output (Gold/Silver/Bronze/Unverified).
4
+
5
+ ```bash
6
+ npx laxy-verify --init # Auto-detect framework, generate config
7
+ npx laxy-verify . # Run verification
8
+ npx laxy-verify --badge # Show shields.io badge
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Initialize
14
+
15
+ ```bash
16
+ cd your-project
17
+ npx laxy-verify --init
18
+ ```
19
+
20
+ This generates `.laxy.yml` and `.github/workflows/laxy-verify.yml` automatically by detecting your framework and package manager.
21
+
22
+ ### 2. Run Locally
23
+
24
+ ```bash
25
+ npx laxy-verify .
26
+ ```
27
+
28
+ ### 3. Add to CI
29
+
30
+ Push the generated workflow file. Every PR gets a quality gate with grade comment and status check.
31
+
32
+ ## Grades
33
+
34
+ | Grade | Requirement |
35
+ |-------|------------|
36
+ | **Silver** | Build passes + Lighthouse exceeds all thresholds |
37
+ | **Bronze** | Build passes (Lighthouse not run or below threshold) |
38
+ | **Unverified** | Build failed |
39
+
40
+ `fail_on` controls the minimum acceptable grade. Default: `bronze`.
41
+
42
+ ## Configuration
43
+
44
+ All fields optional in `.laxy.yml`:
45
+
46
+ ```yaml
47
+ framework: "auto" # auto | nextjs | vite | cra | sveltekit
48
+ build_command: "" # default: auto-detected from package.json
49
+ dev_command: "" # default: auto-detected
50
+ package_manager: "auto" # auto | npm | pnpm | yarn | bun
51
+ port: 3000 # dev server port
52
+ build_timeout: 300 # seconds (default 5m)
53
+ dev_timeout: 60 # seconds for dev server start (90 in CI mode)
54
+ lighthouse_runs: 1 # @lhci/cli runs (CI mode auto-sets to 3)
55
+
56
+ thresholds:
57
+ performance: 70 # CI mode applies -10 offset (effective: 60)
58
+ accessibility: 85
59
+ seo: 80
60
+ best_practices: 80
61
+
62
+ fail_on: "bronze" # unverified | bronze | silver | gold
63
+ # unverified = never fail (informational only)
64
+ ```
65
+
66
+ **fail_on vs build failure:** Build failure always produces grade `Unverified` and exit code 1, regardless of `fail_on`. `fail_on: unverified` means informational only (always exit 0).
67
+
68
+ **--ci flag:** Lowers Performance threshold by 10, sets `lighthouse_runs=3` (when not explicitly set), and increases `dev_timeout` to 90s. Auto-set when `CI=true` env var exists.
69
+
70
+ ## CLI Options
71
+
72
+ ```
73
+ npx laxy-verify [project-dir] Default: current directory
74
+
75
+ Options:
76
+ --format console | json Output format (default: console)
77
+ --ci CI mode: -10 Performance, runs=3
78
+ --config <path> Path to .laxy.yml
79
+ --fail-on unverified|bronze|silver|gold Override fail_on
80
+ --skip-lighthouse Build-only verification (max Bronze)
81
+ --badge Show shields.io badge (reads .laxy-result.json)
82
+ --init Generate .laxy.yml + GitHub workflow
83
+ ```
84
+
85
+ ## exit codes
86
+
87
+ | Code | Meaning |
88
+ |------|--------|
89
+ | 0 | Grade meets or exceeds `fail_on` threshold |
90
+ | 1 | Grade worse than `fail_on`, or build failed |
91
+ | 2 | Configuration error (no package.json, invalid YAML, etc.) |
92
+
93
+ ## GitHub Action
94
+
95
+ ```yaml
96
+ - uses: psungmin24/laxy-verify@v1
97
+ with:
98
+ github-token: ${{ secrets.GITHUB_TOKEN }}
99
+ fail-on: silver # optional, default: bronze
100
+ config: .laxy.yml # optional
101
+ ```
102
+
103
+ Posts a PR comment with grade and Lighthouse scores, and sets a commit status check.
104
+
105
+ ## Limitations (v1)
106
+
107
+ - **Monorepos:** Not supported. Run `npx laxy-verify apps/web` for the app subdirectory.
108
+ - **Lighthouse accuracy:** Scores are measured in dev mode (`npm run dev`). Production scores are typically higher.
109
+ - **Fork PRs:** Comments and status checks are not posted on PRs from forks (GitHub security restriction).
110
+ - **Yarn Berry:** May require manual `package_manager` configuration if using Corepack.
111
+
112
+ ## Expected CI Timing
113
+
114
+ - Build: 15-30s
115
+ - Dev server start: 5-20s
116
+ - Lighthouse (1 run): ~15s
117
+ - Lighthouse (3 runs CI): ~45s
118
+ - **Total: 35-95s per PR**
119
+
120
+ ## .laxy-result.json
121
+
122
+ Written after every run:
123
+
124
+ ```json
125
+ {
126
+ "grade": "Silver",
127
+ "timestamp": "2026-04-07T10:30:00Z",
128
+ "build": { "success": true, "durationMs": 12300, "errors": [] },
129
+ "lighthouse": { "performance": 87, "accessibility": 92, "seo": 88, "bestPractices": 90, "runs": 1 },
130
+ "thresholds": { "performance": 70, "accessibility": 85, "seo": 80, "bestPractices": 80 },
131
+ "ciMode": false,
132
+ "framework": "nextjs",
133
+ "exitCode": 0,
134
+ "config_fail_on": "bronze"
135
+ }
136
+ ```
137
+
138
+ Use `npx laxy-verify --badge` to output a shields.io badge markdown from this file.
139
+
140
+ ## Badge
141
+
142
+ ```bash
143
+ npx laxy-verify --badge
144
+ ```
145
+
146
+ Output: `![Laxy Verify: Silver](https://img.shields.io/badge/laxy_verify-silver-brightgreen)`
147
+
148
+ ## License
149
+
150
+ MIT
@@ -0,0 +1 @@
1
+ export declare function generateBadge(grade: string): string;
package/dist/badge.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateBadge = generateBadge;
4
+ function generateBadge(grade) {
5
+ const gradeLower = grade.toLowerCase();
6
+ const colors = {
7
+ gold: "yellow",
8
+ silver: "brightgreen",
9
+ bronze: "blue",
10
+ unverified: "lightgrey",
11
+ };
12
+ const color = colors[gradeLower] ?? "lightgrey";
13
+ return `![Laxy Verify: ${grade}](https://img.shields.io/badge/laxy_verify-${gradeLower}-${color})`;
14
+ }
@@ -0,0 +1,11 @@
1
+ export interface BuildResult {
2
+ success: boolean;
3
+ durationMs: number;
4
+ errors: string[];
5
+ }
6
+ export declare class BuildError extends Error {
7
+ errors: string[];
8
+ timedOut: boolean;
9
+ constructor(message: string, errors: string[], timedOut?: boolean);
10
+ }
11
+ export declare function runBuild(command: string, timeoutSec: number): Promise<BuildResult>;
package/dist/build.js ADDED
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BuildError = void 0;
7
+ exports.runBuild = runBuild;
8
+ const node_child_process_1 = require("node:child_process");
9
+ const tree_kill_1 = __importDefault(require("tree-kill"));
10
+ class BuildError extends Error {
11
+ errors;
12
+ timedOut;
13
+ constructor(message, errors, timedOut = false) {
14
+ super(message);
15
+ this.errors = errors;
16
+ this.timedOut = timedOut;
17
+ this.name = "BuildError";
18
+ }
19
+ }
20
+ exports.BuildError = BuildError;
21
+ function runBuild(command, timeoutSec) {
22
+ return new Promise((resolve, reject) => {
23
+ const startTime = Date.now();
24
+ const stderrLines = [];
25
+ const errorLines = [];
26
+ console.log(`\n Building: ${command}`);
27
+ const proc = (0, node_child_process_1.spawn)(command, { shell: true, stdio: ["ignore", "pipe", "pipe"] });
28
+ let timedOut = false;
29
+ const timer = setTimeout(() => {
30
+ timedOut = true;
31
+ if (proc.pid) {
32
+ (0, tree_kill_1.default)(proc.pid, "SIGKILL");
33
+ }
34
+ reject(new BuildError(`Build timed out after ${timeoutSec}s`, errorLines, true));
35
+ }, timeoutSec * 1000);
36
+ proc.stdout?.on("data", (chunk) => {
37
+ // Print build output to console
38
+ const lines = chunk.toString().split("\n").filter(Boolean);
39
+ for (const line of lines) {
40
+ console.log(` ${line}`);
41
+ }
42
+ });
43
+ proc.stderr?.on("data", (chunk) => {
44
+ const text = chunk.toString();
45
+ const lines = text.split("\n").filter(Boolean);
46
+ stderrLines.push(...lines);
47
+ errorLines.push(...lines);
48
+ for (const line of lines) {
49
+ console.error(` ${line}`);
50
+ }
51
+ });
52
+ proc.on("exit", (code) => {
53
+ clearTimeout(timer);
54
+ const durationMs = Date.now() - startTime;
55
+ const success = code === 0;
56
+ resolve({
57
+ success,
58
+ durationMs,
59
+ errors: success ? [] : errorLines,
60
+ });
61
+ });
62
+ proc.on("error", (err) => {
63
+ clearTimeout(timer);
64
+ reject(new BuildError(`Build process failed: ${err.message}`, errorLines));
65
+ });
66
+ });
67
+ }