diff --git a/package.json b/package.json index 2ef968b5c5..d729176943 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "db:migrations:check": "tsx scripts/check-migrations.ts", "db:migrations:immutable:check": "tsx scripts/check-released-migrations-immutable.ts", "turbo-inputs:check": "tsx scripts/check-turbo-typecheck-inputs.ts", + "typecheck-coverage:check": "tsx scripts/check-typecheck-coverage.ts", "fixture-clock-races:check": "tsx scripts/check-fixture-clock-races.ts", "workspace-dep-ranges:check": "tsx scripts/check-workspace-dep-ranges.ts", "db:schema-drift:check": "tsx scripts/check-schema-drift.ts", @@ -70,7 +71,7 @@ "ui:build": "npm run ui:kit:build && turbo run build --filter=@loopover/engine --filter=@loopover/contract && npm run ui:openapi && npm --workspace @loopover/ui run build && npm --workspace @loopover/ui-miner run build", "ui:preview": "npm run ui:build && wrangler dev --config apps/loopover-ui/dist/server/wrangler.json --ip 127.0.0.1 --port 4173 --local", "ui:lint": "npm run ui:kit:build && npm --workspace @loopover/ui-kit run format:check && npm --workspace @loopover/ui run format:check && npm --workspace @loopover/ui run lint && npm --workspace @loopover/ui-miner run format:check && npm --workspace @loopover/ui-miner run lint", - "ui:typecheck": "npm run ui:kit:build && npm --workspace @loopover/ui run typecheck && npm --workspace @loopover/ui-miner run typecheck", + "ui:typecheck": "npm run ui:kit:build && npm --workspace @loopover/ui-kit run typecheck && npm --workspace @loopover/ui run typecheck && npm --workspace @loopover/ui-miner run typecheck", "preui:test": "npm run check-node-version", "ui:test": "npm run ui:kit:build && npm --workspace @loopover/ui run test && npm --workspace @loopover/ui-miner run test", "ui:openapi": "tsx scripts/write-ui-openapi.ts", @@ -121,7 +122,7 @@ "changelog:check:mcp": "node --experimental-strip-types scripts/check-changelog.ts --mcp", "mcp:release-due": "tsx scripts/check-mcp-release-due.ts --json", "mcp:release-candidate": "tsx scripts/check-mcp-release-candidate.ts", - "typecheck": "npm run typecheck:root && npm run typecheck:packages", + "typecheck": "npm run typecheck:root && npm run typecheck:packages && npm run ui:typecheck", "typecheck:root": "tsc --noEmit", "typecheck:packages": "tsc -p packages/loopover-contract/tsconfig.json --noEmit && tsc -p packages/loopover-mcp/tsconfig.json --noEmit && tsc -p packages/loopover-miner/tsconfig.json --noEmit", "check-node-version": "node --experimental-strip-types scripts/check-node-version.ts", @@ -145,7 +146,7 @@ "test:smoke:browser:install": "playwright install chromium", "test:smoke:browser": "node --experimental-strip-types scripts/smoke-ui-browser.ts", "pretest:ci": "npm run check-node-version", - "test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:migrations:immutable:check && npm run turbo-inputs:check && npm run workspace-dep-ranges:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run validate:mcp && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:contract-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run control-plane:contract:check && npm run control-plane:openapi:check && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run import-specifiers:check && npm run ui-derived-types:check && npm run server-manifest:check && npm run dead-source-files:check && npm run dead-exports:check && npm run publishable-deps:check && npm run fixture-clock-races:check && npm run checkers-wired:check && npm run release-commit-parsing:check && npm run regate-sort-key:check && npm run maintainer-associations:check && npm run command-redelivery-guards:check && npm run dispatch-gate-reasons:check && npm run validate:no-hand-written-js && npm run replay-runner-manifest:check && npm run coco-dev-versions:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run release-linked-versions:check && npm run command-reference:check && npm run mcp:tool-reference:check && npm run mcp:client-config:check && npm run contract:api-schemas:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build", + "test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:migrations:immutable:check && npm run turbo-inputs:check && npm run workspace-dep-ranges:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run validate:mcp && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:contract-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run control-plane:contract:check && npm run control-plane:openapi:check && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run import-specifiers:check && npm run ui-derived-types:check && npm run server-manifest:check && npm run dead-source-files:check && npm run dead-exports:check && npm run publishable-deps:check && npm run fixture-clock-races:check && npm run typecheck-coverage:check && npm run checkers-wired:check && npm run release-commit-parsing:check && npm run regate-sort-key:check && npm run maintainer-associations:check && npm run command-redelivery-guards:check && npm run dispatch-gate-reasons:check && npm run validate:no-hand-written-js && npm run replay-runner-manifest:check && npm run coco-dev-versions:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run release-linked-versions:check && npm run command-reference:check && npm run mcp:tool-reference:check && npm run mcp:client-config:check && npm run contract:api-schemas:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build", "test:release": "npm run test:ci && npm run changelog:check", "test:release:mcp": "npm run test:ci", "test:watch": "vitest", diff --git a/scripts/check-typecheck-coverage.ts b/scripts/check-typecheck-coverage.ts new file mode 100644 index 0000000000..f20ba9c997 --- /dev/null +++ b/scripts/check-typecheck-coverage.ts @@ -0,0 +1,129 @@ +#!/usr/bin/env node +// `npm run typecheck` must actually typecheck everything that can be typechecked (#9860). +// +// THE INCIDENT. #9815 turned main red because `ChatActionDispatchResult` was closed into a union and a +// miner-UI mock stopped satisfying it. The change was validated locally with `npm run typecheck`, which +// passed -- because `ui:typecheck` was in `test:ci` but NOT in the root `typecheck` chain. A contributor +// running the obvious command got a green result on a tree that does not compile. +// +// That is the worst shape a check can have: not missing, but SILENTLY PARTIAL. A missing check is noticed +// the first time something breaks; a partial one is trusted precisely because it passes. +// +// WHAT THIS COMPUTES. Every workspace that declares its own `typecheck` script, and whether the root +// `typecheck` script reaches it -- following `npm run