sf snapshot: pre-dispatch, uncommitted changes after 2902m inactivity

This commit is contained in:
Mikael Hugo 2026-04-27 23:42:51 +02:00
parent 260d50a823
commit 0d286b991b
3 changed files with 35 additions and 22 deletions

View file

@ -61,6 +61,7 @@
"test:unit": "npm run test:compile && node --import ./scripts/dist-test-resolve.mjs --experimental-test-isolation=process --test-timeout=30000 --test-reporter=./scripts/test-reporter-compact.mjs --test \"dist-test/src/tests/*.test.js\" \"dist-test/src/resources/extensions/sf/tests/*.test.js\" \"dist-test/src/resources/extensions/sf/tests/*.test.mjs\" \"dist-test/src/resources/extensions/shared/tests/*.test.js\" \"dist-test/src/resources/extensions/claude-code-cli/tests/*.test.js\" \"dist-test/src/resources/extensions/github-sync/tests/*.test.js\" \"dist-test/src/resources/extensions/universal-config/tests/*.test.js\" \"dist-test/src/resources/extensions/voice/tests/*.test.js\" \"dist-test/src/resources/extensions/mcp-client/tests/*.test.js\"",
"test:packages": "node --test packages/pi-coding-agent/dist/core/*.test.js packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js",
"test:marketplace": "node scripts/with-env.mjs SF_TEST_CLONE_MARKETPLACES=1 -- node --import ./src/resources/extensions/sf/tests/resolve-ts.mjs --experimental-strip-types --test src/resources/extensions/sf/tests/claude-import-tui.test.ts src/resources/extensions/sf/tests/plugin-importer-live.test.ts src/tests/marketplace-discovery.test.ts",
"test:sf-light": "node --max-old-space-size=2048 --import ./src/resources/extensions/sf/tests/resolve-ts.mjs --experimental-strip-types --test-timeout=30000 --test \"src/resources/extensions/sf/tests/*.test.ts\"",
"test:coverage": "c8 --reporter=text --reporter=lcov --exclude=\"src/resources/extensions/sf/tests/**\" --exclude=\"src/tests/**\" --exclude=\"scripts/**\" --exclude=\"native/**\" --exclude=\"node_modules/**\" --check-coverage --statements=40 --lines=40 --branches=20 --functions=20 node --import ./src/resources/extensions/sf/tests/resolve-ts.mjs --experimental-strip-types --experimental-test-isolation=process --test src/resources/extensions/sf/tests/*.test.ts src/resources/extensions/sf/tests/*.test.mjs src/tests/*.test.ts src/resources/extensions/shared/tests/*.test.ts",
"test:integration": "node --import ./src/resources/extensions/sf/tests/resolve-ts.mjs --experimental-strip-types --test \"src/tests/integration/*.test.ts\" \"src/resources/extensions/sf/tests/integration/*.test.ts\" \"src/resources/extensions/async-jobs/*.test.ts\" \"src/resources/extensions/browser-tools/tests/*.test.mjs\"",
"pretest": "npm run typecheck:extensions",

View file

@ -659,39 +659,51 @@ function detectVerificationCommands(
if (detectedFiles.includes("package.json")) {
const scripts = readPackageJsonScripts(basePath);
if (scripts) {
// Test commands (highest priority)
if (scripts.test && scripts.test !== "echo \"Error: no test specified\" && exit 1") {
commands.push(pm === "npm" ? "npm test" : `${pm} test`);
}
// Build commands
if (scripts.build) {
commands.push(`${run} build`);
}
// Lint commands
if (scripts.lint) {
commands.push(`${run} lint`);
}
// Typecheck commands
if (scripts.typecheck) {
// Typecheck first — fast, no worker processes
if (scripts["typecheck:extensions"]) {
commands.push(`${run} typecheck:extensions`);
} else if (scripts.typecheck) {
commands.push(`${run} typecheck`);
} else if (scripts.tsc) {
commands.push(`${run} tsc`);
}
// Build (compile check when no dedicated typecheck exists)
if (scripts.build) {
commands.push(`${run} build`);
}
// Lint
if (scripts.lint) {
commands.push(`${run} lint`);
}
// Prefer a light test target over the full suite.
// npm test / yarn test can spawn many worker processes and saturate
// CPUs (especially when paired with c8 coverage or test isolation).
// Use a *-light variant when present, otherwise fall back to npm test.
if (scripts["test:sf-light"]) {
commands.push(`${run} test:sf-light`);
} else if (scripts["test:light"]) {
commands.push(`${run} test:light`);
} else if (scripts.test && scripts.test !== "echo \"Error: no test specified\" && exit 1") {
commands.push(pm === "npm" ? "npm test" : `${pm} test`);
}
}
}
if (detectedFiles.includes("Cargo.toml")) {
commands.push("cargo test");
// Limit test threads so Rust tests don't saturate all CPUs.
commands.push("cargo test -- --test-threads=2");
commands.push("cargo clippy");
}
if (detectedFiles.includes("go.mod")) {
commands.push("go test ./...");
// Limit parallelism: Go's default is GOMAXPROCS which can be very high.
commands.push("go test -parallel 2 ./...");
commands.push("go vet ./...");
}
if (detectedFiles.includes("pyproject.toml") || detectedFiles.includes("setup.py") || detectedFiles.includes("requirements.txt")) {
commands.push("pytest");
// Single-process pytest by default; -x stops on first failure (fast feedback).
commands.push("pytest -x");
}
if (detectedFiles.includes("Gemfile")) {

View file

@ -190,7 +190,7 @@ test("detectProjectSignals: Node.js project", (t) => {
assert.equal(signals.isGitRepo, true);
assert.equal(signals.packageManager, "npm");
assert.ok(signals.verificationCommands.includes("npm test"));
assert.ok(signals.verificationCommands.some(c => c.includes("build")));
assert.ok(signals.verificationCommands.some(c => c.includes("build") || c.includes("typecheck")));
assert.ok(signals.verificationCommands.some(c => c.includes("lint")));
});
@ -202,7 +202,7 @@ test("detectProjectSignals: Rust project", (t) => {
const signals = detectProjectSignals(dir);
assert.ok(signals.detectedFiles.includes("Cargo.toml"));
assert.equal(signals.primaryLanguage, "rust");
assert.ok(signals.verificationCommands.includes("cargo test"));
assert.ok(signals.verificationCommands.includes("cargo test -- --test-threads=2"));
assert.ok(signals.verificationCommands.includes("cargo clippy"));
});
@ -214,7 +214,7 @@ test("detectProjectSignals: Go project", (t) => {
const signals = detectProjectSignals(dir);
assert.ok(signals.detectedFiles.includes("go.mod"));
assert.equal(signals.primaryLanguage, "go");
assert.ok(signals.verificationCommands.includes("go test ./..."));
assert.ok(signals.verificationCommands.includes("go test -parallel 2 ./..."));
});
test("detectProjectSignals: Python project", (t) => {
@ -225,7 +225,7 @@ test("detectProjectSignals: Python project", (t) => {
const signals = detectProjectSignals(dir);
assert.ok(signals.detectedFiles.includes("pyproject.toml"));
assert.equal(signals.primaryLanguage, "python");
assert.ok(signals.verificationCommands.includes("pytest"));
assert.ok(signals.verificationCommands.includes("pytest -x"));
});
test("detectProjectSignals: monorepo detection via workspaces", (t) => {
@ -601,7 +601,7 @@ test("detectProjectSignals: requirements.txt sets Python language", () => {
const signals = detectProjectSignals(dir);
assert.ok(signals.detectedFiles.includes("requirements.txt"));
assert.equal(signals.primaryLanguage, "python");
assert.ok(signals.verificationCommands.includes("pytest"), "should suggest pytest for requirements.txt projects");
assert.ok(signals.verificationCommands.includes("pytest -x"), "should suggest pytest for requirements.txt projects");
} finally {
cleanup(dir);
}