needsFixing
What needs fixing on this branch, worked out rather than taken from what was recorded: a definition that couldn't
follow a change (its record, Store.todos, says why) needs fixing only while it's named and still uses a version
something newer replaced, or uses another that needs fixing. So nothing's left over when a branch goes back to what
it was (tcm reset, a merge undone), however the records got there.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; export function needsFixing(cb: Codebase): { hash: string; message: string }[] { const recorded = cb.store.todos(); if (!recorded.length) return []; const live = cb.liveHashes(); const named = new Set(cb.store.names(undefined, true).map((r) => r.hash)); const why = new Map( recorded.filter((t) => live.has(t.hash) && named.has(t.hash)).map((t) => [t.hash, t]), ); const uses = (h: string) => (cb.store.getDef(h)?.deps ?? []) .filter((d) => d.ref.startsWith("#")) .map((d) => d.ref.slice(1)); // (a version something newer replaced: not named, and patched to what replaced it) const behind = (h: string) => !named.has(h) && cb.store.patched(h) !== h; const broken = new Set([...why.keys()].filter((h) => uses(h).some(behind))); for (let grew = true; grew;) { grew = false; for (const h of why.keys()) if (!broken.has(h) && uses(h).some((u) => broken.has(u))) { broken.add(h); grew = true; } } return [...broken].map((h) => why.get(h)!); }