Files
Codeman/test/mocks/test-helpers.ts
T
Codeman maintainer f604deba3e chore: remove backend code nothing references
Found with knip (exports, types, class members) and confirmed by a text
search of src, test, scripts and packages before each removal.

- Per-CLI get<Cli>NotFoundMessage() (nine of them) with their message
  constants: missingCliMessage() builds that text from the registry now.
- Registry leftovers: renderCliCommand, asCliId, cliIds, isCliRunnable,
  createCliResolverForTest, profileExists, and two name lists that only
  repeated schema enums.
- A task-description cache in Session that was written on every chunk of
  terminal output (one regex pass per line) and never read since the
  subagent watcher takes descriptions from transcripts. The cache module,
  its pattern and both parse methods go with it.
- Session.parentAgentId / childAgentIds: never set by anything, so the two
  optional SessionState fields were never on the wire.
- Unreferenced methods on TmuxManager (pipe-pane pair, syncMouseMode),
  RespawnController, StateStore.recoverFromBackup (load() already falls
  back to the .bak file), TeamWatcher, SseStreamManager and the AI
  checkers' getErrorVerdict.
- updateCaseEnvVars: the settings.local.json env path that envOverrides
  replaced.
- Re-exports in the utils, cli-registry, routes and prompts barrels that
  no importer used, and unused test helpers (MockStateStore, the mobile
  throttle helpers and others).

Eight mobile tests imported the WebServer type from a path that does not
exist (../src instead of ../../src); type-only, so nothing failed.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-13 13:58:22 +01:00

75 lines
3.4 KiB
TypeScript

/**
* Guards for tests that delete under the throwaway HOME.
*/
import { rmSync } from 'node:fs';
import { basename, resolve } from 'node:path';
/**
* Prefix of the throwaway HOME `test/setup.ts` creates (`mkdtempSync(join(tmpdir(), 'codeman-vitest-'))`).
* Pinned by test/test-env-isolation.test.ts, so renaming one without the other fails there.
*/
export const TEST_HOME_PREFIX = 'codeman-vitest-';
/**
* True only when `process.env.HOME` is the throwaway directory `test/setup.ts` made.
*
* ⚠️ This is what the helpers below hang on, and it exists because "is the path under HOME"
* is a vacuous question when setup never ran: a bare `vitest` invocation has no setupFiles,
* HOME is the developer's REAL home, and every real file is then "under the test HOME". That is
* how a bare run on 2026-10-10 deleted the real linked-cases registry through a guard that was
* written to prevent exactly that. The temp directory's name is the only thing a real home
* cannot have.
*/
export function isSandboxedHome(): boolean {
const home = process.env.HOME;
return !!home && basename(resolve(home)).startsWith(TEST_HOME_PREFIX);
}
/**
* Throw unless the suite is running under `test/setup.ts`'s temp HOME. The shared route harness
* (`createRouteTestHarness`) calls this, so a route test built on it refuses to start against a real
* `~/.codeman`. A route test that builds its own app from `createMockRouteContext` is not covered.
*/
export function assertSandboxedHome(what = 'this test'): void {
if (!isSandboxedHome()) {
throw new Error(
`${what} reads and writes Codeman's data files and must run under test/setup.ts's temp HOME ` +
`(HOME=${process.env.HOME ?? '(unset)'}). Run it with \`npm test\` or ` +
`\`npx vitest run --config config/vitest.ci.config.ts <file>\`, never with a bare vitest.`
);
}
}
/**
* Delete a directory tree, but ONLY when it lives inside the test HOME.
*
* SAFETY (2026-08-29, tightened 2026-10-12): `test/setup.ts` redirects `process.env.HOME` to a
* throwaway dir and `os.homedir()` follows it, so a `rmSync(CASES_DIR, recursive)` normally
* lands inside the fixture. This gate is defense in depth for the day that stops being true
* (a test that runs outside setup.ts, an env override that anchors a path elsewhere): it
* refuses to delete anything unless HOME IS the throwaway dir ({@link isSandboxedHome}) and the
* target is under it, so the failure mode is a leftover temp dir rather than a deleted
* PRODUCTION `~/codeman-cases`. The first version only checked "under HOME", which a run
* without setup.ts satisfied for the user's real home.
* Lexical `resolve()` is used because the leaf often does not exist and
* `realpathSync` would throw.
*/
export function safeRmHomeTree(path: string): void {
if (!isUnderTestHome(path)) return;
rmSync(resolve(path), { recursive: true, force: true });
}
/**
* True when `path` resolves strictly inside the throwaway test HOME (or to it), and false
* whenever HOME is anything else. Same rationale as `safeRmHomeTree`; use for guarded
* non-recursive deletes (single files like `linked-cases.json`) so they can never touch
* prod state.
*/
export function isUnderTestHome(path: string): boolean {
if (!isSandboxedHome()) return false;
const root = resolve(process.env.HOME as string);
const target = resolve(path);
return target === root || target.startsWith(root + '/');
}