#!/usr/bin/env node // tools/scripts/lint-atlas-hash.mjs // [impl->REQ-MAP-02] // TODO Phase 8: swap tag to [impl->REQ-MAP-01]; activate real hash compare against apps/client/public/atlas-mvp.png. // // Phase 7 stub. When Phase 8 lands TestBed_001.ldtk and the real atlas, // this script will assert no .ldtk under maps/ declares a tilesetSourceHash // mismatching sha256(referenced PNG). For now it no-ops when maps/ is empty // or only contains _smoke/ artifacts (Plan 07-07 smoke files). // // Usage: node tools/scripts/lint-atlas-hash.mjs // Exit: 0 (stub never fails in Phase 7); Phase 8 swap may add exit 1 on mismatch. import { readdirSync, existsSync, readFileSync, statSync } from 'node:fs'; import { createHash } from 'node:crypto'; import { join } from 'node:path'; const MAPS_DIR = 'maps'; if (!existsSync(MAPS_DIR)) { console.log('lint-atlas-hash: OK (maps/ does not exist yet — Phase 7 baseline)'); process.exit(0); } function findLdtk(dir, out = []) { for (const f of readdirSync(dir)) { const p = join(dir, f); const s = statSync(p); if (s.isDirectory()) findLdtk(p, out); else if (p.endsWith('.ldtk')) out.push(p); } return out; } const ldtkFiles = findLdtk(MAPS_DIR).filter((p) => !p.includes('_smoke')); if (ldtkFiles.length === 0) { console.log('lint-atlas-hash: OK (no production .ldtk files yet — Phase 8 will activate)'); process.exit(0); } // PITFALL 4 (07-PATTERNS.md): noisy log on every preflight run when production // .ldtk files exist but the real check is not yet wired — annoying-enough-to-notice. console.log(`lint-atlas-hash: Phase 8 logic not yet wired — ${ldtkFiles.length} file(s) found, deferred`); process.exit(0);