build: shorten local validation loops

This commit is contained in:
morluto
2026-07-23 03:42:41 +08:00
parent c7363178e7
commit d6f2007723
8 changed files with 89 additions and 22 deletions
+1 -1
View File
@@ -1 +1 @@
npm run check
npm run check:fast
+3 -1
View File
@@ -63,6 +63,7 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
- `npm run lint:fix`: auto-fix oxlint violations where possible.
- `npm run format:check`: verify Prettier formatting.
- `npm run check`: run cached typecheck, lint, format:check, knip, and package-metadata freshness tasks.
- `npm run check:fast`: run only cached typecheck and lint for rapid local and pre-push feedback.
- `npm run check:ci`: run the static gate plus duplicate-code and debt-marker scans.
- `npm run check:test`: run the cached static tasks plus the uncached complete test suite.
- `npm run check:pr`: run the test gate plus uncached generated-document validation for PR preparation.
@@ -79,12 +80,13 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
- `npm run verify:replay`: build and run the real Linux Bubblewrap/seccomp/cgroup verifier against source-owned replay fixtures; set `REA_REPLAY_INPUT_PATH` to verify an operator-local manifest.
- `npm run verify:package`: pack and test the CLI, setup transaction, skill, and canonical target-free MCP catalog in an isolated environment.
- `npm run docs:api`: render uncommitted API documentation from JSDoc comments into `build/api-docs/` using TypeDoc.
- `npm run docs:api:cached`: render API documentation through Turbo or restore a valid local result.
- `npm run docs:generate`: refresh committed metadata and render the uncommitted API documentation.
- `npm run docs:check`: verify generated package metadata, the canonical product catalog, caller-visible documentation facts, TypeDoc rendering, and the error JSON schema.
- `npm run config:print -- /path/to/binary`: print an MCP server config with absolute paths.
- `HOPPER_TARGET_PATH=/path/to/binary npm start`: launch Hopper and run the built stdio MCP server.
Pre-commit hooks via Husky format and lint staged files. Pre-push runs `npm run check`. Use `npm run lint:fix` to auto-correct violations locally.
Pre-commit hooks via Husky format then lint staged source files. Pre-push runs `npm run check:fast`; CI owns the broader static and generated-document gates. Use `npm run lint:fix` to auto-correct violations locally.
## Configuration & Environment Variables
+6 -5
View File
@@ -28,11 +28,12 @@ npm run verify:package
npm pack --dry-run
```
`npm run check` runs cached typecheck, lint, formatting, dead-code, and package
metadata freshness tasks; `check:fast` remains as an alias. Use `npm run
check:test` when the complete test suite is relevant. Pre-commit formats and
lints only staged files, and pre-push runs `check`. `check:pr` additionally
renders API documentation and checks all committed generated metadata. Real
`npm run check:fast` runs cached typecheck and lint for rapid local feedback.
`npm run check` adds formatting, dead-code, and package-metadata freshness
checks; use `npm run check:test` when the complete test suite is relevant.
Pre-commit formats then lints staged source files, and pre-push runs
`check:fast`. `check:pr` additionally renders API documentation and checks all
committed generated metadata. Real
provider and replay execution remains uncached, but their deterministic build
prerequisite uses Turbo. CI uploads the rendered TypeDoc site as an `api-docs`
artifact; the generated HTML is not committed.
+10 -6
View File
@@ -58,7 +58,8 @@
"build": "tsc -p tsconfig.build.json",
"precheck": "npm run deps:check",
"check": "turbo run typecheck lint format:check knip metadata:check",
"check:fast": "npm run check",
"precheck:fast": "npm run deps:check",
"check:fast": "turbo run typecheck lint",
"precheck:test": "npm run deps:check",
"check:test": "turbo run typecheck lint format:check knip metadata:check test:run",
"precheck:pr": "npm run deps:check",
@@ -116,17 +117,20 @@
"evidence:generate": "npm run build:cached && node scripts/generate-completion-ledger.mjs",
"evidence:check": "npm run build:cached && node scripts/generate-completion-ledger.mjs --check",
"docs:api": "typedoc",
"docs:generate": "npm run metadata:generate && npm run build:cached && node scripts/generate-skill-metadata.mjs && node scripts/generate-product-catalog.mjs && node scripts/generate-completion-ledger.mjs && npm run docs:api && node scripts/generate-error-schema.mjs",
"docs:api:cached": "turbo run docs:api",
"docs:generate": "npm run metadata:generate && npm run build:cached && node scripts/generate-skill-metadata.mjs && node scripts/generate-product-catalog.mjs && node scripts/generate-completion-ledger.mjs && npm run docs:api:cached && node scripts/generate-error-schema.mjs",
"docs:check": "turbo run docs:check:built",
"docs:check:built": "node scripts/generate-package-metadata.mjs --check && node scripts/generate-skill-metadata.mjs --check && node scripts/generate-product-catalog.mjs --check && node scripts/generate-completion-ledger.mjs --check && node scripts/check-doc-facts.mjs && npm run docs:api && node scripts/generate-error-schema.mjs --check",
"docs:check:built": "node scripts/generate-package-metadata.mjs --check && node scripts/generate-skill-metadata.mjs --check && node scripts/generate-product-catalog.mjs --check && node scripts/generate-completion-ledger.mjs --check && node scripts/check-doc-facts.mjs && node scripts/generate-error-schema.mjs --check",
"docs:error-schema": "npm run build:cached && node scripts/generate-error-schema.mjs",
"prepack": "node scripts/prepack.mjs",
"prepublishOnly": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
"prepare": "node scripts/prepare.mjs"
},
"lint-staged": {
"*.{ts,mjs,json,md,yml,yaml}": "prettier --write",
"*.ts": "oxlint --fix"
"*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}": [
"prettier --write",
"oxlint --fix"
],
"*.{json,md,yml,yaml}": "prettier --write"
},
"dependencies": {
"@babel/parser": "8.0.4",
+2 -2
View File
@@ -12,7 +12,7 @@ const sourceFiles = globSync(
[
"src/**/*.ts",
"tests/**/*.ts",
"scripts/**/*.mjs",
"scripts/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}",
"bridge/**/*.py",
"bridge/**/*.java",
],
@@ -46,7 +46,7 @@ for (const file of sourceFiles) {
if (count > 0) {
console.log(`\n${count} tech-debt marker(s) found.`);
process.exitCode = 0;
process.exitCode = 1;
} else {
console.log("No tech-debt markers found.");
}
+4 -4
View File
@@ -15,9 +15,10 @@ describe("package identity", () => {
start: z.string(),
"metadata:check": z.string(),
prebuild: z.string(),
"precheck:fast": z.string(),
"check:fast": z.string(),
prepare: z.string(),
prepack: z.string(),
prepublishOnly: z.string(),
}),
})
.parse(
@@ -49,10 +50,9 @@ describe("package identity", () => {
expect(packageJson.scripts.prebuild).toBe(
"npm run deps:check && npm run metadata:check",
);
expect(packageJson.scripts["precheck:fast"]).toBe("npm run deps:check");
expect(packageJson.scripts["check:fast"]).toBe("turbo run typecheck lint");
expect(packageJson.scripts.prepare).toBe("node scripts/prepare.mjs");
expect(packageJson.scripts.prepack).toBe("node scripts/prepack.mjs");
expect(packageJson.scripts.prepublishOnly).toBe(
"npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
);
});
});
+33
View File
@@ -0,0 +1,33 @@
import { execFile } from "node:child_process";
import { copyFile, mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { promisify } from "node:util";
import { describe, expect, it } from "vitest";
import { createTestTempDirectory } from "./fixtures/temporaryDirectory.js";
const execute = promisify(execFile);
describe("tech-debt marker scan", () => {
it("passes a clean tree and rejects a tree containing a marker", async () => {
const root = await createTestTempDirectory("rea-scan-todos-");
const scripts = join(root, "scripts");
const source = join(root, "src");
await Promise.all([mkdir(scripts), mkdir(source)]);
const scanner = join(scripts, "scan-todos.mjs");
await copyFile(join(process.cwd(), "scripts/scan-todos.mjs"), scanner);
await writeFile(join(source, "clean.ts"), "export const clean = true;\n");
await expect(execute(process.execPath, [scanner])).resolves.toMatchObject({
stdout: "No tech-debt markers found.\n",
});
const marker = `TO${"DO"}`;
await writeFile(join(scripts, "debt.mts"), `// ${marker}: close the gap\n`);
await expect(execute(process.execPath, [scanner])).rejects.toMatchObject({
code: 1,
stdout: expect.stringContaining(`${marker} - close the gap`),
});
});
});
+30 -3
View File
@@ -41,14 +41,41 @@
"lint": {},
"format:check": {},
"knip": {},
"jscpd": {},
"scan:todos": {},
"jscpd": {
"inputs": [
".gitignore",
".jscpd.json",
"package.json",
"package-lock.json",
"src/**",
"tests/**"
]
},
"scan:todos": {
"inputs": [
"bridge/**/*.{java,py}",
"scripts/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}",
"src/**/*.ts",
"tests/**/*.ts"
]
},
"docs:api": {
"inputs": [
"package.json",
"package-lock.json",
"src/**/*.ts",
"tsconfig.json",
"typedoc.json"
],
"outputs": ["build/api-docs/**"],
"outputLogs": "new-only"
},
"test:run": {
"dependsOn": ["build"],
"cache": false
},
"docs:check:built": {
"dependsOn": ["build"],
"dependsOn": ["build", "docs:api"],
"cache": false
}
}