mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
perf: speed up type check gate
This commit is contained in:
@@ -132,7 +132,9 @@
|
|||||||
- `pnpm tsgo:core:test`: core colocated tests.
|
- `pnpm tsgo:core:test`: core colocated tests.
|
||||||
- `pnpm tsgo:extensions`: bundled extension production graph.
|
- `pnpm tsgo:extensions`: bundled extension production graph.
|
||||||
- `pnpm tsgo:extensions:test`: bundled extension colocated tests.
|
- `pnpm tsgo:extensions:test`: bundled extension colocated tests.
|
||||||
- `pnpm tsgo:all`: every TypeScript graph above; this is what `pnpm check` runs.
|
- `pnpm tsgo:core:all`: core production + core test project references (`tsconfig.core.projects.json`).
|
||||||
|
- `pnpm tsgo:extensions:all`: extension production + extension test project references (`tsconfig.extensions.projects.json`).
|
||||||
|
- `pnpm tsgo:all`: every TypeScript graph above through the project-reference root (`tsconfig.projects.json`); this is what `pnpm check` runs.
|
||||||
- `pnpm tsgo:profile [core-test|extensions-test|--all]`: profile fresh graph cost into `.artifacts/tsgo-profile/`. Diagnostic-only profile slices (`core-test-agents`, `core-test-non-agents`) exist for investigating agent graph cost; do not treat them as normal user-facing checks.
|
- `pnpm tsgo:profile [core-test|extensions-test|--all]`: profile fresh graph cost into `.artifacts/tsgo-profile/`. Diagnostic-only profile slices (`core-test-agents`, `core-test-non-agents`) exist for investigating agent graph cost; do not treat them as normal user-facing checks.
|
||||||
- Narrow aliases remain for local loops: `pnpm tsgo:test:src`, `pnpm tsgo:test:ui`, `pnpm tsgo:test:packages`.
|
- Narrow aliases remain for local loops: `pnpm tsgo:test:src`, `pnpm tsgo:test:ui`, `pnpm tsgo:test:packages`.
|
||||||
- Do not add `tsc --noEmit`, `typecheck`, or `check:types` lanes for repo type checking. Use `tsgo` graphs. `tsc` is allowed only when emitting declaration/package-boundary compatibility artifacts that `tsgo` does not replace.
|
- Do not add `tsc --noEmit`, `typecheck`, or `check:types` lanes for repo type checking. Use `tsgo` graphs. `tsc` is allowed only when emitting declaration/package-boundary compatibility artifacts that `tsgo` does not replace.
|
||||||
@@ -147,6 +149,7 @@
|
|||||||
- A landing gate is the broader bar before pushing `main`, usually `pnpm check`, `pnpm test`, and `pnpm build` when the touched surface can affect build output, packaging, lazy-loading/module boundaries, or published surfaces.
|
- A landing gate is the broader bar before pushing `main`, usually `pnpm check`, `pnpm test`, and `pnpm build` when the touched surface can affect build output, packaging, lazy-loading/module boundaries, or published surfaces.
|
||||||
- A CI gate is whatever the relevant workflow enforces for that lane (for example `check`, `check-additional`, `build-smoke`, or release validation).
|
- A CI gate is whatever the relevant workflow enforces for that lane (for example `check`, `check-additional`, `build-smoke`, or release validation).
|
||||||
- Local dev gate: prefer `pnpm check` for the normal edit loop. It keeps the repo-architecture policy guards out of the default local loop.
|
- Local dev gate: prefer `pnpm check` for the normal edit loop. It keeps the repo-architecture policy guards out of the default local loop.
|
||||||
|
- Timed local gate: use `pnpm check:timed` to see per-stage cost. Add `:architecture` only when investigating the CI architecture gate locally.
|
||||||
- CI architecture gate: `check-additional` enforces architecture and boundary policy guards that are intentionally kept out of the default local loop.
|
- CI architecture gate: `check-additional` enforces architecture and boundary policy guards that are intentionally kept out of the default local loop.
|
||||||
- Formatting gate: the pre-commit hook runs targeted formatting on staged source files before `pnpm check`. If you want a repo-wide formatting-only preflight locally, run `pnpm format:check` explicitly.
|
- Formatting gate: the pre-commit hook runs targeted formatting on staged source files before `pnpm check`. If you want a repo-wide formatting-only preflight locally, run `pnpm format:check` explicitly.
|
||||||
- If you need a fast commit loop, `FAST_COMMIT=1 git commit ...` skips the hook’s repo-wide `pnpm check`; targeted formatting/linting still runs, so use that only when you are deliberately covering the touched surface some other way.
|
- If you need a fast commit loop, `FAST_COMMIT=1 git commit ...` skips the hook’s repo-wide `pnpm check`; targeted formatting/linting still runs, so use that only when you are deliberately covering the touched surface some other way.
|
||||||
@@ -190,7 +193,7 @@
|
|||||||
- New runtime control-flow code should not branch on `error: string` or `reason: string` when a closed code union would be reasonable.
|
- New runtime control-flow code should not branch on `error: string` or `reason: string` when a closed code union would be reasonable.
|
||||||
- Dynamic import guardrail: do not mix `await import("x")` and static `import ... from "x"` for the same module in production code paths. If you need lazy loading, create a dedicated `*.runtime.ts` boundary (that re-exports from `x`) and dynamically import that boundary from lazy callers only.
|
- Dynamic import guardrail: do not mix `await import("x")` and static `import ... from "x"` for the same module in production code paths. If you need lazy loading, create a dedicated `*.runtime.ts` boundary (that re-exports from `x`) and dynamically import that boundary from lazy callers only.
|
||||||
- Dynamic import verification: after refactors that touch lazy-loading/module boundaries, run `pnpm build` and check for `[INEFFECTIVE_DYNAMIC_IMPORT]` warnings before submitting.
|
- Dynamic import verification: after refactors that touch lazy-loading/module boundaries, run `pnpm build` and check for `[INEFFECTIVE_DYNAMIC_IMPORT]` warnings before submitting.
|
||||||
- Circular dependencies: keep both `pnpm check:import-cycles` and `pnpm check:madge-import-cycles` green; do not reintroduce runtime import cycles or madge-detected import loops.
|
- Circular dependencies: `pnpm check` runs the fast runtime import-cycle guard. `pnpm check:architecture` (and CI `check-additional`) also runs the broader madge import-cycle guard; keep both green before landing architecture-sensitive changes.
|
||||||
- Extension SDK self-import guardrail: inside an extension package, do not import that same extension via `openclaw/plugin-sdk/<extension>` from production files. Route internal imports through a local barrel such as `./api.ts` or `./runtime-api.ts`, and keep the `plugin-sdk/<extension>` path as the external contract only.
|
- Extension SDK self-import guardrail: inside an extension package, do not import that same extension via `openclaw/plugin-sdk/<extension>` from production files. Route internal imports through a local barrel such as `./api.ts` or `./runtime-api.ts`, and keep the `plugin-sdk/<extension>` path as the external contract only.
|
||||||
- Extension package boundary guardrail: inside a bundled plugin package, do not use relative imports/exports that resolve outside that same package root. If shared code belongs in the plugin SDK, import `openclaw/plugin-sdk/<subpath>` instead of reaching into `src/plugin-sdk/**` or other repo paths via `../`.
|
- Extension package boundary guardrail: inside a bundled plugin package, do not use relative imports/exports that resolve outside that same package root. If shared code belongs in the plugin SDK, import `openclaw/plugin-sdk/<subpath>` instead of reaching into `src/plugin-sdk/**` or other repo paths via `../`.
|
||||||
- Extension API surface rule: `openclaw/plugin-sdk/<subpath>` is the only public cross-package contract for extension-facing SDK code. If an extension needs a new seam, add a public subpath first; do not reach into `src/plugin-sdk/**` by relative path.
|
- Extension API surface rule: `openclaw/plugin-sdk/<subpath>` is the only public cross-package contract for extension-facing SDK code. If an extension needs a new seam, add a public subpath first; do not reach into `src/plugin-sdk/**` by relative path.
|
||||||
|
|||||||
@@ -57,9 +57,10 @@ On pushes, the `checks` matrix adds the push-only `compat-node22` lane. On pull
|
|||||||
## Local Equivalents
|
## Local Equivalents
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm check # types + lint + format
|
pnpm check # fast local gate: project-reference tsgo + lint + fast guards
|
||||||
|
pnpm check:timed # same gate with per-stage timings
|
||||||
pnpm build:strict-smoke
|
pnpm build:strict-smoke
|
||||||
pnpm check:import-cycles
|
pnpm check:architecture
|
||||||
pnpm test:gateway:watch-regression
|
pnpm test:gateway:watch-regression
|
||||||
pnpm test # vitest tests
|
pnpm test # vitest tests
|
||||||
pnpm test:channels
|
pnpm test:channels
|
||||||
|
|||||||
@@ -1236,7 +1236,8 @@
|
|||||||
"canon:check:json": "node scripts/canon.mjs check --json",
|
"canon:check:json": "node scripts/canon.mjs check --json",
|
||||||
"canon:enforce": "node scripts/canon.mjs enforce --json",
|
"canon:enforce": "node scripts/canon.mjs enforce --json",
|
||||||
"canvas:a2ui:bundle": "node scripts/bundle-a2ui.mjs",
|
"canvas:a2ui:bundle": "node scripts/bundle-a2ui.mjs",
|
||||||
"check": "pnpm check:no-conflict-markers && pnpm tool-display:check && pnpm check:host-env-policy:swift && pnpm tsgo:all && pnpm lint && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope && pnpm check:import-cycles && pnpm check:madge-import-cycles",
|
"check": "pnpm check:no-conflict-markers && pnpm tool-display:check && pnpm check:host-env-policy:swift && pnpm tsgo:all && pnpm lint && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope && pnpm check:import-cycles",
|
||||||
|
"check:architecture": "pnpm check:import-cycles && pnpm check:madge-import-cycles",
|
||||||
"check:base-config-schema": "node --import tsx scripts/generate-base-config-schema.ts --check",
|
"check:base-config-schema": "node --import tsx scripts/generate-base-config-schema.ts --check",
|
||||||
"check:bundled-channel-config-metadata": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --check",
|
"check:bundled-channel-config-metadata": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --check",
|
||||||
"check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-i18n-glossary && pnpm docs:check-links",
|
"check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-i18n-glossary && pnpm docs:check-links",
|
||||||
@@ -1246,6 +1247,8 @@
|
|||||||
"check:madge-import-cycles": "node --import tsx scripts/check-madge-import-cycles.ts",
|
"check:madge-import-cycles": "node --import tsx scripts/check-madge-import-cycles.ts",
|
||||||
"check:no-conflict-markers": "node scripts/check-no-conflict-markers.mjs",
|
"check:no-conflict-markers": "node scripts/check-no-conflict-markers.mjs",
|
||||||
"check:static-import-sccs": "pnpm check:madge-import-cycles",
|
"check:static-import-sccs": "pnpm check:madge-import-cycles",
|
||||||
|
"check:timed": "node scripts/check-timed.mjs",
|
||||||
|
"check:timed:architecture": "node scripts/check-timed.mjs --include-architecture",
|
||||||
"codex-app-server:protocol:check": "node --import tsx scripts/check-codex-app-server-protocol.ts",
|
"codex-app-server:protocol:check": "node --import tsx scripts/check-codex-app-server-protocol.ts",
|
||||||
"config:channels:check": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --check",
|
"config:channels:check": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --check",
|
||||||
"config:channels:gen": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --write",
|
"config:channels:gen": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --write",
|
||||||
@@ -1471,10 +1474,12 @@
|
|||||||
"tool-display:write": "node --import tsx scripts/tool-display.ts --write",
|
"tool-display:write": "node --import tsx scripts/tool-display.ts --write",
|
||||||
"ts-topology": "node --import tsx scripts/ts-topology.ts",
|
"ts-topology": "node --import tsx scripts/ts-topology.ts",
|
||||||
"tsgo": "pnpm tsgo:core",
|
"tsgo": "pnpm tsgo:core",
|
||||||
"tsgo:all": "pnpm tsgo:core && pnpm tsgo:core:test && pnpm tsgo:extensions && pnpm tsgo:extensions:test",
|
"tsgo:all": "node scripts/run-tsgo.mjs -b tsconfig.projects.json",
|
||||||
"tsgo:core": "node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo",
|
"tsgo:core": "node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo",
|
||||||
|
"tsgo:core:all": "node scripts/run-tsgo.mjs -b tsconfig.core.projects.json",
|
||||||
"tsgo:core:test": "node scripts/run-tsgo.mjs -p tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo",
|
"tsgo:core:test": "node scripts/run-tsgo.mjs -p tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo",
|
||||||
"tsgo:extensions": "node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo",
|
"tsgo:extensions": "node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo",
|
||||||
|
"tsgo:extensions:all": "node scripts/run-tsgo.mjs -b tsconfig.extensions.projects.json",
|
||||||
"tsgo:extensions:test": "node scripts/run-tsgo.mjs -p tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo",
|
"tsgo:extensions:test": "node scripts/run-tsgo.mjs -p tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo",
|
||||||
"tsgo:prod": "pnpm tsgo:core && pnpm tsgo:extensions",
|
"tsgo:prod": "pnpm tsgo:core && pnpm tsgo:extensions",
|
||||||
"tsgo:profile": "node scripts/profile-tsgo.mjs",
|
"tsgo:profile": "node scripts/profile-tsgo.mjs",
|
||||||
|
|||||||
57
scripts/check-timed.mjs
Normal file
57
scripts/check-timed.mjs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { spawnSync } from "node:child_process";
|
||||||
|
import { performance } from "node:perf_hooks";
|
||||||
|
|
||||||
|
const includeArchitecture = process.argv.includes("--include-architecture");
|
||||||
|
|
||||||
|
const stages = [
|
||||||
|
{ name: "conflict markers", args: ["check:no-conflict-markers"] },
|
||||||
|
{ name: "tool display", args: ["tool-display:check"] },
|
||||||
|
{ name: "host env policy", args: ["check:host-env-policy:swift"] },
|
||||||
|
{ name: "typecheck", args: ["tsgo:all"] },
|
||||||
|
{ name: "lint", args: ["lint"] },
|
||||||
|
{ name: "webhook body guard", args: ["lint:webhook:no-low-level-body-read"] },
|
||||||
|
{ name: "pairing store guard", args: ["lint:auth:no-pairing-store-group"] },
|
||||||
|
{ name: "pairing account guard", args: ["lint:auth:pairing-account-scope"] },
|
||||||
|
{ name: "runtime import cycles", args: ["check:import-cycles"] },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (includeArchitecture) {
|
||||||
|
stages.push({ name: "architecture import cycles", args: ["check:madge-import-cycles"] });
|
||||||
|
}
|
||||||
|
|
||||||
|
const timings = [];
|
||||||
|
let exitCode = 0;
|
||||||
|
|
||||||
|
for (const { name, args } of stages) {
|
||||||
|
const startedAt = performance.now();
|
||||||
|
console.error(`\n[check:timed] ${name}`);
|
||||||
|
const result = spawnSync("pnpm", args, {
|
||||||
|
stdio: "inherit",
|
||||||
|
shell: process.platform === "win32",
|
||||||
|
});
|
||||||
|
const durationMs = performance.now() - startedAt;
|
||||||
|
timings.push({ name, durationMs, status: result.status ?? 1 });
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
throw result.error;
|
||||||
|
}
|
||||||
|
if (result.status !== 0) {
|
||||||
|
exitCode = result.status ?? 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("\n[check:timed] summary");
|
||||||
|
for (const timing of timings) {
|
||||||
|
const status = timing.status === 0 ? "ok" : `failed:${timing.status}`;
|
||||||
|
console.error(`${formatMs(timing.durationMs).padStart(8)} ${status.padEnd(9)} ${timing.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exitCode = exitCode;
|
||||||
|
|
||||||
|
function formatMs(durationMs) {
|
||||||
|
if (durationMs < 1000) {
|
||||||
|
return `${Math.round(durationMs)}ms`;
|
||||||
|
}
|
||||||
|
return `${(durationMs / 1000).toFixed(2)}s`;
|
||||||
|
}
|
||||||
4
tsconfig.core.projects.json
Normal file
4
tsconfig.core.projects.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [{ "path": "./tsconfig.core.json" }, { "path": "./tsconfig.core.test.json" }]
|
||||||
|
}
|
||||||
7
tsconfig.extensions.projects.json
Normal file
7
tsconfig.extensions.projects.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.extensions.json" },
|
||||||
|
{ "path": "./tsconfig.extensions.test.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
7
tsconfig.projects.json
Normal file
7
tsconfig.projects.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.core.projects.json" },
|
||||||
|
{ "path": "./tsconfig.extensions.projects.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user