retired-command.ts
49 lines · scripts/retired-command.ts at 3f79d81
1#!/usr/bin/env -S bun --no-env-file --config=/dev/null
2/**
3 * One-release stubs for retired package scripts. Each retired name in
4 * package.json runs `bun run scripts/retired-command.ts <name>`, which prints
5 * the replacement and exits 1, so an old command in an agent's memory or a
6 * stale doc fails loudly instead of running zero cases or the wrong lane.
7 *
8 * CONTRIBUTING.md "Retired commands" carries the same table. TODOS.md
9 * "Remove one-release command stubs" deletes this file and the stub entries
10 * in the next release.
11 */
13export interface RetiredCommand {
14 replacement: string;
15 reason: string;
16}
18export const RETIRED_COMMANDS: Record<string, RetiredCommand> = {
19 'test:evals': { replacement: 'bun run eval:bg:pr', reason: 'tierless run skipped every tier-gated paid file' },
20 'test:evals:all': { replacement: 'bun run eval:bg:release', reason: 'tierless run skipped every tier-gated paid file' },
21 'test:e2e': { replacement: 'bun run eval:bg:pr', reason: 'tierless run skipped every tier-gated paid file' },
22 'test:e2e:all': { replacement: 'bun run eval:bg:release', reason: 'tierless run skipped every tier-gated paid file' },
23 'test:gate': { replacement: 'bun run test:gate:sharded', reason: 'the single-process fan-out never completed a run' },
24 'test:periodic': { replacement: 'bun run test:periodic:sharded', reason: 'the single-process fan-out never completed a run' },
25 'test:codex': { replacement: 'bun run test:periodic:sharded', reason: 'it set no EVALS_TIER, so both periodic-tier Codex files ran zero cases' },
26 'test:codex:all': { replacement: 'bun run test:periodic:sharded', reason: 'it set no EVALS_TIER, so both periodic-tier Codex files ran zero cases' },
27 'eval:bg': { replacement: 'bun run eval:bg:pr', reason: 'it detached the retired tierless test:evals' },
28 'eval:bg:all': { replacement: 'bun run eval:bg:release', reason: 'it detached the retired tierless test:evals:all' },
29 'eval:flake-rank': { replacement: 'bun run eval:pass-rates', reason: 'it was a second name for the same script' },
30 'eval:watch': { replacement: 'tail the gstack-detach log under ~/.gstack-dev/eval-runs/, or `gh run watch <run-id>` for a CI run', reason: 'it read a file only the unsharded runner wrote, so it showed nothing for sharded runs' },
31 'test:audit': { replacement: 'bun run test', reason: 'test/audit-compliance.test.ts already runs in the free suite' },
32};
34export function retiredMessage(name: string): string | null {
35 const entry = RETIRED_COMMANDS[name];
36 if (!entry) return null;
37 return `\`bun run ${name}\` is retired (${entry.reason}).\nUse instead: ${entry.replacement}\nSee CONTRIBUTING.md "Retired commands" for the full table.`;
38}
40if (import.meta.main) {
41 const name = process.argv[2] ?? '';
42 const message = retiredMessage(name);
43 if (!message) {
44 console.error(`retired-command: unknown name "${name}". Known: ${Object.keys(RETIRED_COMMANDS).join(', ')}`);
45 process.exit(2);
46 }
47 console.error(message);
48 process.exit(1);
49}