test(#4516): migrate per-runtime install/upgrade adapters to named timeout constants (#4582)

Batch 5 of the ad hoc timeout literal migration (epic #4445). Replaces
every bare numeric timeout/timeoutMs object-literal property across
tests/augment-upgrades.test.cjs, tests/shared-hooks-dir-resolution.test.cjs,
tests/antigravity-upgrades.test.cjs, tests/cursor-hooks.test.cjs,
tests/cursor-hook-workspace-roots.test.cjs, tests/gemini-runtime-removed.test.cjs,
tests/kilo-upgrades.test.cjs, tests/kimi-upgrades.test.cjs,
tests/kimi-variant-disambiguation.test.cjs, tests/opencode-plugin-adapter.test.cjs,
tests/windsurf-hooks-bridge.test.cjs, tests/effort-sync-installed-runtime.test.cjs,
and tests/hooks-commonjs-marker.test.cjs with a named constant, per
eslint-rules/no-adhoc-timeout-literal.cjs. Removes these 13 files from the
rule's allowlist.

Adds one new shared constant to tests/helpers/timeouts.cjs for spawning a
single already-staged hook script directly (a heavier class than the
existing quick-spawn norm), shared across three files in this batch. One
new file-local constant covers a property-test driver process distinct
from any existing class. Every other site reuses an existing shared norm.
No src/bin file touched, no numeric timeout value changed anywhere.

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-09-10 14:11:26 -04:00
committed by GitHub
parent 0b928fe28c
commit 557a0b2876
15 changed files with 65 additions and 40 deletions

View File

@@ -3,12 +3,10 @@
"tests/adr-612-bracket-read-tolerance.test.cjs",
"tests/adr-index-gate.test.cjs",
"tests/adr857-core-without-capabilities.test.cjs",
"tests/antigravity-upgrades.test.cjs",
"tests/api-coverage-gate-e2e.test.cjs",
"tests/api-coverage.test.cjs",
"tests/assumption-delta-checkpoint-e2e.test.cjs",
"tests/assumption-delta.test.cjs",
"tests/augment-upgrades.test.cjs",
"tests/capability-cli.test.cjs",
"tests/capability-probe-fallback.test.cjs",
"tests/capability-state.test.cjs",
@@ -26,18 +24,14 @@
"tests/code-review.test.cjs",
"tests/commands.test.cjs",
"tests/config-get-default.test.cjs",
"tests/cursor-hook-workspace-roots.test.cjs",
"tests/cursor-hooks.test.cjs",
"tests/dispatcher.test.cjs",
"tests/effort-surface-axis.test.cjs",
"tests/effort-sync-installed-runtime.test.cjs",
"tests/emitted-ack-trailer.test.cjs",
"tests/emitted-attribution.test.cjs",
"tests/execute-wave-post-gate-pipeline-e2e.test.cjs",
"tests/feat-2483-review-claude-mds-guard.test.cjs",
"tests/federated-config.test.cjs",
"tests/gate-predicate-evaluator.test.cjs",
"tests/gemini-runtime-removed.test.cjs",
"tests/gen-context-index.test.cjs",
"tests/gen-health-docs.test.cjs",
"tests/gen-section-manifest.test.cjs",
@@ -49,12 +43,8 @@
"tests/gsd-statusline.test.cjs",
"tests/gsd-write-guard.test.cjs",
"tests/health-validation.test.cjs",
"tests/hooks-commonjs-marker.test.cjs",
"tests/hooks-crash-policy.test.cjs",
"tests/init.test.cjs",
"tests/kilo-upgrades.test.cjs",
"tests/kimi-upgrades.test.cjs",
"tests/kimi-variant-disambiguation.test.cjs",
"tests/lint-docs-command-form.test.cjs",
"tests/locking-bugs-1909-1916-1925-1927.test.cjs",
"tests/loop-hooks-empty-points-e2e.test.cjs",
@@ -64,7 +54,6 @@
"tests/loop-walk.qa.test.cjs",
"tests/milestone-lock.test.cjs",
"tests/no-pending-3212-markers.test.cjs",
"tests/opencode-plugin-adapter.test.cjs",
"tests/pattern.test.cjs",
"tests/perf-316-state-lock-buffer-alloc.test.cjs",
"tests/perf-317-context-monitor-fs.test.cjs",
@@ -91,13 +80,11 @@
"tests/security-prompt-injection.security.test.cjs",
"tests/security-scan.security.test.cjs",
"tests/security.test.cjs",
"tests/shared-hooks-dir-resolution.test.cjs",
"tests/shell-command-projection-dispatch.test.cjs",
"tests/state-document.test.cjs",
"tests/state-todos-render.test.cjs",
"tests/task-command-router-resolve-content.test.cjs",
"tests/task-content-resolution.test.cjs",
"tests/task-content-resolver-grammar-parity.test.cjs",
"tests/teams-status.test.cjs",
"tests/windsurf-hooks-bridge.test.cjs"
"tests/teams-status.test.cjs"
]

View File

@@ -37,6 +37,7 @@ const { runNode } = require('./helpers/process-seam.cjs');
const { runMinimalInstall, installerEnv, INSTALL_SCRIPT } = require('./helpers/install-shared.cjs');
const { cleanup } = require('./helpers.cjs');
const { PROBE_TIMEOUT_MS, INSTALL_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const {
toTildePosixPath,
buildAntigravityAllowRules,
@@ -225,7 +226,7 @@ test('UPGRADE 2: gsd-mcp-server companion is reachable — spawn, initialize, to
const res = spawnSync(process.execPath, [MCP_SERVER_BIN], {
input: stdin,
encoding: 'utf-8',
timeout: 15000,
timeout: PROBE_TIMEOUT_MS,
env: { ...process.env, GSD_TEST_MODE: '1' },
});
@@ -252,7 +253,7 @@ test('antigravity --global uninstall removes only GSD-owned permissions.allow ru
const args = [INSTALL_SCRIPT, '--antigravity', '--global', '--config-dir', root];
const installResult = runNode(args, {
env: installerEnv({ HOME: root, USERPROFILE: root }),
timeoutMs: 120000,
timeoutMs: INSTALL_TIMEOUT_MS,
});
assert.strictEqual(installResult.exitCode, 0, `install failed: ${installResult.stderr}`);
@@ -271,7 +272,7 @@ test('antigravity --global uninstall removes only GSD-owned permissions.allow ru
const uninstallArgs = [INSTALL_SCRIPT, '--antigravity', '--global', '--config-dir', root, '--uninstall'];
const uninstallResult = runNode(uninstallArgs, {
env: installerEnv({ HOME: root, USERPROFILE: root }),
timeoutMs: 120000,
timeoutMs: INSTALL_TIMEOUT_MS,
});
assert.strictEqual(uninstallResult.exitCode, 0, `uninstall failed: ${uninstallResult.stderr}`);

View File

@@ -25,6 +25,7 @@ const { runNode } = require('./helpers/process-seam.cjs');
const { runMinimalInstall, installerEnv, INSTALL_SCRIPT } = require('./helpers/install-shared.cjs');
const { cleanup } = require('./helpers.cjs');
const { INSTALL_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const {
mergeGsdMcpServerIntoSettings,
} = require('../bin/install.js');
@@ -169,7 +170,7 @@ test('augment --global: reinstalling does not duplicate or clobber the gsd MCP c
const args = [INSTALL_SCRIPT, '--augment', '--global', '--config-dir', root];
const env = installerEnv({ HOME: root, USERPROFILE: root });
const first = runNode(args, { env, timeoutMs: 120000 });
const first = runNode(args, { env, timeoutMs: INSTALL_TIMEOUT_MS });
assert.strictEqual(first.exitCode, 0, `first install failed: ${first.stderr}`);
const settingsPath = path.join(root, 'settings.json');
@@ -179,7 +180,7 @@ test('augment --global: reinstalling does not duplicate or clobber the gsd MCP c
afterFirst.mcpServers.gsd.args.push('--custom-flag');
fs.writeFileSync(settingsPath, JSON.stringify(afterFirst, null, 2) + '\n');
const second = runNode(args, { env, timeoutMs: 120000 });
const second = runNode(args, { env, timeoutMs: INSTALL_TIMEOUT_MS });
assert.strictEqual(second.exitCode, 0, `second install failed: ${second.stderr}`);
const afterSecond = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
@@ -203,7 +204,7 @@ test('augment --global: installing preserves a pre-existing unrelated mcpServers
const args = [INSTALL_SCRIPT, '--augment', '--global', '--config-dir', root];
const result = runNode(args, {
env: installerEnv({ HOME: root, USERPROFILE: root }),
timeoutMs: 120000,
timeoutMs: INSTALL_TIMEOUT_MS,
});
assert.strictEqual(result.exitCode, 0, `install failed: ${result.stderr}`);
@@ -223,7 +224,7 @@ test('augment --global uninstall removes only the GSD-owned mcpServers.gsd entry
const env = installerEnv({ HOME: root, USERPROFILE: root });
const installArgs = [INSTALL_SCRIPT, '--augment', '--global', '--config-dir', root];
const installResult = runNode(installArgs, { env, timeoutMs: 120000 });
const installResult = runNode(installArgs, { env, timeoutMs: INSTALL_TIMEOUT_MS });
assert.strictEqual(installResult.exitCode, 0, `install failed: ${installResult.stderr}`);
// Seed user-owned data alongside GSD's contributions, post-install.
@@ -233,7 +234,7 @@ test('augment --global uninstall removes only the GSD-owned mcpServers.gsd entry
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
const uninstallArgs = [INSTALL_SCRIPT, '--augment', '--global', '--config-dir', root, '--uninstall'];
const uninstallResult = runNode(uninstallArgs, { env, timeoutMs: 120000 });
const uninstallResult = runNode(uninstallArgs, { env, timeoutMs: INSTALL_TIMEOUT_MS });
assert.strictEqual(uninstallResult.exitCode, 0, `uninstall failed: ${uninstallResult.stderr}`);
const settingsAfter = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));

View File

@@ -33,6 +33,7 @@ const { execFileSync } = require('node:child_process');
const { createTempDir, cleanup } = require('./helpers.cjs');
const { runHook: runHookSeam } = require('./helpers/process-seam.cjs');
const { escapeRegex } = require('../gsd-core/bin/lib/pattern.cjs');
const { STAGED_HOOK_SCRIPT_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const HOOKS = path.join(__dirname, '..', 'hooks');
const SESSION_START = path.join(HOOKS, 'gsd-cursor-session-start.js');
@@ -54,7 +55,7 @@ function runHook(script, { cwd, payload }) {
const r = runHookSeam(script, [], {
cwd,
input: typeof payload === 'string' ? payload : JSON.stringify(payload),
timeoutMs: 20000,
timeoutMs: STAGED_HOOK_SCRIPT_TIMEOUT_MS,
});
return JSON.parse(r.stdout || '{}');
}
@@ -343,7 +344,7 @@ describe('#2587: cursor hooks resolve the workspace from workspace_roots, not cw
cwd: root,
input: JSON.stringify({ workspace_roots: [ws] }),
encoding: 'utf8',
timeout: 20000,
timeout: STAGED_HOOK_SCRIPT_TIMEOUT_MS,
}) || '{}');
assert.ok(
(out.additional_context || '').includes('STATE.md is present'),

View File

@@ -41,6 +41,7 @@ const fs = require('node:fs');
const path = require('node:path');
const os = require('node:os');
const { createTempDir, cleanup } = require('./helpers.cjs');
const { QUICK_SPAWN_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const {
GSD_CURSOR_HOOK_MARKER,
@@ -401,7 +402,7 @@ test('T17: gsd-cursor-session-start.js emits JSON with additional_context', (t,
const input = JSON.stringify({ session_id: 'test-123', composer_mode: 'agent' });
const child = execFile(process.execPath, [scriptPath], {
timeout: 10000,
timeout: QUICK_SPAWN_TIMEOUT_MS,
cwd: os.tmpdir(), // no .planning/ dir here — should get MSG_ABSENT
}, (err, stdout) => {
if (err && !stdout) { done(err); return; }
@@ -432,7 +433,7 @@ test('T18: gsd-cursor-post-tool.js emits {} for non-write tool names', (t, done)
});
const child = execFile(process.execPath, [scriptPath], {
timeout: 10000,
timeout: QUICK_SPAWN_TIMEOUT_MS,
cwd: os.tmpdir(),
}, (err, stdout) => {
if (err && !stdout) { done(err); return; }

View File

@@ -26,6 +26,7 @@ const { runNode } = require('./helpers/process-seam.cjs');
const { runMinimalInstall } = require('./helpers/install-shared.cjs');
const { cleanup } = require('./helpers.cjs');
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
// Absolute path to the built module, spawned in a child process below so the
// JSON `cmdEffortSync` writes straight to fd 1 (via io.cjs's writeAllSync) can
@@ -53,7 +54,7 @@ describe('#2071: effort sync runs in an installed runtime (no package-root bin/i
const gsdTools = path.join(configDir, 'gsd-core', 'bin', 'gsd-tools.cjs');
const result = runNode(
[gsdTools, 'effort', 'sync', '--config-dir', configDir],
{ cwd: root, env: { ...process.env, HOME: root }, timeoutMs: 15000 },
{ cwd: root, env: { ...process.env, HOME: root }, timeoutMs: PROBE_TIMEOUT_MS },
);
const combined = `${result.stdout || ''}${result.stderr || ''}`;

View File

@@ -33,7 +33,7 @@ const ROOT = path.join(__dirname, '..');
const INSTALL_JS = path.join(ROOT, 'bin', 'install.js');
// #3145: class-norm timeout, not a per-suite value — see helpers/timeouts.cjs.
const { BUILD_TIMEOUT_MS: BUILD_HOOKS_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const { BUILD_TIMEOUT_MS: BUILD_HOOKS_TIMEOUT_MS, INSTALL_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
// hooks/dist is gitignored + built; build it idempotently so a real install
// emits hooks (mirrors golden-install-parity / install-minimal-hooks).
@@ -64,7 +64,7 @@ function runInstaller(args, homeDir) {
'XDG_CONFIG_HOME', 'CODEX_CONFIG_DIR', 'OPENCODE_CONFIG_DIR', 'KILO_CONFIG_DIR',
]) delete env[k];
return spawnSync(process.execPath, [INSTALL_JS, ...args], {
cwd: homeDir, env, encoding: 'utf8', timeout: 120000,
cwd: homeDir, env, encoding: 'utf8', timeout: INSTALL_TIMEOUT_MS,
});
}
@@ -127,7 +127,7 @@ describe('#1928 --gemini CLI deprecation redirect', () => {
delete env.GSD_TEST_MODE;
delete env.CLAUDE_CONFIG_DIR;
const r = spawnSync(process.execPath, [INSTALL_JS, '--gemini', '--uninstall', '--global'], {
cwd: home, env, encoding: 'utf8', timeout: 120000,
cwd: home, env, encoding: 'utf8', timeout: INSTALL_TIMEOUT_MS,
});
assert.strictEqual(r.status, 1, 'must exit 1, not fall through to the uninstall dispatch');

View File

@@ -141,6 +141,24 @@ const QUICK_SPAWN_TIMEOUT_MS = 10000;
*/
const FIXTURE_HOOK_TIMEOUT_SECONDS = 5;
/**
* Spawning ONE already-staged or already-bundled hook script directly --
* never the full installer, never a fan-out across several hooks -- where
* the script does a modest amount of real work: a git-root check, a
* version-cache read/write, or an ESM-vs-CommonJS module load probe under a
* hostile config root. This is a distinct, heavier class than
* `QUICK_SPAWN_TIMEOUT_MS` (10000ms, trivial invocations with no real
* git/network work), since every site using this constant measurably does
* more than that. It is also distinct from `HOOK_FANOUT_TIMEOUT_MS`, which
* bounds a different class -- nested shell fan-out across MULTIPLE hooks,
* not a single script.
*
* Shared across 3 files in batch #4516 of the ad hoc timeout literal
* migration, epic #4445 -- that is why it lives here rather than as a
* file-local constant.
*/
const STAGED_HOOK_SCRIPT_TIMEOUT_MS = 20000;
module.exports = {
PROBE_TIMEOUT_MS,
HOOK_FANOUT_TIMEOUT_MS,
@@ -151,4 +169,5 @@ module.exports = {
SEAM_DEFAULT_TIMEOUT_MS,
QUICK_SPAWN_TIMEOUT_MS,
FIXTURE_HOOK_TIMEOUT_SECONDS,
STAGED_HOOK_SCRIPT_TIMEOUT_MS,
};

View File

@@ -19,6 +19,7 @@ const path = require('node:path');
const { execFileSync } = require('node:child_process');
const { createTempDir, cleanup } = require('./helpers.cjs');
const { runMinimalInstall } = require('./helpers/install-shared.cjs');
const { STAGED_HOOK_SCRIPT_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const COMMONJS_MARKER = '{"type":"commonjs"}\n';
@@ -82,7 +83,7 @@ describe('#2717 CommonJS marker for staged .js hooks', () => {
cwd: root,
input: stdinPayload,
encoding: 'utf8',
timeout: 20000,
timeout: STAGED_HOOK_SCRIPT_TIMEOUT_MS,
stdio: ['pipe', 'pipe', 'pipe'],
});
} catch (e) {

View File

@@ -33,6 +33,7 @@ const os = require('node:os');
const path = require('node:path');
const { spawnSync } = require('node:child_process');
const { runNode, runGit } = require('./helpers/process-seam.cjs');
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const { runMinimalInstall, BUILD_SCRIPT } = require('./helpers/install-shared.cjs');
const { cleanup } = require('./helpers.cjs');
@@ -206,7 +207,7 @@ test('UPGRADE 3: gsd-mcp-server companion is reachable — spawn, initialize, to
const res = spawnSync(process.execPath, [MCP_SERVER_BIN], {
input: stdin,
encoding: 'utf-8',
timeout: 15000,
timeout: PROBE_TIMEOUT_MS,
env: { ...process.env, GSD_TEST_MODE: '1' },
});

View File

@@ -40,6 +40,7 @@ const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { runNode } = require('./helpers/process-seam.cjs');
const { INSTALL_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const { runMinimalInstall, INSTALL_SCRIPT, installerEnv } = require('./helpers/install-shared.cjs');
const { cleanup, createTempDir, toPosixPath } = require('./helpers.cjs');
@@ -148,7 +149,7 @@ test('kimi --global: reinstalling is idempotent — the GSD [[hooks]] block is n
const reinstall = runNode([INSTALL_SCRIPT, '--kimi', '--global', '--config-dir', root], {
cwd: process.cwd(),
env: installerEnv({ HOME: root, USERPROFILE: root }),
timeoutMs: 120000,
timeoutMs: INSTALL_TIMEOUT_MS,
});
assert.strictEqual(reinstall.exitCode, 0,
`reinstall exited with status ${reinstall.exitCode}\nstdout: ${reinstall.stdout}\nstderr: ${reinstall.stderr}`);

View File

@@ -12,6 +12,7 @@ const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { cleanup } = require('./helpers.cjs');
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const INSTALL_JS = path.join(__dirname, '..', 'bin', 'install.js');
@@ -29,7 +30,7 @@ function runInstall(args, home) {
const r = spawnSync('node', [INSTALL_JS, ...args], {
env: { ...process.env, HOME: home, USERPROFILE: home, GSD_TEST_MODE: '1' },
encoding: 'utf8',
timeout: 15000,
timeout: PROBE_TIMEOUT_MS,
});
return { stdout: r.stdout || '', stderr: r.stderr || '', exit: r.status };
}

View File

@@ -26,6 +26,7 @@ const fs = require('node:fs');
const path = require('node:path');
const os = require('os');
const { cleanup } = require('./helpers.cjs');
const { INSTALL_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const ADAPTER_SRC = path.join(__dirname, '..', '.opencode', 'plugins', 'gsd-core.js');
@@ -436,7 +437,7 @@ test('installer copies plugin as .js, records it in the manifest, and removes it
const run = (args) => {
const result = runNode([installer, '--opencode', '--global', '--config-dir', cfg, ...args], {
timeoutMs: 120000,
timeoutMs: INSTALL_TIMEOUT_MS,
// #3156: sandbox HOME — the installer writes <home>/.gsd/defaults.json via
// os.homedir() directly, which no env scrub can reach. See installSpawnEnv.
env: require('./helpers.cjs').installSpawnEnv(),

View File

@@ -41,9 +41,17 @@ const path = require('node:path');
const { runNode, OUTCOME } = require('./helpers/process-seam.cjs');
const { createTempDir, cleanup } = require('./helpers.cjs');
const { copyScriptWithDeps } = require('./helpers/copy-script-fixture.cjs');
const { STAGED_HOOK_SCRIPT_TIMEOUT_MS, QUICK_SPAWN_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const REPO_ROOT = path.join(__dirname, '..');
// Bounds a single `driver.cjs` process sweeping many fast-check
// property-based cases in-process against a stubbed registry; digits
// coincide with the shared HOOK_FANOUT_TIMEOUT_MS/SEAM_DEFAULT_TIMEOUT_MS
// constants but this is neither a hook fan-out nor an omitted-default seam
// call, so kept as its own constant.
const PROPERTY_DRIVER_TIMEOUT_MS = 60000;
// Requiring the installer (not as main) never runs the CLI — matches the
// existing tests/claude-imperative-reference.test.cjs convention.
const installMod = require('../bin/install.js');
@@ -282,7 +290,7 @@ describe('GROUP A.2: resolveSharedHooksDirName — malformed/hostile values + pr
UNDEFINED_SENTINEL,
CASES_JSON: JSON.stringify(ALL_SINGLE_CASES),
},
timeoutMs: 60000,
timeoutMs: PROPERTY_DRIVER_TIMEOUT_MS,
});
assert.equal(result.outcome, OUTCOME.EXITED, `driver did not exit cleanly: ${JSON.stringify(result)}`);
@@ -567,7 +575,7 @@ describe('GROUP C: bundle-directory-name-agnostic hook scripts', () => {
GSD_GLOBAL_VERSION_FILE: '',
GSD_CACHE_FILE: cacheFile,
},
timeoutMs: 20000,
timeoutMs: STAGED_HOOK_SCRIPT_TIMEOUT_MS,
},
);
@@ -632,7 +640,7 @@ describe('GROUP C: bundle-directory-name-agnostic hook scripts', () => {
tool_response: { content: injectionContent },
});
const excludedResult = runNode([scannerPath], { input: excludedPayload, timeoutMs: 10000 });
const excludedResult = runNode([scannerPath], { input: excludedPayload, timeoutMs: QUICK_SPAWN_TIMEOUT_MS });
assert.equal(excludedResult.outcome, OUTCOME.EXITED);
assert.equal(excludedResult.exitCode, 0);
assert.equal(
@@ -641,7 +649,7 @@ describe('GROUP C: bundle-directory-name-agnostic hook scripts', () => {
"a path under the scanner's own bundle directory must be excluded (no PostToolUse output at all)",
);
const controlResult = runNode([scannerPath], { input: controlPayload, timeoutMs: 10000 });
const controlResult = runNode([scannerPath], { input: controlPayload, timeoutMs: QUICK_SPAWN_TIMEOUT_MS });
assert.equal(controlResult.outcome, OUTCOME.EXITED);
assert.equal(controlResult.exitCode, 0);
assert.notEqual(

View File

@@ -46,6 +46,7 @@ const path = require('node:path');
const os = require('node:os');
const { runHook: runHookSeam } = require('./helpers/process-seam.cjs');
const { gitOrThrow } = require('./helpers/git-fixture.cjs');
const { QUICK_SPAWN_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
const { createTempDir, cleanup } = require('./helpers.cjs');
@@ -69,7 +70,7 @@ function runHook(scriptPath, payload, opts = {}) {
const input = payload === undefined ? '' : (typeof payload === 'string' ? payload : JSON.stringify(payload));
const r = runHookSeam(scriptPath, [], {
input,
timeoutMs: 10000,
timeoutMs: QUICK_SPAWN_TIMEOUT_MS,
cwd: opts.cwd || os.tmpdir(),
});
return { status: r.exitCode, stdout: r.stdout, stderr: r.stderr, signal: r.signal };