/** * * Purpose: enforce the peaks-qa SKILL.md "Hard contracts for browser * validation" Contract 1 — every Playwright screenshot MUST land under * `.peaks/_runtime//qa/screenshots/`, not at the project * root. When the LLM forgets to pass `filename` to * `browser_take_screenshot`, Playwright MCP writes to the current * working directory (typically the project root), which scatters * `.png` files at the repo top level. This service is the * remediation: scan a directory, move stray screenshot files into * the canonical screenshots/ subdir under the active QA scope. * * CLI surface (peaks qa archive-screenshots): * peaks qa archive-screenshots [--source ] [--project ] * * Behavior: * - Scan `--source` for *.png / *.jpg / *.jpeg files (case-insensitive * extension match). Recurse exactly 1 level deep — the project * root plus one subdir (covers `./foo.png` + `./screenshots/*.png`). * Avoid recursing into `.peaks/` or `node_modules/` (artifact dirs). * - Auto-create `.peaks/_runtime//qa/screenshots/` if * missing (mkdirSync recursive, mode 0o755). * - For each stray file: `fs.renameSync(src, dst)`. If `dst` exists * (filename collision across multiple invocations), suffix with * `-` so the move is non-destructive. * - Return JSON envelope with moved list + skipped list + final * screenshots/ dir contents. */ export type ScreenshotExtension = '.png' | '.jpg' | '.jpeg'; export interface ArchiveScreenshotOptions { readonly sourceDir: string; readonly targetDir: string; readonly now?: Date; } export interface ArchiveScreenshotEnvelope { readonly scannedSource: string; readonly targetDir: string; readonly moved: readonly { readonly from: string; readonly to: string; }[]; readonly skipped: readonly { readonly path: string; readonly reason: string; }[]; readonly targetContentsBefore: readonly string[]; readonly targetContentsAfter: readonly string[]; readonly archivedAt: string; } export declare function archiveScreenshots(options: ArchiveScreenshotOptions): ArchiveScreenshotEnvelope;