Files
rea/scripts/lib/test-projects.mjs
T
791f6328b0 fix(mcp): escalate transient failures before asking for a restart (#6353)
* fix(mcp): escalate transient failures before asking for a restart

Give dropped connections and startup failures one bounded retry, then a
scripted handoff to the user. Point timeout recovery at a named request
field or REA_* setting instead of telling agents those limits are fixed.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): stop unexpected command failures from recommending a retry

The catch can already have launched the target, and the projection stays
non-retryable. Tell the user to check the inputs and run doctor instead.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(mcp): limit retries to safe calls and recommended settings

A dropped connection may already have changed the target, and a bad
catalog rejects the same startup every time. Retry only a repeatable
call, and change a setting only when the remediation recommends it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(mcp): match recovery guidance across wrapped lines

Startup handoff capitalization and markdown wrapping still carry the
same sentences. Compare the prose with whitespace collapsed.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-23 01:32:22 +08:00

108 lines
2.9 KiB
JavaScript

import { matchesGlob } from "node:path";
/** Canonical file ownership shared by Vitest and development-test planning. */
export const SOURCE_TEST_PROJECTS = [
{
name: "domain",
group: "source",
include: ["src/{contracts,domain}/**/*.test.ts"],
},
{
name: "services",
group: "source",
include: ["src/application/**/*.test.ts"],
},
{
name: "adapters",
group: "source",
include: [
"src/*.test.ts",
"src/{android,apkSignature,apktool,jeb,adb,artifacts,browser,config,dotnet,electron,erlang,evm,firmware,flutter,pcap,ghidra,go,gpu,hopper,ida,inspector,javascript,main,native,process,python,reference,rust,server,sqlite,wasm,windows}/**/*.test.ts",
],
},
{
name: "composition",
group: "source",
include: ["tests/composition/**/*.test.ts"],
},
{
name: "conformance",
group: "source",
include: ["tests/conformance/**/*.test.ts"],
exclude: ["tests/conformance/providers/hopper/realHopperSearch.test.ts"],
},
{
name: "evaluation",
group: "source",
include: ["tests/evaluation/**/*.test.ts"],
},
];
export const BUILT_TEST_PROJECTS = [
{
name: "boundary",
group: "built",
include: [
"tests/boundary/**/*.test.ts",
"tests/conformance/providers/hopper/realHopperSearch.test.ts",
],
exclude: [
"tests/boundary/cli/**/*.test.ts",
"tests/boundary/mcp/**/*.test.ts",
"tests/boundary/process/**/*.test.ts",
],
},
{
name: "cli-boundary",
group: "built",
include: ["tests/boundary/cli/**/*.test.ts"],
},
{
name: "process-boundary",
group: "built",
include: ["tests/boundary/process/**/*.test.ts"],
},
{
name: "mcp-boundary",
group: "built",
include: ["tests/boundary/mcp/**/*.test.ts"],
},
{
name: "acceptance",
group: "built",
include: ["tests/acceptance/**/*.test.ts"],
},
{
name: "process-global",
group: "built",
include: ["tests/process-global/**/*.test.ts"],
},
];
const ALL_TEST_PROJECTS = [...SOURCE_TEST_PROJECTS, ...BUILT_TEST_PROJECTS];
/** Return the unique Vitest owner for an exact repository-relative test path. */
export const projectForTest = (testPath) => {
if (
typeof testPath !== "string" ||
testPath.startsWith("/") ||
testPath.includes("\\") ||
testPath.split("/").some((part) => part === ".." || part === ".") ||
!testPath.endsWith(".test.ts")
)
throw new Error(`Expected a normalized repository test path: ${testPath}`);
const owners = ALL_TEST_PROJECTS.filter(
({ include, exclude = [] }) =>
include.some((pattern) => matchesGlob(testPath, pattern)) &&
!exclude.some((pattern) => matchesGlob(testPath, pattern)),
);
if (owners.length !== 1)
throw new Error(
owners.length === 0
? `No test project owns ${testPath}`
: `Multiple test projects own ${testPath}: ${owners.map(({ name }) => name).join(", ")}`,
);
return owners[0];
};