mirror of
https://github.com/morluto/rea.git
synced 2026-11-07 05:56:19 -10:00
perf(ci): use tsrs and reduce PE acceptance startup (#5795)
Use pinned tsrs on supported development hosts while retaining stable official TypeScript on Windows and unsupported platforms. Partition compile/typecheck caches by actual compiler and qualify fallback hosts for compiler inputs and lifecycle hooks. Reduce PE acceptance startup through the existing bounded compiled CLI. Retain upstream named MCP definitions, every fixture/assertion and the original 30s deadline. Verify that browser transport loss preserves the observed target. Validation: full qualification and real host lanes in https://github.com/morluto/rea/actions/runs/39590450889 ; 450 focused regressions passed with two documented conditional skips. All 1724 production emit files match SHA-256 and size across both compilers. Current-head Codex/Greptile review found no actionable issues. Measurements and limitations are in the PR. Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
This commit is contained in:
1 parent
33f912919d
commit
905cbaf239
22 files changed
+837
-46
No files matched your search
@@ -819,6 +819,11 @@ jobs:
|
||||
with:
|
||||
save: "true"
|
||||
- run: npm ci
|
||||
- name: Typecheck with the official Windows compiler
|
||||
env:
|
||||
GOMAXPROCS: "2"
|
||||
GOMEMLIMIT: "3GiB"
|
||||
run: npm run typecheck -- --checkers 2
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: rea-build-cache
|
||||
@@ -849,6 +854,7 @@ jobs:
|
||||
npx vitest run --coverage.enabled=false
|
||||
src/process/capture/FilesystemSnapshot.test.ts
|
||||
tests/process-global/filesystemSnapshotFallbackCancellation.test.ts
|
||||
tests/boundary/filesystem/typescriptCompiler.test.ts
|
||||
tests/boundary/filesystem/binaryTarget.test.ts
|
||||
tests/boundary/filesystem/safeOutputTree.test.ts
|
||||
tests/boundary/providers/native/artifactProvider.archiveSafety.test.ts
|
||||
|
||||
+28
-2
@@ -46,6 +46,24 @@ without executing tests or building. A missing Git base reports how to fetch
|
||||
it or select another revision.
|
||||
|
||||
Source typechecking needs no compiled runtime or generated test metadata.
|
||||
Typecheck, runtime compilation, and Frida binding verification share
|
||||
`scripts/run-typescript.mjs`. The pinned tsrs package supplies Linux x64/arm64
|
||||
(GNU and musl) and macOS arm64 compilers. Windows and other unsupported hosts
|
||||
retain the existing stable official TypeScript compiler. Its upstream version
|
||||
can differ from tsrs, so both compiler tasks hash the selected package and version
|
||||
through `scripts/run-turbo.mjs` before cache lookup. Outputs from different
|
||||
compilers occupy different cache entries. Repository npm scripts and focused-test
|
||||
preparation use that entrypoint; a raw Turbo compiler task without matching
|
||||
identity fails instead of publishing an ambiguous successful cache entry.
|
||||
A missing binary on a supported host also fails without silently falling back.
|
||||
|
||||
The Rust compiler defaults to at most two checker threads. For `--noEmit` checks,
|
||||
`--maxMemory 3G` also sets a soft memory target; emit builds do not use that target.
|
||||
Explicit compiler arguments can override the defaults. These controls do not
|
||||
impose a process-family memory limit. Termux's explicit build, Stryker's compiler
|
||||
API dependency, and independent fixture compiler oracles keep their existing
|
||||
TypeScript versions.
|
||||
|
||||
`npm run build:cached` compiles the CLI/MCP runtime and its packaged skill.
|
||||
Turbo's strict task environment preserves caller-selected `GOMAXPROCS`,
|
||||
`GOMEMLIMIT`, and `UV_THREADPOOL_SIZE` for resource-constrained builds and
|
||||
@@ -233,6 +251,11 @@ and retain representative compiled CLI parity checks. Every distinct source
|
||||
scenario still runs through the public workflow; session-lifecycle scenarios
|
||||
need their own sessions and cleanup assertions.
|
||||
|
||||
When a matrix already holds a named tool definition from live `tools/list`,
|
||||
pass that definition through the SDK's `toolDefinition` call option. This keeps
|
||||
the selected output-schema validation without eagerly compiling unrelated
|
||||
catalog schemas. Re-read definitions if the server advertises a changed list.
|
||||
|
||||
Report unavailable authority as a named skip. Await owned cleanup before a
|
||||
verifier reports success. Native process inspectors are released at Vitest
|
||||
worker teardown; fork termination does not run Node exit hooks, and per-file
|
||||
@@ -648,8 +671,11 @@ missing entries are omitted as whole entries, and consumers rebuild cache misses
|
||||
including when every entry is unavailable. Malformed plans, non-file entries,
|
||||
and I/O errors other than disappearance still fail publication. After a trusted
|
||||
static run, superseded cross-run Turbo snapshots for that OS and architecture
|
||||
are deleted down to the two newest generations. The Windows lane relies on the Linux static job for typechecking. They retain the normal build and prepack
|
||||
commands, which restore matching outputs or rebuild on a cache miss. Native
|
||||
are deleted down to the two newest generations. The Windows lane also runs the
|
||||
official compiler's complete source typecheck with two checker threads,
|
||||
independently of the accelerated Linux checker. Both lanes retain the normal
|
||||
build and prepack commands, which restore matching outputs or rebuild on a cache
|
||||
miss. Native
|
||||
artifacts, dependency installs, package archives, and runtime verification remain
|
||||
host-local. Keep platform-dependent outputs out of this shared cache.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ REA npm dependency inventory
|
||||
Prepared from the root package-lock.json; refresh this inventory when locked dependencies change.
|
||||
License identifiers are upstream lockfile declarations, not a legal assessment.
|
||||
Runtime includes transitive and optional platform packages; development includes build, test and website tooling.
|
||||
Locked package entries: 752; runtime: 180.
|
||||
Locked package entries: 758; runtime: 180.
|
||||
Full runtime copyright/license/NOTICE texts: npm-runtime-notices.txt.
|
||||
|
||||
@algolia/[email protected] | development | MIT
|
||||
@@ -1390,6 +1390,31 @@ [email protected] | runtime | MIT
|
||||
Package: https://www.npmjs.com/package/@toon-format/toon/v/2.3.1
|
||||
Archive: https://registry.npmjs.org/@toon-format/toon/-/toon-2.3.1.tgz
|
||||
Integrity: sha512-sWqEMeAJGMda9qRrfPKrX3C4c33CO9SJuvJzzrcBEn5sbDB+k6pSLkDsfN0rVnLQwR97MV3sDgVbcxQNsq8xVw==
|
||||
@tsrs/[email protected] | development, optional | Apache-2.0
|
||||
Lockfile path: node_modules/@tsrs/darwin-arm64
|
||||
Package: https://www.npmjs.com/package/@tsrs/darwin-arm64/v/0.18.0-ts7.1.0-dev.20260929
|
||||
Archive: https://registry.npmjs.org/@tsrs/darwin-arm64/-/darwin-arm64-0.18.0-ts7.1.0-dev.20260929.tgz
|
||||
Integrity: sha512-sAirMpaGA9uRQm2W+t4zC7PjnijNuFa4PCSIfLKKo0JyAUCRfnMeev0UGBQ9F3g+9Nz187tvikUs5Irh5+eajA==
|
||||
@tsrs/[email protected] | development, optional | Apache-2.0
|
||||
Lockfile path: node_modules/@tsrs/linux-arm64-gnu
|
||||
Package: https://www.npmjs.com/package/@tsrs/linux-arm64-gnu/v/0.18.0-ts7.1.0-dev.20260929
|
||||
Archive: https://registry.npmjs.org/@tsrs/linux-arm64-gnu/-/linux-arm64-gnu-0.18.0-ts7.1.0-dev.20260929.tgz
|
||||
Integrity: sha512-zm9/z9yylig68JiZF4Aq0Cm26n09KEU8YoQRlG7tdDWTBNAIViYw8knxnWYsjMWVZ2XiU4mYq1xdrOKuOgABHg==
|
||||
@tsrs/[email protected] | development, optional | Apache-2.0
|
||||
Lockfile path: node_modules/@tsrs/linux-arm64-musl
|
||||
Package: https://www.npmjs.com/package/@tsrs/linux-arm64-musl/v/0.18.0-ts7.1.0-dev.20260929
|
||||
Archive: https://registry.npmjs.org/@tsrs/linux-arm64-musl/-/linux-arm64-musl-0.18.0-ts7.1.0-dev.20260929.tgz
|
||||
Integrity: sha512-Lw7VVU/YQ9JcarODICEiwzMLdFqZprqh5RGTgbS5Uc6I95P635/g5xA1pOC8RVs4efBvAR30J54iDG3l5JEYiw==
|
||||
@tsrs/[email protected] | development, optional | Apache-2.0
|
||||
Lockfile path: node_modules/@tsrs/linux-x64-gnu
|
||||
Package: https://www.npmjs.com/package/@tsrs/linux-x64-gnu/v/0.18.0-ts7.1.0-dev.20260929
|
||||
Archive: https://registry.npmjs.org/@tsrs/linux-x64-gnu/-/linux-x64-gnu-0.18.0-ts7.1.0-dev.20260929.tgz
|
||||
Integrity: sha512-EdBwBgNICGu1r1h23ixdcKwsMo6E9ll7ZsY3mNERNYqE1Pwdtcat99d5E7zB1J+oy/Xk6YqiizaB6nolIjpDTw==
|
||||
@tsrs/[email protected] | development, optional | Apache-2.0
|
||||
Lockfile path: node_modules/@tsrs/linux-x64-musl
|
||||
Package: https://www.npmjs.com/package/@tsrs/linux-x64-musl/v/0.18.0-ts7.1.0-dev.20260929
|
||||
Archive: https://registry.npmjs.org/@tsrs/linux-x64-musl/-/linux-x64-musl-0.18.0-ts7.1.0-dev.20260929.tgz
|
||||
Integrity: sha512-LHk+AOAtXuTlhJhOJ2+elriEIX17ycXljojeNxrrzckOipTG1LksoVWuCSas2nu00EnWAzrdKpt9oqPylUKZfQ==
|
||||
@turbo/[email protected] | development, optional | MIT
|
||||
Lockfile path: node_modules/@turbo/darwin-64
|
||||
Package: https://www.npmjs.com/package/@turbo/darwin-64/v/2.11.7
|
||||
@@ -3400,6 +3425,11 @@ [email protected] | development | 0BSD
|
||||
Package: https://www.npmjs.com/package/tslib/v/2.8.1
|
||||
Archive: https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz
|
||||
Integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
[email protected] | development | Apache-2.0
|
||||
Lockfile path: node_modules/tsrs
|
||||
Package: https://www.npmjs.com/package/tsrs/v/0.18.0-ts7.1.0-dev.20260929
|
||||
Archive: https://registry.npmjs.org/tsrs/-/tsrs-0.18.0-ts7.1.0-dev.20260929.tgz
|
||||
Integrity: sha512-9T0b4Uam/yMFIK16GUx0fUrJqYZnJ/gvSmV9JB8NTyDePvwCI45WFWxyEV/UMV3KfdNRJG/PBsm3fSIB9WmWsA==
|
||||
[email protected] | development | MIT
|
||||
Lockfile path: node_modules/tsx
|
||||
Package: https://www.npmjs.com/package/tsx/v/4.23.15
|
||||
|
||||
Generated
+118
@@ -74,6 +74,7 @@
|
||||
"oxfmt": "0.72.0",
|
||||
"oxlint": "1.87.0",
|
||||
"rolldown": "1.2.12",
|
||||
"tsrs": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"tsx": "4.23.15",
|
||||
"turbo": "2.11.7",
|
||||
"typescript": "7.0.2",
|
||||
@@ -4407,6 +4408,103 @@
|
||||
"integrity": "sha512-sWqEMeAJGMda9qRrfPKrX3C4c33CO9SJuvJzzrcBEn5sbDB+k6pSLkDsfN0rVnLQwR97MV3sDgVbcxQNsq8xVw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsrs/darwin-arm64": {
|
||||
"version": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"resolved": "https://registry.npmjs.org/@tsrs/darwin-arm64/-/darwin-arm64-0.18.0-ts7.1.0-dev.20260929.tgz",
|
||||
"integrity": "sha512-sAirMpaGA9uRQm2W+t4zC7PjnijNuFa4PCSIfLKKo0JyAUCRfnMeev0UGBQ9F3g+9Nz187tvikUs5Irh5+eajA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsrs/linux-arm64-gnu": {
|
||||
"version": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"resolved": "https://registry.npmjs.org/@tsrs/linux-arm64-gnu/-/linux-arm64-gnu-0.18.0-ts7.1.0-dev.20260929.tgz",
|
||||
"integrity": "sha512-zm9/z9yylig68JiZF4Aq0Cm26n09KEU8YoQRlG7tdDWTBNAIViYw8knxnWYsjMWVZ2XiU4mYq1xdrOKuOgABHg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsrs/linux-arm64-musl": {
|
||||
"version": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"resolved": "https://registry.npmjs.org/@tsrs/linux-arm64-musl/-/linux-arm64-musl-0.18.0-ts7.1.0-dev.20260929.tgz",
|
||||
"integrity": "sha512-Lw7VVU/YQ9JcarODICEiwzMLdFqZprqh5RGTgbS5Uc6I95P635/g5xA1pOC8RVs4efBvAR30J54iDG3l5JEYiw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsrs/linux-x64-gnu": {
|
||||
"version": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"resolved": "https://registry.npmjs.org/@tsrs/linux-x64-gnu/-/linux-x64-gnu-0.18.0-ts7.1.0-dev.20260929.tgz",
|
||||
"integrity": "sha512-EdBwBgNICGu1r1h23ixdcKwsMo6E9ll7ZsY3mNERNYqE1Pwdtcat99d5E7zB1J+oy/Xk6YqiizaB6nolIjpDTw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsrs/linux-x64-musl": {
|
||||
"version": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"resolved": "https://registry.npmjs.org/@tsrs/linux-x64-musl/-/linux-x64-musl-0.18.0-ts7.1.0-dev.20260929.tgz",
|
||||
"integrity": "sha512-LHk+AOAtXuTlhJhOJ2+elriEIX17ycXljojeNxrrzckOipTG1LksoVWuCSas2nu00EnWAzrdKpt9oqPylUKZfQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@turbo/darwin-64": {
|
||||
"version": "2.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@turbo/darwin-64/-/darwin-64-2.11.7.tgz",
|
||||
@@ -9832,6 +9930,26 @@
|
||||
"dev": true,
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tsrs": {
|
||||
"version": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"resolved": "https://registry.npmjs.org/tsrs/-/tsrs-0.18.0-ts7.1.0-dev.20260929.tgz",
|
||||
"integrity": "sha512-9T0b4Uam/yMFIK16GUx0fUrJqYZnJ/gvSmV9JB8NTyDePvwCI45WFWxyEV/UMV3KfdNRJG/PBsm3fSIB9WmWsA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsrs": "bin/tsrs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.20.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tsrs/darwin-arm64": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"@tsrs/linux-arm64-gnu": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"@tsrs/linux-arm64-musl": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"@tsrs/linux-x64-gnu": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"@tsrs/linux-x64-musl": "0.18.0-ts7.1.0-dev.20260929"
|
||||
}
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.23.15",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz",
|
||||
|
||||
+22
-21
@@ -104,31 +104,31 @@
|
||||
"metadata:generate": "node scripts/run-exclusive.mjs artifacts node scripts/generate-package-metadata.mjs",
|
||||
"metadata:check": "node scripts/generate-package-metadata.mjs --check",
|
||||
"mcp-registry:check": "node scripts/verify-mcp-registry-metadata.mjs",
|
||||
"mcp-catalog:generate": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:mcp-catalog",
|
||||
"mcp-catalog:check": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run mcp-catalog:check:built",
|
||||
"mcp-catalog:generate": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:mcp-catalog",
|
||||
"mcp-catalog:check": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run mcp-catalog:check:built",
|
||||
"prebuild": "npm run deps:check",
|
||||
"build": "node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills --force",
|
||||
"build": "node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:skills --force",
|
||||
"precheck": "npm run deps:check",
|
||||
"check": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint:built format:check knip metadata:check && npm run verify:architecture-guards",
|
||||
"check": "node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run typecheck lint:built format:check knip metadata:check && npm run verify:architecture-guards",
|
||||
"precheck:fast": "npm run deps:check",
|
||||
"check:fast": "turbo run typecheck lint --output-logs=errors-only",
|
||||
"check:fast": "node scripts/run-turbo.mjs run typecheck lint --output-logs=errors-only",
|
||||
"precheck:changed": "npm run deps:check",
|
||||
"check:changed": "npm run check:fast && npm run test:changed",
|
||||
"precheck:test": "npm run deps:check",
|
||||
"check:test": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint:built format:check knip metadata:check test:run",
|
||||
"check:test": "node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run typecheck lint:built format:check knip metadata:check test:run",
|
||||
"precheck:pr": "npm run deps:check",
|
||||
"check:pr": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint:built format:check knip metadata:check test:run && npm run test:python && npm run docs:check && npm run jscpd && npm run scan:todos",
|
||||
"check:pr": "node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run typecheck lint:built format:check knip metadata:check test:run && npm run test:python && npm run docs:check && npm run jscpd && npm run scan:todos",
|
||||
"precheck:ci": "npm run deps:check",
|
||||
"precheck:ci:fast": "npm run deps:check",
|
||||
"precheck:ci:deep": "npm run deps:check",
|
||||
"check:ci": "npm run check:ci:fast && npm run check:ci:deep",
|
||||
"check:ci:fast": "node scripts/run-exclusive.mjs artifacts npm run check:ci:fast:tasks",
|
||||
"check:ci:fast:tasks": "turbo run typecheck lint:built format:check",
|
||||
"check:ci:fast:tasks": "node scripts/run-turbo.mjs run typecheck lint:built format:check",
|
||||
"check:ci:deep": "node scripts/run-exclusive.mjs artifacts npm run check:ci:deep:tasks && npm run verify:architecture-guards && npm run verify:test-discovery && npm run test:python",
|
||||
"check:ci:deep:tasks": "turbo run knip metadata:check jscpd scan:todos",
|
||||
"check:ci:tasks": "turbo run typecheck lint:built format:check knip metadata:check jscpd scan:todos",
|
||||
"check:ci:deep:tasks": "node scripts/run-turbo.mjs run knip metadata:check jscpd scan:todos",
|
||||
"check:ci:tasks": "node scripts/run-turbo.mjs run typecheck lint:built format:check knip metadata:check jscpd scan:todos",
|
||||
"ci:static-context": "node scripts/ci/static-task-context.mjs",
|
||||
"build:cached": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills",
|
||||
"build:cached": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:skills",
|
||||
"build:termux": "node scripts/run-exclusive.mjs artifacts npm run build:termux:run",
|
||||
"build:termux:run": "npm run compile:termux && npm run artifacts:skills",
|
||||
"format": "oxfmt .",
|
||||
@@ -151,7 +151,7 @@
|
||||
"test:built": "node scripts/ci/test-group.mjs built",
|
||||
"pretest:boundary": "npm run test:prepare",
|
||||
"test:boundary": "vitest run --project boundary --project cli-boundary --project process-boundary --project mcp-boundary --project process-global",
|
||||
"pretest:mcp": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills artifacts:mcp-catalog",
|
||||
"pretest:mcp": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:skills artifacts:mcp-catalog",
|
||||
"test:mcp": "vitest run --project mcp-boundary",
|
||||
"pretest:acceptance": "npm run build:cached",
|
||||
"test:acceptance": "vitest run --project acceptance",
|
||||
@@ -174,7 +174,7 @@
|
||||
"test:watch": "vitest --project domain --project services --project adapters --project composition --project conformance --project evaluation --changed",
|
||||
"pretest:watch:all": "npm run test:prepare",
|
||||
"test:watch:all": "vitest --changed",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"typecheck": "node scripts/run-typescript.mjs --noEmit",
|
||||
"verify:test-temp-hygiene": "npm run test:prepare && node scripts/verify-test-temp-hygiene.mjs",
|
||||
"verify:hopper": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper.mjs",
|
||||
"verify:hopper:deadlines": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper-deadlines.mjs",
|
||||
@@ -213,7 +213,7 @@
|
||||
"verify:ghidra:windows": "npm run build:cached && npm run build:ghidra-windows-fixture && node scripts/verify-real-ghidra-windows.mjs",
|
||||
"verify:browser": "npm run build:cached && node scripts/verify-real-browser.mjs",
|
||||
"verify:frida": "npm run build:cached && node scripts/verify-frida.mjs",
|
||||
"verify:frida:bindings": "tsc --noEmit -p tsconfig.frida-verification.json",
|
||||
"verify:frida:bindings": "node scripts/run-typescript.mjs --noEmit -p tsconfig.frida-verification.json",
|
||||
"verify:browser:dom": "node scripts/verify-browser-dom-destinations.mjs",
|
||||
"verify:browser:network": "npm run build:cached && node scripts/verify-browser-network.mjs",
|
||||
"verify:electron": "npm run build:cached && node scripts/verify-real-electron.mjs",
|
||||
@@ -256,17 +256,17 @@
|
||||
"probe:windows-capabilities": "npm run build:cached && node scripts/windows-capabilities.mjs",
|
||||
"verify:published": "node scripts/verify-published-package.mjs",
|
||||
"config:print": "node scripts/print-mcp-config.mjs",
|
||||
"evidence:generate": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:managed-evidence",
|
||||
"evidence:check": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run evidence:check:built",
|
||||
"evidence:generate": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:managed-evidence",
|
||||
"evidence:check": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run evidence:check:built",
|
||||
"predocs:dev": "npm run docs:generate",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"predocs:build": "npm run docs:generate",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs",
|
||||
"docs:generate": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts npm run docs:prepare",
|
||||
"docs:check": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run docs:check:built && npm run test:local -- tests/conformance/readmeConsistency.test.ts",
|
||||
"docs:check": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run docs:check:built && npm run test:local -- tests/conformance/readmeConsistency.test.ts",
|
||||
"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 && npm run licenses:check",
|
||||
"docs:error-schema": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:error-schema",
|
||||
"docs:error-schema": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:error-schema",
|
||||
"prepack": "node scripts/prepack.mjs",
|
||||
"prepare": "node scripts/prepare.mjs",
|
||||
"verify:asset-catalog": "npm run build:cached && node scripts/verify/apple/asset-catalog.mjs",
|
||||
@@ -305,16 +305,16 @@
|
||||
"verify:solidity:metadata": "npm run build:cached && node scripts/verify-solidity-metadata.mjs",
|
||||
"verify:recorded:crash": "npm run build:cached && node scripts/verify-recorded-crash.mjs",
|
||||
"mcp-catalog:check:built": "node scripts/generate-mcp-tool-catalog.mjs --check",
|
||||
"compile": "node scripts/clean-build-output.mjs && tsc -p tsconfig.build.json && node scripts/record-catalog-digests.mjs && node scripts/bundle-runtime.mjs",
|
||||
"compile": "node scripts/clean-build-output.mjs && node scripts/run-typescript.mjs -p tsconfig.build.json && node scripts/record-catalog-digests.mjs && node scripts/bundle-runtime.mjs",
|
||||
"compile:termux": "node scripts/clean-build-output.mjs && node --max-old-space-size=3072 node_modules/typescript-termux/lib/tsc.js -p tsconfig.build.json && node scripts/record-catalog-digests.mjs && node scripts/bundle-runtime.mjs",
|
||||
"artifacts:mcp-catalog": "node scripts/generate-mcp-tool-catalog.mjs",
|
||||
"artifacts:skills": "node scripts/generate-skill-metadata.mjs",
|
||||
"artifacts:product-catalog": "node scripts/generate-product-catalog.mjs",
|
||||
"artifacts:managed-evidence": "node scripts/generate-completion-ledger.mjs",
|
||||
"artifacts:error-schema": "node scripts/generate-error-schema.mjs",
|
||||
"test:prepare": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:mcp-catalog artifacts:product-catalog artifacts:managed-evidence",
|
||||
"test:prepare": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts node scripts/run-turbo.mjs run artifacts:mcp-catalog artifacts:product-catalog artifacts:managed-evidence",
|
||||
"evidence:check:built": "node scripts/generate-completion-ledger.mjs --check",
|
||||
"docs:prepare": "node scripts/generate-package-metadata.mjs && turbo run artifacts:product-catalog artifacts:managed-evidence artifacts:error-schema",
|
||||
"docs:prepare": "node scripts/generate-package-metadata.mjs && node scripts/run-turbo.mjs run artifacts:product-catalog artifacts:managed-evidence artifacts:error-schema",
|
||||
"verify:web:qlog": "npm run build:cached && node scripts/verify-qlog-captures.mjs",
|
||||
"licenses:generate": "node scripts/generate-third-party-inventory.mjs",
|
||||
"licenses:check": "node scripts/generate-third-party-inventory.mjs --check"
|
||||
@@ -396,6 +396,7 @@
|
||||
"oxfmt": "0.72.0",
|
||||
"oxlint": "1.87.0",
|
||||
"rolldown": "1.2.12",
|
||||
"tsrs": "0.18.0-ts7.1.0-dev.20260929",
|
||||
"tsx": "4.23.15",
|
||||
"turbo": "2.11.7",
|
||||
"typescript": "7.0.2",
|
||||
|
||||
@@ -63,6 +63,31 @@ function classifyPackage(base, head) {
|
||||
const after = JSON.parse(git("show", `${head}:package.json`));
|
||||
const { scripts: beforeScripts, ...beforeRest } = before;
|
||||
const { scripts: afterScripts, ...afterRest } = after;
|
||||
const compilerDependencies = (metadata) => ({
|
||||
dependencies: {
|
||||
typescript: metadata.dependencies?.typescript,
|
||||
tsrs: metadata.dependencies?.tsrs,
|
||||
},
|
||||
devDependencies: {
|
||||
typescript: metadata.devDependencies?.typescript,
|
||||
tsrs: metadata.devDependencies?.tsrs,
|
||||
},
|
||||
});
|
||||
const compilerScripts = [
|
||||
"compile",
|
||||
"typecheck",
|
||||
"build",
|
||||
"build:cached",
|
||||
"test:prepare",
|
||||
"docs:prepare",
|
||||
"verify:frida:bindings",
|
||||
].flatMap((name) => [name, `pre${name}`, `post${name}`]);
|
||||
selected.package ||=
|
||||
JSON.stringify(compilerDependencies(before)) !==
|
||||
JSON.stringify(compilerDependencies(after)) ||
|
||||
compilerScripts.some(
|
||||
(name) => beforeScripts?.[name] !== afterScripts?.[name],
|
||||
);
|
||||
if (JSON.stringify(beforeRest) !== JSON.stringify(afterRest)) {
|
||||
full("Package metadata or dependencies changed");
|
||||
return;
|
||||
|
||||
@@ -92,6 +92,17 @@ export const SCOPES = {
|
||||
],
|
||||
// Four-host installed-package matrix and the Windows curated lane.
|
||||
package: [
|
||||
// Both host compilers must be exercised when their installation, options,
|
||||
// or entrypoints change; Linux's accelerated checker cannot stand in for Go.
|
||||
"scripts/run-typescript.*",
|
||||
"scripts/run-turbo.mjs",
|
||||
"turbo.json",
|
||||
"tsconfig.json",
|
||||
"tsconfig.build.json",
|
||||
"tsconfig.frida-verification.json",
|
||||
"package-lock.json",
|
||||
".nvmrc",
|
||||
".npmrc",
|
||||
".github/actions/publish-mcp/**",
|
||||
".github/actions/prepare-release-package/**",
|
||||
".github/workflows/release-recovery.yml",
|
||||
@@ -135,6 +146,7 @@ export const SCOPES = {
|
||||
"src/application/DshCordis*.ts",
|
||||
"src/cli/interactiveSetup.ts",
|
||||
"src/cli/setupCommands.ts",
|
||||
"tests/boundary/filesystem/typescriptCompiler.test.ts",
|
||||
"tests/boundary/filesystem/binaryTarget.test.ts",
|
||||
"tests/boundary/filesystem/safeOutputTree.test.ts",
|
||||
"tests/boundary/providers/native/artifactProvider.archiveSafety.test.ts",
|
||||
|
||||
@@ -59,7 +59,7 @@ try {
|
||||
"scripts/run-exclusive.mjs",
|
||||
"artifacts",
|
||||
process.execPath,
|
||||
resolve("node_modules/turbo/bin/turbo"),
|
||||
resolve("scripts/run-turbo.mjs"),
|
||||
"run",
|
||||
...(plan.needsBuild ? ["artifacts:skills"] : []),
|
||||
...plan.artifactTasks,
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { createRequire } from "node:module";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
import { resolveTypeScriptCompiler } from "./run-typescript.mjs";
|
||||
|
||||
// Compute the actual host compiler before Turbo hashes or restores its tasks.
|
||||
process.env.REA_TYPESCRIPT_COMPILER = resolveTypeScriptCompiler().identity;
|
||||
const require = createRequire(import.meta.url);
|
||||
await import(pathToFileURL(require.resolve("turbo/bin/turbo")).href);
|
||||
@@ -0,0 +1,11 @@
|
||||
export function selectTypeScriptCompiler(
|
||||
platform: string,
|
||||
arch: string,
|
||||
optionalDependencies: Readonly<Record<string, string>>,
|
||||
): "tsrs" | "typescript";
|
||||
|
||||
export function resolveTypeScriptCompiler(): {
|
||||
readonly name: "tsrs" | "typescript";
|
||||
readonly identity: string;
|
||||
readonly launcher: string;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import { availableParallelism } from "node:os";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
|
||||
/** Use the pinned package's platform inventory; let its launcher select libc. */
|
||||
export const selectTypeScriptCompiler = (
|
||||
platform,
|
||||
arch,
|
||||
optionalDependencies,
|
||||
) => {
|
||||
if (platform === "win32") return "typescript";
|
||||
const prefix = `@tsrs/${platform}-${arch}`;
|
||||
return Object.keys(optionalDependencies).some(
|
||||
(name) => name === prefix || name.startsWith(`${prefix}-`),
|
||||
)
|
||||
? "tsrs"
|
||||
: "typescript";
|
||||
};
|
||||
|
||||
export const resolveTypeScriptCompiler = () => {
|
||||
const require = createRequire(import.meta.url);
|
||||
const rustPackagePath = require.resolve("tsrs/package.json");
|
||||
const rustPackage = JSON.parse(readFileSync(rustPackagePath, "utf8"));
|
||||
const compiler = selectTypeScriptCompiler(
|
||||
process.platform,
|
||||
process.arch,
|
||||
rustPackage.optionalDependencies,
|
||||
);
|
||||
const packagePath =
|
||||
compiler === "tsrs"
|
||||
? rustPackagePath
|
||||
: require.resolve("typescript/package.json");
|
||||
const metadata =
|
||||
compiler === "tsrs"
|
||||
? rustPackage
|
||||
: JSON.parse(readFileSync(packagePath, "utf8"));
|
||||
const command = compiler === "tsrs" ? "tsrs" : "tsc";
|
||||
return {
|
||||
name: compiler,
|
||||
identity: `${compiler}@${metadata.version}`,
|
||||
launcher: resolve(dirname(packagePath), metadata.bin[command]),
|
||||
};
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const compiler = resolveTypeScriptCompiler();
|
||||
if (
|
||||
process.env.TURBO_HASH !== undefined &&
|
||||
process.env.REA_TYPESCRIPT_COMPILER !== compiler.identity
|
||||
)
|
||||
throw new Error(
|
||||
"Compiler identity is missing or stale. Run Turbo through scripts/run-turbo.mjs.",
|
||||
);
|
||||
if (compiler.name === "tsrs") {
|
||||
const args = process.argv.slice(2);
|
||||
// Rust consumes --maxMemory once; duplicating it becomes an unknown option.
|
||||
// Preserve explicit resource choices rather than injecting another value.
|
||||
const defaults = [
|
||||
["--checkers", String(Math.min(2, availableParallelism()))],
|
||||
["--maxMemory", "3G"],
|
||||
].flatMap(([option, value]) =>
|
||||
args.includes(option) ? [] : [option, value],
|
||||
);
|
||||
process.argv.splice(2, 0, ...defaults);
|
||||
}
|
||||
// Delegate execution, diagnostics, status and signals to the package's launcher.
|
||||
// An unavailable binary on a supported host must fail rather than hide drift.
|
||||
await import(pathToFileURL(compiler.launcher).href);
|
||||
};
|
||||
|
||||
if (process.argv[1] === fileURLToPath(import.meta.url)) await main();
|
||||
@@ -555,6 +555,12 @@ async function verifyPageScopedTransport(provider, proxy, origin) {
|
||||
throw new Error(
|
||||
"Page-scoped CDP disconnect must report transport loss without claiming a target crash",
|
||||
);
|
||||
const remaining = await provider.listTargets(
|
||||
listBrowserTargetsInputSchema.parse({ cdp_endpoint: proxy.endpoint }),
|
||||
);
|
||||
if (!remaining.ok) throw remaining.error;
|
||||
if (!remaining.value.targets.some(({ target_id }) => target_id === target))
|
||||
throw new Error("Page-scoped CDP disconnect removed its live target");
|
||||
}
|
||||
|
||||
async function browserExecutable() {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
createAnalysisExecution,
|
||||
type AnalysisClient,
|
||||
type AnalysisProviderCandidate,
|
||||
type AnalysisProviderInspectionOptions,
|
||||
type CapabilityDescriptor,
|
||||
type ProviderAvailability,
|
||||
type ProviderIdentity,
|
||||
@@ -825,7 +826,9 @@ it("joins cancelled readiness finalization and shutdown before admitting another
|
||||
const registry = new AnalysisProviderRegistry([
|
||||
{
|
||||
...base,
|
||||
inspectAvailability: async ({ signal } = {}) => {
|
||||
inspectAvailability: async ({
|
||||
signal,
|
||||
}: AnalysisProviderInspectionOptions = {}) => {
|
||||
calls++;
|
||||
if (calls === 1) {
|
||||
observed = signal;
|
||||
@@ -982,7 +985,9 @@ it("registers selection before async readiness can race shutdown", async () => {
|
||||
const registry = new AnalysisProviderRegistry([
|
||||
{
|
||||
...base,
|
||||
inspectAvailability: async ({ signal } = {}) => {
|
||||
inspectAvailability: async ({
|
||||
signal,
|
||||
}: AnalysisProviderInspectionOptions = {}) => {
|
||||
calls++;
|
||||
observed = signal;
|
||||
return base.inspectAvailability();
|
||||
|
||||
@@ -9,7 +9,11 @@ import { peResourcesSchema } from "../../../src/domain/native/peResources.js";
|
||||
import { peResourceFixture } from "../../../src/native/pe/PeResources.fixture.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
|
||||
import { cliTest, type TestCli } from "../../support/cli/cliFixture.js";
|
||||
import {
|
||||
cliTest,
|
||||
runFileCli,
|
||||
type TestCli,
|
||||
} from "../../support/cli/cliFixture.js";
|
||||
|
||||
type PeResourceCall = (
|
||||
arguments_: Record<string, unknown>,
|
||||
@@ -22,7 +26,7 @@ const expectPeInputFailureAcrossAdapters = async (input: {
|
||||
readonly reason: "invalid_format" | "invalid_value";
|
||||
}) => {
|
||||
const { cli, call, path, reason } = input;
|
||||
const result = await cli.run({
|
||||
const result = await runFileCli(cli, {
|
||||
arguments: ["inspect-pe-resources", path, "--json"],
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
@@ -105,7 +109,7 @@ const expectPeWordAlignedRecordsAcrossAdapters = async (input: {
|
||||
);
|
||||
const path = join(root, `word-aligned-${plus}-${index}.exe`);
|
||||
await writeFile(path, fixture.bytes);
|
||||
const result = await cli.run({
|
||||
const result = await runFileCli(cli, {
|
||||
arguments: ["inspect-pe-resources", path, "--json"],
|
||||
});
|
||||
expect(result.exitCode, result.stderr).toBe(0);
|
||||
@@ -196,7 +200,7 @@ const expectPeMappingOwnershipAcrossAdapters = async (
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const result = await cli.run({
|
||||
const result = await runFileCli(cli, {
|
||||
arguments: ["inspect-pe-resources", path, "--json"],
|
||||
});
|
||||
expect(result.exitCode, name).toBe(0);
|
||||
@@ -249,9 +253,14 @@ const expectPeInventoriesAcrossAdapters = async (
|
||||
`resource${plus ? "64" : "32"}${empty ? "-empty" : ""}.exe`,
|
||||
);
|
||||
await writeFile(path, fixture.bytes);
|
||||
const result = await cli.run({
|
||||
const invocation = {
|
||||
arguments: ["inspect-pe-resources", path, "--json"],
|
||||
});
|
||||
};
|
||||
// Keep an independent public-wrapper process for both PE32 and PE32+.
|
||||
// The empty-payload variants reuse only compiled-command startup.
|
||||
const result = await (empty
|
||||
? runFileCli(cli, invocation)
|
||||
: cli.run(invocation));
|
||||
expect(result.exitCode).toBe(0);
|
||||
const evidence = contract.outputSchema.parse(result.json);
|
||||
const report = peResourcesSchema.parse(evidence.normalized_result);
|
||||
|
||||
@@ -660,7 +660,7 @@ it.each([
|
||||
{
|
||||
code: true,
|
||||
runtime: true,
|
||||
package: false,
|
||||
package: true,
|
||||
evm: false,
|
||||
browser: false,
|
||||
},
|
||||
@@ -1155,7 +1155,7 @@ it.each([
|
||||
{
|
||||
code: true,
|
||||
runtime: true,
|
||||
package: false,
|
||||
package: true,
|
||||
browser: false,
|
||||
evm: false,
|
||||
sqlite: false,
|
||||
@@ -1166,7 +1166,7 @@ it.each([
|
||||
{
|
||||
code: true,
|
||||
runtime: true,
|
||||
package: false,
|
||||
package: true,
|
||||
browser: false,
|
||||
evm: false,
|
||||
},
|
||||
@@ -1496,3 +1496,89 @@ it("never runs a manual-only verifier from an automatic workflow", async () => {
|
||||
),
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
"scripts/run-typescript.mjs",
|
||||
"scripts/run-typescript.d.mts",
|
||||
"scripts/run-turbo.mjs",
|
||||
"turbo.json",
|
||||
"tsconfig.json",
|
||||
"tsconfig.build.json",
|
||||
"tsconfig.frida-verification.json",
|
||||
"package-lock.json",
|
||||
".nvmrc",
|
||||
".npmrc",
|
||||
])("selects package hosts for compiler input %s", async (path) => {
|
||||
const { directory, base } = await fixture();
|
||||
const head = await change(directory, [path]);
|
||||
const plan = await classify(directory, base, head);
|
||||
expect(plan).toMatchObject({
|
||||
tier: "fast",
|
||||
code: true,
|
||||
runtime: true,
|
||||
package: true,
|
||||
});
|
||||
expect(plan.matrix).toEqual({
|
||||
include: [
|
||||
{ os: "ubuntu-latest", platform: "linux", architecture: "x64" },
|
||||
{ os: "ubuntu-24.04-arm", platform: "linux", architecture: "arm64" },
|
||||
{ os: "macos-15", platform: "darwin", architecture: "arm64" },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it.each(["typescript", "tsrs"])(
|
||||
"selects fallback host checks when compiler dependency %s changes",
|
||||
async (name) => {
|
||||
const { directory } = await fixture();
|
||||
const before = { name: "fixture", devDependencies: { [name]: "1.0.0" } };
|
||||
const base = await change(
|
||||
directory,
|
||||
["package.json"],
|
||||
JSON.stringify(before),
|
||||
);
|
||||
const head = await change(
|
||||
directory,
|
||||
["package.json"],
|
||||
JSON.stringify({ ...before, devDependencies: { [name]: "2.0.0" } }),
|
||||
);
|
||||
expect(await classify(directory, base, head)).toMatchObject({
|
||||
code: true,
|
||||
runtime: true,
|
||||
package: true,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
"compile",
|
||||
"typecheck",
|
||||
"build",
|
||||
"build:cached",
|
||||
"test:prepare",
|
||||
"docs:prepare",
|
||||
"verify:frida:bindings",
|
||||
"prebuild:cached",
|
||||
"postcompile",
|
||||
"pretypecheck",
|
||||
])(
|
||||
"selects fallback host checks when compiler command %s changes",
|
||||
async (name) => {
|
||||
const { directory } = await fixture();
|
||||
const base = await change(
|
||||
directory,
|
||||
["package.json"],
|
||||
JSON.stringify({ scripts: { [name]: "node scripts/old.mjs" } }),
|
||||
);
|
||||
const head = await change(
|
||||
directory,
|
||||
["package.json"],
|
||||
JSON.stringify({ scripts: { [name]: "node scripts/new.mjs" } }),
|
||||
);
|
||||
expect(await classify(directory, base, head)).toMatchObject({
|
||||
code: true,
|
||||
runtime: true,
|
||||
package: true,
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -364,7 +364,7 @@ it("runs the existing onboarding and Python producer guards from their selected
|
||||
"node scripts/run-exclusive.mjs artifacts npm run check:ci:fast:tasks",
|
||||
);
|
||||
expect(scripts["check:ci:fast:tasks"]).toBe(
|
||||
"turbo run typecheck lint:built format:check",
|
||||
"node scripts/run-turbo.mjs run typecheck lint:built format:check",
|
||||
);
|
||||
expect(scripts["test:python"]).toContain(
|
||||
"bridge/native/test_rea_lldb_tracer.py",
|
||||
|
||||
@@ -196,6 +196,8 @@ const createBuildCacheFixture = async (): Promise<string> => {
|
||||
"tsconfig.json",
|
||||
"tsconfig.build.json",
|
||||
"scripts/check-dependency-install.mjs",
|
||||
"scripts/run-turbo.mjs",
|
||||
"scripts/run-typescript.mjs",
|
||||
"scripts/run-exclusive.mjs",
|
||||
"scripts/run-exclusive-command.mjs",
|
||||
"scripts/lib/windows-owned-command.mjs",
|
||||
@@ -277,7 +279,7 @@ const runTurbo = (cwd: string, environment: NodeJS.ProcessEnv = process.env) =>
|
||||
run(
|
||||
process.execPath,
|
||||
[
|
||||
join(cwd, "node_modules", "turbo", "bin", "turbo"),
|
||||
join(cwd, "scripts", "run-turbo.mjs"),
|
||||
"run",
|
||||
"artifacts:skills",
|
||||
"--output-logs=full",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { createRequire } from "node:module";
|
||||
import { mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { dirname, join, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { expect, it } from "vitest";
|
||||
@@ -8,9 +9,10 @@ import { z } from "zod";
|
||||
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { workflowGit } from "../../support/workflowGit.js";
|
||||
import { resolveTypeScriptCompiler } from "../../../scripts/run-typescript.mjs";
|
||||
|
||||
const repository = fileURLToPath(new URL("../../../", import.meta.url));
|
||||
const turbo = join(repository, "node_modules/turbo/bin/turbo");
|
||||
const turbo = join(repository, "scripts/run-turbo.mjs");
|
||||
const reportScript = join(repository, "scripts/ci/static-check-report.mjs");
|
||||
const rootConfigSchema = z.object({
|
||||
globalDependencies: z.array(z.string()).optional(),
|
||||
@@ -349,6 +351,13 @@ it.each([
|
||||
diagnostic: "TS2322",
|
||||
invalidatesCompile: false,
|
||||
},
|
||||
{
|
||||
label: "compiler launcher",
|
||||
path: "scripts/run-typescript.mjs",
|
||||
content: 'throw new Error("compiler launcher changed");\n',
|
||||
diagnostic: "compiler launcher changed",
|
||||
invalidatesCompile: true,
|
||||
},
|
||||
{
|
||||
label: "source declaration",
|
||||
path: "src/types.d.mts",
|
||||
@@ -410,11 +419,15 @@ it.each([
|
||||
["compile", "typecheck"],
|
||||
{
|
||||
// Exercise the real compiler phase with the production task inputs.
|
||||
compile: "tsc -p tsconfig.build.json",
|
||||
typecheck: "tsc --noEmit",
|
||||
compile: "node scripts/run-typescript.mjs -p tsconfig.build.json",
|
||||
typecheck: "node scripts/run-typescript.mjs --noEmit",
|
||||
},
|
||||
{ "#compiler-scope": "./scripts/root-types.d.mts" },
|
||||
);
|
||||
await writeFile(
|
||||
join(root, "scripts/run-typescript.mjs"),
|
||||
await readFile(join(repository, "scripts/run-typescript.mjs")),
|
||||
);
|
||||
for (const name of [
|
||||
"tsconfig.json",
|
||||
"tsconfig.build.json",
|
||||
@@ -612,3 +625,125 @@ it("invalidates checker task hashes for Node, ignore, and VitePress config chang
|
||||
`${task} must ignore vitest.config.ts`,
|
||||
).toBe(initial.get(task));
|
||||
});
|
||||
|
||||
it.skipIf(resolveTypeScriptCompiler().name !== "tsrs")(
|
||||
"does not replay an official compiler success for a Rust compiler error",
|
||||
async () => {
|
||||
const root = await createTestTempDirectory("rea-cross-compiler-cache-");
|
||||
const cache = await createTestTempDirectory("rea-cross-compiler-store-");
|
||||
const require = createRequire(import.meta.url);
|
||||
await mkdir(join(root, "scripts"));
|
||||
await mkdir(join(root, "src"));
|
||||
await mkdir(join(root, "node_modules/tsrs"), { recursive: true });
|
||||
for (const name of ["typescript", "turbo"])
|
||||
await symlink(
|
||||
dirname(require.resolve(`${name}/package.json`)),
|
||||
join(root, "node_modules", name),
|
||||
"junction",
|
||||
);
|
||||
for (const name of ["run-typescript.mjs", "run-turbo.mjs"])
|
||||
await writeFile(
|
||||
join(root, "scripts", name),
|
||||
await readFile(join(repository, "scripts", name)),
|
||||
);
|
||||
await writeTaskFixture(root, ["compile", "typecheck"], {
|
||||
compile: "node scripts/run-typescript.mjs -p tsconfig.build.json",
|
||||
typecheck: "node scripts/run-typescript.mjs --noEmit",
|
||||
});
|
||||
const rustPath = require.resolve("tsrs/package.json");
|
||||
const rust = z
|
||||
.object({ version: z.string(), bin: z.object({ tsrs: z.string() }) })
|
||||
.parse(JSON.parse(await readFile(rustPath, "utf8")));
|
||||
const writeInventory = (supported: boolean) =>
|
||||
writeFile(
|
||||
join(root, "node_modules/tsrs/package.json"),
|
||||
JSON.stringify({
|
||||
name: "tsrs",
|
||||
version: rust.version,
|
||||
bin: { tsrs: resolve(dirname(rustPath), rust.bin.tsrs) },
|
||||
optionalDependencies: supported
|
||||
? { [`@tsrs/${process.platform}-${process.arch}`]: rust.version }
|
||||
: {},
|
||||
}),
|
||||
);
|
||||
await writeInventory(false);
|
||||
await writeFile(
|
||||
join(root, "tsconfig.json"),
|
||||
JSON.stringify({
|
||||
compilerOptions: {
|
||||
strict: true,
|
||||
rootDir: "src",
|
||||
types: [],
|
||||
lib: ["ES2023", "DOM"],
|
||||
target: "ES2023",
|
||||
module: "NodeNext",
|
||||
outDir: "dist",
|
||||
},
|
||||
include: ["src/**/*.ts"],
|
||||
}),
|
||||
);
|
||||
await writeFile(
|
||||
join(root, "tsconfig.build.json"),
|
||||
'{"extends":"./tsconfig.json"}\n',
|
||||
);
|
||||
await writeFile(
|
||||
join(root, ".gitignore"),
|
||||
"node_modules/\ndist/\n.cache/\n.turbo/\n",
|
||||
);
|
||||
// TS 7.0 accepts this contextual callback; TS 7.1 reports TS7031.
|
||||
// The source stays identical while only the selected compiler changes.
|
||||
await writeFile(
|
||||
join(root, "src/repro.ts"),
|
||||
[
|
||||
"interface Options { signal?: AbortSignal }",
|
||||
"interface Provider { inspect(options?: Options): Promise<void> }",
|
||||
"declare const base: Provider;",
|
||||
"const providers: Provider[] = [{ ...base, inspect: async ({ signal } = {}) => {",
|
||||
" if (signal?.aborted) throw signal.reason;",
|
||||
"} }];",
|
||||
].join("\n"),
|
||||
);
|
||||
await workflowGit(root, ["init", "--initial-branch=main"]);
|
||||
await workflowGit(root, ["add", "."]);
|
||||
await workflowGit(root, ["commit", "-m", "test: seed compiler isolation"]);
|
||||
const run = (task: string, dryRun = false) =>
|
||||
execute(
|
||||
join(root, "scripts/run-turbo.mjs"),
|
||||
[
|
||||
"run",
|
||||
task,
|
||||
...(dryRun ? ["--dry=json"] : ["--output-logs=errors-only"]),
|
||||
"--cache=local:rw",
|
||||
"--cache-dir",
|
||||
cache,
|
||||
],
|
||||
root,
|
||||
);
|
||||
const hash = (task: string) => {
|
||||
const result = run(task, true);
|
||||
expect(result.status, result.stdout + result.stderr).toBe(0);
|
||||
const entry = dryRunSchema
|
||||
.parse(JSON.parse(result.stdout))
|
||||
.tasks.find((value) => value.taskId === task);
|
||||
if (entry === undefined) throw new Error(`Missing compiler task ${task}`);
|
||||
return entry.hash;
|
||||
};
|
||||
const hashes = new Map<string, string>();
|
||||
for (const task of ["compile", "typecheck"]) {
|
||||
const cold = run(task);
|
||||
expect(cold.status, cold.stdout + cold.stderr).toBe(0);
|
||||
hashes.set(task, hash(task));
|
||||
const warm = run(task);
|
||||
expect(warm.status, warm.stdout + warm.stderr).toBe(0);
|
||||
expect(warm.stdout).toMatch(/Cached:\s+1 cached/u);
|
||||
}
|
||||
await writeInventory(true);
|
||||
for (const task of ["compile", "typecheck"]) {
|
||||
const result = run(task);
|
||||
expect(result.status, result.stdout + result.stderr).toBeGreaterThan(0);
|
||||
expect(result.stdout + result.stderr).toContain("TS7031");
|
||||
expect(result.stdout).toMatch(/Cached:\s+0 cached/u);
|
||||
expect(hash(task)).not.toBe(hashes.get(task));
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,206 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
||||
import { createRequire } from "node:module";
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { expect, it } from "vitest";
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
resolveTypeScriptCompiler,
|
||||
selectTypeScriptCompiler,
|
||||
} from "../../../scripts/run-typescript.mjs";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
const repository = fileURLToPath(new URL("../../../", import.meta.url));
|
||||
const launcher = join(repository, "scripts/run-typescript.mjs");
|
||||
const require = createRequire(import.meta.url);
|
||||
const rustPackage = z
|
||||
.object({
|
||||
version: z.string(),
|
||||
optionalDependencies: z.record(z.string(), z.string()),
|
||||
})
|
||||
.parse(
|
||||
JSON.parse(await readFile(require.resolve("tsrs/package.json"), "utf8")),
|
||||
);
|
||||
const officialPackage = z
|
||||
.object({ version: z.string() })
|
||||
.parse(
|
||||
JSON.parse(
|
||||
await readFile(require.resolve("typescript/package.json"), "utf8"),
|
||||
),
|
||||
);
|
||||
const execute = (script: string, args: string[]) =>
|
||||
spawnSync(process.execPath, [script, ...args], {
|
||||
encoding: "utf8",
|
||||
timeout: 15_000,
|
||||
env: { ...process.env, TURBO_HASH: undefined },
|
||||
});
|
||||
|
||||
it.each([
|
||||
["linux", "x64", "tsrs"],
|
||||
["linux", "arm64", "tsrs"],
|
||||
["darwin", "arm64", "tsrs"],
|
||||
["win32", "x64", "typescript"],
|
||||
["win32", "arm64", "typescript"],
|
||||
["darwin", "x64", "typescript"],
|
||||
["android", "arm64", "typescript"],
|
||||
["linux", "riscv64", "typescript"],
|
||||
])(
|
||||
"selects %s/%s compiler %s from the pinned inventory",
|
||||
(platform, arch, compiler) => {
|
||||
expect(
|
||||
selectTypeScriptCompiler(
|
||||
platform,
|
||||
arch,
|
||||
rustPackage.optionalDependencies,
|
||||
),
|
||||
).toBe(compiler);
|
||||
},
|
||||
);
|
||||
|
||||
it("always retains the official compiler on Windows", () => {
|
||||
expect(
|
||||
selectTypeScriptCompiler("win32", "x64", { "@tsrs/win32-x64": "future" }),
|
||||
).toBe("typescript");
|
||||
});
|
||||
|
||||
it("runs the selected installed compiler", () => {
|
||||
const result = execute(launcher, ["--version"]);
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.status, result.stderr).toBe(0);
|
||||
const compiler = selectTypeScriptCompiler(
|
||||
process.platform,
|
||||
process.arch,
|
||||
rustPackage.optionalDependencies,
|
||||
);
|
||||
expect(result.stdout).toContain(
|
||||
compiler === "tsrs"
|
||||
? `tsrs ${rustPackage.version}`
|
||||
: `Version ${officialPackage.version}`,
|
||||
);
|
||||
});
|
||||
|
||||
it("forwards build arguments and preserves real type errors and exit status", async () => {
|
||||
const root = await createTestTempDirectory("rea-typescript-compiler-");
|
||||
const input = join(root, "input.ts");
|
||||
await writeFile(
|
||||
join(root, "tsconfig.json"),
|
||||
JSON.stringify({
|
||||
compilerOptions: {
|
||||
strict: true,
|
||||
target: "ES2023",
|
||||
types: [],
|
||||
outDir: "output",
|
||||
},
|
||||
files: ["input.ts"],
|
||||
}),
|
||||
);
|
||||
await writeFile(input, "export const value: number = 1;\n");
|
||||
const valid = execute(launcher, ["-p", root, "--pretty", "false"]);
|
||||
expect(valid.error).toBeUndefined();
|
||||
expect(valid.status, valid.stdout + valid.stderr).toBe(0);
|
||||
expect(await readFile(join(root, "output/input.js"), "utf8")).toContain(
|
||||
"value = 1",
|
||||
);
|
||||
const resourceArgs =
|
||||
resolveTypeScriptCompiler().name === "tsrs"
|
||||
? ["--checkers", "1", "--maxMemory", "1G"]
|
||||
: ["--checkers", "1"];
|
||||
const checked = execute(launcher, ["-p", root, "--noEmit", ...resourceArgs]);
|
||||
expect(checked.error).toBeUndefined();
|
||||
expect(checked.status, checked.stdout + checked.stderr).toBe(0);
|
||||
await writeFile(input, 'export const value: number = "invalid";\n');
|
||||
const invalid = execute(launcher, [
|
||||
"-p",
|
||||
root,
|
||||
"--noEmit",
|
||||
"--pretty",
|
||||
"false",
|
||||
]);
|
||||
const direct = execute(resolveTypeScriptCompiler().launcher, [
|
||||
"-p",
|
||||
root,
|
||||
"--noEmit",
|
||||
"--pretty",
|
||||
"false",
|
||||
]);
|
||||
expect(direct.error).toBeUndefined();
|
||||
expect(direct.status, direct.stdout + direct.stderr).toBeGreaterThan(0);
|
||||
expect(direct.stdout + direct.stderr).toContain("TS2322");
|
||||
expect(invalid.error).toBeUndefined();
|
||||
expect(invalid.status, invalid.stdout + invalid.stderr).toBe(direct.status);
|
||||
expect(invalid.stdout + invalid.stderr).toContain("TS2322");
|
||||
expect(await readFile(join(root, "output/input.js"), "utf8")).toContain(
|
||||
"value = 1",
|
||||
);
|
||||
});
|
||||
|
||||
it.skipIf(process.platform === "win32")(
|
||||
"does not retry failed supported compilers with the official compiler",
|
||||
async () => {
|
||||
const root = await createTestTempDirectory("rea-typescript-failure-");
|
||||
const script = join(root, "run-typescript.mjs");
|
||||
await copyFile(launcher, script);
|
||||
for (const name of ["tsrs", "typescript"]) {
|
||||
const directory = join(root, "node_modules", name);
|
||||
await mkdir(directory, { recursive: true });
|
||||
await writeFile(
|
||||
join(directory, "package.json"),
|
||||
JSON.stringify({
|
||||
name,
|
||||
type: "module",
|
||||
bin: { [name === "tsrs" ? "tsrs" : "tsc"]: "cli.mjs" },
|
||||
optionalDependencies: {
|
||||
[`@tsrs/${process.platform}-${process.arch}`]: "fixture",
|
||||
},
|
||||
}),
|
||||
);
|
||||
await writeFile(
|
||||
join(directory, "cli.mjs"),
|
||||
name === "tsrs"
|
||||
? 'console.error("supported compiler failed"); process.exitCode = 42;\n'
|
||||
: 'console.log("unexpected fallback");\n',
|
||||
);
|
||||
}
|
||||
const result = execute(script, ["--noEmit"]);
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.status, result.stdout + result.stderr).toBe(42);
|
||||
expect(result.stderr).toContain("supported compiler failed");
|
||||
expect(result.stdout).not.toContain("unexpected fallback");
|
||||
// The same selection must expose a missing installed launcher as a failure.
|
||||
await writeFile(
|
||||
join(root, "node_modules/tsrs/package.json"),
|
||||
JSON.stringify({
|
||||
name: "tsrs",
|
||||
bin: { tsrs: "missing.mjs" },
|
||||
optionalDependencies: {
|
||||
[`@tsrs/${process.platform}-${process.arch}`]: "fixture",
|
||||
},
|
||||
}),
|
||||
);
|
||||
const missing = execute(script, ["--noEmit"]);
|
||||
expect(missing.status, missing.stdout + missing.stderr).toBe(1);
|
||||
expect(missing.stderr).toContain("ERR_MODULE_NOT_FOUND");
|
||||
expect(missing.stdout).not.toContain("unexpected fallback");
|
||||
},
|
||||
);
|
||||
|
||||
it.each([undefined, "typescript@stale"])(
|
||||
"rejects missing or stale compiler identity %s inside a Turbo task",
|
||||
(identity) => {
|
||||
const result = spawnSync(process.execPath, [launcher, "--version"], {
|
||||
encoding: "utf8",
|
||||
timeout: 15_000,
|
||||
env: {
|
||||
...process.env,
|
||||
TURBO_HASH: "compiler-task",
|
||||
REA_TYPESCRIPT_COMPILER: identity,
|
||||
},
|
||||
});
|
||||
expect(result.error).toBeUndefined();
|
||||
expect(result.status, result.stdout + result.stderr).toBe(1);
|
||||
expect(result.stderr).toContain("Compiler identity is missing or stale");
|
||||
},
|
||||
);
|
||||
@@ -12,6 +12,7 @@ import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import {
|
||||
createAnalysisExecution,
|
||||
type AnalysisProviderCandidate,
|
||||
type AnalysisProviderInspectionOptions,
|
||||
type CapabilityDescriptor,
|
||||
type ProviderIdentity,
|
||||
} from "../../../src/application/AnalysisProvider.js";
|
||||
@@ -411,7 +412,9 @@ it.each(["ready", "cancelled", "physical"] as const)(
|
||||
new AnalysisProviderRegistry([
|
||||
{
|
||||
...base,
|
||||
inspectAvailability: async ({ signal } = {}) => {
|
||||
inspectAvailability: async ({
|
||||
signal,
|
||||
}: AnalysisProviderInspectionOptions = {}) => {
|
||||
enter();
|
||||
await gate;
|
||||
if (mode === "physical")
|
||||
|
||||
@@ -136,3 +136,16 @@ it("keeps every explicit focused CI test path executable after file moves", asyn
|
||||
);
|
||||
expect(missing.filter((path) => path !== undefined)).toEqual([]);
|
||||
}, 10_000);
|
||||
|
||||
it("checks the complete source with the fallback compiler before Windows build reuse", async () => {
|
||||
const workflow = workflowSchema.parse(
|
||||
parse(await readFile(WORKFLOW, "utf8")),
|
||||
);
|
||||
const steps = workflow.jobs["windows-curated"]?.steps ?? [];
|
||||
const checked = steps.findIndex(
|
||||
(step) => step.run === "npm run typecheck -- --checkers 2",
|
||||
);
|
||||
const built = steps.findIndex((step) => step.run === "npm run build:cached");
|
||||
expect(checked).toBeGreaterThan(-1);
|
||||
expect(built).toBeGreaterThan(checked);
|
||||
});
|
||||
+14
-3
@@ -3,13 +3,20 @@
|
||||
"cacheMaxAge": "7d",
|
||||
"cacheMaxSize": "500MB",
|
||||
"globalDependencies": [".nvmrc", ".npmrc"],
|
||||
"globalPassThroughEnv": ["GOMAXPROCS", "GOMEMLIMIT", "UV_THREADPOOL_SIZE"],
|
||||
"globalPassThroughEnv": [
|
||||
"GOMAXPROCS",
|
||||
"GOMEMLIMIT",
|
||||
"UV_THREADPOOL_SIZE",
|
||||
"REA_TYPESCRIPT_COMPILER"
|
||||
],
|
||||
"tasks": {
|
||||
"compile": {
|
||||
"dependsOn": ["metadata:check"],
|
||||
"inputs": [
|
||||
"package.json",
|
||||
"package-lock.json",
|
||||
"scripts/run-turbo.mjs",
|
||||
"scripts/run-typescript.mjs",
|
||||
"scripts/check-dependency-install.mjs",
|
||||
"scripts/clean-build-output.mjs",
|
||||
"scripts/bundle-runtime.mjs",
|
||||
@@ -22,12 +29,15 @@
|
||||
"tsconfig.json",
|
||||
"tsconfig.build.json"
|
||||
],
|
||||
"outputs": ["dist/**"]
|
||||
"outputs": ["dist/**"],
|
||||
"env": ["REA_TYPESCRIPT_COMPILER"]
|
||||
},
|
||||
"typecheck": {
|
||||
"inputs": [
|
||||
"package.json",
|
||||
"package-lock.json",
|
||||
"scripts/run-turbo.mjs",
|
||||
"scripts/run-typescript.mjs",
|
||||
"src/**/*.{cts,mts,ts,tsx}",
|
||||
"src/**/package.json",
|
||||
"tests/**/*.{cts,mts,ts,tsx}",
|
||||
@@ -44,7 +54,8 @@
|
||||
"!docs/.vitepress/cache/**",
|
||||
"!docs/.vitepress/dist/**"
|
||||
],
|
||||
"outputs": []
|
||||
"outputs": [],
|
||||
"env": ["REA_TYPESCRIPT_COMPILER"]
|
||||
},
|
||||
"metadata:check": {
|
||||
"inputs": [
|
||||
|
||||
Reference in new issue
Block a user