diff --git a/scripts/eval-compare.ts b/scripts/eval-compare.ts index a7b0dba03..30bc3864e 100644 --- a/scripts/eval-compare.ts +++ b/scripts/eval-compare.ts @@ -1,6 +1,7 @@ #!/usr/bin/env bun /** - * Compare two eval runs from ~/.gstack-dev/evals/ + * Compare two eval runs from the project eval dir (~/.gstack/projects//evals; + * legacy fallback ~/.gstack-dev/evals) * * Usage: * bun run eval:compare # compare two most recent of same tier diff --git a/scripts/eval-list.ts b/scripts/eval-list.ts index bb4ee9a83..38c14e7f2 100644 --- a/scripts/eval-list.ts +++ b/scripts/eval-list.ts @@ -1,6 +1,7 @@ #!/usr/bin/env bun /** - * List eval runs from ~/.gstack-dev/evals/ + * List eval runs from the project eval dir (~/.gstack/projects//evals; + * legacy fallback ~/.gstack-dev/evals) * * Usage: bun run eval:list [--branch ] [--tier e2e|llm-judge] [--limit N] */ diff --git a/scripts/eval-summary.ts b/scripts/eval-summary.ts index a3b8d8bc6..5122b165d 100644 --- a/scripts/eval-summary.ts +++ b/scripts/eval-summary.ts @@ -1,6 +1,7 @@ #!/usr/bin/env bun /** - * Aggregate summary of all eval runs from ~/.gstack-dev/evals/ + * Aggregate summary of eval runs from the project eval dir + * (~/.gstack/projects//evals; legacy fallback ~/.gstack-dev/evals) * * Usage: bun run eval:summary */ diff --git a/scripts/eval-watch.ts b/scripts/eval-watch.ts index ba96faf4b..1b5a0d2ad 100644 --- a/scripts/eval-watch.ts +++ b/scripts/eval-watch.ts @@ -11,10 +11,19 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; +import { getProjectEvalDir } from '../test/helpers/eval-store'; const GSTACK_DEV_DIR = path.join(os.homedir(), '.gstack-dev'); +// Heartbeat + per-run progress logs are GLOBAL by design — session-runner.ts +// writes ~/.gstack-dev/e2e-live.json regardless of project ("heartbeat stays +// global"). The PARTIAL file is per-project: EvalCollector writes it into +// getProjectEvalDir() (or GSTACK_EVAL_DIR), so watching the legacy global +// path missed it whenever slug detection succeeded — i.e. the normal case. const HEARTBEAT_PATH = path.join(GSTACK_DEV_DIR, 'e2e-live.json'); -const PARTIAL_PATH = path.join(GSTACK_DEV_DIR, 'evals', '_partial-e2e.json'); +const PARTIAL_PATH = path.join( + process.env.GSTACK_EVAL_DIR || getProjectEvalDir(), + '_partial-e2e.json', +); const STALE_THRESHOLD_SEC = 600; // 10 minutes export interface HeartbeatData { diff --git a/test/helpers/claude-pty-runner.ts b/test/helpers/claude-pty-runner.ts index 669dacb48..ea8a46ea1 100644 --- a/test/helpers/claude-pty-runner.ts +++ b/test/helpers/claude-pty-runner.ts @@ -454,8 +454,11 @@ ${tail} }; try { + // Use the same binary resolution as every PTY launch in this file — + // judgePtyState previously hardcoded bare 'claude' three definitions + // below resolveClaudeBinary(), breaking under hermetic PATHs. const result = nodeSpawnSync( - 'claude', + resolveClaudeBinary() ?? 'claude', ['-p', '--model', 'claude-haiku-4-5', '--max-turns', '1'], { input: prompt,