refactor(#1679): ADR-1239 Phase B — collapse is<Runtime> flag blocks into runtimeFlags [AC2 slice 3] (#1811)

* refactor(#1679): ADR-1239 Phase B — collapse is<Runtime> flag blocks into runtimeFlags [AC2 slice 3]

Phase 2 AC2 slice 3. Collapses the four duplicated 'const isX = runtime === x'
declaration blocks in bin/install.js (uninstall / writeManifest / install / a
fourth helper — 48 of the 101 remaining runtime=== branches) into a single
runtimeFlags(runtime) helper in src/runtime-name-policy.cts, sibling to
getDirName / getRuntimeLabel / getGlobalConfigHomeFragment.

The purest add-a-host tax: a new runtime meant remembering to add ~12 flag lines
to each of four functions. Now it is one entry in RUNTIME_FLAG_IDS.

- src/runtime-name-policy.cts: RUNTIME_FLAG_IDS + runtimeFlags(runtime) -> frozen
  map of is<Runtime> booleans (single runtime=== source, via loop).
- bin/install.js: import runtimeFlags; replace the 4 declaration blocks with one
  destructure each. ZERO usage-site churn (flag names preserved; install.js's
  eslint block has no no-unused-vars rule so destructure-all is clean).
- tests/runtime-flags.test.cjs: 4 tests (each runtime sets exactly its flag,
  claude/unknown/empty -> all false, all 15 flags present + frozen, drift guard).

runtime === count: 101 -> 53 (-48). golden-install-parity 16/16 byte-identical
(behavior-identical collapse). AC2 data-collapse now substantially complete;
ADR-1235 agent-loop tail + per-runtime semantic residue remain (separate).

* chore(changeset): add Changed fragment for runtimeFlags collapse (#1679)
This commit is contained in:
Tom Boucher
2026-06-28 14:59:29 -04:00
committed by GitHub
parent 41193a44bd
commit f954bb4cac
4 changed files with 93 additions and 49 deletions

View File

@@ -257,3 +257,30 @@ export function getGlobalConfigHomeFragment(runtime: string): string {
const frag = GLOBAL_CONFIG_HOME_FRAGMENTS[runtime];
return typeof frag === 'string' && frag.length > 0 ? frag : DEFAULT_CONFIG_HOME_FRAGMENT;
}
/**
* The runtime ids for which `bin/install.js` needs an `is<Runtime>` boolean
* predicate (every installed host that takes a non-claude install branch).
* Single source of truth — adding a runtime is one entry here, not a per-
* function declaration block (the add-a-host tax ADR-1239 Phase B / #1679 AC2
* removes).
*/
const RUNTIME_FLAG_IDS = Object.freeze([
'opencode', 'kilo', 'gemini', 'codex', 'copilot', 'antigravity', 'cursor',
'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'kimi',
] as const);
/**
* Return a frozen map of `is<Runtime>` boolean predicates for the given runtime
* id (e.g. `flags.isOpencode`). Collapses the four duplicated `const isX =
* runtime === 'x'` declaration blocks that lived in `bin/install.js`'s
* `uninstall`/`writeManifest`/`install`/etc. into one helper (sibling to
* `getDirName`/`getRuntimeLabel`). Pure: no I/O.
*/
export function runtimeFlags(runtime: string): Readonly<Record<string, boolean>> {
const flags: Record<string, boolean> = {};
for (const id of RUNTIME_FLAG_IDS) {
flags['is' + id.charAt(0).toUpperCase() + id.slice(1)] = runtime === id;
}
return Object.freeze(flags);
}