Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36cbe31e19 | ||
|
|
092de8f08b |
@@ -82,7 +82,7 @@ jobs:
|
|||||||
|
|
||||||
test-shard:
|
test-shard:
|
||||||
name: Test shard (${{ matrix.shard }})
|
name: Test shard (${{ matrix.shard }})
|
||||||
needs: changes
|
needs: [changes, build]
|
||||||
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
|
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -96,7 +96,11 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- run: npm run test:ci:shard -- --shard=${{ matrix.shard }}
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: rea-dist
|
||||||
|
path: dist
|
||||||
|
- run: npm run test:ci:shard:run -- --shard=${{ matrix.shard }}
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
with:
|
with:
|
||||||
@@ -107,6 +111,26 @@ jobs:
|
|||||||
overwrite: true
|
overwrite: true
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build package
|
||||||
|
needs: changes
|
||||||
|
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .nvmrc
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build:cached
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: rea-dist
|
||||||
|
path: dist
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test (coverage + timing)
|
name: Test (coverage + timing)
|
||||||
needs: [changes, test-shard]
|
needs: [changes, test-shard]
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ coverage/
|
|||||||
.vitest-reports/
|
.vitest-reports/
|
||||||
test-results.xml
|
test-results.xml
|
||||||
.turbo/
|
.turbo/
|
||||||
|
.cache/
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
".": "2.4.0"
|
".": "2.4.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,10 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
|
|||||||
- `npm run build`: compile `src/` into `dist/`.
|
- `npm run build`: compile `src/` into `dist/`.
|
||||||
- `npm run build:cached`: compile through Turbo and reuse a valid local build cache entry.
|
- `npm run build:cached`: compile through Turbo and reuse a valid local build cache entry.
|
||||||
- `npm test`: restore or build `dist/`, then run the Vitest suite once without coverage or retries locally.
|
- `npm test`: restore or build `dist/`, then run the Vitest suite once without coverage or retries locally.
|
||||||
- `npm run test:fast`: run the parallel test project without the serial integration group.
|
- `npm run test:fast`: run pure and subprocess test projects without the serial integration group.
|
||||||
|
- `npm run test:changed`: run changed and related non-serial tests once.
|
||||||
- `npm run test:integration`: run the serial filesystem, process, and CLI integration group.
|
- `npm run test:integration`: run the serial filesystem, process, and CLI integration group.
|
||||||
- `npm run test:watch`: watch tests affected by working-tree changes in the parallel project, without coverage.
|
- `npm run test:watch`: watch changed and related non-serial tests, without coverage.
|
||||||
- `npm run test:coverage`: run the complete suite with coverage; CI shards the suite and owns JUnit reporting.
|
- `npm run test:coverage`: run the complete suite with coverage; CI shards the suite and owns JUnit reporting.
|
||||||
- `npm run typecheck`: run strict TypeScript checks without emitting files.
|
- `npm run typecheck`: run strict TypeScript checks without emitting files.
|
||||||
- `npm run lint`: apply oxlint rules (complexity, max-lines, unused vars, and TypeScript-specific checks).
|
- `npm run lint`: apply oxlint rules (complexity, max-lines, unused vars, and TypeScript-specific checks).
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.4.1](https://github.com/morluto/rea/compare/rea-agents-2.4.0...rea-agents-2.4.1) (2026-07-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **hopper:** add bounded analysis recovery ([e0bc7fd](https://github.com/morluto/rea/commit/e0bc7fd973b26448fb2192a2059ab1229bec0817))
|
||||||
|
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
* **package:** stabilize fake Hopper ownership ([0b70131](https://github.com/morluto/rea/commit/0b7013134c58085b72177f2954e55534be053ebe))
|
||||||
|
|
||||||
## [2.4.0](https://github.com/morluto/rea/compare/rea-agents-2.3.0...rea-agents-2.4.0) (2026-07-23)
|
## [2.4.0](https://github.com/morluto/rea/compare/rea-agents-2.3.0...rea-agents-2.4.0) (2026-07-23)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -39,9 +39,11 @@ prerequisite uses Turbo. CI uploads the rendered TypeDoc site as an `api-docs`
|
|||||||
artifact; the generated HTML is not committed.
|
artifact; the generated HTML is not committed.
|
||||||
|
|
||||||
Local `npm test` runs without coverage, retries, or verbose output. Use `npm run
|
Local `npm test` runs without coverage, retries, or verbose output. Use `npm run
|
||||||
test:fast` for the parallel group, `npm run test:integration` for serial
|
test:fast` for pure and subprocess groups, `npm run test:integration` for serial
|
||||||
filesystem/process/CLI cases, and `npm run test:watch` to watch tests affected by
|
filesystem/process/CLI cases. `npm run test:changed` runs changed and related
|
||||||
working-tree changes. CI splits the complete suite across two native Vitest
|
non-serial tests once; `npm run test:watch` keeps that selection live. Pure tests
|
||||||
|
use Vitest threads, while subprocess tests stay in isolated forks. CI splits the
|
||||||
|
complete suite across two native Vitest
|
||||||
shards, then merges their coverage and JUnit reports. `npm run test:ci` runs the
|
shards, then merges their coverage and JUnit reports. `npm run test:ci` runs the
|
||||||
equivalent unsharded gate locally. Coverage thresholds remain in
|
equivalent unsharded gate locally. Coverage thresholds remain in
|
||||||
`vitest.config.ts`.
|
`vitest.config.ts`.
|
||||||
|
|||||||
@@ -479,7 +479,7 @@ Setup detects Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf,
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"rea": {
|
"rea": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "rea-agents@2.4.0", "mcp"]
|
"args": ["-y", "rea-agents@2.4.1", "mcp"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -182,7 +182,7 @@ rea uninstall --purge-data
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"rea": {
|
"rea": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "rea-agents@2.4.0", "mcp"]
|
"args": ["-y", "rea-agents@2.4.1", "mcp"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -172,7 +172,7 @@ Setup は Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"rea": {
|
"rea": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "rea-agents@2.4.0", "mcp"]
|
"args": ["-y", "rea-agents@2.4.1", "mcp"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -172,7 +172,7 @@ Setup은 Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"rea": {
|
"rea": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "rea-agents@2.4.0", "mcp"]
|
"args": ["-y", "rea-agents@2.4.1", "mcp"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -172,7 +172,7 @@ Setup 会检测 Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Win
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"rea": {
|
"rea": {
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["-y", "rea-agents@2.4.0", "mcp"]
|
"args": ["-y", "rea-agents@2.4.1", "mcp"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"catalog_schema_version": 1,
|
"catalog_schema_version": 1,
|
||||||
"package": {
|
"package": {
|
||||||
"name": "rea-agents",
|
"name": "rea-agents",
|
||||||
"version": "2.4.0",
|
"version": "2.4.1",
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"server": "2.0.0-beta.4",
|
"server": "2.0.0-beta.4",
|
||||||
"client": "2.0.0-beta.4",
|
"client": "2.0.0-beta.4",
|
||||||
@@ -87,7 +87,10 @@
|
|||||||
"id": "artifact",
|
"id": "artifact",
|
||||||
"surface": "artifact-provider",
|
"surface": "artifact-provider",
|
||||||
"count": 2,
|
"count": 2,
|
||||||
"tools": ["extract_artifact", "inventory_artifact"]
|
"tools": [
|
||||||
|
"extract_artifact",
|
||||||
|
"inventory_artifact"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "managed",
|
"id": "managed",
|
||||||
@@ -259,7 +262,10 @@
|
|||||||
"id": "rea-artifact-graph",
|
"id": "rea-artifact-graph",
|
||||||
"name": "REA safe artifact graph provider",
|
"name": "REA safe artifact graph provider",
|
||||||
"version": "1",
|
"version": "1",
|
||||||
"capabilities": ["extract_artifact", "inventory_artifact"]
|
"capabilities": [
|
||||||
|
"extract_artifact",
|
||||||
|
"inventory_artifact"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rea-cdp-browser",
|
"id": "rea-cdp-browser",
|
||||||
@@ -280,7 +286,10 @@
|
|||||||
"id": "rea-cdp-electron",
|
"id": "rea-cdp-electron",
|
||||||
"name": "REA Electron file-page CDP observation provider",
|
"name": "REA Electron file-page CDP observation provider",
|
||||||
"version": "1",
|
"version": "1",
|
||||||
"capabilities": ["inspect_electron_page", "list_electron_targets"]
|
"capabilities": [
|
||||||
|
"inspect_electron_page",
|
||||||
|
"list_electron_targets"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rea-dotnet-static",
|
"id": "rea-dotnet-static",
|
||||||
@@ -308,7 +317,9 @@
|
|||||||
"id": "rea-javascript-application",
|
"id": "rea-javascript-application",
|
||||||
"name": "REA JavaScript application analyzer",
|
"name": "REA JavaScript application analyzer",
|
||||||
"version": "1",
|
"version": "1",
|
||||||
"capabilities": ["analyze_javascript_application"]
|
"capabilities": [
|
||||||
|
"analyze_javascript_application"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rea-javascript-application-workflows",
|
"id": "rea-javascript-application-workflows",
|
||||||
@@ -330,7 +341,9 @@
|
|||||||
"id": "rea-javascript-runtime-reconciliation",
|
"id": "rea-javascript-runtime-reconciliation",
|
||||||
"name": "REA JavaScript runtime reconciliation",
|
"name": "REA JavaScript runtime reconciliation",
|
||||||
"version": "1",
|
"version": "1",
|
||||||
"capabilities": ["reconcile_javascript_runtime"]
|
"capabilities": [
|
||||||
|
"reconcile_javascript_runtime"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"setup_clients": [
|
"setup_clients": [
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "rea-agents",
|
"name": "rea-agents",
|
||||||
"version": "2.4.0",
|
"version": "2.4.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "rea-agents",
|
"name": "rea-agents",
|
||||||
"version": "2.4.0",
|
"version": "2.4.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "8.0.4",
|
"@babel/parser": "8.0.4",
|
||||||
|
|||||||
+7
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rea-agents",
|
"name": "rea-agents",
|
||||||
"version": "2.4.0",
|
"version": "2.4.1",
|
||||||
"description": "Reverse engineer anything from your terminal or agent with one CLI and MCP server.",
|
"description": "Reverse engineer anything from your terminal or agent with one CLI and MCP server.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -80,19 +80,22 @@
|
|||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
"test:run": "vitest run",
|
"test:run": "vitest run",
|
||||||
"pretest:fast": "npm run build:cached",
|
"pretest:fast": "npm run build:cached",
|
||||||
"test:fast": "vitest run --project parallel",
|
"test:fast": "vitest run --project parallel --project subprocess",
|
||||||
|
"pretest:changed": "npm run build:cached",
|
||||||
|
"test:changed": "vitest run --project parallel --project subprocess --changed",
|
||||||
"pretest:integration": "npm run build:cached",
|
"pretest:integration": "npm run build:cached",
|
||||||
"test:integration": "vitest run --project serial-integration",
|
"test:integration": "vitest run --project serial-integration",
|
||||||
"pretest:coverage": "npm run build:cached",
|
"pretest:coverage": "npm run build:cached",
|
||||||
"test:coverage": "vitest run --coverage.enabled --coverage.provider=v8",
|
"test:coverage": "vitest run --coverage.enabled --coverage.provider=v8",
|
||||||
"test:ci": "npm run test:coverage -- --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
|
"test:ci": "npm run test:coverage -- --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
|
||||||
"pretest:ci:shard": "npm run build:cached",
|
"pretest:ci:shard": "npm run build:cached",
|
||||||
"test:ci:shard": "vitest run --coverage.enabled --coverage.provider=v8 --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 --reporter=default --reporter=blob",
|
"test:ci:shard": "npm run test:ci:shard:run",
|
||||||
|
"test:ci:shard:run": "vitest run --coverage.enabled --coverage.provider=v8 --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 --reporter=default --reporter=blob",
|
||||||
"test:ci:merge": "vitest --merge-reports --coverage.enabled --coverage.provider=v8 --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
|
"test:ci:merge": "vitest --merge-reports --coverage.enabled --coverage.provider=v8 --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
|
||||||
"pretest:verbose": "npm run build:cached",
|
"pretest:verbose": "npm run build:cached",
|
||||||
"test:verbose": "vitest run --reporter=verbose",
|
"test:verbose": "vitest run --reporter=verbose",
|
||||||
"pretest:watch": "npm run build:cached",
|
"pretest:watch": "npm run build:cached",
|
||||||
"test:watch": "vitest --project parallel --changed",
|
"test:watch": "vitest --project parallel --project subprocess --changed",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"verify:test-temp-hygiene": "npm run build:cached && node scripts/verify-test-temp-hygiene.mjs",
|
"verify:test-temp-hygiene": "npm run build:cached && 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": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper.mjs",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** Generated from package.json and package-lock.json; do not edit. */
|
/** Generated from package.json and package-lock.json; do not edit. */
|
||||||
export const PACKAGE_METADATA = {
|
export const PACKAGE_METADATA = {
|
||||||
name: "rea-agents",
|
name: "rea-agents",
|
||||||
version: "2.4.0", // x-release-please-version
|
version: "2.4.1", // x-release-please-version
|
||||||
serverSdkVersion: "2.0.0-beta.4",
|
serverSdkVersion: "2.0.0-beta.4",
|
||||||
clientSdkVersion: "2.0.0-beta.4",
|
clientSdkVersion: "2.0.0-beta.4",
|
||||||
coreSdkVersion: "2.0.0-beta.4",
|
coreSdkVersion: "2.0.0-beta.4",
|
||||||
|
|||||||
@@ -1361,7 +1361,9 @@ describe("CdpBrowserProvider", () => {
|
|||||||
}),
|
}),
|
||||||
{ signal: controller.signal },
|
{ signal: controller.signal },
|
||||||
);
|
);
|
||||||
await waitForCommand(browser, "Target.attachToTarget");
|
// Wait until the attach response has been consumed and capture has begun.
|
||||||
|
// Seeing the attach request alone races its response under worker load.
|
||||||
|
await waitForCommand(browser, "Page.getFrameTree");
|
||||||
controller.abort();
|
controller.abort();
|
||||||
const result = await pending;
|
const result = await pending;
|
||||||
expect(result).toMatchObject({
|
expect(result).toMatchObject({
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ describe("package installation workflows", () => {
|
|||||||
expect(continuousIntegration).toContain("name: Static checks");
|
expect(continuousIntegration).toContain("name: Static checks");
|
||||||
expect(continuousIntegration).toContain("npm run check:ci");
|
expect(continuousIntegration).toContain("npm run check:ci");
|
||||||
expect(continuousIntegration).toContain("shard: [1/2, 2/2]");
|
expect(continuousIntegration).toContain("shard: [1/2, 2/2]");
|
||||||
|
expect(continuousIntegration).toContain("name: Build package");
|
||||||
|
expect(continuousIntegration).toContain("npm run build:cached");
|
||||||
|
expect(continuousIntegration).toContain("name: rea-dist");
|
||||||
|
expect(continuousIntegration).toContain("npm run test:ci:shard:run");
|
||||||
expect(continuousIntegration).toContain("needs: [changes, test-shard]");
|
expect(continuousIntegration).toContain("needs: [changes, test-shard]");
|
||||||
expect(continuousIntegration).toContain("if-no-files-found: error");
|
expect(continuousIntegration).toContain("if-no-files-found: error");
|
||||||
expect(continuousIntegration).toContain("overwrite: true");
|
expect(continuousIntegration).toContain("overwrite: true");
|
||||||
|
|||||||
@@ -1809,12 +1809,14 @@ describe("process capture adapter", () => {
|
|||||||
reactive: {
|
reactive: {
|
||||||
version: 1,
|
version: 1,
|
||||||
initial_state: "waiting",
|
initial_state: "waiting",
|
||||||
deadline_ms: 2_000,
|
deadline_ms: 5_000,
|
||||||
states: [
|
states: [
|
||||||
{
|
{
|
||||||
id: "waiting",
|
id: "waiting",
|
||||||
max_visits: 1,
|
max_visits: 1,
|
||||||
deadline_ms: 300,
|
// Leave process startup scheduling headroom; this test targets
|
||||||
|
// post-exit settlement ordering, not a 300ms startup deadline.
|
||||||
|
deadline_ms: 2_000,
|
||||||
on: [
|
on: [
|
||||||
{
|
{
|
||||||
id: "unreachable",
|
id: "unreachable",
|
||||||
@@ -1913,7 +1915,7 @@ describe("process capture adapter", () => {
|
|||||||
} finally {
|
} finally {
|
||||||
await rm(root, { recursive: true, force: true });
|
await rm(root, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
});
|
}, 10_000);
|
||||||
|
|
||||||
it("renders terminal state, records shim invocations, and captures literal checkpoints", async () => {
|
it("renders terminal state, records shim invocations, and captures literal checkpoints", async () => {
|
||||||
const root = await createTestTempDirectory("rea-v3-test-");
|
const root = await createTestTempDirectory("rea-v3-test-");
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ describe("process-capture MCP elicitation", () => {
|
|||||||
);
|
);
|
||||||
const echoedState =
|
const echoedState =
|
||||||
failure === "tampered"
|
failure === "tampered"
|
||||||
? `${requestState.slice(0, -1)}${requestState.endsWith("A") ? "B" : "A"}`
|
? `${requestState.startsWith("A") ? "B" : "A"}${requestState.slice(1)}`
|
||||||
: requestState;
|
: requestState;
|
||||||
const retryMethod: string = "tools/call";
|
const retryMethod: string = "tools/call";
|
||||||
await expect(
|
await expect(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
|
|
||||||
import vitestConfiguration, {
|
import vitestConfiguration, {
|
||||||
SERIAL_INTEGRATION_TESTS,
|
SERIAL_INTEGRATION_TESTS,
|
||||||
|
SUBPROCESS_TESTS,
|
||||||
} from "../vitest.config.js";
|
} from "../vitest.config.js";
|
||||||
|
|
||||||
const execute = promisify(execFile);
|
const execute = promisify(execFile);
|
||||||
@@ -24,7 +25,7 @@ describe("Vitest project configuration", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("collects exact disjoint parallel and serial test sets", async () => {
|
it("collects exact disjoint unit, subprocess, and serial test sets", async () => {
|
||||||
const { stdout } = await execute(
|
const { stdout } = await execute(
|
||||||
process.execPath,
|
process.execPath,
|
||||||
[
|
[
|
||||||
@@ -37,14 +38,18 @@ describe("Vitest project configuration", () => {
|
|||||||
);
|
);
|
||||||
const projects = parseProjects(stdout);
|
const projects = parseProjects(stdout);
|
||||||
const parallel = projects.get("parallel") ?? [];
|
const parallel = projects.get("parallel") ?? [];
|
||||||
|
const subprocess = projects.get("subprocess") ?? [];
|
||||||
const serial = projects.get("serial-integration") ?? [];
|
const serial = projects.get("serial-integration") ?? [];
|
||||||
const repositoryTests = await testFiles("tests");
|
const repositoryTests = await testFiles("tests");
|
||||||
|
|
||||||
expect(serial).toEqual([...SERIAL_INTEGRATION_TESTS].sort());
|
expect(serial).toEqual([...SERIAL_INTEGRATION_TESTS].sort());
|
||||||
expect(parallel.filter((path) => serial.includes(path))).toEqual([]);
|
expect(parallel.filter((path) => serial.includes(path))).toEqual([]);
|
||||||
expect([...new Set([...parallel, ...serial])].sort()).toEqual(
|
expect(subprocess).toEqual([...SUBPROCESS_TESTS].sort());
|
||||||
repositoryTests,
|
expect(subprocess.filter((path) => serial.includes(path))).toEqual([]);
|
||||||
);
|
expect(parallel.filter((path) => subprocess.includes(path))).toEqual([]);
|
||||||
|
expect(
|
||||||
|
[...new Set([...parallel, ...subprocess, ...serial])].sort(),
|
||||||
|
).toEqual(repositoryTests);
|
||||||
}, 20_000);
|
}, 20_000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"extends": "./tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"incremental": true,
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
|
"tsBuildInfoFile": ".cache/tsconfig.build.tsbuildinfo",
|
||||||
"types": ["node"]
|
"types": ["node"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts"],
|
"include": ["src/**/*.ts"],
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
"rootDir": ".",
|
"rootDir": ".",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"incremental": true,
|
||||||
|
"tsBuildInfoFile": ".cache/tsconfig.typecheck.tsbuildinfo",
|
||||||
"target": "ES2023",
|
"target": "ES2023",
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
"verbatimModuleSyntax": true
|
"verbatimModuleSyntax": true
|
||||||
|
|||||||
+29
-4
@@ -14,7 +14,7 @@
|
|||||||
"tsconfig.json",
|
"tsconfig.json",
|
||||||
"tsconfig.build.json"
|
"tsconfig.build.json"
|
||||||
],
|
],
|
||||||
"outputs": ["dist/**"]
|
"outputs": ["dist/**", ".cache/tsconfig.build.tsbuildinfo"]
|
||||||
},
|
},
|
||||||
"typecheck": {
|
"typecheck": {
|
||||||
"inputs": [
|
"inputs": [
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
"tsconfig.json",
|
"tsconfig.json",
|
||||||
"tsconfig.build.json",
|
"tsconfig.build.json",
|
||||||
"vitest.config.ts"
|
"vitest.config.ts"
|
||||||
]
|
],
|
||||||
|
"outputs": [".cache/tsconfig.typecheck.tsbuildinfo"]
|
||||||
},
|
},
|
||||||
"metadata:check": {
|
"metadata:check": {
|
||||||
"inputs": [
|
"inputs": [
|
||||||
@@ -38,9 +39,33 @@
|
|||||||
"src/generatedPackageMetadata.ts"
|
"src/generatedPackageMetadata.ts"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lint": {},
|
"lint": {
|
||||||
|
"inputs": [
|
||||||
|
".nvmrc",
|
||||||
|
".oxlintrc.json",
|
||||||
|
"eslint.config.js",
|
||||||
|
"package.json",
|
||||||
|
"package-lock.json",
|
||||||
|
"scripts/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}",
|
||||||
|
"src/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}",
|
||||||
|
"tests/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}",
|
||||||
|
"vitest.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
"format:check": {},
|
"format:check": {},
|
||||||
"knip": {},
|
"knip": {
|
||||||
|
"inputs": [
|
||||||
|
".nvmrc",
|
||||||
|
"knip.json",
|
||||||
|
"package.json",
|
||||||
|
"package-lock.json",
|
||||||
|
"scripts/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}",
|
||||||
|
"src/**/*.ts",
|
||||||
|
"tests/**/*.ts",
|
||||||
|
"tsconfig.json",
|
||||||
|
"tsconfig.build.json"
|
||||||
|
]
|
||||||
|
},
|
||||||
"jscpd": {
|
"jscpd": {
|
||||||
"inputs": [
|
"inputs": [
|
||||||
".gitignore",
|
".gitignore",
|
||||||
|
|||||||
+43
-2
@@ -8,6 +8,7 @@ export const TEST_FILES = ["tests/**/*.test.ts"];
|
|||||||
const IS_CONTINUOUS_INTEGRATION = process.env.CI === "true";
|
const IS_CONTINUOUS_INTEGRATION = process.env.CI === "true";
|
||||||
// Subprocess-heavy parallel tests exceed their existing deadlines above two workers.
|
// Subprocess-heavy parallel tests exceed their existing deadlines above two workers.
|
||||||
const MAX_TEST_WORKERS = 2;
|
const MAX_TEST_WORKERS = 2;
|
||||||
|
const MAX_UNIT_TEST_WORKERS = 4;
|
||||||
const PROCESS_CAPTURE_TEST = "tests/processCapture.test.ts";
|
const PROCESS_CAPTURE_TEST = "tests/processCapture.test.ts";
|
||||||
const CANONICAL_TEMPORARY_DIRECTORY = realpathSync(tmpdir());
|
const CANONICAL_TEMPORARY_DIRECTORY = realpathSync(tmpdir());
|
||||||
export const SERIAL_INTEGRATION_TESTS = [
|
export const SERIAL_INTEGRATION_TESTS = [
|
||||||
@@ -19,6 +20,33 @@ export const SERIAL_INTEGRATION_TESTS = [
|
|||||||
PROCESS_CAPTURE_TEST,
|
PROCESS_CAPTURE_TEST,
|
||||||
"tests/runtime.test.ts",
|
"tests/runtime.test.ts",
|
||||||
];
|
];
|
||||||
|
// Keep tests that launch child processes or production runtimes in the forks pool.
|
||||||
|
// In-memory MCP and filesystem-seam tests remain safe in the faster threads pool.
|
||||||
|
export const SUBPROCESS_TESTS = [
|
||||||
|
"tests/applicationWorkflowVerifier.test.ts",
|
||||||
|
"tests/bridgeLauncher.test.ts",
|
||||||
|
"tests/bridgeRegex.test.ts",
|
||||||
|
"tests/browserProcessStartup.test.ts",
|
||||||
|
"tests/cliPolicyCommands.test.ts",
|
||||||
|
"tests/cliSetup.test.ts",
|
||||||
|
"tests/dependencyInstall.test.ts",
|
||||||
|
"tests/dispatcher.test.ts",
|
||||||
|
"tests/ghidraClient.test.ts",
|
||||||
|
"tests/ghidraWindowsFixture.test.ts",
|
||||||
|
"tests/hopperClient.test.ts",
|
||||||
|
"tests/installScript.test.ts",
|
||||||
|
"tests/javascriptReplayWorker.test.ts",
|
||||||
|
"tests/javascriptRuntimeReconciliation.test.ts",
|
||||||
|
"tests/linuxPrivateDisplay.test.ts",
|
||||||
|
"tests/mcpDoctor.test.ts",
|
||||||
|
"tests/processCli.test.ts",
|
||||||
|
"tests/providerProcess.test.ts",
|
||||||
|
"tests/runtimeExecutableDiagnostics.test.ts",
|
||||||
|
"tests/scanTodos.test.ts",
|
||||||
|
"tests/sessionMcp.test.ts",
|
||||||
|
"tests/verifierRun.test.ts",
|
||||||
|
"tests/vitestConfiguration.test.ts",
|
||||||
|
];
|
||||||
const isolatedProjects = {
|
const isolatedProjects = {
|
||||||
maxWorkers: Math.min(MAX_TEST_WORKERS, availableParallelism()),
|
maxWorkers: Math.min(MAX_TEST_WORKERS, availableParallelism()),
|
||||||
projects: [
|
projects: [
|
||||||
@@ -27,17 +55,30 @@ const isolatedProjects = {
|
|||||||
test: {
|
test: {
|
||||||
name: "parallel",
|
name: "parallel",
|
||||||
include: TEST_FILES,
|
include: TEST_FILES,
|
||||||
exclude: SERIAL_INTEGRATION_TESTS,
|
exclude: [...SERIAL_INTEGRATION_TESTS, ...SUBPROCESS_TESTS],
|
||||||
|
pool: "threads",
|
||||||
|
maxWorkers: Math.min(MAX_UNIT_TEST_WORKERS, availableParallelism()),
|
||||||
sequence: { groupOrder: 0 },
|
sequence: { groupOrder: 0 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
extends: true as const,
|
||||||
|
test: {
|
||||||
|
name: "subprocess",
|
||||||
|
include: SUBPROCESS_TESTS,
|
||||||
|
pool: "forks",
|
||||||
|
maxWorkers: Math.min(MAX_TEST_WORKERS, availableParallelism()),
|
||||||
|
sequence: { groupOrder: 1 },
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
extends: true as const,
|
extends: true as const,
|
||||||
test: {
|
test: {
|
||||||
name: "serial-integration",
|
name: "serial-integration",
|
||||||
include: SERIAL_INTEGRATION_TESTS,
|
include: SERIAL_INTEGRATION_TESTS,
|
||||||
fileParallelism: false,
|
fileParallelism: false,
|
||||||
sequence: { groupOrder: 1 },
|
pool: "forks",
|
||||||
|
sequence: { groupOrder: 2 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user