@ncoderz/awa 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts","../src/_generated/package_info.ts","../src/core/check/code-spec-checker.ts","../src/core/check/marker-scanner.ts","../src/core/check/glob.ts","../src/core/check/reporter.ts","../src/core/check/rule-loader.ts","../src/core/check/schema-checker.ts","../src/core/check/spec-parser.ts","../src/core/check/spec-spec-checker.ts","../src/core/check/types.ts","../src/commands/check.ts","../src/commands/diff.ts","../src/core/batch-runner.ts","../src/core/differ.ts","../src/core/delete-list.ts","../src/core/generator.ts","../src/core/resolver.ts","../src/core/template.ts","../src/core/feature-resolver.ts","../src/core/json-output.ts","../src/core/overlay.ts","../src/core/template-resolver.ts","../src/utils/file-watcher.ts","../src/utils/debouncer.ts","../src/commands/features.ts","../src/core/features/reporter.ts","../src/core/features/scanner.ts","../src/commands/generate.ts","../src/commands/test.ts","../src/core/template-test/fixture-loader.ts","../src/core/template-test/reporter.ts","../src/core/template-test/runner.ts","../src/core/template-test/snapshot.ts","../src/utils/update-check.ts","../src/utils/update-check-cache.ts"],"sourcesContent":["// @awa-component: CLI-ArgumentParser\n// @awa-impl: CLI-1_AC-1\n// @awa-impl: CLI-1_AC-2\n// @awa-impl: CLI-1_AC-3\n// @awa-impl: CLI-1_AC-4\n// @awa-impl: CLI-1_AC-5\n// @awa-impl: CLI-2_AC-1\n// @awa-impl: CLI-2_AC-2\n// @awa-impl: CLI-2_AC-3\n// @awa-impl: CLI-2_AC-5\n// @awa-impl: CLI-2_AC-6\n// @awa-impl: CLI-3_AC-1\n// @awa-impl: CLI-4_AC-1\n// @awa-impl: CLI-4_AC-2\n// @awa-impl: CLI-5_AC-1\n// @awa-impl: CLI-6_AC-1\n// @awa-impl: CLI-7_AC-1\n// @awa-impl: CLI-8_AC-1\n// @awa-impl: CLI-9_AC-1\n// @awa-impl: CLI-9_AC-2\n// @awa-impl: CLI-9_AC-3\n// @awa-impl: CLI-10_AC-1\n// @awa-impl: CLI-10_AC-2\n// @awa-impl: CLI-11_AC-1\n// @awa-impl: CLI-11_AC-2\n// @awa-impl: CLI-11_AC-3\n// @awa-impl: CFG-5_AC-2\n// @awa-impl: DIFF-7_AC-1\n// @awa-impl: DIFF-7_AC-2\n// @awa-impl: DIFF-7_AC-3\n// @awa-impl: DIFF-7_AC-4\n// @awa-impl: DIFF-7_AC-5\n// @awa-impl: DIFF-7_AC-6\n// @awa-impl: DIFF-7_AC-7\n// @awa-impl: DIFF-7_AC-8\n// @awa-impl: DIFF-7_AC-9\n// @awa-impl: DIFF-7_AC-10\n// @awa-impl: DIFF-7_AC-11\n// @awa-impl: FP-2_AC-1\n// @awa-impl: FP-2_AC-2\n// @awa-impl: FP-2_AC-4\n// @awa-impl: FP-4_AC-1\n// @awa-impl: FP-4_AC-2\n// @awa-impl: FP-4_AC-3\n// @awa-impl: FP-4_AC-5\n// @awa-impl: GEN-10_AC-1\n// @awa-impl: GEN-10_AC-2\n// @awa-impl: INIT-1_AC-1\n// @awa-impl: INIT-2_AC-1\n// @awa-impl: INIT-3_AC-1\n// @awa-impl: INIT-4_AC-1\n\nimport { Command } from 'commander';\nimport { PACKAGE_INFO } from '../_generated/package_info.js';\nimport { checkCommand } from '../commands/check.js';\nimport { diffCommand } from '../commands/diff.js';\nimport { featuresCommand } from '../commands/features.js';\nimport { generateCommand } from '../commands/generate.js';\nimport { testCommand } from '../commands/test.js';\nimport type { RawCheckOptions } from '../core/check/types.js';\nimport type { RawTestOptions } from '../core/template-test/types.js';\nimport type { RawCliOptions } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\nimport {\n checkForUpdate,\n printUpdateWarning,\n type UpdateCheckResult,\n} from '../utils/update-check.js';\nimport { shouldCheck, writeCache } from '../utils/update-check-cache.js';\n\nconst version = PACKAGE_INFO.version;\n\n// @awa-impl: CLI-1_AC-2, CLI-9_AC-1, CLI-9_AC-2, CLI-9_AC-3, CLI-10_AC-1, CLI-10_AC-2\nconst program = new Command();\n\nprogram\n .name('awa')\n .description('awa - tool for generating AI coding agent configuration files')\n .version(version, '-v, --version', 'Display version number');\n\n// @awa-impl: CLI-1_AC-1, CLI-1_AC-2, CLI-1_AC-3, CLI-1_AC-4, CLI-1_AC-5\n// @awa-impl: INIT-1_AC-1, INIT-2_AC-1, INIT-3_AC-1, INIT-4_AC-1\nprogram\n .command('generate')\n .alias('init')\n .description('Generate AI agent configuration files from templates')\n // @awa-impl: CLI-2_AC-1, CLI-2_AC-5, CLI-2_AC-6\n .argument('[output]', 'Output directory (optional if specified in config)')\n // @awa-impl: CLI-3_AC-1\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n // @awa-impl: CLI-4_AC-1, CLI-4_AC-2\n .option('-f, --features <flag...>', 'Feature flags (can be specified multiple times)')\n .option('--preset <name...>', 'Preset names to enable (can be specified multiple times)')\n .option(\n '--remove-features <flag...>',\n 'Feature flags to remove (can be specified multiple times)'\n )\n // @awa-impl: CLI-5_AC-1\n .option('--force', 'Force overwrite existing files without prompting', false)\n // @awa-impl: CLI-6_AC-1\n .option('--dry-run', 'Preview changes without modifying files', false)\n .option(\n '--delete',\n 'Enable deletion of files listed in the delete list (default: warn only)',\n false\n )\n // @awa-impl: CLI-7_AC-1\n .option('-c, --config <path>', 'Path to configuration file')\n // @awa-impl: CLI-8_AC-1\n .option('--refresh', 'Force refresh of cached Git templates', false)\n .option('--all', 'Process all named targets from config', false)\n .option('--target <name>', 'Process a specific named target from config')\n // @awa-impl: OVL-1_AC-1\n .option('--overlay <path...>', 'Overlay directory paths applied over base template (repeatable)')\n // @awa-impl: JSON-1_AC-1\n .option('--json', 'Output results as JSON (implies --dry-run)', false)\n // @awa-impl: JSON-5_AC-1\n .option('--summary', 'Output compact one-line summary', false)\n .action(async (output: string | undefined, options) => {\n // @awa-impl: CLI-11_AC-1, CLI-11_AC-2, CLI-11_AC-3\n const cliOptions: RawCliOptions = {\n output,\n template: options.template,\n features: options.features,\n preset: options.preset,\n removeFeatures: options.removeFeatures,\n force: options.force,\n dryRun: options.dryRun,\n delete: options.delete,\n config: options.config,\n refresh: options.refresh,\n all: options.all,\n target: options.target,\n overlay: options.overlay || [],\n json: options.json,\n summary: options.summary,\n };\n\n await generateCommand(cliOptions);\n });\n\n// @awa-impl: DIFF-7_AC-1, DIFF-7_AC-2, DIFF-7_AC-3, DIFF-7_AC-4, DIFF-7_AC-5, DIFF-7_AC-6, DIFF-7_AC-7, DIFF-7_AC-8, DIFF-7_AC-9, DIFF-7_AC-10\nprogram\n .command('diff')\n .description('Compare template output with existing target directory')\n // @awa-impl: DIFF-7_AC-1, DIFF-7_AC-2, DIFF-7_AC-3, DIFF-7_AC-4, DIFF-7_AC-5\n .argument('[target]', 'Target directory to compare against (optional if specified in config)')\n // @awa-impl: DIFF-7_AC-6\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n // @awa-impl: DIFF-7_AC-7\n .option('-f, --features <flag...>', 'Feature flags (can be specified multiple times)')\n .option('--preset <name...>', 'Preset names to enable (can be specified multiple times)')\n .option(\n '--remove-features <flag...>',\n 'Feature flags to remove (can be specified multiple times)'\n )\n // @awa-impl: DIFF-7_AC-8\n .option('-c, --config <path>', 'Path to configuration file')\n // @awa-impl: DIFF-7_AC-9\n .option('--refresh', 'Force refresh of cached Git templates', false)\n // @awa-impl: DIFF-7_AC-11\n .option('--list-unknown', 'Include target-only files in diff results', false)\n .option('--all', 'Process all named targets from config', false)\n .option('--target <name>', 'Process a specific named target from config')\n .option('-w, --watch', 'Watch template directory for changes and re-run diff', false)\n // @awa-impl: OVL-7_AC-1\n .option('--overlay <path...>', 'Overlay directory paths applied over base template (repeatable)')\n // @awa-impl: JSON-2_AC-1\n .option('--json', 'Output results as JSON', false)\n // @awa-impl: JSON-5_AC-1\n .option('--summary', 'Output compact one-line summary', false)\n // @awa-impl: DIFF-7_AC-10\n // Note: --force and --dry-run are intentionally NOT accepted for diff command\n .action(async (target: string | undefined, options) => {\n const cliOptions: RawCliOptions = {\n output: target, // Use target as output for consistency\n template: options.template,\n features: options.features,\n preset: options.preset,\n removeFeatures: options.removeFeatures,\n config: options.config,\n refresh: options.refresh,\n listUnknown: options.listUnknown,\n all: options.all,\n target: options.target,\n watch: options.watch,\n overlay: options.overlay || [],\n json: options.json,\n summary: options.summary,\n };\n\n const exitCode = await diffCommand(cliOptions);\n process.exit(exitCode);\n });\n\n// @awa-impl: CHK-8_AC-1, CHK-9_AC-1, CHK-10_AC-1\nprogram\n .command('check')\n .description(\n 'Validate spec files against schemas and check traceability between code markers and specs'\n )\n .option('-c, --config <path>', 'Path to configuration file')\n // @awa-impl: CHK-10_AC-1\n .option('--spec-ignore <pattern...>', 'Glob patterns to exclude from spec file scanning')\n .option('--code-ignore <pattern...>', 'Glob patterns to exclude from code file scanning')\n // @awa-impl: CHK-9_AC-1\n .option('--format <format>', 'Output format (text or json)', 'text')\n .option(\n '--allow-warnings',\n 'Allow warnings without failing (default: warnings are errors)',\n false\n )\n .option(\n '--spec-only',\n 'Run only spec-level checks (schema and cross-refs); skip code-to-spec traceability',\n false\n )\n .action(async (options) => {\n const cliOptions: RawCheckOptions = {\n config: options.config,\n specIgnore: options.specIgnore,\n codeIgnore: options.codeIgnore,\n format: options.format,\n allowWarnings: options.allowWarnings,\n specOnly: options.specOnly,\n };\n\n const exitCode = await checkCommand(cliOptions);\n process.exit(exitCode);\n });\n\n// @awa-impl: DISC-4_AC-1, DISC-5_AC-1\nprogram\n .command('features')\n .description('Discover feature flags available in a template')\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n .option('-c, --config <path>', 'Path to configuration file')\n .option('--refresh', 'Force refresh of cached Git templates', false)\n .option('--json', 'Output results as JSON', false)\n .action(async (options) => {\n const exitCode = await featuresCommand({\n template: options.template,\n config: options.config,\n refresh: options.refresh,\n json: options.json,\n });\n process.exit(exitCode);\n });\n\n// @awa-impl: TTST-7_AC-1, TTST-5_AC-1\nprogram\n .command('test')\n .description('Run template test fixtures to verify expected output')\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n .option('-c, --config <path>', 'Path to configuration file')\n .option('--update-snapshots', 'Update stored snapshots with current rendered output', false)\n .action(async (options) => {\n const testOptions: RawTestOptions = {\n template: options.template,\n config: options.config,\n updateSnapshots: options.updateSnapshots,\n };\n\n const exitCode = await testCommand(testOptions);\n process.exit(exitCode);\n });\n\n// Fire update check asynchronously (non-blocking) before parse\nlet updateCheckPromise: Promise<UpdateCheckResult | null> | null = null;\n\nconst isJsonOrSummary = process.argv.includes('--json') || process.argv.includes('--summary');\nconst isTTY = process.stdout.isTTY === true;\nconst isDisabledByEnv = !!process.env.NO_UPDATE_NOTIFIER;\n\nif (!isJsonOrSummary && isTTY && !isDisabledByEnv) {\n updateCheckPromise = (async () => {\n try {\n // Load config to check update-check settings\n const { configLoader } = await import('../core/config.js');\n const configPath =\n process.argv.indexOf('-c') !== -1\n ? process.argv[process.argv.indexOf('-c') + 1]\n : process.argv.indexOf('--config') !== -1\n ? process.argv[process.argv.indexOf('--config') + 1]\n : undefined;\n const fileConfig = await configLoader.load(configPath ?? null);\n\n const updateCheckConfig = fileConfig?.['update-check'];\n if (updateCheckConfig?.enabled === false) return null;\n\n const intervalSeconds = updateCheckConfig?.interval ?? 86400;\n const intervalMs = intervalSeconds * 1000;\n\n const needsCheck = await shouldCheck(intervalMs);\n if (!needsCheck) return null;\n\n const result = await checkForUpdate();\n if (result) {\n await writeCache(result.latest);\n }\n return result;\n } catch {\n return null;\n }\n })();\n}\n\n// Print update warning after command completes\nprogram.hook('postAction', async () => {\n if (!updateCheckPromise) return;\n try {\n const result = await updateCheckPromise;\n if (result?.isOutdated) {\n printUpdateWarning(logger, result);\n }\n } catch {\n // Silently ignore\n }\n});\n\n// @awa-impl: GEN-10_AC-1, GEN-10_AC-2\nprogram.parseAsync();\n","// This file is automatically generated. DO NOT EDIT.\n\n/* eslint-disable */\n\nexport const PACKAGE_INFO = {\n \"name\": \"@ncoderz/awa\",\n \"version\": \"1.2.0\",\n \"author\": \"Richard Sewell <richard.sewell@ncoderz.com>\",\n \"license\": \"MIT\",\n \"description\": \"awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage agent workflow files using templates.\"\n};\n","// @awa-component: CHK-CodeSpecChecker\n// @awa-impl: CHK-3_AC-1\n// @awa-impl: CHK-4_AC-1\n// @awa-impl: CHK-6_AC-1\n// @awa-impl: CHK-14_AC-1\n\nimport type {\n CheckConfig,\n CheckResult,\n Finding,\n MarkerScanResult,\n SpecParseResult,\n} from './types.js';\n\n// @awa-impl: CHK-3_AC-1, CHK-4_AC-1, CHK-6_AC-1\nexport function checkCodeAgainstSpec(\n markers: MarkerScanResult,\n specs: SpecParseResult,\n config: CheckConfig\n): CheckResult {\n const findings: Finding[] = [];\n\n // @awa-impl: CHK-6_AC-1, CHK-14_AC-1\n // Validate ID format for all markers\n const idRegex = new RegExp(`^${config.idPattern}$`);\n for (const marker of markers.markers) {\n if (marker.type === 'component') {\n // Component names have different format — skip ID pattern check\n continue;\n }\n if (!idRegex.test(marker.id)) {\n findings.push({\n severity: 'error',\n code: 'invalid-id-format',\n message: `Marker ID '${marker.id}' does not match expected pattern: ${config.idPattern}`,\n filePath: marker.filePath,\n line: marker.line,\n id: marker.id,\n });\n }\n }\n\n // @awa-impl: CHK-3_AC-1\n // Check for orphaned markers (code references non-existent spec ID)\n for (const marker of markers.markers) {\n if (marker.type === 'component') {\n // Component markers reference component names\n if (!specs.componentNames.has(marker.id)) {\n findings.push({\n severity: 'error',\n code: 'orphaned-marker',\n message: `Component marker '${marker.id}' not found in any spec file`,\n filePath: marker.filePath,\n line: marker.line,\n id: marker.id,\n });\n }\n } else {\n // impl and test markers reference IDs (ACs, properties, requirement IDs)\n if (!specs.allIds.has(marker.id)) {\n findings.push({\n severity: 'error',\n code: 'orphaned-marker',\n message: `Marker '${marker.id}' not found in any spec file`,\n filePath: marker.filePath,\n line: marker.line,\n id: marker.id,\n });\n }\n }\n }\n\n // @awa-impl: CHK-4_AC-1\n // Check for uncovered ACs (spec ACs with no @awa-test reference)\n const testedIds = new Set(markers.markers.filter((m) => m.type === 'test').map((m) => m.id));\n\n for (const acId of specs.acIds) {\n if (!testedIds.has(acId)) {\n // Look up location from idLocations map, fall back to spec file path\n const loc = specs.idLocations.get(acId);\n const specFile = loc ? undefined : specs.specFiles.find((sf) => sf.acIds.includes(acId));\n findings.push({\n severity: 'warning',\n code: 'uncovered-ac',\n message: `Acceptance criterion '${acId}' has no @awa-test reference`,\n filePath: loc?.filePath ?? specFile?.filePath,\n line: loc?.line,\n id: acId,\n });\n }\n }\n\n return { findings };\n}\n","// @awa-component: CHK-MarkerScanner\n// @awa-impl: CHK-1_AC-1\n// @awa-impl: CHK-11_AC-1\n// @awa-impl: CHK-13_AC-1\n\nimport { readFile } from 'node:fs/promises';\nimport { collectFiles, matchSimpleGlob } from './glob.js';\nimport type { CheckConfig, CodeMarker, Finding, MarkerScanResult, MarkerType } from './types.js';\n\nconst MARKER_TYPE_MAP: Record<string, MarkerType> = {\n '@awa-impl': 'impl',\n '@awa-test': 'test',\n '@awa-component': 'component',\n};\n\n/** Ignore directive patterns (similar to eslint-disable comments). */\nconst IGNORE_FILE_RE = /@awa-ignore-file\\b/;\nconst IGNORE_NEXT_LINE_RE = /@awa-ignore-next-line\\b/;\nconst IGNORE_LINE_RE = /@awa-ignore\\b/;\nconst IGNORE_START_RE = /@awa-ignore-start\\b/;\nconst IGNORE_END_RE = /@awa-ignore-end\\b/;\n\n// @awa-impl: CHK-1_AC-1\nexport async function scanMarkers(config: CheckConfig): Promise<MarkerScanResult> {\n const files = await collectCodeFiles(config.codeGlobs, config.codeIgnore);\n const markers: CodeMarker[] = [];\n const findings: Finding[] = [];\n\n for (const filePath of files) {\n // Skip files matching ignoreMarkers globs\n if (config.ignoreMarkers.some((ig) => matchSimpleGlob(filePath, ig))) {\n continue;\n }\n\n const result = await scanFile(filePath, config.markers);\n markers.push(...result.markers);\n findings.push(...result.findings);\n }\n\n return { markers, findings };\n}\n\n// @awa-impl: CHK-11_AC-1\nfunction buildMarkerRegex(markerNames: readonly string[]): RegExp {\n const escaped = markerNames.map((m) => m.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'));\n // Match marker followed by colon, then capture the rest of the line (IDs)\n return new RegExp(`(${escaped.join('|')}):\\\\s*(.+)`, 'g');\n}\n\n/** Pattern matching valid impl/test IDs and component names. */\nconst ID_TOKEN_RE = /^([A-Z][A-Z0-9]*(?:[-_][A-Za-z0-9]+)*(?:\\.\\d+)?)/;\n\nasync function scanFile(\n filePath: string,\n markerNames: readonly string[]\n): Promise<{ markers: CodeMarker[]; findings: Finding[] }> {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n return { markers: [], findings: [] };\n }\n\n // Check for @awa-ignore-file directive anywhere in the file\n if (IGNORE_FILE_RE.test(content)) {\n return { markers: [], findings: [] };\n }\n\n const regex = buildMarkerRegex(markerNames);\n const lines = content.split('\\n');\n const markers: CodeMarker[] = [];\n const findings: Finding[] = [];\n let ignoreNextLine = false;\n let ignoreBlock = false;\n\n for (const [i, line] of lines.entries()) {\n // Check for block ignore boundaries\n if (IGNORE_START_RE.test(line)) {\n ignoreBlock = true;\n continue;\n }\n if (IGNORE_END_RE.test(line)) {\n ignoreBlock = false;\n continue;\n }\n if (ignoreBlock) {\n continue;\n }\n\n // Check if previous line had @awa-ignore-next-line\n if (ignoreNextLine) {\n ignoreNextLine = false;\n continue;\n }\n\n // Check if this line is an @awa-ignore-next-line directive\n if (IGNORE_NEXT_LINE_RE.test(line)) {\n ignoreNextLine = true;\n continue;\n }\n\n // Check for inline @awa-ignore on this line (ignores markers on this line)\n if (IGNORE_LINE_RE.test(line)) {\n continue;\n }\n\n regex.lastIndex = 0;\n let match = regex.exec(line);\n\n while (match !== null) {\n const markerName = match[1] ?? '';\n const idsRaw = match[2] ?? '';\n const type = resolveMarkerType(markerName, markerNames);\n\n // Split by comma to support multiple IDs per marker line\n const ids = idsRaw\n .split(',')\n .map((id) => id.trim())\n .filter(Boolean);\n\n for (const id of ids) {\n // Extract only the leading ID token\n const tokenMatch = ID_TOKEN_RE.exec(id);\n const cleanId = tokenMatch?.[1]?.trim() ?? '';\n if (cleanId && tokenMatch) {\n // Check for trailing text after the ID (only whitespace allowed)\n const remainder = id.slice(tokenMatch[0].length).trim();\n if (remainder) {\n findings.push({\n severity: 'error',\n code: 'marker-trailing-text',\n message: `Marker has trailing text after ID '${cleanId}': '${remainder}' — use comma-separated IDs only`,\n filePath,\n line: i + 1,\n id: cleanId,\n });\n }\n markers.push({ type, id: cleanId, filePath, line: i + 1 });\n }\n }\n\n match = regex.exec(line);\n }\n }\n\n return { markers, findings };\n}\n\nfunction resolveMarkerType(markerName: string, configuredMarkers: readonly string[]): MarkerType {\n // Check default mapping first\n const mapped = MARKER_TYPE_MAP[markerName];\n if (mapped) return mapped;\n // For custom markers, infer type by position in configured array\n // Default order: [impl, test, component]\n const idx = configuredMarkers.indexOf(markerName);\n if (idx === 1) return 'test';\n if (idx === 2) return 'component';\n return 'impl';\n}\n\n// @awa-impl: CHK-13_AC-1\nasync function collectCodeFiles(\n codeGlobs: readonly string[],\n ignore: readonly string[]\n): Promise<string[]> {\n return collectFiles(codeGlobs, ignore);\n}\n","// @awa-component: CHK-MarkerScanner\n// @awa-impl: CHK-13_AC-1\n\nimport { glob } from 'node:fs/promises';\n\n/**\n * Matches a path against a simple glob pattern supporting * and **.\n * Also matches a directory prefix against `dir/**` patterns (e.g. \"src\" matches \"src/**\").\n */\nexport function matchSimpleGlob(path: string, pattern: string): boolean {\n const regex = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<GLOBSTAR>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<GLOBSTAR>>/g, '.*');\n return new RegExp(`(^|/)${regex}($|/)`).test(path);\n}\n\n/**\n * Collect files matching globs while applying ignore patterns.\n * Uses fs.glob exclude callback for directory-level skipping (perf optimization)\n * and post-filters results for file-level ignore matching.\n */\nexport async function collectFiles(\n globs: readonly string[],\n ignore: readonly string[]\n): Promise<string[]> {\n const files: string[] = [];\n\n // For exclude callback, also match directory prefixes (e.g. \"src\" for \"src/**\")\n const dirPrefixes = ignore.filter((ig) => ig.endsWith('/**')).map((ig) => ig.slice(0, -3));\n\n for (const pattern of globs) {\n for await (const filePath of glob(pattern, {\n exclude: (p) => dirPrefixes.includes(p) || ignore.some((ig) => matchSimpleGlob(p, ig)),\n })) {\n // Post-filter: fs.glob exclude only receives directory names,\n // so we must also filter the yielded file paths\n if (!ignore.some((ig) => matchSimpleGlob(filePath, ig))) {\n files.push(filePath);\n }\n }\n }\n\n return [...new Set(files)];\n}\n","// @awa-component: CHK-Reporter\n// @awa-impl: CHK-9_AC-1\n\nimport chalk from 'chalk';\nimport type { Finding } from './types.js';\n\n// @awa-impl: CHK-9_AC-1\nexport function report(findings: readonly Finding[], format: 'text' | 'json'): void {\n if (format === 'json') {\n reportJson(findings);\n } else {\n reportText(findings);\n }\n}\n\nfunction reportJson(findings: readonly Finding[]): void {\n const errors = findings.filter((f) => f.severity === 'error');\n const warnings = findings.filter((f) => f.severity === 'warning');\n\n const output = {\n valid: errors.length === 0,\n errors: errors.length,\n warnings: warnings.length,\n findings: findings.map((f) => ({\n severity: f.severity,\n code: f.code,\n message: f.message,\n ...(f.filePath ? { filePath: f.filePath } : {}),\n ...(f.line ? { line: f.line } : {}),\n ...(f.id ? { id: f.id } : {}),\n ...(f.ruleSource ? { ruleSource: f.ruleSource } : {}),\n ...(f.rule ? { rule: f.rule } : {}),\n })),\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n\nfunction reportText(findings: readonly Finding[]): void {\n const errors = findings.filter((f) => f.severity === 'error');\n const warnings = findings.filter((f) => f.severity === 'warning');\n\n if (errors.length > 0) {\n console.log(chalk.red(`\\n${errors.length} error(s):\\n`));\n for (const f of errors) {\n const location = formatLocation(f.filePath, f.line);\n console.log(chalk.red(' ✖'), f.message, location ? chalk.dim(location) : '');\n printRuleContext(f);\n }\n }\n\n if (warnings.length > 0) {\n console.log(chalk.yellow(`\\n${warnings.length} warning(s):\\n`));\n for (const f of warnings) {\n const location = formatLocation(f.filePath, f.line);\n console.log(chalk.yellow(' ⚠'), f.message, location ? chalk.dim(location) : '');\n printRuleContext(f);\n }\n }\n\n if (errors.length === 0 && warnings.length === 0) {\n console.log(chalk.green('\\n✔ Validation passed — no issues found'));\n } else {\n console.log('');\n const parts: string[] = [];\n if (errors.length > 0) parts.push(chalk.red(`${errors.length} error(s)`));\n if (warnings.length > 0) parts.push(chalk.yellow(`${warnings.length} warning(s)`));\n console.log(`Summary: ${parts.join(', ')}`);\n }\n}\n\nfunction formatLocation(filePath?: string, line?: number): string {\n if (!filePath) return '';\n return line ? `(${filePath}:${line})` : `(${filePath})`;\n}\n\nfunction printRuleContext(f: Finding): void {\n if (!f.ruleSource && !f.rule) return;\n const parts: string[] = [];\n if (f.ruleSource) parts.push(f.ruleSource);\n if (f.rule) parts.push(f.rule);\n console.log(chalk.dim(` rule: ${parts.join(' — ')}`));\n}\n","// @awa-component: CHK-RuleLoader\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { collectFiles, matchSimpleGlob } from './glob.js';\nimport type {\n CodeBlockContainsRule,\n ContainsRule,\n HeadingOrTextContainsRule,\n ListContainsRule,\n LoadedRuleSet,\n PatternContainsRule,\n RuleFile,\n SectionRule,\n TableContainsRule,\n WhenCondition,\n} from './rule-types.js';\n\n/**\n * Discover and load all *.schema.yaml files from the given schema directory.\n * Parses YAML, validates rule structure, and returns typed rule sets.\n */\nexport async function loadRules(schemaDir: string): Promise<LoadedRuleSet[]> {\n const pattern = join(schemaDir, '*.schema.yaml');\n const files = await collectFiles([pattern], []);\n const results: LoadedRuleSet[] = [];\n\n for (const filePath of files) {\n const ruleSet = await loadRuleFile(filePath);\n if (ruleSet) {\n results.push(ruleSet);\n }\n }\n\n return results;\n}\n\n/**\n * Match spec file paths against a loaded rule set's target-files glob.\n */\nexport function matchesTargetGlob(filePath: string, targetGlob: string): boolean {\n return matchSimpleGlob(filePath, targetGlob);\n}\n\nasync function loadRuleFile(filePath: string): Promise<LoadedRuleSet | null> {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n\n const parsed = parseYaml(content) as unknown;\n if (!parsed || typeof parsed !== 'object') {\n throw new RuleValidationError(`Rule file is not a valid YAML object: ${filePath}`);\n }\n\n const raw = parsed as Record<string, unknown>;\n const ruleFile = validateRuleFile(raw, filePath);\n\n return {\n ruleFile,\n sourcePath: filePath,\n targetGlob: ruleFile['target-files'],\n };\n}\n\nfunction validateRuleFile(raw: Record<string, unknown>, filePath: string): RuleFile {\n // target-files is required\n if (typeof raw['target-files'] !== 'string' || raw['target-files'].length === 0) {\n throw new RuleValidationError(`Missing or empty 'target-files' in ${filePath}`);\n }\n\n // sections is optional (e.g., API rules target non-markdown files)\n let sections: SectionRule[] | undefined;\n if (raw.sections !== undefined) {\n if (!Array.isArray(raw.sections) || raw.sections.length === 0) {\n throw new RuleValidationError(\n `'sections' must be a non-empty array if present in ${filePath}`\n );\n }\n sections = raw.sections.map((s: unknown, i: number) =>\n validateSectionRule(s, `sections[${i}]`, filePath)\n );\n }\n\n // sections-prohibited is optional\n let sectionsProhibited: string[] | undefined;\n if (raw['sections-prohibited'] !== undefined) {\n if (\n !Array.isArray(raw['sections-prohibited']) ||\n !raw['sections-prohibited'].every((v: unknown) => typeof v === 'string')\n ) {\n throw new RuleValidationError(`'sections-prohibited' must be a string array in ${filePath}`);\n }\n sectionsProhibited = raw['sections-prohibited'] as string[];\n }\n\n return {\n 'target-files': raw['target-files'] as string,\n ...(typeof raw.description === 'string' ? { description: raw.description } : {}),\n ...(typeof raw['line-limit'] === 'number' && raw['line-limit'] > 0\n ? { 'line-limit': raw['line-limit'] }\n : {}),\n sections: sections ?? [],\n ...(sectionsProhibited ? { 'sections-prohibited': sectionsProhibited } : {}),\n ...(typeof raw.example === 'string' ? { example: raw.example } : {}),\n };\n}\n\nfunction validateSectionRule(raw: unknown, path: string, filePath: string): SectionRule {\n if (!raw || typeof raw !== 'object') {\n throw new RuleValidationError(`${path} must be an object in ${filePath}`);\n }\n\n const section = raw as Record<string, unknown>;\n\n if (typeof section.heading !== 'string' || section.heading.length === 0) {\n throw new RuleValidationError(`${path}.heading must be a non-empty string in ${filePath}`);\n }\n\n if (typeof section.level !== 'number' || section.level < 1 || section.level > 6) {\n throw new RuleValidationError(`${path}.level must be 1-6 in ${filePath}`);\n }\n\n // Validate heading as regex if it looks like a pattern\n validatePattern(section.heading as string, `${path}.heading`, filePath);\n\n // Validate optional contains rules\n let contains: ContainsRule[] | undefined;\n if (section.contains !== undefined) {\n if (!Array.isArray(section.contains)) {\n throw new RuleValidationError(`${path}.contains must be an array in ${filePath}`);\n }\n contains = section.contains.map((c: unknown, i: number) =>\n validateContainsRule(c, `${path}.contains[${i}]`, filePath)\n );\n }\n\n // Validate optional children rules\n let children: SectionRule[] | undefined;\n if (section.children !== undefined) {\n if (!Array.isArray(section.children)) {\n throw new RuleValidationError(`${path}.children must be an array in ${filePath}`);\n }\n children = section.children.map((c: unknown, i: number) =>\n validateSectionRule(c, `${path}.children[${i}]`, filePath)\n );\n }\n\n return {\n heading: section.heading as string,\n level: section.level as number,\n ...(typeof section.required === 'boolean' ? { required: section.required } : {}),\n ...(typeof section.repeatable === 'boolean' ? { repeatable: section.repeatable } : {}),\n ...(typeof section.description === 'string' ? { description: section.description } : {}),\n ...(contains ? { contains } : {}),\n ...(children ? { children } : {}),\n };\n}\n\nfunction validateContainsRule(raw: unknown, path: string, filePath: string): ContainsRule {\n if (!raw || typeof raw !== 'object') {\n throw new RuleValidationError(`${path} must be an object in ${filePath}`);\n }\n\n const rule = raw as Record<string, unknown>;\n\n // Parse optional 'when' condition (applicable to all rule types)\n const when =\n rule.when !== undefined\n ? validateWhenCondition(rule.when, `${path}.when`, filePath)\n : undefined;\n\n // Pattern rule\n if (typeof rule.pattern === 'string') {\n validatePattern(rule.pattern, `${path}.pattern`, filePath);\n return {\n pattern: rule.pattern,\n ...(typeof rule.label === 'string' ? { label: rule.label } : {}),\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(typeof rule.required === 'boolean' ? { required: rule.required } : {}),\n ...(typeof rule.prohibited === 'boolean' ? { prohibited: rule.prohibited } : {}),\n ...(when ? { when } : {}),\n } satisfies PatternContainsRule;\n }\n\n // List rule\n if (rule.list && typeof rule.list === 'object') {\n const list = rule.list as Record<string, unknown>;\n if (typeof list.pattern !== 'string') {\n throw new RuleValidationError(`${path}.list.pattern must be a string in ${filePath}`);\n }\n validatePattern(list.pattern, `${path}.list.pattern`, filePath);\n return {\n list: {\n pattern: list.pattern,\n ...(typeof list.min === 'number' ? { min: list.min } : {}),\n ...(typeof list.label === 'string' ? { label: list.label } : {}),\n },\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies ListContainsRule;\n }\n\n // Table rule\n if (rule.table && typeof rule.table === 'object') {\n const table = rule.table as Record<string, unknown>;\n if (\n !Array.isArray(table.columns) ||\n !table.columns.every((c: unknown) => typeof c === 'string')\n ) {\n throw new RuleValidationError(`${path}.table.columns must be a string array in ${filePath}`);\n }\n return {\n table: {\n ...(typeof table.heading === 'string' ? { heading: table.heading } : {}),\n columns: table.columns as string[],\n ...(typeof table['min-rows'] === 'number' ? { 'min-rows': table['min-rows'] } : {}),\n },\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies TableContainsRule;\n }\n\n // Code block rule\n if (rule['code-block'] === true) {\n return {\n 'code-block': true,\n ...(typeof rule.label === 'string' ? { label: rule.label } : {}),\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies CodeBlockContainsRule;\n }\n\n // Heading-or-text rule\n if (typeof rule['heading-or-text'] === 'string') {\n return {\n 'heading-or-text': rule['heading-or-text'],\n ...(typeof rule.required === 'boolean' ? { required: rule.required } : {}),\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies HeadingOrTextContainsRule;\n }\n\n throw new RuleValidationError(`${path} has no recognized rule type in ${filePath}`);\n}\n\nfunction validateWhenCondition(raw: unknown, path: string, filePath: string): WhenCondition {\n if (!raw || typeof raw !== 'object') {\n throw new RuleValidationError(`${path} must be an object in ${filePath}`);\n }\n\n const condition = raw as Record<string, unknown>;\n const result: Record<string, string> = {};\n\n if (typeof condition['heading-matches'] === 'string') {\n validatePattern(condition['heading-matches'], `${path}.heading-matches`, filePath);\n result['heading-matches'] = condition['heading-matches'];\n }\n\n if (typeof condition['heading-not-matches'] === 'string') {\n validatePattern(condition['heading-not-matches'], `${path}.heading-not-matches`, filePath);\n result['heading-not-matches'] = condition['heading-not-matches'];\n }\n\n if (!result['heading-matches'] && !result['heading-not-matches']) {\n throw new RuleValidationError(\n `${path} must have 'heading-matches' or 'heading-not-matches' in ${filePath}`\n );\n }\n\n return result as unknown as WhenCondition;\n}\n\nfunction validatePattern(pattern: string, path: string, filePath: string): void {\n // Only validate if it looks like a regex (contains regex special chars)\n if (/[.+*?^${}()|[\\]\\\\]/.test(pattern)) {\n try {\n new RegExp(pattern);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new RuleValidationError(`Invalid regex in ${path}: ${msg} (${filePath})`);\n }\n }\n}\n\nexport class RuleValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'RuleValidationError';\n }\n}\n","// @awa-component: CHK-SchemaChecker\n\nimport { readFile } from 'node:fs/promises';\nimport type { Code, Heading, List, PhrasingContent, Root, Table, TableRow } from 'mdast';\nimport remarkGfm from 'remark-gfm';\nimport remarkParse from 'remark-parse';\nimport { unified } from 'unified';\nimport { matchesTargetGlob } from './rule-loader.js';\nimport type {\n CodeBlockContainsRule,\n ContainsRule,\n HeadingOrTextContainsRule,\n ListContainsRule,\n LoadedRuleSet,\n PatternContainsRule,\n SectionRule,\n TableContainsRule,\n WhenCondition,\n} from './rule-types.js';\nimport type { CheckResult, Finding, SpecFile } from './types.js';\n\n// --- Rule formatting helpers ---\n\nfunction formatSectionRule(rule: SectionRule): string {\n const parts = [`section: heading=\"${rule.heading}\" level=${rule.level}`];\n if (rule.required) parts.push('required');\n if (rule.repeatable) parts.push('repeatable');\n return parts.join(' ');\n}\n\nfunction formatContainsRule(rule: ContainsRule): string {\n if ('pattern' in rule && typeof rule.pattern === 'string') {\n const r = rule as PatternContainsRule;\n if (r.prohibited) return `contains: prohibited pattern=\"${r.pattern}\"`;\n return `contains: pattern=\"${r.pattern}\"${r.required === false ? '' : ' required'}`;\n }\n if ('list' in rule) {\n const r = rule as ListContainsRule;\n return `contains: list pattern=\"${r.list.pattern}\"${r.list.min !== undefined ? ` min=${r.list.min}` : ''}`;\n }\n if ('table' in rule) {\n const r = rule as TableContainsRule;\n return `contains: table columns=[${r.table.columns.join(', ')}]${r.table['min-rows'] !== undefined ? ` min-rows=${r.table['min-rows']}` : ''}`;\n }\n if ('code-block' in rule) {\n return 'contains: code-block';\n }\n if ('heading-or-text' in rule) {\n const r = rule as HeadingOrTextContainsRule;\n return `contains: heading-or-text=\"${r['heading-or-text']}\"`;\n }\n return 'contains: (unknown rule)';\n}\n\nfunction formatLineLimitRule(limit: number): string {\n return `line-limit: ${limit}`;\n}\n\nfunction formatProhibitedRule(pattern: string): string {\n return `sections-prohibited: \"${pattern}\"`;\n}\n\n/** A section with heading info and all AST nodes belonging to it. */\ninterface SectionNode {\n readonly heading: Heading;\n readonly headingText: string;\n readonly level: number;\n readonly children: SectionNode[];\n readonly contentNodes: Root['children'];\n}\n\n/**\n * Check all spec files against loaded rule sets.\n * Reads file content, parses to mdast, walks AST checking rules.\n */\nexport async function checkSchemasAsync(\n specFiles: readonly SpecFile[],\n ruleSets: readonly LoadedRuleSet[]\n): Promise<CheckResult> {\n const findings: Finding[] = [];\n const parser = unified().use(remarkParse).use(remarkGfm);\n\n for (const spec of specFiles) {\n const matchingRules = ruleSets.filter((rs) => matchesTargetGlob(spec.filePath, rs.targetGlob));\n if (matchingRules.length === 0) continue;\n\n let content: string;\n try {\n content = await readFile(spec.filePath, 'utf-8');\n } catch {\n continue;\n }\n\n const tree = parser.parse(content);\n const sectionTree = buildSectionTree(tree);\n const allSections = flattenSections(sectionTree);\n\n for (const ruleSet of matchingRules) {\n const ruleSource = ruleSet.sourcePath;\n\n // Check line limit if defined\n if (ruleSet.ruleFile['line-limit'] !== undefined) {\n const lineCount = content.split('\\n').length;\n if (lineCount > ruleSet.ruleFile['line-limit']) {\n findings.push({\n severity: 'warning',\n code: 'schema-line-limit',\n message: `File has ${lineCount} lines, exceeds limit of ${ruleSet.ruleFile['line-limit']}`,\n filePath: spec.filePath,\n ruleSource,\n rule: formatLineLimitRule(ruleSet.ruleFile['line-limit']),\n });\n }\n }\n\n findings.push(\n ...checkRulesAgainstSections(\n allSections,\n ruleSet.ruleFile.sections,\n spec.filePath,\n ruleSource\n )\n );\n\n if (ruleSet.ruleFile['sections-prohibited']) {\n findings.push(\n ...checkProhibited(\n content,\n ruleSet.ruleFile['sections-prohibited'],\n spec.filePath,\n ruleSource\n )\n );\n }\n }\n }\n\n return { findings };\n}\n\n// --- Section tree building ---\n\nfunction buildSectionTree(tree: Root): SectionNode[] {\n return buildSectionsFromNodes(tree.children, 0, 0).sections;\n}\n\nfunction buildSectionsFromNodes(\n nodes: Root['children'],\n start: number,\n parentLevel: number\n): { sections: SectionNode[]; nextIndex: number } {\n const sections: SectionNode[] = [];\n let i = start;\n\n while (i < nodes.length) {\n const node = nodes[i];\n if (!node) break;\n if (node.type === 'heading') {\n const h = node as Heading;\n if (parentLevel > 0 && h.depth <= parentLevel) break;\n\n const headingText = extractText(h.children);\n const contentNodes: Root['children'] = [];\n i++;\n\n // Collect content until next heading of same-or-higher level\n while (i < nodes.length) {\n const next = nodes[i];\n if (!next || next.type === 'heading') break;\n contentNodes.push(next);\n i++;\n }\n\n // Collect child headings (deeper level)\n const childResult = buildSectionsFromNodes(nodes, i, h.depth);\n i = childResult.nextIndex;\n\n sections.push({\n heading: h,\n headingText,\n level: h.depth,\n children: childResult.sections,\n contentNodes,\n });\n } else {\n i++;\n }\n }\n\n return { sections, nextIndex: i };\n}\n\nfunction flattenSections(sections: SectionNode[]): SectionNode[] {\n const result: SectionNode[] = [];\n for (const s of sections) {\n result.push(s);\n result.push(...flattenSections(s.children));\n }\n return result;\n}\n\nfunction extractText(children: PhrasingContent[]): string {\n return children\n .map((c) => {\n if ('value' in c) return c.value;\n if ('children' in c) return extractText(c.children as PhrasingContent[]);\n return '';\n })\n .join('');\n}\n\n// --- Rule checking ---\n\n/**\n * Top-level rules match against the flattened view of all sections.\n * `children` sub-rules match only within the matched section's children.\n */\nfunction checkRulesAgainstSections(\n allSections: SectionNode[],\n rules: readonly SectionRule[],\n filePath: string,\n ruleSource: string\n): Finding[] {\n const findings: Finding[] = [];\n\n for (const rule of rules) {\n const matches = findMatchingSections(allSections, rule);\n\n if (matches.length === 0 && rule.required) {\n findings.push({\n severity: 'error',\n code: 'schema-missing-section',\n message: `Missing required section: '${rule.heading}' (level ${rule.level})`,\n filePath,\n ruleSource,\n rule: formatSectionRule(rule),\n });\n continue;\n }\n\n for (const match of matches) {\n if (match.level !== rule.level) {\n findings.push({\n severity: 'warning',\n code: 'schema-wrong-level',\n message: `Section '${match.headingText}' is level ${match.level}, expected ${rule.level}`,\n filePath,\n line: match.heading.position?.start.line,\n ruleSource,\n rule: formatSectionRule(rule),\n });\n }\n\n if (rule.contains) {\n for (const cr of rule.contains) {\n findings.push(...checkContainsRule(match, cr, filePath, ruleSource));\n }\n }\n\n if (rule.children) {\n const childFlat = flattenSections(match.children);\n findings.push(...checkRulesAgainstSections(childFlat, rule.children, filePath, ruleSource));\n }\n }\n }\n\n return findings;\n}\n\nfunction findMatchingSections(allSections: SectionNode[], rule: SectionRule): SectionNode[] {\n const regex = createHeadingRegex(rule.heading);\n const matches = allSections.filter((s) => s.level === rule.level && regex.test(s.headingText));\n\n if (!rule.repeatable && matches.length > 1) {\n return [matches[0] as SectionNode];\n }\n return matches;\n}\n\nfunction createHeadingRegex(pattern: string): RegExp {\n if (/[.+*?^${}()|[\\]\\\\]/.test(pattern)) {\n try {\n return new RegExp(`^${pattern}$`);\n } catch {\n return new RegExp(`^${escapeRegex(pattern)}$`);\n }\n }\n return new RegExp(`^${escapeRegex(pattern)}$`, 'i');\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// --- Contains rule dispatching ---\n\nfunction checkContainsRule(\n section: SectionNode,\n rule: ContainsRule,\n filePath: string,\n ruleSource: string\n): Finding[] {\n // Evaluate 'when' condition gate — skip rule if condition not met\n const when = 'when' in rule ? (rule as { when?: WhenCondition }).when : undefined;\n if (when && !evaluateWhenCondition(when, section.headingText)) {\n return [];\n }\n\n const formattedRule = formatContainsRule(rule);\n\n if ('pattern' in rule && typeof rule.pattern === 'string') {\n return checkPatternContains(\n section,\n rule as PatternContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('list' in rule) {\n return checkListContains(\n section,\n rule as ListContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('table' in rule) {\n return checkTableContains(\n section,\n rule as TableContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('code-block' in rule) {\n return checkCodeBlockContains(\n section,\n rule as CodeBlockContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('heading-or-text' in rule) {\n return checkHeadingOrText(\n section,\n rule as HeadingOrTextContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n return [];\n}\n\nfunction checkPatternContains(\n section: SectionNode,\n rule: PatternContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const text = getFullSectionText(section);\n const found = new RegExp(rule.pattern, 'm').test(text);\n\n // Prohibited mode: pattern must NOT appear\n if (rule.prohibited) {\n if (found) {\n return [\n {\n severity: 'warning',\n code: 'schema-prohibited',\n message: `Section '${section.headingText}' contains prohibited content: ${rule.label ?? rule.pattern}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n }\n\n // Normal mode: pattern must appear\n if (found) return [];\n\n if (rule.required !== false) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required content: ${rule.label ?? rule.pattern}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n}\n\nfunction checkListContains(\n section: SectionNode,\n rule: ListContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const items = collectAllListItems(section);\n const regex = new RegExp(rule.list.pattern);\n const count = items.filter((item) => regex.test(item)).length;\n\n if (rule.list.min !== undefined && count < rule.list.min) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' has ${count} matching ${rule.list.label ?? 'list items'}, expected at least ${rule.list.min}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n}\n\nfunction checkTableContains(\n section: SectionNode,\n rule: TableContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const tables = collectAllTables(section);\n\n if (tables.length === 0) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required table${rule.table.heading ? ` (${rule.table.heading})` : ''}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n\n // Find the first table whose columns match the rule. If none match, report\n // the column mismatch for the first table. This avoids false positives when a\n // section contains multiple tables with different column sets.\n let matched: Table | undefined;\n let firstMismatch: { table: Table; headers: string[] } | undefined;\n\n for (const table of tables) {\n const headerRow = table.children[0] as TableRow | undefined;\n if (!headerRow) continue;\n\n const headers = headerRow.children.map((cell) =>\n extractText(cell.children as PhrasingContent[]).trim()\n );\n\n if (rule.table.columns.every((col) => headers.includes(col))) {\n matched = table;\n break;\n }\n if (!firstMismatch) {\n firstMismatch = { table, headers };\n }\n }\n\n if (!matched) {\n const mm = firstMismatch;\n return [\n {\n severity: 'error',\n code: 'schema-table-columns',\n message: `No table in '${section.headingText}' has columns [${rule.table.columns.join(', ')}]${mm ? `, found [${mm.headers.join(', ')}]` : ''}`,\n filePath,\n line: mm?.table.position?.start.line ?? section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n\n const findings: Finding[] = [];\n const dataRows = matched.children.length - 1;\n if (rule.table['min-rows'] !== undefined && dataRows < rule.table['min-rows']) {\n findings.push({\n severity: 'error',\n code: 'schema-missing-content',\n message: `Table in '${section.headingText}' has ${dataRows} data rows, expected at least ${rule.table['min-rows']}`,\n filePath,\n line: matched.position?.start.line,\n ruleSource,\n rule: formattedRule,\n });\n }\n return findings;\n}\n\nfunction checkCodeBlockContains(\n section: SectionNode,\n rule: CodeBlockContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n if (collectAllCodeBlocks(section).length > 0) return [];\n\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required ${rule.label ?? 'code block'}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n}\n\nfunction checkHeadingOrText(\n section: SectionNode,\n rule: HeadingOrTextContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const needle = rule['heading-or-text'].toUpperCase();\n\n if (section.children.some((c) => c.headingText.toUpperCase().includes(needle))) return [];\n if (getFullSectionText(section).toUpperCase().includes(needle)) return [];\n\n if (rule.required !== false) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required heading or text: '${rule['heading-or-text']}'`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n}\n\n// --- When condition evaluation ---\n\nfunction evaluateWhenCondition(when: WhenCondition, headingText: string): boolean {\n if (when['heading-matches']) {\n if (!new RegExp(when['heading-matches']).test(headingText)) return false;\n }\n if (when['heading-not-matches']) {\n if (new RegExp(when['heading-not-matches']).test(headingText)) return false;\n }\n return true;\n}\n\n// --- Prohibited patterns ---\n\nfunction checkProhibited(\n content: string,\n prohibited: readonly string[],\n filePath: string,\n ruleSource: string\n): Finding[] {\n const findings: Finding[] = [];\n const lines = content.split('\\n');\n\n for (const pattern of prohibited) {\n const regex = new RegExp(escapeRegex(pattern));\n let inCodeBlock = false;\n\n for (const [i, line] of lines.entries()) {\n if (line.startsWith('```')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n if (regex.test(line)) {\n findings.push({\n severity: 'warning',\n code: 'schema-prohibited',\n message: `Prohibited formatting '${pattern}' found`,\n filePath,\n line: i + 1,\n ruleSource,\n rule: formatProhibitedRule(pattern),\n });\n break;\n }\n }\n }\n return findings;\n}\n\n// --- Content extraction helpers ---\n\nfunction getFullSectionText(section: SectionNode): string {\n let text = section.contentNodes.map(nodeToText).join('\\n');\n for (const child of section.children) {\n text += `\\n${child.headingText}\\n${getFullSectionText(child)}`;\n }\n return text;\n}\n\nfunction nodeToText(node: Root['children'][number]): string {\n if ('value' in node) return node.value as string;\n if ('children' in node) {\n return (node.children as Root['children'])\n .map((c) => nodeToText(c as Root['children'][number]))\n .join('');\n }\n return '';\n}\n\nfunction extractListItems(nodes: Root['children']): string[] {\n const items: string[] = [];\n for (const node of nodes) {\n if (node.type === 'list') {\n for (const item of (node as List).children) {\n const raw = nodeToText(item as unknown as Root['children'][number]);\n // remark-gfm stores checkbox state as a `checked` property on the listItem\n // rather than preserving the literal [ ] / [x] text. Reconstruct it for\n // rules that match checkbox syntax (e.g. \\[ \\] T-CODE-nnn).\n const li = item as { checked?: boolean | null };\n if (li.checked === true) {\n items.push(`[x] ${raw}`);\n } else if (li.checked === false) {\n items.push(`[ ] ${raw}`);\n } else {\n items.push(raw);\n }\n }\n }\n }\n return items;\n}\n\nfunction collectAllListItems(section: SectionNode): string[] {\n const items = extractListItems(section.contentNodes);\n for (const child of section.children) items.push(...collectAllListItems(child));\n return items;\n}\n\nfunction collectAllTables(section: SectionNode): Table[] {\n const tables = section.contentNodes.filter((n) => n.type === 'table') as Table[];\n for (const child of section.children) tables.push(...collectAllTables(child));\n return tables;\n}\n\nfunction collectAllCodeBlocks(section: SectionNode): Code[] {\n const blocks = section.contentNodes.filter((n) => n.type === 'code') as Code[];\n for (const child of section.children) blocks.push(...collectAllCodeBlocks(child));\n return blocks;\n}\n","// @awa-component: CHK-SpecParser\n// @awa-impl: CHK-2_AC-1\n// @awa-impl: CHK-12_AC-1\n\nimport { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport { collectFiles } from './glob.js';\nimport type { CheckConfig, CrossReference, SpecFile, SpecParseResult } from './types.js';\n\n// @awa-impl: CHK-2_AC-1\nexport async function parseSpecs(config: CheckConfig): Promise<SpecParseResult> {\n const files = await collectSpecFiles(config.specGlobs, config.specIgnore);\n const specFiles: SpecFile[] = [];\n\n const requirementIds = new Set<string>();\n const acIds = new Set<string>();\n const propertyIds = new Set<string>();\n const componentNames = new Set<string>();\n const idLocations = new Map<string, { filePath: string; line: number }>();\n\n for (const filePath of files) {\n const specFile = await parseSpecFile(filePath, config.crossRefPatterns);\n if (specFile) {\n specFiles.push(specFile);\n for (const id of specFile.requirementIds) requirementIds.add(id);\n for (const id of specFile.acIds) acIds.add(id);\n for (const id of specFile.propertyIds) propertyIds.add(id);\n for (const name of specFile.componentNames) componentNames.add(name);\n // Merge id locations from parsed spec file\n for (const [id, loc] of specFile.idLocations ?? []) {\n idLocations.set(id, loc);\n }\n }\n }\n\n const allIds = new Set<string>([...requirementIds, ...acIds, ...propertyIds, ...componentNames]);\n\n return { requirementIds, acIds, propertyIds, componentNames, allIds, specFiles, idLocations };\n}\n\nasync function parseSpecFile(\n filePath: string,\n crossRefPatterns: readonly string[]\n): Promise<SpecFile | null> {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n\n const code = extractCodePrefix(filePath);\n const lines = content.split('\\n');\n\n const requirementIds: string[] = [];\n const acIds: string[] = [];\n const propertyIds: string[] = [];\n const componentNames: string[] = [];\n const crossRefs: CrossReference[] = [];\n const idLocations = new Map<string, { filePath: string; line: number }>();\n\n // Requirement ID: ### CODE-N: Title or ### CODE-N.P: Title\n const reqIdRegex = /^###\\s+([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?)\\s*:/;\n // AC ID: - [ ] CODE-N_AC-M or - [x] CODE-N.P_AC-M\n const acIdRegex = /^-\\s+\\[[ x]\\]\\s+([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?_AC-\\d+)\\s/;\n // Property ID: - CODE_P-N [Name]\n const propIdRegex = /^-\\s+([A-Z][A-Z0-9]*_P-\\d+)\\s/;\n // Component name: ### CODE-ComponentName\n const componentRegex = /^###\\s+([A-Z][A-Z0-9]*-[A-Za-z][A-Za-z0-9]*(?:[A-Z][a-z0-9]*)*)\\s*$/;\n\n for (const [i, line] of lines.entries()) {\n const lineNum = i + 1;\n\n // Requirement IDs\n const reqMatch = reqIdRegex.exec(line);\n if (reqMatch?.[1]) {\n requirementIds.push(reqMatch[1]);\n idLocations.set(reqMatch[1], { filePath, line: lineNum });\n }\n\n // AC IDs\n const acMatch = acIdRegex.exec(line);\n if (acMatch?.[1]) {\n acIds.push(acMatch[1]);\n idLocations.set(acMatch[1], { filePath, line: lineNum });\n }\n\n // Property IDs\n const propMatch = propIdRegex.exec(line);\n if (propMatch?.[1]) {\n propertyIds.push(propMatch[1]);\n idLocations.set(propMatch[1], { filePath, line: lineNum });\n }\n\n // Component names (from DESIGN files)\n const compMatch = componentRegex.exec(line);\n if (compMatch?.[1]) {\n // Only count as component if it doesn't match requirement pattern\n if (!reqIdRegex.test(line)) {\n componentNames.push(compMatch[1]);\n idLocations.set(compMatch[1], { filePath, line: lineNum });\n }\n }\n\n // Cross-references (IMPLEMENTS:, VALIDATES:)\n for (const pattern of crossRefPatterns) {\n const patIdx = line.indexOf(pattern);\n if (patIdx !== -1) {\n const afterPattern = line.slice(patIdx + pattern.length);\n const ids = extractIdsFromText(afterPattern);\n if (ids.length > 0) {\n const type = pattern.toLowerCase().includes('implements') ? 'implements' : 'validates';\n crossRefs.push({ type, ids, filePath, line: i + 1 });\n }\n }\n }\n }\n\n return {\n filePath,\n code,\n requirementIds,\n acIds,\n propertyIds,\n componentNames,\n crossRefs,\n idLocations,\n };\n}\n\nfunction extractCodePrefix(filePath: string): string {\n const name = basename(filePath, '.md');\n // Extract CODE from patterns like REQ-CODE-feature, DESIGN-CODE-feature, FEAT-CODE-feature\n const match = /^(?:REQ|DESIGN|FEAT|EXAMPLES|API)-([A-Z][A-Z0-9]*)-/.exec(name);\n if (match?.[1]) return match[1];\n // Fallback: ARCHITECTURE.md has no code prefix\n return '';\n}\n\nfunction extractIdsFromText(text: string): string[] {\n const idRegex = /[A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?(?:_AC-\\d+)?|[A-Z][A-Z0-9]*_P-\\d+/g;\n const ids: string[] = [];\n let match = idRegex.exec(text);\n while (match !== null) {\n ids.push(match[0]);\n match = idRegex.exec(text);\n }\n return ids;\n}\n\n// @awa-impl: CHK-12_AC-1\nasync function collectSpecFiles(\n specGlobs: readonly string[],\n ignore: readonly string[]\n): Promise<string[]> {\n return collectFiles(specGlobs, ignore);\n}\n","// @awa-component: CHK-SpecSpecChecker\n// @awa-impl: CHK-5_AC-1\n// @awa-impl: CHK-7_AC-1\n// @awa-impl: CHK-15_AC-1\n\nimport type {\n CheckConfig,\n CheckResult,\n Finding,\n MarkerScanResult,\n SpecParseResult,\n} from './types.js';\n\n// @awa-impl: CHK-5_AC-1, CHK-7_AC-1\nexport function checkSpecAgainstSpec(\n specs: SpecParseResult,\n markers: MarkerScanResult,\n config: CheckConfig\n): CheckResult {\n const findings: Finding[] = [];\n\n // @awa-impl: CHK-5_AC-1\n // Check cross-references resolve to real IDs\n for (const specFile of specs.specFiles) {\n for (const crossRef of specFile.crossRefs) {\n for (const refId of crossRef.ids) {\n if (!specs.allIds.has(refId)) {\n findings.push({\n severity: 'error',\n code: 'broken-cross-ref',\n message: `Cross-reference '${refId}' (${crossRef.type}) not found in any spec file`,\n filePath: crossRef.filePath,\n line: crossRef.line,\n id: refId,\n });\n }\n }\n }\n }\n\n // @awa-impl: CHK-7_AC-1\n // Check for orphaned spec files (CODE not referenced by any other spec or code)\n // Skip when specOnly — orphaned-spec detection depends on code markers to be meaningful\n if (!config.specOnly) {\n const referencedCodes = new Set<string>();\n\n // Collect codes referenced in code markers\n for (const marker of markers.markers) {\n const codeMatch = /^([A-Z][A-Z0-9]*)[-_]/.exec(marker.id);\n if (codeMatch?.[1]) {\n referencedCodes.add(codeMatch[1]);\n }\n }\n\n // Collect codes referenced in cross-references\n for (const specFile of specs.specFiles) {\n for (const crossRef of specFile.crossRefs) {\n for (const refId of crossRef.ids) {\n const codeMatch = /^([A-Z][A-Z0-9]*)[-_]/.exec(refId);\n if (codeMatch?.[1]) {\n referencedCodes.add(codeMatch[1]);\n }\n }\n }\n }\n\n for (const specFile of specs.specFiles) {\n if (!specFile.code) continue; // Skip ARCHITECTURE.md etc.\n if (!referencedCodes.has(specFile.code)) {\n findings.push({\n severity: 'warning',\n code: 'orphaned-spec',\n message: `Spec file code '${specFile.code}' is not referenced by any other spec or code marker`,\n filePath: specFile.filePath,\n id: specFile.code,\n });\n }\n }\n }\n\n return { findings };\n}\n","// @awa-component: CHK-CheckCommand\n\n// @awa-impl: CHK-16_AC-1\nexport interface CheckConfig {\n readonly specGlobs: readonly string[];\n readonly codeGlobs: readonly string[];\n readonly specIgnore: readonly string[];\n readonly codeIgnore: readonly string[];\n readonly ignoreMarkers: readonly string[];\n readonly markers: readonly string[];\n readonly idPattern: string;\n readonly crossRefPatterns: readonly string[];\n readonly format: 'text' | 'json';\n readonly schemaDir: string;\n readonly schemaEnabled: boolean;\n readonly allowWarnings: boolean;\n readonly specOnly: boolean;\n}\n\nexport const DEFAULT_CHECK_CONFIG: CheckConfig = {\n specGlobs: [\n '.awa/specs/ARCHITECTURE.md',\n '.awa/specs/FEAT-*.md',\n '.awa/specs/REQ-*.md',\n '.awa/specs/DESIGN-*.md',\n '.awa/specs/EXAMPLES-*.md',\n '.awa/specs/API-*.tsp',\n '.awa/tasks/TASK-*.md',\n '.awa/plans/PLAN-*.md',\n '.awa/align/ALIGN-*.md',\n ],\n codeGlobs: [\n '**/*.{ts,js,tsx,jsx,mts,mjs,cjs,py,go,rs,java,kt,kts,cs,c,h,cpp,cc,cxx,hpp,hxx,swift,rb,php,scala,ex,exs,dart,lua,zig}',\n ],\n specIgnore: [],\n codeIgnore: [\n 'node_modules/**',\n 'dist/**',\n 'vendor/**',\n 'target/**',\n 'build/**',\n 'out/**',\n '.awa/**',\n ],\n ignoreMarkers: [],\n markers: ['@awa-impl', '@awa-test', '@awa-component'],\n idPattern: '([A-Z][A-Z0-9]*-\\\\d+(?:\\\\.\\\\d+)?(?:_AC-\\\\d+)?|[A-Z][A-Z0-9]*_P-\\\\d+)',\n crossRefPatterns: ['IMPLEMENTS:', 'VALIDATES:'],\n format: 'text',\n schemaDir: '.awa/.agent/schemas',\n schemaEnabled: true,\n allowWarnings: false,\n specOnly: false,\n};\n\nexport type FindingSeverity = 'error' | 'warning';\n\nexport type FindingCode =\n | 'orphaned-marker'\n | 'uncovered-ac'\n | 'broken-cross-ref'\n | 'invalid-id-format'\n | 'marker-trailing-text'\n | 'orphaned-spec'\n | 'schema-missing-section'\n | 'schema-wrong-level'\n | 'schema-missing-content'\n | 'schema-table-columns'\n | 'schema-prohibited'\n | 'schema-no-rule'\n | 'schema-line-limit';\n\nexport interface Finding {\n readonly severity: FindingSeverity;\n readonly code: FindingCode;\n readonly message: string;\n readonly filePath?: string;\n readonly line?: number;\n readonly id?: string;\n /** Path to the .schema.yaml file that defines the violated rule. */\n readonly ruleSource?: string;\n /** Concise representation of the violated rule. */\n readonly rule?: string;\n}\n\nexport type MarkerType = 'impl' | 'test' | 'component';\n\nexport interface CodeMarker {\n readonly type: MarkerType;\n readonly id: string;\n readonly filePath: string;\n readonly line: number;\n}\n\nexport interface MarkerScanResult {\n readonly markers: readonly CodeMarker[];\n readonly findings: readonly Finding[];\n}\n\nexport interface CrossReference {\n readonly type: 'implements' | 'validates';\n readonly ids: readonly string[];\n readonly filePath: string;\n readonly line: number;\n}\n\nexport interface SpecFile {\n readonly filePath: string;\n readonly code: string;\n readonly requirementIds: readonly string[];\n readonly acIds: readonly string[];\n readonly propertyIds: readonly string[];\n readonly componentNames: readonly string[];\n readonly crossRefs: readonly CrossReference[];\n /** Maps IDs parsed from this file to their line number. Populated by spec-parser. */\n readonly idLocations?: ReadonlyMap<string, { filePath: string; line: number }>;\n}\n\nexport interface SpecParseResult {\n readonly requirementIds: Set<string>;\n readonly acIds: Set<string>;\n readonly propertyIds: Set<string>;\n readonly componentNames: Set<string>;\n readonly allIds: Set<string>;\n readonly specFiles: readonly SpecFile[];\n /** Maps spec IDs (requirements, ACs, properties, components) to their source location. */\n readonly idLocations: ReadonlyMap<string, { filePath: string; line: number }>;\n}\n\nexport interface CheckResult {\n readonly findings: readonly Finding[];\n}\n\nexport interface RawCheckOptions {\n readonly specIgnore?: string[];\n readonly codeIgnore?: string[];\n readonly format?: string;\n readonly config?: string;\n readonly allowWarnings?: boolean;\n readonly specOnly?: boolean;\n}\n","// @awa-component: CHK-CheckCommand\n// @awa-impl: CHK-8_AC-1\n// @awa-impl: CHK-10_AC-1\n\nimport { checkCodeAgainstSpec } from '../core/check/code-spec-checker.js';\nimport { scanMarkers } from '../core/check/marker-scanner.js';\nimport { report } from '../core/check/reporter.js';\nimport { loadRules } from '../core/check/rule-loader.js';\nimport { checkSchemasAsync } from '../core/check/schema-checker.js';\nimport { parseSpecs } from '../core/check/spec-parser.js';\nimport { checkSpecAgainstSpec } from '../core/check/spec-spec-checker.js';\nimport type { CheckConfig, RawCheckOptions } from '../core/check/types.js';\nimport { DEFAULT_CHECK_CONFIG } from '../core/check/types.js';\nimport { configLoader } from '../core/config.js';\nimport type { FileConfig } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\n\n// @awa-impl: CHK-8_AC-1\nexport async function checkCommand(cliOptions: RawCheckOptions): Promise<number> {\n try {\n // Load config from file\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // Build check config from file [check] section + CLI overrides\n const config = buildCheckConfig(fileConfig, cliOptions);\n\n // Scan code markers (skip when --spec-only), parse specs, and load schema rules in parallel\n const emptyMarkers: import('../core/check/types.js').MarkerScanResult = {\n markers: [],\n findings: [],\n };\n const [markers, specs, ruleSets] = await Promise.all([\n config.specOnly ? Promise.resolve(emptyMarkers) : scanMarkers(config),\n parseSpecs(config),\n config.schemaEnabled ? loadRules(config.schemaDir) : Promise.resolve([]),\n ]);\n\n // Run checkers (code-spec and spec-spec are synchronous; schema is async)\n // When --spec-only, skip code-to-spec traceability checks entirely\n const codeSpecResult = config.specOnly\n ? { findings: [] as const }\n : checkCodeAgainstSpec(markers, specs, config);\n const specSpecResult = checkSpecAgainstSpec(specs, markers, config);\n const schemaResult =\n config.schemaEnabled && ruleSets.length > 0\n ? await checkSchemasAsync(specs.specFiles, ruleSets)\n : { findings: [] as const };\n\n // Combine findings\n const combinedFindings = [\n ...markers.findings,\n ...codeSpecResult.findings,\n ...specSpecResult.findings,\n ...schemaResult.findings,\n ];\n\n // Unless --allow-warnings, promote warnings to errors\n const allFindings = config.allowWarnings\n ? combinedFindings\n : combinedFindings.map((f) =>\n f.severity === 'warning' ? { ...f, severity: 'error' as const } : f\n );\n\n // Report results\n report(allFindings, config.format);\n\n // Exit code: 0 = clean, 1 = any errors present\n const hasErrors = allFindings.some((f) => f.severity === 'error');\n return hasErrors ? 1 : 0;\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n return 2;\n }\n}\n\n// @awa-impl: CHK-10_AC-1, CHK-16_AC-1\nfunction buildCheckConfig(fileConfig: FileConfig | null, cliOptions: RawCheckOptions): CheckConfig {\n const section = fileConfig?.check;\n\n const specGlobs = toStringArray(section?.['spec-globs']) ?? [...DEFAULT_CHECK_CONFIG.specGlobs];\n const codeGlobs = toStringArray(section?.['code-globs']) ?? [...DEFAULT_CHECK_CONFIG.codeGlobs];\n const markers = toStringArray(section?.markers) ?? [...DEFAULT_CHECK_CONFIG.markers];\n const crossRefPatterns = toStringArray(section?.['cross-ref-patterns']) ?? [\n ...DEFAULT_CHECK_CONFIG.crossRefPatterns,\n ];\n const idPattern =\n typeof section?.['id-pattern'] === 'string'\n ? section['id-pattern']\n : DEFAULT_CHECK_CONFIG.idPattern;\n\n // CLI --spec-ignore / --code-ignore append to their respective config lists\n const configSpecIgnore = toStringArray(section?.['spec-ignore']) ?? [\n ...DEFAULT_CHECK_CONFIG.specIgnore,\n ];\n const configCodeIgnore = toStringArray(section?.['code-ignore']) ?? [\n ...DEFAULT_CHECK_CONFIG.codeIgnore,\n ];\n const specIgnore = [...configSpecIgnore, ...(cliOptions.specIgnore ?? [])];\n const codeIgnore = [...configCodeIgnore, ...(cliOptions.codeIgnore ?? [])];\n\n const ignoreMarkers = toStringArray(section?.['ignore-markers']) ?? [\n ...DEFAULT_CHECK_CONFIG.ignoreMarkers,\n ];\n\n const format: 'text' | 'json' =\n cliOptions.format === 'json'\n ? 'json'\n : section?.format === 'json'\n ? 'json'\n : DEFAULT_CHECK_CONFIG.format;\n\n const schemaDir =\n typeof section?.['schema-dir'] === 'string'\n ? section['schema-dir']\n : DEFAULT_CHECK_CONFIG.schemaDir;\n\n const schemaEnabled =\n typeof section?.['schema-enabled'] === 'boolean'\n ? section['schema-enabled']\n : DEFAULT_CHECK_CONFIG.schemaEnabled;\n\n const allowWarnings =\n cliOptions.allowWarnings === true\n ? true\n : typeof section?.['allow-warnings'] === 'boolean'\n ? section['allow-warnings']\n : DEFAULT_CHECK_CONFIG.allowWarnings;\n\n const specOnly =\n cliOptions.specOnly === true\n ? true\n : typeof section?.['spec-only'] === 'boolean'\n ? section['spec-only']\n : DEFAULT_CHECK_CONFIG.specOnly;\n\n return {\n specGlobs,\n codeGlobs,\n specIgnore,\n codeIgnore,\n ignoreMarkers,\n markers,\n idPattern,\n crossRefPatterns,\n format,\n schemaDir,\n schemaEnabled,\n allowWarnings,\n specOnly,\n };\n}\n\nfunction toStringArray(value: unknown): string[] | null {\n if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {\n return value as string[];\n }\n return null;\n}\n","// @awa-component: DIFF-DiffCommand\n// @awa-component: JSON-DiffCommand\n// @awa-impl: DIFF-5_AC-1\n// @awa-impl: DIFF-5_AC-2\n// @awa-impl: DIFF-5_AC-3\n// @awa-impl: MULTI-6_AC-1\n// @awa-impl: MULTI-12_AC-1\n\nimport { intro, outro } from '@clack/prompts';\nimport { batchRunner } from '../core/batch-runner.js';\nimport { configLoader } from '../core/config.js';\nimport { diffEngine } from '../core/differ.js';\nimport { featureResolver } from '../core/feature-resolver.js';\nimport { formatDiffSummary, serializeDiffResult, writeJsonOutput } from '../core/json-output.js';\nimport { buildMergedDir, resolveOverlays } from '../core/overlay.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport { DiffError, type RawCliOptions, type ResolvedOptions } from '../types/index.js';\nimport { FileWatcher } from '../utils/file-watcher.js';\nimport { pathExists, rmDir } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nasync function runDiff(\n diffOptions: {\n templatePath: string;\n targetPath: string;\n features: string[];\n listUnknown: boolean;\n },\n options: { json: boolean; summary: boolean },\n mergedDir: string | null\n): Promise<number> {\n try {\n // Perform diff\n const result = await diffEngine.diff(diffOptions);\n\n // @awa-impl: JSON-2_AC-1, JSON-8_AC-1\n if (options.json) {\n writeJsonOutput(serializeDiffResult(result));\n // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2\n return result.hasDifferences ? 1 : 0;\n }\n\n // @awa-impl: JSON-5_AC-1\n if (options.summary) {\n console.log(formatDiffSummary(result));\n return result.hasDifferences ? 1 : 0;\n }\n\n // Display diff output\n for (const file of result.files) {\n switch (file.status) {\n case 'modified':\n logger.info(`Modified: ${file.relativePath}`);\n if (file.unifiedDiff) {\n // Parse and display unified diff with colors\n const lines = file.unifiedDiff.split('\\n');\n for (const line of lines) {\n if (\n line.startsWith('diff --git') ||\n line.startsWith('index ') ||\n line.startsWith('--- ') ||\n line.startsWith('+++ ')\n ) {\n logger.diffLine(line, 'context');\n } else if (line.startsWith('+')) {\n logger.diffLine(line, 'add');\n } else if (line.startsWith('-')) {\n logger.diffLine(line, 'remove');\n } else if (line.startsWith('@@')) {\n logger.diffLine(line, 'context');\n } else {\n logger.diffLine(line, 'context');\n }\n }\n }\n break;\n case 'new':\n logger.info(`New file: ${file.relativePath}`);\n break;\n case 'extra':\n logger.warn(`Extra file (not in template): ${file.relativePath}`);\n break;\n case 'binary-differs':\n logger.warn(`binary files differ: ${file.relativePath}`);\n break;\n case 'delete-listed':\n logger.warn(`Delete listed: ${file.relativePath}`);\n break;\n case 'identical':\n // Skip identical files from output\n break;\n }\n }\n\n // Display summary\n logger.diffSummary(result);\n\n // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2\n return result.hasDifferences ? 1 : 0;\n } finally {\n // Clean up merged overlay temp directory\n if (mergedDir) {\n try {\n await rmDir(mergedDir);\n } catch {\n // Swallow cleanup errors — temp dir will be cleaned by OS eventually\n }\n }\n }\n}\n\nasync function prepareDiff(options: ResolvedOptions): Promise<{\n diffOptions: {\n templatePath: string;\n targetPath: string;\n features: string[];\n listUnknown: boolean;\n };\n template: { type: string; localPath: string; source: string };\n mergedDir: string | null;\n}> {\n // Validate target directory exists (now from options.output)\n if (!(await pathExists(options.output))) {\n throw new DiffError(`Target directory does not exist: ${options.output}`);\n }\n\n const targetPath = options.output;\n\n // Resolve template source\n const template = await templateResolver.resolve(options.template, options.refresh);\n\n const features = featureResolver.resolve({\n baseFeatures: [...options.features],\n presetNames: [...options.preset],\n removeFeatures: [...options.removeFeatures],\n presetDefinitions: options.presets,\n });\n\n // @awa-impl: OVL-7_AC-1\n // Build merged template dir if overlays are specified\n let mergedDir: string | null = null;\n let templatePath = template.localPath;\n if (options.overlay.length > 0) {\n const overlayDirs = await resolveOverlays([...options.overlay], options.refresh);\n mergedDir = await buildMergedDir(template.localPath, overlayDirs);\n templatePath = mergedDir;\n }\n\n return {\n diffOptions: {\n templatePath,\n targetPath,\n features,\n listUnknown: options.listUnknown,\n },\n template,\n mergedDir,\n };\n}\n\nexport async function diffCommand(cliOptions: RawCliOptions): Promise<number> {\n try {\n // Load configuration file\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // Batch mode: --all or --target\n if (cliOptions.all || cliOptions.target) {\n const mode = cliOptions.all ? 'all' : 'single';\n const targets = batchRunner.resolveTargets(cliOptions, fileConfig, mode, cliOptions.target);\n\n // @awa-impl: MULTI-12_AC-1\n // Exit code aggregation: 0 if all identical, 1 if any differ, 2 on error (first error short-circuits)\n let hasDifferences = false;\n for (const { targetName, options } of targets) {\n batchRunner.logForTarget(targetName, 'Starting diff...');\n const { diffOptions, mergedDir } = await prepareDiff(options);\n const exitCode = await runDiff(diffOptions, options, mergedDir);\n if (exitCode === 1) {\n hasDifferences = true;\n }\n batchRunner.logForTarget(targetName, 'Diff complete.');\n }\n\n outro('All targets diffed!');\n return hasDifferences ? 1 : 0;\n }\n\n // Standard single-target mode (backward compatible)\n const options = configLoader.merge(cliOptions, fileConfig);\n\n const silent = options.json || options.summary;\n\n // @awa-impl: JSON-6_AC-1\n // Suppress interactive output when --json or --summary is active\n if (!silent) {\n intro('awa CLI - Template Diff');\n }\n\n const { diffOptions, template, mergedDir } = await prepareDiff(options);\n\n // Validate watch mode: only local templates are supported\n if (cliOptions.watch && template.type !== 'local' && template.type !== 'bundled') {\n throw new DiffError('--watch is only supported with local template sources');\n }\n\n // Run diff once\n const result = await runDiff(diffOptions, options, mergedDir);\n\n if (!cliOptions.watch) {\n if (!silent) {\n outro('Diff complete!');\n }\n return result;\n }\n\n // Watch mode: re-run diff on template changes\n // Resolves only on SIGINT (Ctrl+C) — this is intentional for watch mode\n logger.info(`Watching for changes in ${template.localPath}...`);\n\n return new Promise<number>((resolve) => {\n let running = false;\n const watcher = new FileWatcher({\n directory: template.localPath,\n onChange: async () => {\n if (running) return;\n running = true;\n try {\n console.clear();\n logger.info(`[${new Date().toLocaleTimeString()}] Change detected, re-running diff...`);\n logger.info('---');\n await runDiff(diffOptions, options, null);\n } finally {\n running = false;\n }\n },\n });\n\n watcher.start();\n\n process.once('SIGINT', () => {\n watcher.stop();\n logger.info('\\nWatch mode stopped.');\n resolve(0);\n });\n });\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n\n // @awa-impl: DIFF-5_AC-3\n return 2;\n }\n}\n","// @awa-component: MULTI-BatchRunner\n// @awa-impl: MULTI-4_AC-1\n// @awa-impl: MULTI-4_AC-2\n// @awa-impl: MULTI-8_AC-1\n// @awa-impl: MULTI-9_AC-1\n\nimport {\n ConfigError,\n type FileConfig,\n type RawCliOptions,\n type ResolvedOptions,\n} from '../types/index.js';\nimport { logger } from '../utils/logger.js';\nimport { configLoader } from './config.js';\n\nexport interface BatchTargetResult {\n targetName: string;\n options: ResolvedOptions;\n}\n\nexport class BatchRunner {\n // Resolve all targets or a single named target from config\n resolveTargets(\n cli: RawCliOptions,\n fileConfig: FileConfig | null,\n mode: 'all' | 'single',\n targetName?: string\n ): BatchTargetResult[] {\n if (!fileConfig) {\n throw new ConfigError(\n 'No configuration file found. --all and --target require a config file with [targets.*] sections.',\n 'NO_TARGETS',\n null\n );\n }\n\n const targetNames = configLoader.getTargetNames(fileConfig);\n\n if (targetNames.length === 0) {\n throw new ConfigError(\n 'No targets defined in configuration. Add [targets.<name>] sections to .awa.toml.',\n 'NO_TARGETS',\n null\n );\n }\n\n const namesToProcess = mode === 'all' ? targetNames : [targetName as string];\n\n const results: BatchTargetResult[] = [];\n\n for (const name of namesToProcess) {\n const resolved = configLoader.resolveTarget(name, fileConfig);\n\n // Build CLI options for this target:\n // - When --all, ignore CLI positional output\n // - When --target, CLI positional overrides target output\n const targetCli: RawCliOptions = {\n ...cli,\n output: mode === 'all' ? undefined : cli.output,\n };\n\n let options: ResolvedOptions;\n try {\n options = configLoader.merge(targetCli, resolved);\n } catch (error) {\n // Re-throw MISSING_OUTPUT with target-specific message\n if (error instanceof ConfigError && error.code === 'MISSING_OUTPUT') {\n throw new ConfigError(\n `Target '${name}' has no output directory. Specify 'output' in [targets.${name}] or in the root config.`,\n 'MISSING_OUTPUT',\n null\n );\n }\n throw error;\n }\n\n results.push({ targetName: name, options });\n }\n\n return results;\n }\n\n // Log a message prefixed with target name\n logForTarget(targetName: string, message: string): void {\n logger.info(`[${targetName}] ${message}`);\n }\n\n warnForTarget(targetName: string, message: string): void {\n logger.warn(`[${targetName}] ${message}`);\n }\n\n errorForTarget(targetName: string, message: string): void {\n logger.error(`[${targetName}] ${message}`);\n }\n}\n\nexport const batchRunner = new BatchRunner();\n","// @awa-component: DIFF-DiffEngine\n// @awa-impl: DIFF-1_AC-1\n// @awa-impl: DIFF-1_AC-2\n// @awa-impl: DIFF-1_AC-3\n// @awa-impl: DIFF-2_AC-1\n// @awa-impl: DIFF-2_AC-2\n// @awa-impl: DIFF-2_AC-3\n// @awa-impl: DIFF-2_AC-4\n// @awa-impl: DIFF-2_AC-5\n// @awa-impl: DIFF-3_AC-1\n// @awa-impl: DIFF-3_AC-2\n// @awa-impl: DIFF-3_AC-3\n// @awa-impl: DIFF-4_AC-1\n// @awa-impl: DIFF-4_AC-2\n// @awa-impl: DIFF-5_AC-1\n// @awa-impl: DIFF-5_AC-2\n// @awa-impl: DIFF-5_AC-3\n// @awa-impl: DIFF-6_AC-1\n// @awa-impl: DIFF-6_AC-2\n// @awa-impl: DIFF-6_AC-3\n\nimport { tmpdir } from 'node:os';\nimport { join, relative } from 'node:path';\nimport { structuredPatch } from 'diff';\nimport { isBinaryFile as detectBinaryFile } from 'isbinaryfile';\nimport type { DiffOptions, DiffResult, FileDiff, GenerateOptions } from '../types/index.js';\nimport { ensureDir, pathExists, readBinaryFile, rmDir, walkDirectory } from '../utils/fs.js';\nimport { loadDeleteList, resolveDeleteList } from './delete-list.js';\nimport { fileGenerator } from './generator.js';\n\nexport class DiffEngine {\n // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2, DIFF-1_AC-3\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5\n // @awa-impl: DIFF-3_AC-1, DIFF-3_AC-2, DIFF-3_AC-3\n // @awa-impl: DIFF-4_AC-1, DIFF-4_AC-2\n // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2, DIFF-5_AC-3\n // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3\n async diff(options: DiffOptions): Promise<DiffResult> {\n const { templatePath, targetPath, features, listUnknown } = options;\n\n // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2\n const tempPath = await this.createTempDir();\n\n try {\n // Generate templates to temp directory\n const generateOptions: GenerateOptions = {\n templatePath,\n outputPath: tempPath,\n features,\n force: true,\n dryRun: false,\n delete: false,\n };\n\n await fileGenerator.generate(generateOptions);\n\n // Collect all files from both directories\n const generatedFiles = new Set<string>();\n const targetFiles = new Set<string>();\n\n // Walk generated directory (if exists - may be empty if template generates nothing)\n if (await pathExists(tempPath)) {\n for await (const file of walkDirectory(tempPath)) {\n const relPath = relative(tempPath, file);\n generatedFiles.add(relPath);\n }\n }\n\n // Walk target directory (if exists)\n if (await pathExists(targetPath)) {\n for await (const file of walkDirectory(targetPath)) {\n const relPath = relative(targetPath, file);\n targetFiles.add(relPath);\n }\n }\n\n // Compare files: iterate generated files first; optionally include target-only files when requested\n const files: FileDiff[] = [];\n\n for (const relPath of generatedFiles) {\n const generatedFilePath = join(tempPath, relPath);\n const targetFilePath = join(targetPath, relPath);\n\n if (targetFiles.has(relPath)) {\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5\n const fileDiff = await this.compareFiles(generatedFilePath, targetFilePath, relPath);\n files.push(fileDiff);\n } else {\n // @awa-impl: DIFF-3_AC-1\n files.push({\n relativePath: relPath,\n status: 'new',\n });\n }\n }\n\n if (listUnknown) {\n for (const relPath of targetFiles) {\n if (generatedFiles.has(relPath)) {\n continue;\n }\n\n // @awa-impl: DIFF-3_AC-2, DIFF-3_AC-3, DIFF-3_AC-4\n files.push({\n relativePath: relPath,\n status: 'extra',\n });\n }\n }\n\n // Check delete list for files that exist in target\n const deleteEntries = await loadDeleteList(templatePath);\n const deleteList = resolveDeleteList(deleteEntries, features ?? []);\n for (const relPath of deleteList) {\n if (targetFiles.has(relPath) && !generatedFiles.has(relPath)) {\n // Remove any existing 'extra' entry for this path (to avoid double-reporting)\n const existingIdx = files.findIndex(\n (f) => f.relativePath === relPath && f.status === 'extra'\n );\n if (existingIdx !== -1) {\n files.splice(existingIdx, 1);\n }\n files.push({\n relativePath: relPath,\n status: 'delete-listed',\n });\n }\n }\n\n // Calculate summary\n const identical = files.filter((f) => f.status === 'identical').length;\n const modified = files.filter((f) => f.status === 'modified').length;\n const newFiles = files.filter((f) => f.status === 'new').length;\n const extraFiles = files.filter((f) => f.status === 'extra').length;\n const binaryDiffers = files.filter((f) => f.status === 'binary-differs').length;\n const deleteListed = files.filter((f) => f.status === 'delete-listed').length;\n\n const hasDifferences =\n modified > 0 || newFiles > 0 || extraFiles > 0 || binaryDiffers > 0 || deleteListed > 0;\n\n return {\n files,\n identical,\n modified,\n newFiles,\n extraFiles,\n binaryDiffers,\n deleteListed,\n hasDifferences,\n };\n } finally {\n // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3\n await this.cleanupTempDir(tempPath);\n }\n }\n\n // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2\n async createTempDir(): Promise<string> {\n const systemTemp = tmpdir();\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n const tempPath = join(systemTemp, `awa-diff-${timestamp}-${random}`);\n\n await ensureDir(tempPath);\n return tempPath;\n }\n\n // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3\n async cleanupTempDir(tempPath: string): Promise<void> {\n try {\n if (await pathExists(tempPath)) {\n await rmDir(tempPath);\n }\n } catch (_error) {\n // Swallow cleanup errors - temp directory will be cleaned by OS eventually\n // This ensures cleanup errors don't mask the actual diff results\n }\n }\n\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5\n async compareFiles(\n generatedPath: string,\n targetPath: string,\n relativePath: string\n ): Promise<FileDiff> {\n // Read raw bytes for byte-for-byte comparison.\n const generatedBytes = await readBinaryFile(generatedPath);\n const targetBytes = await readBinaryFile(targetPath);\n\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-3\n if (generatedBytes.equals(targetBytes)) {\n return {\n relativePath,\n status: 'identical',\n };\n }\n\n // @awa-impl: DIFF-2_AC-5\n // If either side is binary, do not attempt a text diff.\n const isBinaryGenerated = await this.isBinaryFile(generatedPath);\n const isBinaryTarget = await this.isBinaryFile(targetPath);\n\n if (isBinaryGenerated || isBinaryTarget) {\n return {\n relativePath,\n status: 'binary-differs',\n };\n }\n\n // Text files: unified diff (diff library is text-based)\n const generatedContent = generatedBytes.toString('utf-8');\n const targetContent = targetBytes.toString('utf-8');\n\n // @awa-impl: DIFF-2_AC-4\n // Generate unified diff\n const patch = structuredPatch(\n `a/${relativePath}`,\n `b/${relativePath}`,\n targetContent,\n generatedContent,\n 'target',\n 'generated',\n {\n context: 3,\n }\n );\n\n // Format as git-style unified diff string (with file headers)\n const headerLines = [\n `diff --git a/${relativePath} b/${relativePath}`,\n `--- a/${relativePath}`,\n `+++ b/${relativePath}`,\n ];\n\n const hunkLines = patch.hunks.flatMap((hunk) => {\n const lines = [`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`];\n lines.push(...hunk.lines);\n return lines;\n });\n\n const unifiedDiff = [...headerLines, ...hunkLines].join('\\n');\n\n return {\n relativePath,\n status: 'modified',\n unifiedDiff,\n };\n }\n\n // @awa-impl: DIFF-2_AC-5\n async isBinaryFile(filePath: string): Promise<boolean> {\n try {\n return await detectBinaryFile(filePath);\n } catch {\n // If detection fails, assume text file\n return false;\n }\n }\n}\n\nexport const diffEngine = new DiffEngine();\n","// @awa-component: GEN-DeleteList\n\nimport { join } from 'node:path';\nimport { pathExists, readTextFile } from '../utils/fs.js';\n\nconst DELETE_LIST_FILENAME = '_delete.txt';\n\n/**\n * A delete list entry. When `features` is set, the path is only deleted\n * when NONE of those features are present in the active feature set\n * (stale tool cleanup). When `features` is absent, the path is always\n * deleted (legacy removal).\n */\nexport interface DeleteEntry {\n path: string;\n /** One or more feature names — keep (don't delete) if any is active. */\n features?: string[];\n}\n\n/**\n * Parse `_delete.txt` content into structured entries.\n *\n * Format:\n * - Blank lines and `#` comments are ignored.\n * - `# @feature <name> [<name2> ...]` starts a feature-gated section: subsequent\n * paths are deleted only when NONE of the listed features are active.\n * - Any other comment line clears the current feature section (returns to\n * always-delete behaviour).\n * - Path lines inherit the current section's feature tag (if any).\n */\nexport function parseDeleteList(content: string): DeleteEntry[] {\n const entries: DeleteEntry[] = [];\n let currentFeatures: string[] | undefined;\n\n for (const raw of content.split('\\n')) {\n const line = raw.trim();\n if (line.length === 0) continue;\n\n if (line.startsWith('#')) {\n const featureMatch = line.match(/^#\\s*@feature\\s+(.+)$/);\n if (featureMatch) {\n const featureSection = featureMatch[1];\n currentFeatures = featureSection ? featureSection.trim().split(/\\s+/) : undefined;\n } else {\n // Any other comment resets the feature section\n currentFeatures = undefined;\n }\n continue;\n }\n\n entries.push({ path: line, features: currentFeatures });\n }\n\n return entries;\n}\n\n/**\n * Resolve which paths from the delete list should actually be deleted,\n * given the currently active feature flags.\n *\n * - Entries without a feature tag are always included (legacy removals).\n * - Entries with feature tags are included only when NONE of those features are active\n * (stale tool output cleanup).\n */\nexport function resolveDeleteList(entries: DeleteEntry[], activeFeatures: string[]): string[] {\n const activeSet = new Set(activeFeatures);\n return entries\n .filter((e) => e.features === undefined || !e.features.some((f) => activeSet.has(f)))\n .map((e) => e.path);\n}\n\n/**\n * Load and parse `_delete.txt` from the template directory.\n * Returns empty array if the file does not exist.\n */\nexport async function loadDeleteList(templatePath: string): Promise<DeleteEntry[]> {\n const deleteListPath = join(templatePath, DELETE_LIST_FILENAME);\n\n if (!(await pathExists(deleteListPath))) {\n return [];\n }\n\n const content = await readTextFile(deleteListPath);\n return parseDeleteList(content);\n}\n","// @awa-component: GEN-FileGenerator\n// @awa-impl: GEN-1_AC-1\n// @awa-impl: GEN-1_AC-2\n// @awa-impl: GEN-1_AC-3\n// @awa-impl: GEN-2_AC-1\n// @awa-impl: GEN-2_AC-2\n// @awa-impl: GEN-2_AC-3\n// @awa-impl: GEN-3_AC-1\n// @awa-impl: GEN-3_AC-2\n// @awa-impl: GEN-3_AC-3\n// @awa-impl: GEN-8_AC-1\n// @awa-impl: GEN-8_AC-2\n// @awa-impl: GEN-8_AC-3\n// @awa-impl: GEN-11_AC-3\n// @awa-impl: TPL-9_AC-1\n// @awa-impl: TPL-9_AC-2\n\nimport { join, relative } from 'node:path';\nimport { PACKAGE_INFO } from '../_generated/package_info.js';\nimport {\n type ConflictItem,\n type FileAction,\n type GenerateOptions,\n GenerationError,\n type GenerationResult,\n} from '../types/index.js';\nimport { deleteFile, pathExists, readTextFile, walkDirectory, writeTextFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { loadDeleteList, resolveDeleteList } from './delete-list.js';\nimport { conflictResolver, deleteResolver } from './resolver.js';\nimport { templateEngine } from './template.js';\n\nexport class FileGenerator {\n // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3\n // @awa-impl: GEN-2_AC-1, GEN-2_AC-2, GEN-2_AC-3\n // @awa-impl: GEN-3_AC-1, GEN-3_AC-2, GEN-3_AC-3\n async generate(options: GenerateOptions): Promise<GenerationResult> {\n const { templatePath, outputPath, features, force, dryRun } = options;\n const enableDelete = options.delete;\n\n // Configure template engine\n templateEngine.configure(templatePath);\n\n const actions: FileAction[] = [];\n let created = 0;\n let overwritten = 0;\n let deleted = 0;\n let skippedEmpty = 0;\n let skippedUser = 0;\n let skippedEqual = 0;\n\n // Collect files to process\n interface FileToProcess {\n templateFile: string;\n outputFile: string;\n content: string;\n isNew: boolean;\n }\n\n const filesToProcess: FileToProcess[] = [];\n const conflicts: ConflictItem[] = [];\n\n try {\n // First pass: render all templates and categorize files\n for await (const templateFile of this.walkTemplates(templatePath)) {\n // Compute output path\n const outputFile = this.computeOutputPath(templateFile, templatePath, outputPath);\n\n // Render template\n const result = await templateEngine.render(templateFile, {\n features,\n version: PACKAGE_INFO.version,\n });\n\n // Handle empty output\n if (result.isEmpty && !result.isEmptyFileMarker) {\n // Skip empty files\n actions.push({\n type: 'skip-empty',\n sourcePath: templateFile,\n outputPath: outputFile,\n });\n skippedEmpty++;\n continue;\n }\n\n // Get final content (empty string if marker)\n const content = result.isEmptyFileMarker ? '' : result.content;\n\n // Check for conflicts\n const fileExists = await pathExists(outputFile);\n\n if (fileExists) {\n // Read existing content for comparison\n const existingContent = await readTextFile(outputFile);\n conflicts.push({\n outputPath: outputFile,\n sourcePath: templateFile,\n newContent: content,\n existingContent,\n });\n }\n\n filesToProcess.push({\n templateFile,\n outputFile,\n content,\n isNew: !fileExists,\n });\n }\n\n // Resolve all conflicts at once if there are any\n let resolution: { overwrite: string[]; skip: string[]; equal: string[] } = {\n overwrite: [],\n skip: [],\n equal: [],\n };\n if (conflicts.length > 0) {\n resolution = await conflictResolver.resolveBatch(conflicts, force, dryRun);\n }\n\n // Second pass: process files based on resolution\n for (const file of filesToProcess) {\n if (file.isNew) {\n // Create new file\n if (!dryRun) {\n await writeTextFile(file.outputFile, file.content);\n }\n actions.push({\n type: 'create',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n created++;\n logger.fileAction({\n type: 'create',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n } else if (resolution.overwrite.includes(file.outputFile)) {\n // Overwrite existing file\n if (!dryRun) {\n await writeTextFile(file.outputFile, file.content);\n }\n actions.push({\n type: 'overwrite',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n overwritten++;\n logger.fileAction({\n type: 'overwrite',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n } else if (resolution.equal.includes(file.outputFile)) {\n // Skip file — content is identical\n actions.push({\n type: 'skip-equal',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n skippedEqual++;\n logger.fileAction({\n type: 'skip-equal',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n } else if (resolution.skip.includes(file.outputFile)) {\n // Skip file — user declined overwrite\n actions.push({\n type: 'skip-user',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n skippedUser++;\n logger.fileAction({\n type: 'skip-user',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n }\n }\n\n // Process delete list (after file generation)\n const deleteEntries = await loadDeleteList(templatePath);\n if (deleteEntries.length > 0) {\n const deleteList = resolveDeleteList(deleteEntries, features);\n\n // Collect generated output paths to detect conflicts\n const generatedOutputPaths = new Set(filesToProcess.map((f) => f.outputFile));\n\n // Filter: only files that exist and aren't being generated\n const deleteCandidates: string[] = [];\n for (const relPath of deleteList) {\n const absPath = join(outputPath, relPath);\n if (generatedOutputPaths.has(absPath)) {\n logger.warn(\n `Delete list entry '${relPath}' conflicts with generated file — skipping deletion`\n );\n continue;\n }\n if (await pathExists(absPath)) {\n deleteCandidates.push(absPath);\n }\n }\n\n if (deleteCandidates.length > 0) {\n if (!enableDelete) {\n // --delete not passed: warn but do nothing\n for (const absPath of deleteCandidates) {\n logger.warn(\n `Would delete (pass --delete to enable): ${relative(outputPath, absPath)}`\n );\n }\n } else {\n const confirmed = await deleteResolver.resolveDeletes(deleteCandidates, force, dryRun);\n\n for (const absPath of confirmed) {\n if (!dryRun) {\n await deleteFile(absPath);\n }\n actions.push({ type: 'delete', outputPath: absPath });\n deleted++;\n logger.fileAction({ type: 'delete', outputPath: absPath });\n }\n }\n }\n }\n\n return {\n actions,\n created,\n overwritten,\n deleted,\n skipped: skippedEmpty + skippedUser + skippedEqual,\n skippedEmpty,\n skippedUser,\n skippedEqual,\n };\n } catch (error) {\n // @awa-impl: GEN-2_AC-3, GEN-11_AC-3\n if (error instanceof Error && 'code' in error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'EACCES' || code === 'EPERM') {\n throw new GenerationError(`Permission denied: ${error.message}`, 'PERMISSION_DENIED');\n }\n if (code === 'ENOSPC') {\n throw new GenerationError(`Disk full: ${error.message}`, 'DISK_FULL');\n }\n }\n throw error;\n }\n }\n\n // @awa-impl: GEN-8_AC-1, GEN-8_AC-2, GEN-8_AC-3\n // @awa-impl: TPL-9_AC-1, TPL-9_AC-2\n async *walkTemplates(dir: string): AsyncIterable<string> {\n // Use utility function that already handles underscore exclusion\n yield* walkDirectory(dir);\n }\n\n // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3\n computeOutputPath(templatePath: string, templateRoot: string, outputRoot: string): string {\n // Get relative path from template root\n const relativePath = relative(templateRoot, templatePath);\n\n // Join with output root to mirror structure\n return join(outputRoot, relativePath);\n }\n}\n\nexport const fileGenerator = new FileGenerator();\n","// @awa-component: GEN-ConflictResolver\n// @awa-impl: CLI-5_AC-2\n// @awa-impl: CLI-5_AC-3\n// @awa-impl: GEN-4_AC-1\n// @awa-impl: GEN-4_AC-2\n// @awa-impl: GEN-4_AC-3\n// @awa-impl: GEN-5_AC-1\n// @awa-impl: GEN-5_AC-2\n// @awa-impl: GEN-5_AC-3\n// @awa-impl: GEN-5_AC-4\n// @awa-impl: GEN-5_AC-5\n// @awa-impl: GEN-5_AC-6\n// @awa-impl: GEN-5_AC-7\n// @awa-impl: GEN-6_AC-3\n// @awa-impl: GEN-10_AC-3\n\nimport { MultiSelectPrompt } from '@clack/core';\nimport { isCancel, multiselect } from '@clack/prompts';\nimport chalk from 'chalk';\nimport type { BatchConflictResolution, ConflictItem } from '../types/index.js';\n\n// Unicode symbols (mirrors @clack/prompts internals)\nconst _unicode = process.platform !== 'win32';\nconst _s = (c: string, fb: string) => (_unicode ? c : fb);\nconst _CHECKED = _s('\\u25FC', '[+]'); // ◼\nconst _UNCHECKED_A = _s('\\u25FB', '[·]'); // ◻ active\nconst _UNCHECKED = _s('\\u25FB', '[ ]'); // ◻ inactive\nconst _BAR = _s('\\u2502', '|'); // │\nconst _BAR_END = _s('\\u2514', '-'); // └\n\ntype SelectOption = { value: string; label?: string; hint?: string };\n\nfunction _renderDeleteItem(opt: SelectOption, state: string): string {\n const label = opt.label ?? opt.value;\n const hint = opt.hint ? ` ${chalk.dim(`(${opt.hint})`)}` : '';\n switch (state) {\n case 'active':\n return `${chalk.cyan(_UNCHECKED_A)} ${label}${hint}`;\n case 'selected':\n return `${chalk.red(_CHECKED)} ${chalk.dim(label)}${hint}`;\n case 'active-selected':\n return `${chalk.red(_CHECKED)} ${label}${hint}`;\n case 'cancelled':\n return chalk.strikethrough(chalk.dim(label));\n case 'submitted':\n return chalk.dim(label);\n default:\n return `${chalk.dim(_UNCHECKED)} ${chalk.dim(label)}`;\n }\n}\n\n/** Like @clack/prompts `multiselect` but with red checkboxes for destructive operations. */\nasync function deleteMultiselect(opts: {\n message: string;\n options: SelectOption[];\n initialValues?: string[];\n required?: boolean;\n}): Promise<string[] | symbol> {\n const { message, options, initialValues, required = false } = opts;\n return new MultiSelectPrompt({\n options,\n initialValues,\n required,\n render() {\n const self = this as unknown as {\n state: string;\n options: SelectOption[];\n cursor: number;\n value: string[];\n };\n const header = `${chalk.gray(_BAR)}\\n${chalk.cyan(_BAR)} ${message}\\n`;\n const getState = (opt: SelectOption, idx: number): string => {\n const active = idx === self.cursor;\n const sel = self.value.includes(opt.value);\n if (active && sel) return 'active-selected';\n if (sel) return 'selected';\n if (active) return 'active';\n return 'inactive';\n };\n switch (self.state) {\n case 'submit':\n return (\n `${header}${chalk.gray(_BAR)} ` +\n (self.options\n .filter((o) => self.value.includes(o.value))\n .map((o) => _renderDeleteItem(o, 'submitted'))\n .join(chalk.dim(', ')) || chalk.dim('none'))\n );\n case 'cancel': {\n const cancelled = self.options\n .filter((o) => self.value.includes(o.value))\n .map((o) => _renderDeleteItem(o, 'cancelled'))\n .join(chalk.dim(', '));\n return `${header}${chalk.gray(_BAR)} ${cancelled.trim() ? `${cancelled}\\n${chalk.gray(_BAR)}` : chalk.dim('none')}`;\n }\n default:\n return (\n `${header}${chalk.cyan(_BAR)} ` +\n self.options\n .map((o, i) => _renderDeleteItem(o, getState(o, i)))\n .join(`\\n${chalk.cyan(_BAR)} `) +\n `\\n${chalk.cyan(_BAR_END)}\\n`\n );\n }\n },\n }).prompt() as Promise<string[] | symbol>;\n}\n\nexport class ConflictResolver {\n // @awa-impl: GEN-4_AC-1, GEN-4_AC-2, GEN-4_AC-3\n // @awa-impl: GEN-5_AC-1, GEN-5_AC-2, GEN-5_AC-3, GEN-5_AC-4, GEN-5_AC-5, GEN-5_AC-6, GEN-5_AC-7\n // @awa-impl: CLI-5_AC-2, CLI-5_AC-3\n // @awa-impl: GEN-6_AC-3\n async resolveBatch(\n conflicts: ConflictItem[],\n force: boolean,\n dryRun: boolean\n ): Promise<BatchConflictResolution> {\n // Separate identical-content files from different files\n const identicalPaths = conflicts\n .filter((c) => c.newContent === c.existingContent)\n .map((c) => c.outputPath);\n const differentFiles = conflicts.filter((c) => c.newContent !== c.existingContent);\n\n // In dry-run mode, never modify files (P7: Dry Run Immutable)\n if (dryRun) {\n return {\n overwrite: [],\n skip: differentFiles.map((c) => c.outputPath),\n equal: identicalPaths,\n };\n }\n\n // In force mode, always overwrite without prompting (P8: Force No Prompt)\n if (force) {\n return {\n overwrite: differentFiles.map((c) => c.outputPath),\n skip: [],\n equal: identicalPaths,\n };\n }\n\n // If all files are identical, skip them all\n if (differentFiles.length === 0) {\n return {\n overwrite: [],\n skip: [],\n equal: identicalPaths,\n };\n }\n\n // @awa-impl: GEN-5_AC-1, GEN-5_AC-2, GEN-5_AC-5, GEN-5_AC-6\n // Prompt user with multi-select (all selected by default)\n const selected = await multiselect({\n message: 'The following files already exist. Select files to overwrite:',\n options: differentFiles.map((c) => ({\n value: c.outputPath,\n label: c.outputPath,\n })),\n initialValues: differentFiles.map((c) => c.outputPath), // All selected by default (AC-5.6)\n required: false,\n });\n\n // @awa-impl: GEN-10_AC-3\n // Handle user cancellation (Ctrl+C)\n if (isCancel(selected)) {\n process.exit(1);\n }\n\n const selectedPaths = selected as string[];\n const allPaths = differentFiles.map((c) => c.outputPath);\n\n return {\n overwrite: selectedPaths,\n skip: allPaths.filter((p) => !selectedPaths.includes(p)),\n equal: identicalPaths,\n };\n }\n}\n\nexport const conflictResolver = new ConflictResolver();\n\nexport class DeleteResolver {\n /**\n * Prompt user to confirm which files to delete.\n * Returns the list of absolute paths confirmed for deletion.\n */\n async resolveDeletes(candidates: string[], force: boolean, dryRun: boolean): Promise<string[]> {\n if (candidates.length === 0) {\n return [];\n }\n\n // In dry-run mode, return all candidates (caller logs but won't delete)\n if (dryRun) {\n return candidates;\n }\n\n // In force mode, delete without prompting\n if (force) {\n return candidates;\n }\n\n // Prompt user with multi-select (all selected by default, red checkboxes)\n const selected = await deleteMultiselect({\n message:\n '⚠ WARNING: The selected files will be PERMANENTLY DELETED from disk.\\n' +\n ' Deselect any files you want to keep. Press Enter to confirm deletion:',\n options: candidates.map((p) => ({\n value: p,\n label: p,\n })),\n initialValues: candidates,\n required: false,\n });\n\n // Handle user cancellation (Ctrl+C)\n if (isCancel(selected)) {\n process.exit(1);\n }\n\n return selected as string[];\n }\n}\n\nexport const deleteResolver = new DeleteResolver();\n","// @awa-component: TPL-TemplateEngine\n// @awa-impl: TPL-4_AC-1\n// @awa-impl: TPL-4_AC-2\n// @awa-impl: TPL-4_AC-3\n// @awa-impl: TPL-4_AC-4\n// @awa-impl: TPL-5_AC-1\n// @awa-impl: TPL-5_AC-2\n// @awa-impl: TPL-5_AC-3\n// @awa-impl: TPL-6_AC-1\n// @awa-impl: TPL-6_AC-2\n// @awa-impl: TPL-7_AC-1\n// @awa-impl: TPL-7_AC-2\n// @awa-impl: TPL-8_AC-1\n// @awa-impl: TPL-8_AC-2\n// @awa-impl: TPL-8_AC-3\n// @awa-impl: TPL-8_AC-4\n// @awa-impl: TPL-11_AC-1\n// @awa-impl: TPL-11_AC-2\n\nimport { Eta } from 'eta';\nimport { type RenderResult, type TemplateContext, TemplateError } from '../types/index.js';\nimport { readTextFile } from '../utils/fs.js';\n\nconst EMPTY_FILE_MARKER = '<!-- AWA:EMPTY_FILE -->';\n\nexport class TemplateEngine {\n private eta: Eta | null = null;\n private templateDir: string | null = null;\n private compiledCache = new Map<string, unknown>();\n\n // @awa-impl: TPL-8_AC-1, TPL-8_AC-2, TPL-8_AC-3, TPL-8_AC-4\n configure(templateDir: string): void {\n this.templateDir = templateDir;\n this.compiledCache.clear();\n\n // @awa-impl: TPL-4_AC-1, TPL-4_AC-2, TPL-4_AC-3, TPL-4_AC-4\n // Configure Eta with partials support\n this.eta = new Eta({\n views: templateDir,\n cache: true, // Enable compilation caching\n autoEscape: false, // Don't escape HTML by default\n defaultExtension: '', // No automatic extension - use exact path as specified (AC-8.2)\n });\n }\n\n // @awa-impl: TPL-5_AC-1, TPL-5_AC-2, TPL-5_AC-3\n // @awa-impl: TPL-6_AC-1, TPL-6_AC-2\n // @awa-impl: TPL-7_AC-1, TPL-7_AC-2\n // @awa-impl: TPL-11_AC-1, TPL-11_AC-2\n async render(templatePath: string, context: TemplateContext): Promise<RenderResult> {\n if (!this.eta || !this.templateDir) {\n throw new TemplateError(\n 'Template engine not configured. Call configure() first.',\n 'RENDER_ERROR'\n );\n }\n\n try {\n // Read template content\n const templateContent = await readTextFile(templatePath);\n\n // Render with features context\n // The context is available as 'it' in templates\n const rendered = await this.eta.renderStringAsync(templateContent, {\n features: context.features,\n version: context.version ?? '',\n });\n\n // Check if output is empty or only whitespace\n const trimmed = rendered.trim();\n const isEmpty = trimmed.length === 0;\n\n // Check for empty file marker\n const isEmptyFileMarker = trimmed === EMPTY_FILE_MARKER;\n\n return {\n content: rendered,\n isEmpty,\n isEmptyFileMarker,\n };\n } catch (error) {\n throw new TemplateError(\n `Failed to render template ${templatePath}: ${error instanceof Error ? error.message : String(error)}`,\n 'RENDER_ERROR',\n templatePath\n );\n }\n }\n}\n\nexport const templateEngine = new TemplateEngine();\n","// @awa-component: FP-FeatureResolver\n\nimport { ConfigError, type PresetDefinitions } from '../types/index.js';\n\nexport interface FeatureResolutionInput {\n baseFeatures: string[];\n presetNames: string[];\n removeFeatures: string[];\n presetDefinitions: PresetDefinitions;\n}\n\nexport class FeatureResolver {\n validatePresets(presetNames: string[], definitions: PresetDefinitions): void {\n for (const name of presetNames) {\n if (!definitions[name]) {\n throw new ConfigError(`Unknown preset: ${name}`, 'UNKNOWN_PRESET');\n }\n }\n }\n\n resolve(input: FeatureResolutionInput): string[] {\n const { baseFeatures, presetNames, removeFeatures, presetDefinitions } = input;\n\n this.validatePresets(presetNames, presetDefinitions);\n\n const finalFeatures: string[] = [];\n const seen = new Set<string>();\n\n const add = (feature: string) => {\n if (seen.has(feature)) return;\n seen.add(feature);\n finalFeatures.push(feature);\n };\n\n for (const feature of baseFeatures) add(feature);\n\n for (const presetName of presetNames) {\n for (const feature of presetDefinitions[presetName] ?? []) add(feature);\n }\n\n if (removeFeatures.length === 0) return finalFeatures;\n\n const removeSet = new Set(removeFeatures);\n return finalFeatures.filter((f) => !removeSet.has(f));\n }\n}\n\nexport const featureResolver = new FeatureResolver();\n","// @awa-component: JSON-JsonSerializer\n// @awa-impl: JSON-1_AC-1\n// @awa-impl: JSON-2_AC-1\n// @awa-impl: JSON-3_AC-1\n// @awa-impl: JSON-4_AC-1\n// @awa-impl: JSON-5_AC-1\n// @awa-impl: JSON-8_AC-1\n\nimport type {\n DiffFileJSON,\n DiffJSON,\n DiffResult,\n GenerationActionJSON,\n GenerationJSON,\n GenerationResult,\n} from '../types/index.js';\n\n// @awa-impl: JSON-1_AC-1, JSON-3_AC-1\nexport function serializeGenerationResult(result: GenerationResult): GenerationJSON {\n const actions: GenerationActionJSON[] = result.actions.map((action) => ({\n type: action.type,\n path: action.outputPath,\n }));\n\n return {\n actions,\n counts: {\n created: result.created,\n overwritten: result.overwritten,\n skipped: result.skipped,\n deleted: result.deleted,\n },\n };\n}\n\n// @awa-impl: JSON-2_AC-1, JSON-4_AC-1\nexport function serializeDiffResult(result: DiffResult): DiffJSON {\n const diffs: DiffFileJSON[] = result.files.map((file) => {\n const entry: DiffFileJSON = {\n path: file.relativePath,\n status: file.status,\n };\n if (file.unifiedDiff) {\n entry.diff = file.unifiedDiff;\n }\n return entry;\n });\n\n return {\n diffs,\n counts: {\n changed: result.modified,\n new: result.newFiles,\n matching: result.identical,\n deleted: result.deleteListed,\n },\n };\n}\n\n// @awa-impl: JSON-5_AC-1\nexport function formatGenerationSummary(result: GenerationResult): string {\n return `created: ${result.created}, overwritten: ${result.overwritten}, skipped: ${result.skipped}, deleted: ${result.deleted}`;\n}\n\n// @awa-impl: JSON-5_AC-1\nexport function formatDiffSummary(result: DiffResult): string {\n return `changed: ${result.modified}, new: ${result.newFiles}, matching: ${result.identical}, deleted: ${result.deleteListed}`;\n}\n\n// @awa-impl: JSON-8_AC-1\nexport function writeJsonOutput(data: GenerationJSON | DiffJSON): void {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n}\n","// @awa-component: OVL-OverlayResolver\n// @awa-component: OVL-MergedTemplateView\n// @awa-impl: OVL-1_AC-1\n// @awa-impl: OVL-2_AC-1\n// @awa-impl: OVL-3_AC-1\n// @awa-impl: OVL-4_AC-1\n// @awa-impl: OVL-5_AC-1\n// @awa-impl: OVL-6_AC-1\n\nimport { cp } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { ensureDir } from '../utils/fs.js';\nimport { templateResolver } from './template-resolver.js';\n\n/**\n * Resolve each overlay source string to a local directory path.\n * Delegates to TemplateResolver so local paths and Git sources are both handled.\n *\n * @awa-impl: OVL-1_AC-1, OVL-6_AC-1\n */\nexport async function resolveOverlays(overlays: string[], refresh: boolean): Promise<string[]> {\n const dirs: string[] = [];\n for (const source of overlays) {\n const resolved = await templateResolver.resolve(source, refresh);\n dirs.push(resolved.localPath);\n }\n return dirs;\n}\n\n/**\n * Build a temporary merged directory by copying baseDir then applying each\n * overlay in order. Later overlay files overwrite earlier ones at the same\n * relative path; base-only files are left intact; overlay-only files are added.\n *\n * Caller is responsible for cleaning up the returned temp directory.\n *\n * @awa-impl: OVL-2_AC-1, OVL-3_AC-1, OVL-4_AC-1, OVL-5_AC-1\n */\nexport async function buildMergedDir(baseDir: string, overlayDirs: string[]): Promise<string> {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n const tempPath = join(tmpdir(), `awa-overlay-${timestamp}-${random}`);\n\n await ensureDir(tempPath);\n\n // Copy base template files into the temp directory\n await cp(baseDir, tempPath, { recursive: true });\n\n // Apply overlays in order — later overlays win (force: true is the default for fs.cp)\n for (const overlayDir of overlayDirs) {\n await cp(overlayDir, tempPath, { recursive: true });\n }\n\n return tempPath;\n}\n","// @awa-component: TPL-TemplateResolver\n// @awa-impl: CLI-3_AC-2\n// @awa-impl: CLI-3_AC-3\n// @awa-impl: CLI-8_AC-2\n// @awa-impl: TPL-1_AC-1\n// @awa-impl: TPL-1_AC-2\n// @awa-impl: TPL-1_AC-3\n// @awa-impl: TPL-1_AC-4\n// @awa-impl: TPL-2_AC-1\n// @awa-impl: TPL-2_AC-2\n// @awa-impl: TPL-2_AC-3\n// @awa-impl: TPL-2_AC-4\n// @awa-impl: TPL-2_AC-5\n// @awa-impl: TPL-2_AC-6\n// @awa-impl: TPL-3_AC-1\n// @awa-impl: TPL-3_AC-2\n// @awa-impl: TPL-3_AC-3\n// @awa-impl: TPL-3_AC-4\n// @awa-impl: TPL-10_AC-1\n// @awa-impl: TPL-10_AC-2\n// @awa-impl: TPL-10_AC-3\n\nimport { createHash } from 'node:crypto';\nimport { rm } from 'node:fs/promises';\nimport { isAbsolute, join, resolve } from 'node:path';\nimport degit from 'degit';\nimport { type ResolvedTemplate, TemplateError, type TemplateSourceType } from '../types/index.js';\nimport { ensureDir, getCacheDir, getTemplateDir, pathExists } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nexport class TemplateResolver {\n // @awa-impl: CLI-3_AC-2, TPL-10_AC-1\n async resolve(source: string | null, refresh: boolean): Promise<ResolvedTemplate> {\n // If no source provided, use bundled templates\n if (!source) {\n const bundledPath = join(getTemplateDir(), 'awa');\n return {\n type: 'bundled',\n localPath: bundledPath,\n source: 'bundled',\n };\n }\n\n const type = this.detectType(source);\n\n // @awa-impl: TPL-1_AC-1, TPL-1_AC-2, TPL-1_AC-3, TPL-1_AC-4\n if (type === 'local') {\n // Resolve relative/absolute paths\n const localPath = isAbsolute(source) ? source : resolve(process.cwd(), source);\n\n // Check if path exists\n if (!(await pathExists(localPath))) {\n throw new TemplateError(\n `Template source not found: ${localPath}`,\n 'SOURCE_NOT_FOUND',\n source\n );\n }\n\n // Local templates are not cached\n return {\n type: 'local',\n localPath,\n source,\n };\n }\n\n // @awa-impl: TPL-2_AC-1, TPL-2_AC-2, TPL-2_AC-3, TPL-2_AC-4, TPL-2_AC-5, TPL-2_AC-6, TPL-3_AC-1, TPL-3_AC-2, TPL-3_AC-3, TPL-3_AC-4\n if (type === 'git') {\n const cachePath = this.getCachePath(source);\n\n // @awa-impl: CLI-8_AC-2, TPL-3_AC-2\n // Check if cached version exists\n const cacheExists = await pathExists(cachePath);\n\n if (cacheExists && !refresh) {\n // Use cached version\n logger.info(`Using cached template: ${source}`);\n return {\n type: 'git',\n localPath: cachePath,\n source,\n };\n }\n\n // Fetch from Git\n try {\n // Remove existing cache if refresh\n if (cacheExists && refresh) {\n logger.info(`Refreshing template: ${source}`);\n await rm(cachePath, { recursive: true, force: true });\n } else {\n logger.info(`Fetching template: ${source}`);\n }\n\n await ensureDir(cachePath);\n\n // Use degit for shallow fetch\n const emitter = degit(source, { cache: false, force: true });\n await emitter.clone(cachePath);\n\n return {\n type: 'git',\n localPath: cachePath,\n source,\n };\n } catch (error) {\n throw new TemplateError(\n `Failed to fetch Git template: ${error instanceof Error ? error.message : String(error)}`,\n 'FETCH_FAILED',\n source\n );\n }\n }\n\n throw new TemplateError(\n `Unable to resolve template source: ${source}`,\n 'SOURCE_NOT_FOUND',\n source\n );\n }\n\n // @awa-impl: TPL-2_AC-1, TPL-2_AC-2, TPL-2_AC-3, TPL-2_AC-4, TPL-2_AC-5, TPL-2_AC-6\n detectType(source: string): TemplateSourceType {\n // Check for local path indicators\n if (source.startsWith('.') || source.startsWith('/') || source.startsWith('~')) {\n return 'local';\n }\n\n // Check for Windows absolute paths\n if (/^[a-zA-Z]:/.test(source)) {\n return 'local';\n }\n\n // All other formats are treated as Git sources:\n // - GitHub shorthand: owner/repo\n // - Prefixed: github:owner/repo, gitlab:owner/repo, bitbucket:owner/repo\n // - HTTPS: https://github.com/owner/repo\n // - SSH: git@github.com:owner/repo\n // - With subdirs: owner/repo/path/to/templates\n // - With refs: owner/repo#branch\n return 'git';\n }\n\n // @awa-impl: TPL-3_AC-1\n getCachePath(source: string): string {\n // Create a stable cache path based on source hash\n const hash = createHash('sha256').update(source).digest('hex').substring(0, 16);\n const cacheDir = getCacheDir();\n return join(cacheDir, hash);\n }\n}\n\nexport const templateResolver = new TemplateResolver();\n","// @awa-component: DIFF-FileWatcher\n\nimport { type FSWatcher, watch } from 'node:fs';\nimport { Debouncer } from './debouncer.js';\n\nexport interface FileWatcherOptions {\n directory: string;\n debounceMs?: number;\n onChange: () => void;\n}\n\nexport class FileWatcher {\n private watcher: FSWatcher | null = null;\n private debouncer: Debouncer;\n private readonly directory: string;\n private readonly onChange: () => void;\n\n constructor(options: FileWatcherOptions) {\n this.directory = options.directory;\n this.debouncer = new Debouncer(options.debounceMs ?? 300);\n this.onChange = options.onChange;\n }\n\n start(): void {\n this.watcher = watch(this.directory, { recursive: true }, () => {\n this.debouncer.trigger(this.onChange);\n });\n }\n\n stop(): void {\n this.debouncer.cancel();\n if (this.watcher) {\n this.watcher.close();\n this.watcher = null;\n }\n }\n}\n","// @awa-component: DIFF-Debouncer\n\nexport class Debouncer {\n private timer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private readonly delayMs: number) {}\n\n trigger(callback: () => void): void {\n if (this.timer) {\n clearTimeout(this.timer);\n }\n this.timer = setTimeout(() => {\n this.timer = null;\n callback();\n }, this.delayMs);\n }\n\n cancel(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n","// @awa-component: DISC-FeaturesCommand\n// @awa-impl: DISC-4_AC-1\n// @awa-impl: DISC-5_AC-1\n\nimport { intro, outro } from '@clack/prompts';\nimport { configLoader } from '../core/config.js';\nimport { featuresReporter } from '../core/features/reporter.js';\nimport { featureScanner } from '../core/features/scanner.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport { logger } from '../utils/logger.js';\n\nexport interface FeaturesCommandOptions {\n template?: string;\n config?: string;\n refresh?: boolean;\n json?: boolean;\n}\n\n// @awa-impl: DISC-4_AC-1, DISC-5_AC-1\nexport async function featuresCommand(cliOptions: FeaturesCommandOptions): Promise<number> {\n try {\n if (!cliOptions.json) {\n intro('awa CLI - Feature Discovery');\n }\n\n // Load configuration file (for presets and default template)\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // Resolve template source — reuse same resolver as generate/diff\n const templateSource = cliOptions.template ?? fileConfig?.template ?? null;\n const refresh = cliOptions.refresh ?? fileConfig?.refresh ?? false;\n const template = await templateResolver.resolve(templateSource, refresh);\n\n // Scan template for feature flags\n const scanResult = await featureScanner.scan(template.localPath);\n\n // Retrieve preset definitions from config if available\n const presets = fileConfig?.presets;\n\n // Report results\n featuresReporter.report({\n scanResult,\n json: cliOptions.json ?? false,\n presets,\n });\n\n if (!cliOptions.json) {\n outro('Feature discovery complete!');\n }\n\n return 0;\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n return 1;\n }\n}\n","// @awa-component: DISC-Reporter\n// @awa-impl: DISC-6_AC-1\n// @awa-impl: DISC-7_AC-1\n\nimport chalk from 'chalk';\nimport type { PresetDefinitions } from '../../types/index.js';\nimport type { ScanResult } from './scanner.js';\n\n/** Options for rendering the features report. */\nexport interface ReportOptions {\n /** Scan results from the feature scanner. */\n scanResult: ScanResult;\n /** Whether to output JSON instead of a human-readable table. */\n json: boolean;\n /** Preset definitions from the user's .awa.toml, if available. */\n presets?: PresetDefinitions;\n}\n\n/** JSON output structure for --json mode. */\nexport interface FeaturesJsonOutput {\n features: Array<{\n name: string;\n files: string[];\n }>;\n presets?: Record<string, string[]>;\n filesScanned: number;\n}\n\nexport class FeaturesReporter {\n // @awa-impl: DISC-6_AC-1, DISC-7_AC-1\n /** Render the features report to stdout. */\n report(options: ReportOptions): void {\n const { scanResult, json, presets } = options;\n\n if (json) {\n this.reportJson(scanResult, presets);\n } else {\n this.reportTable(scanResult, presets);\n }\n }\n\n // @awa-impl: DISC-6_AC-1\n /** Build the JSON output object (also used by tests). */\n buildJsonOutput(scanResult: ScanResult, presets?: PresetDefinitions): FeaturesJsonOutput {\n const output: FeaturesJsonOutput = {\n features: scanResult.features.map((f) => ({\n name: f.name,\n files: f.files,\n })),\n filesScanned: scanResult.filesScanned,\n };\n\n if (presets && Object.keys(presets).length > 0) {\n output.presets = presets;\n }\n\n return output;\n }\n\n private reportJson(scanResult: ScanResult, presets?: PresetDefinitions): void {\n const output = this.buildJsonOutput(scanResult, presets);\n console.log(JSON.stringify(output, null, 2));\n }\n\n // @awa-impl: DISC-7_AC-1\n private reportTable(scanResult: ScanResult, presets?: PresetDefinitions): void {\n const { features, filesScanned } = scanResult;\n\n if (features.length === 0) {\n console.log(chalk.yellow('No feature flags found.'));\n console.log(chalk.dim(`(${filesScanned} files scanned)`));\n return;\n }\n\n console.log(chalk.bold(`Feature flags (${features.length} found):\\n`));\n\n for (const feature of features) {\n console.log(` ${chalk.cyan(feature.name)}`);\n for (const file of feature.files) {\n console.log(` ${chalk.dim(file)}`);\n }\n }\n\n console.log('');\n console.log(chalk.dim(`${filesScanned} files scanned`));\n\n // Show presets if available\n if (presets && Object.keys(presets).length > 0) {\n console.log('');\n console.log(chalk.bold('Presets (from .awa.toml):\\n'));\n for (const [name, flags] of Object.entries(presets)) {\n console.log(` ${chalk.green(name)}: ${flags.join(', ')}`);\n }\n }\n }\n}\n\nexport const featuresReporter = new FeaturesReporter();\n","// @awa-component: DISC-FeatureScanner\n// @awa-impl: DISC-1_AC-1\n// @awa-impl: DISC-2_AC-1\n// @awa-impl: DISC-3_AC-1\n\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\n\n/** A single feature flag discovered in a template. */\nexport interface DiscoveredFeature {\n /** The flag name (e.g. \"copilot\"). */\n name: string;\n /** Relative paths of template files that reference this flag. */\n files: string[];\n}\n\n/** Result of scanning a template directory for feature flags. */\nexport interface ScanResult {\n /** All discovered feature flags, sorted by name. */\n features: DiscoveredFeature[];\n /** Total number of template files scanned. */\n filesScanned: number;\n}\n\n// Matches: it.features.includes('name') or it.features.includes(\"name\")\n// Also matches: it.features.indexOf('name') or it.features.indexOf(\"name\")\nconst FEATURE_PATTERN = /it\\.features\\.(?:includes|indexOf)\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n/**\n * Recursively walk a directory yielding all file paths (including those\n * starting with underscore, since partials may reference feature flags).\n */\nasync function* walkAllFiles(dir: string): AsyncGenerator<string> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkAllFiles(fullPath);\n } else if (entry.isFile()) {\n yield fullPath;\n }\n }\n}\n\nexport class FeatureScanner {\n // @awa-impl: DISC-1_AC-1, DISC-2_AC-1\n /** Extract feature flag names from a single file's content. */\n extractFlags(content: string): string[] {\n const flags = new Set<string>();\n for (const match of content.matchAll(FEATURE_PATTERN)) {\n if (match[1]) {\n flags.add(match[1]);\n }\n }\n return [...flags];\n }\n\n // @awa-impl: DISC-1_AC-1, DISC-2_AC-1, DISC-3_AC-1\n /** Scan a template directory and return all discovered feature flags. */\n async scan(templatePath: string): Promise<ScanResult> {\n const flagToFiles = new Map<string, Set<string>>();\n let filesScanned = 0;\n\n for await (const filePath of walkAllFiles(templatePath)) {\n filesScanned++;\n try {\n const content = await readFile(filePath, 'utf-8');\n const flags = this.extractFlags(content);\n const relPath = relative(templatePath, filePath);\n for (const flag of flags) {\n const existing = flagToFiles.get(flag);\n if (existing) {\n existing.add(relPath);\n } else {\n flagToFiles.set(flag, new Set([relPath]));\n }\n }\n } catch {\n // Skip binary files or files that can't be read as UTF-8\n }\n }\n\n const features: DiscoveredFeature[] = [...flagToFiles.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, files]) => ({\n name,\n files: [...files].sort(),\n }));\n\n return { features, filesScanned };\n }\n}\n\nexport const featureScanner = new FeatureScanner();\n","// @awa-component: GEN-GenerateCommand\n// @awa-component: JSON-GenerateCommand\n// @awa-impl: INIT-5_AC-1\n\nimport { intro, isCancel, multiselect, outro } from '@clack/prompts';\nimport { batchRunner } from '../core/batch-runner.js';\nimport { configLoader } from '../core/config.js';\nimport { featureResolver } from '../core/feature-resolver.js';\nimport { fileGenerator } from '../core/generator.js';\nimport {\n formatGenerationSummary,\n serializeGenerationResult,\n writeJsonOutput,\n} from '../core/json-output.js';\nimport { buildMergedDir, resolveOverlays } from '../core/overlay.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport type { RawCliOptions, ResolvedOptions } from '../types/index.js';\nimport { rmDir } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\n/** Known AI tool feature flags for interactive selection. */\nconst TOOL_FEATURES = [\n { value: 'copilot', label: 'GitHub Copilot' },\n { value: 'claude', label: 'Claude Code' },\n { value: 'cursor', label: 'Cursor' },\n { value: 'windsurf', label: 'Windsurf' },\n { value: 'kilocode', label: 'Kilocode' },\n { value: 'opencode', label: 'OpenCode' },\n { value: 'gemini', label: 'Gemini CLI' },\n { value: 'roo', label: 'Roo Code' },\n { value: 'qwen', label: 'Qwen Code' },\n { value: 'codex', label: 'Codex CLI' },\n { value: 'agy', label: 'Antigravity (agy)' },\n { value: 'agents-md', label: 'AGENTS.md (cross-tool)' },\n] as const;\n\nconst TOOL_FEATURE_VALUES = new Set<string>(TOOL_FEATURES.map((t) => t.value));\n\nasync function runGenerate(options: ResolvedOptions, batchMode: boolean): Promise<void> {\n const silent = options.json || options.summary;\n\n // Resolve template source\n const template = await templateResolver.resolve(options.template, options.refresh);\n\n const features = featureResolver.resolve({\n baseFeatures: [...options.features],\n presetNames: [...options.preset],\n removeFeatures: [...options.removeFeatures],\n presetDefinitions: options.presets,\n });\n\n // @awa-impl: MTT-1_AC-1 // @awa-ignore\n // If no tool feature flag is present, prompt the user to select tools interactively\n // In batch mode (--all / --target), skip prompting\n // @awa-impl: JSON-6_AC-1\n if (!batchMode) {\n const hasToolFlag = features.some((f) => TOOL_FEATURE_VALUES.has(f));\n if (!hasToolFlag && !silent) {\n const selected = await multiselect({\n message: 'Select AI tools to generate for (space to toggle, enter to confirm):',\n options: TOOL_FEATURES.map((t) => ({ value: t.value, label: t.label })),\n required: true,\n });\n if (isCancel(selected)) {\n logger.info('Generation cancelled.');\n process.exit(0);\n }\n features.push(...(selected as string[]));\n }\n }\n\n // @awa-impl: JSON-7_AC-1\n // --json implies --dry-run for generate\n const effectiveDryRun = options.json || options.dryRun;\n\n // Display mode indicators\n if (!silent) {\n if (effectiveDryRun) {\n logger.info('Running in dry-run mode (no files will be modified)');\n }\n if (options.force) {\n logger.info('Force mode enabled (existing files will be overwritten)');\n }\n }\n\n // @awa-impl: OVL-2_AC-1\n // Build merged template dir if overlays are specified\n let mergedDir: string | null = null;\n let templatePath = template.localPath;\n if (options.overlay.length > 0) {\n const overlayDirs = await resolveOverlays([...options.overlay], options.refresh);\n mergedDir = await buildMergedDir(template.localPath, overlayDirs);\n templatePath = mergedDir;\n }\n\n try {\n // Generate files\n const result = await fileGenerator.generate({\n templatePath,\n outputPath: options.output,\n features,\n force: options.force,\n dryRun: effectiveDryRun,\n delete: options.delete,\n });\n\n // @awa-impl: JSON-1_AC-1, JSON-8_AC-1\n if (options.json) {\n writeJsonOutput(serializeGenerationResult(result));\n } else if (options.summary) {\n // @awa-impl: JSON-5_AC-1\n console.log(formatGenerationSummary(result));\n } else {\n // Display summary\n logger.summary(result);\n }\n } finally {\n // Clean up merged overlay temp directory\n if (mergedDir) {\n try {\n await rmDir(mergedDir);\n } catch {\n // Swallow cleanup errors — temp dir will be cleaned by OS eventually\n }\n }\n }\n}\n\nexport async function generateCommand(cliOptions: RawCliOptions): Promise<void> {\n try {\n // Load configuration file\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // @awa-impl: INIT-5_AC-1\n // Non-blocking hint when no config file is present and --config was not provided\n if (!cliOptions.config && fileConfig === null) {\n logger.info('Tip: create .awa.toml to save your options for next time.');\n }\n\n // Batch mode: --all or --target\n if (cliOptions.all || cliOptions.target) {\n const mode = cliOptions.all ? 'all' : 'single';\n const targets = batchRunner.resolveTargets(cliOptions, fileConfig, mode, cliOptions.target);\n\n for (const { targetName, options } of targets) {\n batchRunner.logForTarget(targetName, 'Starting generation...');\n await runGenerate(options, true);\n batchRunner.logForTarget(targetName, 'Generation complete.');\n }\n\n outro('All targets generated!');\n return;\n }\n\n // Standard single-target mode (backward compatible)\n const options = configLoader.merge(cliOptions, fileConfig);\n\n const silent = options.json || options.summary;\n\n // @awa-impl: JSON-6_AC-1\n // Suppress interactive output when --json or --summary is active\n if (!silent) {\n intro('awa CLI - Template Generator');\n }\n\n await runGenerate(options, false);\n\n if (!silent) {\n outro('Generation complete!');\n }\n } catch (error) {\n // @awa-impl: JSON-8_AC-1\n // Error handling with proper exit codes — errors always go to stderr\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","// @awa-component: TTST-TestCommand\n// @awa-impl: TTST-7_AC-1\n\nimport { intro, outro } from '@clack/prompts';\nimport { configLoader } from '../core/config.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport { discoverFixtures } from '../core/template-test/fixture-loader.js';\nimport { report } from '../core/template-test/reporter.js';\nimport { runAll } from '../core/template-test/runner.js';\nimport type { RawTestOptions } from '../core/template-test/types.js';\nimport { logger } from '../utils/logger.js';\n\n// @awa-impl: TTST-7_AC-1\nexport async function testCommand(options: RawTestOptions): Promise<number> {\n try {\n intro('awa CLI - Template Test');\n\n // Load configuration file\n const fileConfig = await configLoader.load(options.config ?? null);\n const templateSource = options.template ?? fileConfig?.template ?? null;\n\n // Resolve template source\n const template = await templateResolver.resolve(templateSource, false);\n\n // Discover fixtures\n const fixtures = await discoverFixtures(template.localPath);\n\n if (fixtures.length === 0) {\n logger.warn('No test fixtures found in _tests/ directory');\n outro('No tests to run.');\n return 0;\n }\n\n logger.info(`Found ${fixtures.length} fixture(s)`);\n\n // Extract preset definitions from config\n const presetDefinitions = fileConfig?.presets ?? {};\n\n // Run all fixtures\n const result = await runAll(\n fixtures,\n template.localPath,\n { updateSnapshots: options.updateSnapshots },\n presetDefinitions\n );\n\n // Report results\n report(result);\n\n if (result.failed > 0) {\n outro(`${result.failed} fixture(s) failed.`);\n return 1;\n }\n\n outro('All tests passed!');\n return 0;\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n return 2;\n }\n}\n","// @awa-component: TTST-FixtureLoader\n// @awa-impl: TTST-1_AC-1\n// @awa-impl: TTST-2_AC-1\n\nimport { readdir } from 'node:fs/promises';\nimport { basename, extname, join } from 'node:path';\nimport { parse } from 'smol-toml';\nimport { readTextFile } from '../../utils/fs.js';\nimport type { TestFixture } from './types.js';\n\n// @awa-impl: TTST-1_AC-1\nexport async function discoverFixtures(templatePath: string): Promise<TestFixture[]> {\n const testsDir = join(templatePath, '_tests');\n\n let entries: string[];\n try {\n const dirEntries = await readdir(testsDir, { withFileTypes: true });\n entries = dirEntries\n .filter((e) => e.isFile() && extname(e.name) === '.toml')\n .map((e) => e.name)\n .sort();\n } catch {\n // _tests/ directory doesn't exist — no fixtures\n return [];\n }\n\n const fixtures: TestFixture[] = [];\n for (const filename of entries) {\n const filePath = join(testsDir, filename);\n const fixture = await parseFixture(filePath);\n fixtures.push(fixture);\n }\n\n return fixtures;\n}\n\n// @awa-impl: TTST-2_AC-1\nexport async function parseFixture(filePath: string): Promise<TestFixture> {\n const content = await readTextFile(filePath);\n const parsed = parse(content) as Record<string, unknown>;\n\n const name = basename(filePath, extname(filePath));\n\n const features = toStringArray(parsed.features) ?? [];\n const preset = toStringArray(parsed.preset) ?? [];\n const removeFeatures = toStringArray(parsed['remove-features']) ?? [];\n const expectedFiles = toStringArray(parsed['expected-files']) ?? [];\n\n return {\n name,\n features,\n preset,\n removeFeatures,\n expectedFiles,\n filePath,\n };\n}\n\nfunction toStringArray(value: unknown): string[] | null {\n if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {\n return value as string[];\n }\n return null;\n}\n","// @awa-component: TTST-Reporter\n// @awa-impl: TTST-6_AC-1\n\nimport chalk from 'chalk';\nimport type { FixtureResult, TestSuiteResult } from './types.js';\n\n// @awa-impl: TTST-6_AC-1\nexport function report(result: TestSuiteResult): void {\n console.log('');\n\n for (const fixture of result.results) {\n reportFixture(fixture);\n }\n\n // Summary\n console.log('');\n console.log(chalk.bold('Test Summary:'));\n console.log(` Total: ${result.total}`);\n console.log(chalk.green(` Passed: ${result.passed}`));\n if (result.failed > 0) {\n console.log(chalk.red(` Failed: ${result.failed}`));\n }\n console.log('');\n}\n\nfunction reportFixture(fixture: FixtureResult): void {\n const icon = fixture.passed ? chalk.green('✔') : chalk.red('✖');\n console.log(`${icon} ${fixture.name}`);\n\n if (fixture.error) {\n console.log(chalk.red(` Error: ${fixture.error}`));\n return;\n }\n\n // Report missing files\n const missingFiles = fixture.fileResults.filter((r) => !r.found);\n for (const missing of missingFiles) {\n console.log(chalk.red(` Missing file: ${missing.path}`));\n }\n\n // Report snapshot mismatches\n const snapshotFailures = fixture.snapshotResults.filter((r) => r.status !== 'match');\n for (const failure of snapshotFailures) {\n switch (failure.status) {\n case 'mismatch':\n console.log(chalk.yellow(` Snapshot mismatch: ${failure.path}`));\n break;\n case 'missing-snapshot':\n console.log(chalk.yellow(` Missing snapshot: ${failure.path}`));\n break;\n case 'extra-snapshot':\n console.log(chalk.yellow(` Extra snapshot (not in output): ${failure.path}`));\n break;\n }\n }\n}\n","// @awa-component: TTST-TestRunner\n// @awa-impl: TTST-3_AC-1\n// @awa-impl: TTST-4_AC-1\n// @awa-impl: TTST-5_AC-1\n\nimport { mkdir, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { pathExists } from '../../utils/fs.js';\nimport { featureResolver } from '../feature-resolver.js';\nimport { fileGenerator } from '../generator.js';\nimport { compareSnapshots, updateSnapshots } from './snapshot.js';\nimport type {\n FileAssertionResult,\n FixtureResult,\n SnapshotFileResult,\n TestFixture,\n TestRunOptions,\n TestSuiteResult,\n} from './types.js';\n\n// @awa-impl: TTST-3_AC-1\nexport async function runFixture(\n fixture: TestFixture,\n templatePath: string,\n options: TestRunOptions,\n presetDefinitions: Record<string, string[]> = {}\n): Promise<FixtureResult> {\n const tempDir = join(tmpdir(), `awa-test-${fixture.name}-${Date.now()}`);\n\n try {\n await mkdir(tempDir, { recursive: true });\n\n // Resolve features using presets and remove-features\n const features = featureResolver.resolve({\n baseFeatures: [...fixture.features],\n presetNames: [...fixture.preset],\n removeFeatures: [...fixture.removeFeatures],\n presetDefinitions,\n });\n\n // Render templates to temp dir\n await fileGenerator.generate({\n templatePath,\n outputPath: tempDir,\n features,\n force: true,\n dryRun: false,\n delete: false,\n });\n\n // @awa-impl: TTST-4_AC-1\n // Check expected files\n const fileResults: FileAssertionResult[] = [];\n for (const expectedFile of fixture.expectedFiles) {\n const fullPath = join(tempDir, expectedFile);\n const found = await pathExists(fullPath);\n fileResults.push({ path: expectedFile, found });\n }\n\n const missingFiles = fileResults.filter((r) => !r.found);\n\n // @awa-impl: TTST-5_AC-1\n // Snapshot comparison\n const snapshotDir = join(templatePath, '_tests', fixture.name);\n let snapshotResults: SnapshotFileResult[] = [];\n if (options.updateSnapshots) {\n await updateSnapshots(tempDir, snapshotDir);\n } else if (await pathExists(snapshotDir)) {\n snapshotResults = await compareSnapshots(tempDir, snapshotDir);\n }\n\n const snapshotFailures = snapshotResults.filter((r) => r.status !== 'match');\n\n const passed = missingFiles.length === 0 && snapshotFailures.length === 0;\n\n return {\n name: fixture.name,\n passed,\n fileResults,\n snapshotResults,\n };\n } catch (error) {\n return {\n name: fixture.name,\n passed: false,\n fileResults: [],\n snapshotResults: [],\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n // Clean up temp dir\n await rm(tempDir, { recursive: true, force: true }).catch(() => {});\n }\n}\n\nexport async function runAll(\n fixtures: TestFixture[],\n templatePath: string,\n options: TestRunOptions,\n presetDefinitions: Record<string, string[]> = {}\n): Promise<TestSuiteResult> {\n const results: FixtureResult[] = [];\n\n for (const fixture of fixtures) {\n const result = await runFixture(fixture, templatePath, options, presetDefinitions);\n results.push(result);\n }\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.filter((r) => !r.passed).length;\n\n return {\n results,\n total: results.length,\n passed,\n failed,\n };\n}\n","// @awa-component: TTST-TestRunner\n// @awa-impl: TTST-5_AC-1\n\nimport { mkdir, readdir, rm } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { pathExists, readTextFile, writeTextFile } from '../../utils/fs.js';\nimport type { SnapshotFileResult } from './types.js';\n\n/** Walk a directory recursively and yield relative file paths. */\nasync function walkRelative(dir: string, base: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const sub = await walkRelative(fullPath, base);\n results.push(...sub);\n } else if (entry.isFile()) {\n results.push(relative(base, fullPath));\n }\n }\n\n return results;\n}\n\n// @awa-impl: TTST-5_AC-1\nexport async function compareSnapshots(\n renderedDir: string,\n snapshotDir: string\n): Promise<SnapshotFileResult[]> {\n const results: SnapshotFileResult[] = [];\n\n const renderedFiles = await walkRelative(renderedDir, renderedDir);\n const snapshotFiles = await walkRelative(snapshotDir, snapshotDir);\n\n const snapshotSet = new Set(snapshotFiles);\n const renderedSet = new Set(renderedFiles);\n\n // Check rendered files against snapshots\n for (const file of renderedFiles) {\n const renderedPath = join(renderedDir, file);\n const snapshotPath = join(snapshotDir, file);\n\n if (!snapshotSet.has(file)) {\n results.push({ path: file, status: 'missing-snapshot' });\n continue;\n }\n\n const renderedContent = await readTextFile(renderedPath);\n const snapshotContent = await readTextFile(snapshotPath);\n\n results.push({\n path: file,\n status: renderedContent === snapshotContent ? 'match' : 'mismatch',\n });\n }\n\n // Check for extra snapshot files not in rendered output\n for (const file of snapshotFiles) {\n if (!renderedSet.has(file)) {\n results.push({ path: file, status: 'extra-snapshot' });\n }\n }\n\n return results;\n}\n\n// @awa-impl: TTST-5_AC-1\nexport async function updateSnapshots(renderedDir: string, snapshotDir: string): Promise<void> {\n // Remove existing snapshot directory\n if (await pathExists(snapshotDir)) {\n await rm(snapshotDir, { recursive: true, force: true });\n }\n\n await mkdir(snapshotDir, { recursive: true });\n\n // Copy rendered files to snapshot directory\n const files = await walkRelative(renderedDir, renderedDir);\n for (const file of files) {\n const srcPath = join(renderedDir, file);\n const destPath = join(snapshotDir, file);\n const content = await readTextFile(srcPath);\n await writeTextFile(destPath, content);\n }\n}\n","import chalk from 'chalk';\nimport { PACKAGE_INFO } from '../_generated/package_info.js';\nimport type { Logger } from './logger.js';\n\nexport interface UpdateCheckResult {\n current: string;\n latest: string;\n isOutdated: boolean;\n isMajorBump: boolean;\n}\n\n/**\n * Compare two semver version strings numerically (major.minor.patch only).\n * Returns a negative number if a < b, 0 if equal, positive if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const partsA = a.split('.').map((s) => Number.parseInt(s, 10));\n const partsB = b.split('.').map((s) => Number.parseInt(s, 10));\n\n for (let i = 0; i < 3; i++) {\n const diff = (partsA[i] ?? 0) - (partsB[i] ?? 0);\n if (diff !== 0) return diff;\n }\n return 0;\n}\n\n/**\n * Check if a version bump is a major version bump.\n */\nexport function isMajorVersionBump(current: string, latest: string): boolean {\n const currentMajor = Number.parseInt(current.split('.')[0] ?? '0', 10);\n const latestMajor = Number.parseInt(latest.split('.')[0] ?? '0', 10);\n return latestMajor > currentMajor;\n}\n\n/**\n * Fetch the latest version from the npm registry.\n * Returns the update check result or null on any error.\n */\nexport async function checkForUpdate(): Promise<UpdateCheckResult | null> {\n try {\n const response = await fetch('https://registry.npmjs.org/@ncoderz/awa/latest', {\n signal: AbortSignal.timeout(5000),\n });\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n const latest = data.version;\n if (!latest || typeof latest !== 'string') return null;\n\n const current = PACKAGE_INFO.version;\n const isOutdated = compareSemver(current, latest) < 0;\n\n return {\n current,\n latest,\n isOutdated,\n isMajorBump: isOutdated && isMajorVersionBump(current, latest),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Print an update warning to the console using the logger.\n */\nexport function printUpdateWarning(log: Logger, result: UpdateCheckResult): void {\n if (!result.isOutdated) return;\n\n console.log('');\n if (result.isMajorBump) {\n log.warn(\n chalk.yellow(\n `New major version available: ${result.current} → ${result.latest} (breaking changes)`\n )\n );\n log.warn(chalk.dim(' See https://github.com/ncoderz/awa/releases for details'));\n } else {\n log.warn(chalk.yellow(`Update available: ${result.current} → ${result.latest}`));\n }\n log.warn(chalk.dim(' Run `npm install -g @ncoderz/awa` to update'));\n console.log('');\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst CACHE_DIR = join(homedir(), '.cache', 'awa');\nconst CACHE_FILE = join(CACHE_DIR, 'update-check.json');\nconst DEFAULT_INTERVAL_MS = 86_400_000; // 1 day\n\ninterface CacheData {\n timestamp: number;\n latestVersion: string;\n}\n\n/**\n * Determine whether a new update check should be performed.\n * Returns true if the cache is missing, corrupt, or stale.\n */\nexport async function shouldCheck(intervalMs: number = DEFAULT_INTERVAL_MS): Promise<boolean> {\n try {\n const raw = await readFile(CACHE_FILE, 'utf-8');\n const data = JSON.parse(raw) as CacheData;\n\n if (typeof data.timestamp !== 'number' || typeof data.latestVersion !== 'string') {\n return true;\n }\n\n return Date.now() - data.timestamp >= intervalMs;\n } catch {\n return true;\n }\n}\n\n/**\n * Write the latest version and current timestamp to the cache file.\n */\nexport async function writeCache(latestVersion: string): Promise<void> {\n try {\n await mkdir(dirname(CACHE_FILE), { recursive: true });\n\n const data: CacheData = {\n timestamp: Date.now(),\n latestVersion,\n };\n\n await writeFile(CACHE_FILE, JSON.stringify(data), 'utf-8');\n } catch {\n // Silently ignore write failures\n }\n}\n\n/**\n * Read the cached latest version. Returns null if cache is missing or corrupt.\n */\nexport async function readCachedVersion(): Promise<string | null> {\n try {\n const raw = await readFile(CACHE_FILE, 'utf-8');\n const data = JSON.parse(raw) as CacheData;\n if (typeof data.latestVersion === 'string') {\n return data.latestVersion;\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":["readFile","readFile","readFile","readFile","readFile","readFile","join","relative","join","join","join","chalk","join","relative","join","tmpdir","join","join","join","join","tmpdir","options","diffOptions","mergedDir","resolve","intro","outro","chalk","readFile","join","relative","intro","outro","intro","isCancel","multiselect","outro","multiselect","isCancel","options","outro","intro","intro","outro","readdir","basename","join","join","readdir","basename","toStringArray","chalk","report","mkdir","rm","tmpdir","join","readdir","rm","join","relative","readdir","join","relative","rm","join","tmpdir","mkdir","rm","intro","outro","report","chalk","chalk","mkdir","readFile","join","configLoader"]}
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/_generated/package_info.ts","../src/core/check/code-spec-checker.ts","../src/core/check/marker-scanner.ts","../src/core/check/glob.ts","../src/core/check/reporter.ts","../src/core/check/rule-loader.ts","../src/core/check/schema-checker.ts","../src/core/check/spec-parser.ts","../src/core/check/spec-spec-checker.ts","../src/core/check/types.ts","../src/commands/check.ts","../src/commands/diff.ts","../src/core/batch-runner.ts","../src/core/differ.ts","../src/core/delete-list.ts","../src/core/generator.ts","../src/core/resolver.ts","../src/core/template.ts","../src/core/feature-resolver.ts","../src/core/json-output.ts","../src/core/overlay.ts","../src/core/template-resolver.ts","../src/utils/file-watcher.ts","../src/utils/debouncer.ts","../src/commands/features.ts","../src/core/features/reporter.ts","../src/core/features/scanner.ts","../src/commands/generate.ts","../src/commands/test.ts","../src/core/template-test/fixture-loader.ts","../src/core/template-test/reporter.ts","../src/core/template-test/runner.ts","../src/core/template-test/snapshot.ts","../src/utils/update-check.ts","../src/utils/update-check-cache.ts"],"sourcesContent":["// @awa-component: CLI-ArgumentParser\n// @awa-impl: CLI-1_AC-1\n// @awa-impl: CLI-1_AC-2\n// @awa-impl: CLI-1_AC-3\n// @awa-impl: CLI-1_AC-4\n// @awa-impl: CLI-1_AC-5\n// @awa-impl: CLI-2_AC-1\n// @awa-impl: CLI-2_AC-2\n// @awa-impl: CLI-2_AC-3\n// @awa-impl: CLI-2_AC-5\n// @awa-impl: CLI-2_AC-6\n// @awa-impl: CLI-3_AC-1\n// @awa-impl: CLI-4_AC-1\n// @awa-impl: CLI-4_AC-2\n// @awa-impl: CLI-5_AC-1\n// @awa-impl: CLI-6_AC-1\n// @awa-impl: CLI-7_AC-1\n// @awa-impl: CLI-8_AC-1\n// @awa-impl: CLI-9_AC-1\n// @awa-impl: CLI-9_AC-2\n// @awa-impl: CLI-9_AC-3\n// @awa-impl: CLI-10_AC-1\n// @awa-impl: CLI-10_AC-2\n// @awa-impl: CLI-11_AC-1\n// @awa-impl: CLI-11_AC-2\n// @awa-impl: CLI-11_AC-3\n// @awa-impl: CLI-12_AC-1\n// @awa-impl: CLI-13_AC-1\n// @awa-impl: CLI-13_AC-2\n// @awa-impl: CLI-14_AC-1\n// @awa-impl: CLI-14_AC-2\n// @awa-impl: CLI-6_AC-2\n// @awa-impl: CFG-5_AC-2\n// @awa-impl: DIFF-7_AC-1\n// @awa-impl: DIFF-7_AC-2\n// @awa-impl: DIFF-7_AC-3\n// @awa-impl: DIFF-7_AC-4\n// @awa-impl: DIFF-7_AC-5\n// @awa-impl: DIFF-7_AC-6\n// @awa-impl: DIFF-7_AC-7\n// @awa-impl: DIFF-7_AC-8\n// @awa-impl: DIFF-7_AC-9\n// @awa-impl: DIFF-7_AC-10\n// @awa-impl: DIFF-7_AC-11\n// @awa-impl: DIFF-7_AC-12\n// @awa-impl: DIFF-7_AC-13\n// @awa-impl: FP-2_AC-1\n// @awa-impl: FP-2_AC-2\n// @awa-impl: FP-2_AC-4\n// @awa-impl: FP-4_AC-1\n// @awa-impl: FP-4_AC-2\n// @awa-impl: FP-4_AC-3\n// @awa-impl: FP-4_AC-5\n// @awa-impl: GEN-10_AC-1\n// @awa-impl: GEN-10_AC-2\n// @awa-impl: INIT-1_AC-1\n// @awa-impl: INIT-2_AC-1\n// @awa-impl: INIT-3_AC-1\n// @awa-impl: INIT-4_AC-1\n\nimport { Command } from 'commander';\nimport { PACKAGE_INFO } from '../_generated/package_info.js';\nimport { checkCommand } from '../commands/check.js';\nimport { diffCommand } from '../commands/diff.js';\nimport { featuresCommand } from '../commands/features.js';\nimport { generateCommand } from '../commands/generate.js';\nimport { testCommand } from '../commands/test.js';\nimport type { RawCheckOptions } from '../core/check/types.js';\nimport type { RawTestOptions } from '../core/template-test/types.js';\nimport type { RawCliOptions } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\nimport {\n checkForUpdate,\n printUpdateWarning,\n type UpdateCheckResult,\n} from '../utils/update-check.js';\nimport { shouldCheck, writeCache } from '../utils/update-check-cache.js';\n\nconst version = PACKAGE_INFO.version;\n\n// @awa-impl: CLI-1_AC-2, CLI-9_AC-1, CLI-9_AC-2, CLI-9_AC-3, CLI-10_AC-1, CLI-10_AC-2\nconst program = new Command();\n\nprogram\n .name('awa')\n .description('awa - tool for generating AI coding agent configuration files')\n .version(version, '-v, --version', 'Display version number');\n\n// @awa-impl: CLI-1_AC-1, CLI-1_AC-2, CLI-1_AC-3, CLI-1_AC-4, CLI-1_AC-5\n// @awa-impl: INIT-1_AC-1, INIT-2_AC-1, INIT-3_AC-1, INIT-4_AC-1\nprogram\n .command('generate')\n .alias('init')\n .description('Generate AI agent configuration files from templates')\n // @awa-impl: CLI-2_AC-1, CLI-2_AC-5, CLI-2_AC-6\n .argument('[output]', 'Output directory (optional if specified in config)')\n // @awa-impl: CLI-3_AC-1\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n // @awa-impl: CLI-4_AC-1, CLI-4_AC-2\n .option('-f, --features <flag...>', 'Feature flags (can be specified multiple times)')\n .option('--preset <name...>', 'Preset names to enable (can be specified multiple times)')\n .option(\n '--remove-features <flag...>',\n 'Feature flags to remove (can be specified multiple times)'\n )\n // @awa-impl: CLI-5_AC-1\n .option('--force', 'Force overwrite existing files without prompting', false)\n // @awa-impl: CLI-6_AC-1\n .option('--dry-run', 'Preview changes without modifying files', false)\n .option(\n '--delete',\n 'Enable deletion of files listed in the delete list (default: warn only)',\n false\n )\n // @awa-impl: CLI-7_AC-1\n .option('-c, --config <path>', 'Path to configuration file')\n // @awa-impl: CLI-8_AC-1\n .option('--refresh', 'Force refresh of cached Git templates', false)\n .option('--all', 'Process all named targets from config', false)\n .option('--target <name>', 'Process a specific named target from config')\n // @awa-impl: OVL-1_AC-1\n .option('--overlay <path...>', 'Overlay directory paths applied over base template (repeatable)')\n // @awa-impl: JSON-1_AC-1\n .option('--json', 'Output results as JSON (implies --dry-run)', false)\n // @awa-impl: JSON-5_AC-1\n .option('--summary', 'Output compact one-line summary', false)\n .action(async (output: string | undefined, options) => {\n // @awa-impl: CLI-11_AC-1, CLI-11_AC-2, CLI-11_AC-3\n const cliOptions: RawCliOptions = {\n output,\n template: options.template,\n features: options.features,\n preset: options.preset,\n removeFeatures: options.removeFeatures,\n force: options.force,\n dryRun: options.dryRun,\n delete: options.delete,\n config: options.config,\n refresh: options.refresh,\n all: options.all,\n target: options.target,\n overlay: options.overlay || [],\n json: options.json,\n summary: options.summary,\n };\n\n await generateCommand(cliOptions);\n });\n\n// @awa-impl: DIFF-7_AC-1, DIFF-7_AC-2, DIFF-7_AC-3, DIFF-7_AC-4, DIFF-7_AC-5, DIFF-7_AC-6, DIFF-7_AC-7, DIFF-7_AC-8, DIFF-7_AC-9, DIFF-7_AC-10\nprogram\n .command('diff')\n .description('Compare template output with existing target directory')\n // @awa-impl: DIFF-7_AC-1, DIFF-7_AC-2, DIFF-7_AC-3, DIFF-7_AC-4, DIFF-7_AC-5\n .argument('[target]', 'Target directory to compare against (optional if specified in config)')\n // @awa-impl: DIFF-7_AC-6\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n // @awa-impl: DIFF-7_AC-7\n .option('-f, --features <flag...>', 'Feature flags (can be specified multiple times)')\n .option('--preset <name...>', 'Preset names to enable (can be specified multiple times)')\n .option(\n '--remove-features <flag...>',\n 'Feature flags to remove (can be specified multiple times)'\n )\n // @awa-impl: DIFF-7_AC-8\n .option('-c, --config <path>', 'Path to configuration file')\n // @awa-impl: DIFF-7_AC-9\n .option('--refresh', 'Force refresh of cached Git templates', false)\n // @awa-impl: DIFF-7_AC-11\n .option('--list-unknown', 'Include target-only files in diff results', false)\n .option('--all', 'Process all named targets from config', false)\n .option('--target <name>', 'Process a specific named target from config')\n .option('-w, --watch', 'Watch template directory for changes and re-run diff', false)\n // @awa-impl: OVL-7_AC-1\n .option('--overlay <path...>', 'Overlay directory paths applied over base template (repeatable)')\n // @awa-impl: JSON-2_AC-1\n .option('--json', 'Output results as JSON', false)\n // @awa-impl: JSON-5_AC-1\n .option('--summary', 'Output compact one-line summary', false)\n // @awa-impl: DIFF-7_AC-10\n // Note: --force and --dry-run are intentionally NOT accepted for diff command\n .action(async (target: string | undefined, options) => {\n const cliOptions: RawCliOptions = {\n output: target, // Use target as output for consistency\n template: options.template,\n features: options.features,\n preset: options.preset,\n removeFeatures: options.removeFeatures,\n config: options.config,\n refresh: options.refresh,\n listUnknown: options.listUnknown,\n all: options.all,\n target: options.target,\n watch: options.watch,\n overlay: options.overlay || [],\n json: options.json,\n summary: options.summary,\n };\n\n const exitCode = await diffCommand(cliOptions);\n process.exit(exitCode);\n });\n\n// @awa-impl: CHK-8_AC-1, CHK-9_AC-1, CHK-10_AC-1\nprogram\n .command('check')\n .description(\n 'Validate spec files against schemas and check traceability between code markers and specs'\n )\n .option('-c, --config <path>', 'Path to configuration file')\n // @awa-impl: CHK-10_AC-1\n .option('--spec-ignore <pattern...>', 'Glob patterns to exclude from spec file scanning')\n .option('--code-ignore <pattern...>', 'Glob patterns to exclude from code file scanning')\n // @awa-impl: CHK-9_AC-1\n .option('--format <format>', 'Output format (text or json)', 'text')\n .option(\n '--allow-warnings',\n 'Allow warnings without failing (default: warnings are errors)',\n false\n )\n .option(\n '--spec-only',\n 'Run only spec-level checks (schema and cross-refs); skip code-to-spec traceability',\n false\n )\n .action(async (options) => {\n const cliOptions: RawCheckOptions = {\n config: options.config,\n specIgnore: options.specIgnore,\n codeIgnore: options.codeIgnore,\n format: options.format,\n allowWarnings: options.allowWarnings,\n specOnly: options.specOnly,\n };\n\n const exitCode = await checkCommand(cliOptions);\n process.exit(exitCode);\n });\n\n// @awa-impl: DISC-4_AC-1, DISC-5_AC-1\nprogram\n .command('features')\n .description('Discover feature flags available in a template')\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n .option('-c, --config <path>', 'Path to configuration file')\n .option('--refresh', 'Force refresh of cached Git templates', false)\n .option('--json', 'Output results as JSON', false)\n .action(async (options) => {\n const exitCode = await featuresCommand({\n template: options.template,\n config: options.config,\n refresh: options.refresh,\n json: options.json,\n });\n process.exit(exitCode);\n });\n\n// @awa-impl: TTST-7_AC-1, TTST-5_AC-1\nprogram\n .command('test')\n .description('Run template test fixtures to verify expected output')\n .option('-t, --template <source>', 'Template source (local path or Git repository)')\n .option('-c, --config <path>', 'Path to configuration file')\n .option('--update-snapshots', 'Update stored snapshots with current rendered output', false)\n .action(async (options) => {\n const testOptions: RawTestOptions = {\n template: options.template,\n config: options.config,\n updateSnapshots: options.updateSnapshots,\n };\n\n const exitCode = await testCommand(testOptions);\n process.exit(exitCode);\n });\n\n// Fire update check asynchronously (non-blocking) before parse\nlet updateCheckPromise: Promise<UpdateCheckResult | null> | null = null;\n\nconst isJsonOrSummary = process.argv.includes('--json') || process.argv.includes('--summary');\nconst isTTY = process.stdout.isTTY === true;\nconst isDisabledByEnv = !!process.env.NO_UPDATE_NOTIFIER;\n\nif (!isJsonOrSummary && isTTY && !isDisabledByEnv) {\n updateCheckPromise = (async () => {\n try {\n // Load config to check update-check settings\n const { configLoader } = await import('../core/config.js');\n const configPath =\n process.argv.indexOf('-c') !== -1\n ? process.argv[process.argv.indexOf('-c') + 1]\n : process.argv.indexOf('--config') !== -1\n ? process.argv[process.argv.indexOf('--config') + 1]\n : undefined;\n const fileConfig = await configLoader.load(configPath ?? null);\n\n const updateCheckConfig = fileConfig?.['update-check'];\n if (updateCheckConfig?.enabled === false) return null;\n\n const intervalSeconds = updateCheckConfig?.interval ?? 86400;\n const intervalMs = intervalSeconds * 1000;\n\n const needsCheck = await shouldCheck(intervalMs);\n if (!needsCheck) return null;\n\n const result = await checkForUpdate();\n if (result) {\n await writeCache(result.latest);\n }\n return result;\n } catch {\n return null;\n }\n })();\n}\n\n// Print update warning after command completes\nprogram.hook('postAction', async () => {\n if (!updateCheckPromise) return;\n try {\n const result = await updateCheckPromise;\n if (result?.isOutdated) {\n printUpdateWarning(logger, result);\n }\n } catch {\n // Silently ignore\n }\n});\n\n// @awa-impl: GEN-10_AC-1, GEN-10_AC-2\nprogram.parseAsync();\n","// This file is automatically generated. DO NOT EDIT.\n\n/* eslint-disable */\n\nexport const PACKAGE_INFO = {\n \"name\": \"@ncoderz/awa\",\n \"version\": \"1.3.1\",\n \"author\": \"Richard Sewell <richard.sewell@ncoderz.com>\",\n \"license\": \"MIT\",\n \"description\": \"awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage agent workflow files using templates.\"\n};\n","// @awa-component: CHK-CodeSpecChecker\n// @awa-impl: CHK-3_AC-1\n// @awa-impl: CHK-4_AC-1\n// @awa-impl: CHK-6_AC-1\n// @awa-impl: CHK-14_AC-1\n// @awa-impl: CHK-18_AC-1\n// @awa-impl: CHK-19_AC-1\n\nimport type {\n CheckConfig,\n CheckResult,\n Finding,\n MarkerScanResult,\n SpecParseResult,\n} from './types.js';\n\n// @awa-impl: CHK-3_AC-1, CHK-4_AC-1, CHK-6_AC-1, CHK-18_AC-1, CHK-19_AC-1\nexport function checkCodeAgainstSpec(\n markers: MarkerScanResult,\n specs: SpecParseResult,\n config: CheckConfig\n): CheckResult {\n const findings: Finding[] = [];\n\n // @awa-impl: CHK-6_AC-1, CHK-14_AC-1\n // Validate ID format for all markers\n const idRegex = new RegExp(`^${config.idPattern}$`);\n for (const marker of markers.markers) {\n if (marker.type === 'component') {\n // Component names have different format — skip ID pattern check\n continue;\n }\n if (!idRegex.test(marker.id)) {\n findings.push({\n severity: 'error',\n code: 'invalid-id-format',\n message: `Marker ID '${marker.id}' does not match expected pattern: ${config.idPattern}`,\n filePath: marker.filePath,\n line: marker.line,\n id: marker.id,\n });\n }\n }\n\n // @awa-impl: CHK-3_AC-1\n // Check for orphaned markers (code references non-existent spec ID)\n for (const marker of markers.markers) {\n if (marker.type === 'component') {\n // Component markers reference component names\n if (!specs.componentNames.has(marker.id)) {\n findings.push({\n severity: 'error',\n code: 'orphaned-marker',\n message: `Component marker '${marker.id}' not found in any spec file`,\n filePath: marker.filePath,\n line: marker.line,\n id: marker.id,\n });\n }\n } else {\n // impl and test markers reference IDs (ACs, properties, requirement IDs)\n if (!specs.allIds.has(marker.id)) {\n findings.push({\n severity: 'error',\n code: 'orphaned-marker',\n message: `Marker '${marker.id}' not found in any spec file`,\n filePath: marker.filePath,\n line: marker.line,\n id: marker.id,\n });\n }\n }\n }\n\n // @awa-impl: CHK-4_AC-1\n // Check for uncovered ACs (spec ACs with no @awa-test reference)\n const testedIds = new Set(markers.markers.filter((m) => m.type === 'test').map((m) => m.id));\n\n for (const acId of specs.acIds) {\n if (!testedIds.has(acId)) {\n // Look up location from idLocations map, fall back to spec file path\n const loc = specs.idLocations.get(acId);\n const specFile = loc ? undefined : specs.specFiles.find((sf) => sf.acIds.includes(acId));\n findings.push({\n severity: 'warning',\n code: 'uncovered-ac',\n message: `Acceptance criterion '${acId}' has no @awa-test reference`,\n filePath: loc?.filePath ?? specFile?.filePath,\n line: loc?.line,\n id: acId,\n });\n }\n }\n\n // @awa-impl: CHK-18_AC-1\n // Check for uncovered components (DESIGN components with no @awa-component marker)\n const implementedComponents = new Set(\n markers.markers.filter((m) => m.type === 'component').map((m) => m.id)\n );\n\n for (const componentName of specs.componentNames) {\n if (!implementedComponents.has(componentName)) {\n const loc = specs.idLocations.get(componentName);\n const specFile = loc\n ? undefined\n : specs.specFiles.find((sf) => sf.componentNames.includes(componentName));\n findings.push({\n severity: 'warning',\n code: 'uncovered-component',\n message: `Component '${componentName}' has no @awa-component reference`,\n filePath: loc?.filePath ?? specFile?.filePath,\n line: loc?.line,\n id: componentName,\n });\n }\n }\n\n // @awa-impl: CHK-19_AC-1\n // Check for unimplemented ACs (spec ACs with no @awa-impl marker)\n const implementedIds = new Set(markers.markers.filter((m) => m.type === 'impl').map((m) => m.id));\n\n for (const acId of specs.acIds) {\n if (!implementedIds.has(acId)) {\n const loc = specs.idLocations.get(acId);\n const specFile = loc ? undefined : specs.specFiles.find((sf) => sf.acIds.includes(acId));\n findings.push({\n severity: 'warning',\n code: 'unimplemented-ac',\n message: `Acceptance criterion '${acId}' has no @awa-impl reference`,\n filePath: loc?.filePath ?? specFile?.filePath,\n line: loc?.line,\n id: acId,\n });\n }\n }\n\n return { findings };\n}\n","// @awa-component: CHK-MarkerScanner\n// @awa-impl: CHK-1_AC-1\n// @awa-impl: CHK-11_AC-1\n// @awa-impl: CHK-13_AC-1\n\nimport { readFile } from 'node:fs/promises';\nimport { collectFiles, matchSimpleGlob } from './glob.js';\nimport type { CheckConfig, CodeMarker, Finding, MarkerScanResult, MarkerType } from './types.js';\n\nconst MARKER_TYPE_MAP: Record<string, MarkerType> = {\n '@awa-impl': 'impl',\n '@awa-test': 'test',\n '@awa-component': 'component',\n};\n\n/** Ignore directive patterns (similar to eslint-disable comments). */\n// Use RegExp constructor so the literal token does not appear in this source file,\n// preventing the marker scanner from self-ignoring when it scans its own code.\nconst IGNORE_FILE_RE = new RegExp('@awa-ignore' + '-file\\\\b');\nconst IGNORE_NEXT_LINE_RE = /@awa-ignore-next-line\\b/;\nconst IGNORE_LINE_RE = /@awa-ignore\\b/;\nconst IGNORE_START_RE = /@awa-ignore-start\\b/;\nconst IGNORE_END_RE = /@awa-ignore-end\\b/;\n\n// @awa-impl: CHK-1_AC-1\nexport async function scanMarkers(config: CheckConfig): Promise<MarkerScanResult> {\n const files = await collectCodeFiles(config.codeGlobs, config.codeIgnore);\n const markers: CodeMarker[] = [];\n const findings: Finding[] = [];\n\n for (const filePath of files) {\n // Skip files matching ignoreMarkers globs\n if (config.ignoreMarkers.some((ig) => matchSimpleGlob(filePath, ig))) {\n continue;\n }\n\n const result = await scanFile(filePath, config.markers);\n markers.push(...result.markers);\n findings.push(...result.findings);\n }\n\n return { markers, findings };\n}\n\n// @awa-impl: CHK-11_AC-1\nfunction buildMarkerRegex(markerNames: readonly string[]): RegExp {\n const escaped = markerNames.map((m) => m.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'));\n // Match marker followed by colon, then capture the rest of the line (IDs)\n return new RegExp(`(${escaped.join('|')}):\\\\s*(.+)`, 'g');\n}\n\n/** Pattern matching valid impl/test IDs and component names. */\nconst ID_TOKEN_RE = /^([A-Z][A-Z0-9]*(?:[-_][A-Za-z0-9]+)*(?:\\.\\d+)?)/;\n\nasync function scanFile(\n filePath: string,\n markerNames: readonly string[]\n): Promise<{ markers: CodeMarker[]; findings: Finding[] }> {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n return { markers: [], findings: [] };\n }\n\n // Check for file-level ignore directive anywhere in the file\n if (IGNORE_FILE_RE.test(content)) {\n return { markers: [], findings: [] };\n }\n\n const regex = buildMarkerRegex(markerNames);\n const lines = content.split('\\n');\n const markers: CodeMarker[] = [];\n const findings: Finding[] = [];\n let ignoreNextLine = false;\n let ignoreBlock = false;\n\n for (const [i, line] of lines.entries()) {\n // Check for block ignore boundaries\n if (IGNORE_START_RE.test(line)) {\n ignoreBlock = true;\n continue;\n }\n if (IGNORE_END_RE.test(line)) {\n ignoreBlock = false;\n continue;\n }\n if (ignoreBlock) {\n continue;\n }\n\n // Check if previous line had @awa-ignore-next-line\n if (ignoreNextLine) {\n ignoreNextLine = false;\n continue;\n }\n\n // Check if this line is an @awa-ignore-next-line directive\n if (IGNORE_NEXT_LINE_RE.test(line)) {\n ignoreNextLine = true;\n continue;\n }\n\n // Check for inline @awa-ignore on this line (ignores markers on this line)\n if (IGNORE_LINE_RE.test(line)) {\n continue;\n }\n\n regex.lastIndex = 0;\n let match = regex.exec(line);\n\n while (match !== null) {\n const markerName = match[1] ?? '';\n const idsRaw = match[2] ?? '';\n const type = resolveMarkerType(markerName, markerNames);\n\n // Split by comma to support multiple IDs per marker line\n const ids = idsRaw\n .split(',')\n .map((id) => id.trim())\n .filter(Boolean);\n\n for (const id of ids) {\n // Extract only the leading ID token\n const tokenMatch = ID_TOKEN_RE.exec(id);\n const cleanId = tokenMatch?.[1]?.trim() ?? '';\n if (cleanId && tokenMatch) {\n // Check for trailing text after the ID (only whitespace allowed)\n const remainder = id.slice(tokenMatch[0].length).trim();\n if (remainder) {\n findings.push({\n severity: 'error',\n code: 'marker-trailing-text',\n message: `Marker has trailing text after ID '${cleanId}': '${remainder}' — use comma-separated IDs only`,\n filePath,\n line: i + 1,\n id: cleanId,\n });\n }\n markers.push({ type, id: cleanId, filePath, line: i + 1 });\n }\n }\n\n match = regex.exec(line);\n }\n }\n\n return { markers, findings };\n}\n\nfunction resolveMarkerType(markerName: string, configuredMarkers: readonly string[]): MarkerType {\n // Check default mapping first\n const mapped = MARKER_TYPE_MAP[markerName];\n if (mapped) return mapped;\n // For custom markers, infer type by position in configured array\n // Default order: [impl, test, component]\n const idx = configuredMarkers.indexOf(markerName);\n if (idx === 1) return 'test';\n if (idx === 2) return 'component';\n return 'impl';\n}\n\n// @awa-impl: CHK-13_AC-1\nasync function collectCodeFiles(\n codeGlobs: readonly string[],\n ignore: readonly string[]\n): Promise<string[]> {\n return collectFiles(codeGlobs, ignore);\n}\n","// @awa-component: CHK-MarkerScanner\n// @awa-impl: CHK-13_AC-1\n\nimport { glob } from 'node:fs/promises';\n\n/**\n * Matches a path against a simple glob pattern supporting * and **.\n * Also matches a directory prefix against `dir/**` patterns (e.g. \"src\" matches \"src/**\").\n */\nexport function matchSimpleGlob(path: string, pattern: string): boolean {\n const regex = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<GLOBSTAR>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<GLOBSTAR>>/g, '.*');\n return new RegExp(`(^|/)${regex}($|/)`).test(path);\n}\n\n/**\n * Collect files matching globs while applying ignore patterns.\n * Uses fs.glob exclude callback for directory-level skipping (perf optimization)\n * and post-filters results for file-level ignore matching.\n */\nexport async function collectFiles(\n globs: readonly string[],\n ignore: readonly string[]\n): Promise<string[]> {\n const files: string[] = [];\n\n // For exclude callback, also match directory prefixes (e.g. \"src\" for \"src/**\")\n const dirPrefixes = ignore.filter((ig) => ig.endsWith('/**')).map((ig) => ig.slice(0, -3));\n\n for (const pattern of globs) {\n for await (const filePath of glob(pattern, {\n exclude: (p) => dirPrefixes.includes(p) || ignore.some((ig) => matchSimpleGlob(p, ig)),\n })) {\n // Post-filter: fs.glob exclude only receives directory names,\n // so we must also filter the yielded file paths\n if (!ignore.some((ig) => matchSimpleGlob(filePath, ig))) {\n files.push(filePath);\n }\n }\n }\n\n return [...new Set(files)];\n}\n","// @awa-component: CHK-Reporter\n// @awa-impl: CHK-9_AC-1\n\nimport chalk from 'chalk';\nimport type { Finding } from './types.js';\n\n// @awa-impl: CHK-9_AC-1\nexport function report(findings: readonly Finding[], format: 'text' | 'json'): void {\n if (format === 'json') {\n reportJson(findings);\n } else {\n reportText(findings);\n }\n}\n\nfunction reportJson(findings: readonly Finding[]): void {\n const errors = findings.filter((f) => f.severity === 'error');\n const warnings = findings.filter((f) => f.severity === 'warning');\n\n const output = {\n valid: errors.length === 0,\n errors: errors.length,\n warnings: warnings.length,\n findings: findings.map((f) => ({\n severity: f.severity,\n code: f.code,\n message: f.message,\n ...(f.filePath ? { filePath: f.filePath } : {}),\n ...(f.line ? { line: f.line } : {}),\n ...(f.id ? { id: f.id } : {}),\n ...(f.ruleSource ? { ruleSource: f.ruleSource } : {}),\n ...(f.rule ? { rule: f.rule } : {}),\n })),\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n\nfunction reportText(findings: readonly Finding[]): void {\n const errors = findings.filter((f) => f.severity === 'error');\n const warnings = findings.filter((f) => f.severity === 'warning');\n\n if (errors.length > 0) {\n console.log(chalk.red(`\\n${errors.length} error(s):\\n`));\n for (const f of errors) {\n const location = formatLocation(f.filePath, f.line);\n console.log(chalk.red(' ✖'), f.message, location ? chalk.dim(location) : '');\n printRuleContext(f);\n }\n }\n\n if (warnings.length > 0) {\n console.log(chalk.yellow(`\\n${warnings.length} warning(s):\\n`));\n for (const f of warnings) {\n const location = formatLocation(f.filePath, f.line);\n console.log(chalk.yellow(' ⚠'), f.message, location ? chalk.dim(location) : '');\n printRuleContext(f);\n }\n }\n\n if (errors.length === 0 && warnings.length === 0) {\n console.log(chalk.green('\\n✔ Validation passed — no issues found'));\n } else {\n console.log('');\n const parts: string[] = [];\n if (errors.length > 0) parts.push(chalk.red(`${errors.length} error(s)`));\n if (warnings.length > 0) parts.push(chalk.yellow(`${warnings.length} warning(s)`));\n console.log(`Summary: ${parts.join(', ')}`);\n }\n}\n\nfunction formatLocation(filePath?: string, line?: number): string {\n if (!filePath) return '';\n return line ? `(${filePath}:${line})` : `(${filePath})`;\n}\n\nfunction printRuleContext(f: Finding): void {\n if (!f.ruleSource && !f.rule) return;\n const parts: string[] = [];\n if (f.ruleSource) parts.push(f.ruleSource);\n if (f.rule) parts.push(f.rule);\n console.log(chalk.dim(` rule: ${parts.join(' — ')}`));\n}\n","// @awa-component: CHK-RuleLoader\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { collectFiles, matchSimpleGlob } from './glob.js';\nimport type {\n CodeBlockContainsRule,\n ContainsRule,\n HeadingOrTextContainsRule,\n ListContainsRule,\n LoadedRuleSet,\n PatternContainsRule,\n RuleFile,\n SectionRule,\n TableContainsRule,\n WhenCondition,\n} from './rule-types.js';\n\n/**\n * Discover and load all *.schema.yaml files from the given schema directory.\n * Parses YAML, validates rule structure, and returns typed rule sets.\n */\nexport async function loadRules(schemaDir: string): Promise<LoadedRuleSet[]> {\n const pattern = join(schemaDir, '*.schema.yaml');\n const files = await collectFiles([pattern], []);\n const results: LoadedRuleSet[] = [];\n\n for (const filePath of files) {\n const ruleSet = await loadRuleFile(filePath);\n if (ruleSet) {\n results.push(ruleSet);\n }\n }\n\n return results;\n}\n\n/**\n * Match spec file paths against a loaded rule set's target-files glob.\n */\nexport function matchesTargetGlob(filePath: string, targetGlob: string): boolean {\n return matchSimpleGlob(filePath, targetGlob);\n}\n\nasync function loadRuleFile(filePath: string): Promise<LoadedRuleSet | null> {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n\n const parsed = parseYaml(content) as unknown;\n if (!parsed || typeof parsed !== 'object') {\n throw new RuleValidationError(`Rule file is not a valid YAML object: ${filePath}`);\n }\n\n const raw = parsed as Record<string, unknown>;\n const ruleFile = validateRuleFile(raw, filePath);\n\n return {\n ruleFile,\n sourcePath: filePath,\n targetGlob: ruleFile['target-files'],\n };\n}\n\nfunction validateRuleFile(raw: Record<string, unknown>, filePath: string): RuleFile {\n // target-files is required\n if (typeof raw['target-files'] !== 'string' || raw['target-files'].length === 0) {\n throw new RuleValidationError(`Missing or empty 'target-files' in ${filePath}`);\n }\n\n // sections is optional (e.g., API rules target non-markdown files)\n let sections: SectionRule[] | undefined;\n if (raw.sections !== undefined) {\n if (!Array.isArray(raw.sections) || raw.sections.length === 0) {\n throw new RuleValidationError(\n `'sections' must be a non-empty array if present in ${filePath}`\n );\n }\n sections = raw.sections.map((s: unknown, i: number) =>\n validateSectionRule(s, `sections[${i}]`, filePath)\n );\n }\n\n // sections-prohibited is optional\n let sectionsProhibited: string[] | undefined;\n if (raw['sections-prohibited'] !== undefined) {\n if (\n !Array.isArray(raw['sections-prohibited']) ||\n !raw['sections-prohibited'].every((v: unknown) => typeof v === 'string')\n ) {\n throw new RuleValidationError(`'sections-prohibited' must be a string array in ${filePath}`);\n }\n sectionsProhibited = raw['sections-prohibited'] as string[];\n }\n\n return {\n 'target-files': raw['target-files'] as string,\n ...(typeof raw.description === 'string' ? { description: raw.description } : {}),\n ...(typeof raw['line-limit'] === 'number' && raw['line-limit'] > 0\n ? { 'line-limit': raw['line-limit'] }\n : {}),\n sections: sections ?? [],\n ...(sectionsProhibited ? { 'sections-prohibited': sectionsProhibited } : {}),\n ...(typeof raw.example === 'string' ? { example: raw.example } : {}),\n };\n}\n\nfunction validateSectionRule(raw: unknown, path: string, filePath: string): SectionRule {\n if (!raw || typeof raw !== 'object') {\n throw new RuleValidationError(`${path} must be an object in ${filePath}`);\n }\n\n const section = raw as Record<string, unknown>;\n\n if (typeof section.heading !== 'string' || section.heading.length === 0) {\n throw new RuleValidationError(`${path}.heading must be a non-empty string in ${filePath}`);\n }\n\n if (typeof section.level !== 'number' || section.level < 1 || section.level > 6) {\n throw new RuleValidationError(`${path}.level must be 1-6 in ${filePath}`);\n }\n\n // Validate heading as regex if it looks like a pattern\n validatePattern(section.heading as string, `${path}.heading`, filePath);\n\n // Validate optional contains rules\n let contains: ContainsRule[] | undefined;\n if (section.contains !== undefined) {\n if (!Array.isArray(section.contains)) {\n throw new RuleValidationError(`${path}.contains must be an array in ${filePath}`);\n }\n contains = section.contains.map((c: unknown, i: number) =>\n validateContainsRule(c, `${path}.contains[${i}]`, filePath)\n );\n }\n\n // Validate optional children rules\n let children: SectionRule[] | undefined;\n if (section.children !== undefined) {\n if (!Array.isArray(section.children)) {\n throw new RuleValidationError(`${path}.children must be an array in ${filePath}`);\n }\n children = section.children.map((c: unknown, i: number) =>\n validateSectionRule(c, `${path}.children[${i}]`, filePath)\n );\n }\n\n return {\n heading: section.heading as string,\n level: section.level as number,\n ...(typeof section.required === 'boolean' ? { required: section.required } : {}),\n ...(typeof section.repeatable === 'boolean' ? { repeatable: section.repeatable } : {}),\n ...(typeof section.description === 'string' ? { description: section.description } : {}),\n ...(contains ? { contains } : {}),\n ...(children ? { children } : {}),\n };\n}\n\nfunction validateContainsRule(raw: unknown, path: string, filePath: string): ContainsRule {\n if (!raw || typeof raw !== 'object') {\n throw new RuleValidationError(`${path} must be an object in ${filePath}`);\n }\n\n const rule = raw as Record<string, unknown>;\n\n // Parse optional 'when' condition (applicable to all rule types)\n const when =\n rule.when !== undefined\n ? validateWhenCondition(rule.when, `${path}.when`, filePath)\n : undefined;\n\n // Pattern rule\n if (typeof rule.pattern === 'string') {\n validatePattern(rule.pattern, `${path}.pattern`, filePath);\n return {\n pattern: rule.pattern,\n ...(typeof rule.label === 'string' ? { label: rule.label } : {}),\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(typeof rule.required === 'boolean' ? { required: rule.required } : {}),\n ...(typeof rule.prohibited === 'boolean' ? { prohibited: rule.prohibited } : {}),\n ...(when ? { when } : {}),\n } satisfies PatternContainsRule;\n }\n\n // List rule\n if (rule.list && typeof rule.list === 'object') {\n const list = rule.list as Record<string, unknown>;\n if (typeof list.pattern !== 'string') {\n throw new RuleValidationError(`${path}.list.pattern must be a string in ${filePath}`);\n }\n validatePattern(list.pattern, `${path}.list.pattern`, filePath);\n return {\n list: {\n pattern: list.pattern,\n ...(typeof list.min === 'number' ? { min: list.min } : {}),\n ...(typeof list.label === 'string' ? { label: list.label } : {}),\n },\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies ListContainsRule;\n }\n\n // Table rule\n if (rule.table && typeof rule.table === 'object') {\n const table = rule.table as Record<string, unknown>;\n if (\n !Array.isArray(table.columns) ||\n !table.columns.every((c: unknown) => typeof c === 'string')\n ) {\n throw new RuleValidationError(`${path}.table.columns must be a string array in ${filePath}`);\n }\n return {\n table: {\n ...(typeof table.heading === 'string' ? { heading: table.heading } : {}),\n columns: table.columns as string[],\n ...(typeof table['min-rows'] === 'number' ? { 'min-rows': table['min-rows'] } : {}),\n },\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies TableContainsRule;\n }\n\n // Code block rule\n if (rule['code-block'] === true) {\n return {\n 'code-block': true,\n ...(typeof rule.label === 'string' ? { label: rule.label } : {}),\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies CodeBlockContainsRule;\n }\n\n // Heading-or-text rule\n if (typeof rule['heading-or-text'] === 'string') {\n return {\n 'heading-or-text': rule['heading-or-text'],\n ...(typeof rule.required === 'boolean' ? { required: rule.required } : {}),\n ...(typeof rule.description === 'string' ? { description: rule.description } : {}),\n ...(when ? { when } : {}),\n } satisfies HeadingOrTextContainsRule;\n }\n\n throw new RuleValidationError(`${path} has no recognized rule type in ${filePath}`);\n}\n\nfunction validateWhenCondition(raw: unknown, path: string, filePath: string): WhenCondition {\n if (!raw || typeof raw !== 'object') {\n throw new RuleValidationError(`${path} must be an object in ${filePath}`);\n }\n\n const condition = raw as Record<string, unknown>;\n const result: Record<string, string> = {};\n\n if (typeof condition['heading-matches'] === 'string') {\n validatePattern(condition['heading-matches'], `${path}.heading-matches`, filePath);\n result['heading-matches'] = condition['heading-matches'];\n }\n\n if (typeof condition['heading-not-matches'] === 'string') {\n validatePattern(condition['heading-not-matches'], `${path}.heading-not-matches`, filePath);\n result['heading-not-matches'] = condition['heading-not-matches'];\n }\n\n if (!result['heading-matches'] && !result['heading-not-matches']) {\n throw new RuleValidationError(\n `${path} must have 'heading-matches' or 'heading-not-matches' in ${filePath}`\n );\n }\n\n return result as unknown as WhenCondition;\n}\n\nfunction validatePattern(pattern: string, path: string, filePath: string): void {\n // Only validate if it looks like a regex (contains regex special chars)\n if (/[.+*?^${}()|[\\]\\\\]/.test(pattern)) {\n try {\n new RegExp(pattern);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new RuleValidationError(`Invalid regex in ${path}: ${msg} (${filePath})`);\n }\n }\n}\n\nexport class RuleValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'RuleValidationError';\n }\n}\n","// @awa-component: CHK-SchemaChecker\n\nimport { readFile } from 'node:fs/promises';\nimport type { Code, Heading, List, PhrasingContent, Root, Table, TableRow } from 'mdast';\nimport remarkGfm from 'remark-gfm';\nimport remarkParse from 'remark-parse';\nimport { unified } from 'unified';\nimport { matchesTargetGlob } from './rule-loader.js';\nimport type {\n CodeBlockContainsRule,\n ContainsRule,\n HeadingOrTextContainsRule,\n ListContainsRule,\n LoadedRuleSet,\n PatternContainsRule,\n SectionRule,\n TableContainsRule,\n WhenCondition,\n} from './rule-types.js';\nimport type { CheckResult, Finding, SpecFile } from './types.js';\n\n// --- Rule formatting helpers ---\n\nfunction formatSectionRule(rule: SectionRule): string {\n const parts = [`section: heading=\"${rule.heading}\" level=${rule.level}`];\n if (rule.required) parts.push('required');\n if (rule.repeatable) parts.push('repeatable');\n return parts.join(' ');\n}\n\nfunction formatContainsRule(rule: ContainsRule): string {\n if ('pattern' in rule && typeof rule.pattern === 'string') {\n const r = rule as PatternContainsRule;\n if (r.prohibited) return `contains: prohibited pattern=\"${r.pattern}\"`;\n return `contains: pattern=\"${r.pattern}\"${r.required === false ? '' : ' required'}`;\n }\n if ('list' in rule) {\n const r = rule as ListContainsRule;\n return `contains: list pattern=\"${r.list.pattern}\"${r.list.min !== undefined ? ` min=${r.list.min}` : ''}`;\n }\n if ('table' in rule) {\n const r = rule as TableContainsRule;\n return `contains: table columns=[${r.table.columns.join(', ')}]${r.table['min-rows'] !== undefined ? ` min-rows=${r.table['min-rows']}` : ''}`;\n }\n if ('code-block' in rule) {\n return 'contains: code-block';\n }\n if ('heading-or-text' in rule) {\n const r = rule as HeadingOrTextContainsRule;\n return `contains: heading-or-text=\"${r['heading-or-text']}\"`;\n }\n return 'contains: (unknown rule)';\n}\n\nfunction formatLineLimitRule(limit: number): string {\n return `line-limit: ${limit}`;\n}\n\nfunction formatProhibitedRule(pattern: string): string {\n return `sections-prohibited: \"${pattern}\"`;\n}\n\n/** A section with heading info and all AST nodes belonging to it. */\ninterface SectionNode {\n readonly heading: Heading;\n readonly headingText: string;\n readonly level: number;\n readonly children: SectionNode[];\n readonly contentNodes: Root['children'];\n}\n\n/**\n * Check all spec files against loaded rule sets.\n * Reads file content, parses to mdast, walks AST checking rules.\n */\nexport async function checkSchemasAsync(\n specFiles: readonly SpecFile[],\n ruleSets: readonly LoadedRuleSet[]\n): Promise<CheckResult> {\n const findings: Finding[] = [];\n const parser = unified().use(remarkParse).use(remarkGfm);\n\n for (const spec of specFiles) {\n const matchingRules = ruleSets.filter((rs) => matchesTargetGlob(spec.filePath, rs.targetGlob));\n if (matchingRules.length === 0) continue;\n\n let content: string;\n try {\n content = await readFile(spec.filePath, 'utf-8');\n } catch {\n continue;\n }\n\n const tree = parser.parse(content);\n const sectionTree = buildSectionTree(tree);\n const allSections = flattenSections(sectionTree);\n\n for (const ruleSet of matchingRules) {\n const ruleSource = ruleSet.sourcePath;\n\n // Check line limit if defined\n if (ruleSet.ruleFile['line-limit'] !== undefined) {\n const lineCount = content.split('\\n').length;\n if (lineCount > ruleSet.ruleFile['line-limit']) {\n findings.push({\n severity: 'warning',\n code: 'schema-line-limit',\n message: `File has ${lineCount} lines, exceeds limit of ${ruleSet.ruleFile['line-limit']}`,\n filePath: spec.filePath,\n ruleSource,\n rule: formatLineLimitRule(ruleSet.ruleFile['line-limit']),\n });\n }\n }\n\n findings.push(\n ...checkRulesAgainstSections(\n allSections,\n ruleSet.ruleFile.sections,\n spec.filePath,\n ruleSource\n )\n );\n\n if (ruleSet.ruleFile['sections-prohibited']) {\n findings.push(\n ...checkProhibited(\n content,\n ruleSet.ruleFile['sections-prohibited'],\n spec.filePath,\n ruleSource\n )\n );\n }\n }\n }\n\n return { findings };\n}\n\n// --- Section tree building ---\n\nfunction buildSectionTree(tree: Root): SectionNode[] {\n return buildSectionsFromNodes(tree.children, 0, 0).sections;\n}\n\nfunction buildSectionsFromNodes(\n nodes: Root['children'],\n start: number,\n parentLevel: number\n): { sections: SectionNode[]; nextIndex: number } {\n const sections: SectionNode[] = [];\n let i = start;\n\n while (i < nodes.length) {\n const node = nodes[i];\n if (!node) break;\n if (node.type === 'heading') {\n const h = node as Heading;\n if (parentLevel > 0 && h.depth <= parentLevel) break;\n\n const headingText = extractText(h.children);\n const contentNodes: Root['children'] = [];\n i++;\n\n // Collect content until next heading of same-or-higher level\n while (i < nodes.length) {\n const next = nodes[i];\n if (!next || next.type === 'heading') break;\n contentNodes.push(next);\n i++;\n }\n\n // Collect child headings (deeper level)\n const childResult = buildSectionsFromNodes(nodes, i, h.depth);\n i = childResult.nextIndex;\n\n sections.push({\n heading: h,\n headingText,\n level: h.depth,\n children: childResult.sections,\n contentNodes,\n });\n } else {\n i++;\n }\n }\n\n return { sections, nextIndex: i };\n}\n\nfunction flattenSections(sections: SectionNode[]): SectionNode[] {\n const result: SectionNode[] = [];\n for (const s of sections) {\n result.push(s);\n result.push(...flattenSections(s.children));\n }\n return result;\n}\n\nfunction extractText(children: PhrasingContent[]): string {\n return children\n .map((c) => {\n if ('value' in c) return c.value;\n if ('children' in c) return extractText(c.children as PhrasingContent[]);\n return '';\n })\n .join('');\n}\n\n// --- Rule checking ---\n\n/**\n * Top-level rules match against the flattened view of all sections.\n * `children` sub-rules match only within the matched section's children.\n */\nfunction checkRulesAgainstSections(\n allSections: SectionNode[],\n rules: readonly SectionRule[],\n filePath: string,\n ruleSource: string\n): Finding[] {\n const findings: Finding[] = [];\n\n for (const rule of rules) {\n const matches = findMatchingSections(allSections, rule);\n\n if (matches.length === 0 && rule.required) {\n findings.push({\n severity: 'error',\n code: 'schema-missing-section',\n message: `Missing required section: '${rule.heading}' (level ${rule.level})`,\n filePath,\n ruleSource,\n rule: formatSectionRule(rule),\n });\n continue;\n }\n\n for (const match of matches) {\n if (match.level !== rule.level) {\n findings.push({\n severity: 'warning',\n code: 'schema-wrong-level',\n message: `Section '${match.headingText}' is level ${match.level}, expected ${rule.level}`,\n filePath,\n line: match.heading.position?.start.line,\n ruleSource,\n rule: formatSectionRule(rule),\n });\n }\n\n if (rule.contains) {\n for (const cr of rule.contains) {\n findings.push(...checkContainsRule(match, cr, filePath, ruleSource));\n }\n }\n\n if (rule.children) {\n const childFlat = flattenSections(match.children);\n findings.push(...checkRulesAgainstSections(childFlat, rule.children, filePath, ruleSource));\n }\n }\n }\n\n return findings;\n}\n\nfunction findMatchingSections(allSections: SectionNode[], rule: SectionRule): SectionNode[] {\n const regex = createHeadingRegex(rule.heading);\n const matches = allSections.filter((s) => s.level === rule.level && regex.test(s.headingText));\n\n if (!rule.repeatable && matches.length > 1) {\n return [matches[0] as SectionNode];\n }\n return matches;\n}\n\nfunction createHeadingRegex(pattern: string): RegExp {\n if (/[.+*?^${}()|[\\]\\\\]/.test(pattern)) {\n try {\n return new RegExp(`^${pattern}$`);\n } catch {\n return new RegExp(`^${escapeRegex(pattern)}$`);\n }\n }\n return new RegExp(`^${escapeRegex(pattern)}$`, 'i');\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// --- Contains rule dispatching ---\n\nfunction checkContainsRule(\n section: SectionNode,\n rule: ContainsRule,\n filePath: string,\n ruleSource: string\n): Finding[] {\n // Evaluate 'when' condition gate — skip rule if condition not met\n const when = 'when' in rule ? (rule as { when?: WhenCondition }).when : undefined;\n if (when && !evaluateWhenCondition(when, section.headingText)) {\n return [];\n }\n\n const formattedRule = formatContainsRule(rule);\n\n if ('pattern' in rule && typeof rule.pattern === 'string') {\n return checkPatternContains(\n section,\n rule as PatternContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('list' in rule) {\n return checkListContains(\n section,\n rule as ListContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('table' in rule) {\n return checkTableContains(\n section,\n rule as TableContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('code-block' in rule) {\n return checkCodeBlockContains(\n section,\n rule as CodeBlockContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n if ('heading-or-text' in rule) {\n return checkHeadingOrText(\n section,\n rule as HeadingOrTextContainsRule,\n filePath,\n ruleSource,\n formattedRule\n );\n }\n return [];\n}\n\nfunction checkPatternContains(\n section: SectionNode,\n rule: PatternContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const text = getFullSectionText(section);\n const found = new RegExp(rule.pattern, 'm').test(text);\n\n // Prohibited mode: pattern must NOT appear\n if (rule.prohibited) {\n if (found) {\n return [\n {\n severity: 'warning',\n code: 'schema-prohibited',\n message: `Section '${section.headingText}' contains prohibited content: ${rule.label ?? rule.pattern}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n }\n\n // Normal mode: pattern must appear\n if (found) return [];\n\n if (rule.required !== false) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required content: ${rule.label ?? rule.pattern}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n}\n\nfunction checkListContains(\n section: SectionNode,\n rule: ListContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const items = collectAllListItems(section);\n const regex = new RegExp(rule.list.pattern);\n const count = items.filter((item) => regex.test(item)).length;\n\n if (rule.list.min !== undefined && count < rule.list.min) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' has ${count} matching ${rule.list.label ?? 'list items'}, expected at least ${rule.list.min}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n}\n\nfunction checkTableContains(\n section: SectionNode,\n rule: TableContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const tables = collectAllTables(section);\n\n if (tables.length === 0) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required table${rule.table.heading ? ` (${rule.table.heading})` : ''}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n\n // Find the first table whose columns match the rule. If none match, report\n // the column mismatch for the first table. This avoids false positives when a\n // section contains multiple tables with different column sets.\n let matched: Table | undefined;\n let firstMismatch: { table: Table; headers: string[] } | undefined;\n\n for (const table of tables) {\n const headerRow = table.children[0] as TableRow | undefined;\n if (!headerRow) continue;\n\n const headers = headerRow.children.map((cell) =>\n extractText(cell.children as PhrasingContent[]).trim()\n );\n\n if (rule.table.columns.every((col) => headers.includes(col))) {\n matched = table;\n break;\n }\n if (!firstMismatch) {\n firstMismatch = { table, headers };\n }\n }\n\n if (!matched) {\n const mm = firstMismatch;\n return [\n {\n severity: 'error',\n code: 'schema-table-columns',\n message: `No table in '${section.headingText}' has columns [${rule.table.columns.join(', ')}]${mm ? `, found [${mm.headers.join(', ')}]` : ''}`,\n filePath,\n line: mm?.table.position?.start.line ?? section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n\n const findings: Finding[] = [];\n const dataRows = matched.children.length - 1;\n if (rule.table['min-rows'] !== undefined && dataRows < rule.table['min-rows']) {\n findings.push({\n severity: 'error',\n code: 'schema-missing-content',\n message: `Table in '${section.headingText}' has ${dataRows} data rows, expected at least ${rule.table['min-rows']}`,\n filePath,\n line: matched.position?.start.line,\n ruleSource,\n rule: formattedRule,\n });\n }\n return findings;\n}\n\nfunction checkCodeBlockContains(\n section: SectionNode,\n rule: CodeBlockContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n if (collectAllCodeBlocks(section).length > 0) return [];\n\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required ${rule.label ?? 'code block'}`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n}\n\nfunction checkHeadingOrText(\n section: SectionNode,\n rule: HeadingOrTextContainsRule,\n filePath: string,\n ruleSource: string,\n formattedRule: string\n): Finding[] {\n const needle = rule['heading-or-text'].toUpperCase();\n\n if (section.children.some((c) => c.headingText.toUpperCase().includes(needle))) return [];\n if (getFullSectionText(section).toUpperCase().includes(needle)) return [];\n\n if (rule.required !== false) {\n return [\n {\n severity: 'error',\n code: 'schema-missing-content',\n message: `Section '${section.headingText}' missing required heading or text: '${rule['heading-or-text']}'`,\n filePath,\n line: section.heading.position?.start.line,\n ruleSource,\n rule: formattedRule,\n },\n ];\n }\n return [];\n}\n\n// --- When condition evaluation ---\n\nfunction evaluateWhenCondition(when: WhenCondition, headingText: string): boolean {\n if (when['heading-matches']) {\n if (!new RegExp(when['heading-matches']).test(headingText)) return false;\n }\n if (when['heading-not-matches']) {\n if (new RegExp(when['heading-not-matches']).test(headingText)) return false;\n }\n return true;\n}\n\n// --- Prohibited patterns ---\n\nfunction checkProhibited(\n content: string,\n prohibited: readonly string[],\n filePath: string,\n ruleSource: string\n): Finding[] {\n const findings: Finding[] = [];\n const lines = content.split('\\n');\n\n for (const pattern of prohibited) {\n const regex = new RegExp(escapeRegex(pattern));\n let inCodeBlock = false;\n\n for (const [i, line] of lines.entries()) {\n if (line.startsWith('```')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n if (regex.test(line)) {\n findings.push({\n severity: 'warning',\n code: 'schema-prohibited',\n message: `Prohibited formatting '${pattern}' found`,\n filePath,\n line: i + 1,\n ruleSource,\n rule: formatProhibitedRule(pattern),\n });\n break;\n }\n }\n }\n return findings;\n}\n\n// --- Content extraction helpers ---\n\nfunction getFullSectionText(section: SectionNode): string {\n let text = section.contentNodes.map(nodeToText).join('\\n');\n for (const child of section.children) {\n text += `\\n${child.headingText}\\n${getFullSectionText(child)}`;\n }\n return text;\n}\n\nfunction nodeToText(node: Root['children'][number]): string {\n if ('value' in node) return node.value as string;\n if ('children' in node) {\n return (node.children as Root['children'])\n .map((c) => nodeToText(c as Root['children'][number]))\n .join('');\n }\n return '';\n}\n\nfunction extractListItems(nodes: Root['children']): string[] {\n const items: string[] = [];\n for (const node of nodes) {\n if (node.type === 'list') {\n for (const item of (node as List).children) {\n const raw = nodeToText(item as unknown as Root['children'][number]);\n // remark-gfm stores checkbox state as a `checked` property on the listItem\n // rather than preserving the literal [ ] / [x] text. Reconstruct it for\n // rules that match checkbox syntax (e.g. \\[ \\] T-CODE-nnn).\n const li = item as { checked?: boolean | null };\n if (li.checked === true) {\n items.push(`[x] ${raw}`);\n } else if (li.checked === false) {\n items.push(`[ ] ${raw}`);\n } else {\n items.push(raw);\n }\n }\n }\n }\n return items;\n}\n\nfunction collectAllListItems(section: SectionNode): string[] {\n const items = extractListItems(section.contentNodes);\n for (const child of section.children) items.push(...collectAllListItems(child));\n return items;\n}\n\nfunction collectAllTables(section: SectionNode): Table[] {\n const tables = section.contentNodes.filter((n) => n.type === 'table') as Table[];\n for (const child of section.children) tables.push(...collectAllTables(child));\n return tables;\n}\n\nfunction collectAllCodeBlocks(section: SectionNode): Code[] {\n const blocks = section.contentNodes.filter((n) => n.type === 'code') as Code[];\n for (const child of section.children) blocks.push(...collectAllCodeBlocks(child));\n return blocks;\n}\n","// @awa-component: CHK-SpecParser\n// @awa-impl: CHK-2_AC-1\n// @awa-impl: CHK-12_AC-1\n\nimport { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport { collectFiles } from './glob.js';\nimport type { CheckConfig, CrossReference, SpecFile, SpecParseResult } from './types.js';\n\n// @awa-impl: CHK-2_AC-1\nexport async function parseSpecs(config: CheckConfig): Promise<SpecParseResult> {\n const files = await collectSpecFiles(config.specGlobs, config.specIgnore);\n const specFiles: SpecFile[] = [];\n\n const requirementIds = new Set<string>();\n const acIds = new Set<string>();\n const propertyIds = new Set<string>();\n const componentNames = new Set<string>();\n const idLocations = new Map<string, { filePath: string; line: number }>();\n\n for (const filePath of files) {\n const specFile = await parseSpecFile(filePath, config.crossRefPatterns);\n if (specFile) {\n specFiles.push(specFile);\n for (const id of specFile.requirementIds) requirementIds.add(id);\n for (const id of specFile.acIds) acIds.add(id);\n for (const id of specFile.propertyIds) propertyIds.add(id);\n for (const name of specFile.componentNames) componentNames.add(name);\n // Merge id locations from parsed spec file\n for (const [id, loc] of specFile.idLocations ?? []) {\n idLocations.set(id, loc);\n }\n }\n }\n\n const allIds = new Set<string>([...requirementIds, ...acIds, ...propertyIds, ...componentNames]);\n\n return { requirementIds, acIds, propertyIds, componentNames, allIds, specFiles, idLocations };\n}\n\nasync function parseSpecFile(\n filePath: string,\n crossRefPatterns: readonly string[]\n): Promise<SpecFile | null> {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n\n const code = extractCodePrefix(filePath);\n const lines = content.split('\\n');\n\n const requirementIds: string[] = [];\n const acIds: string[] = [];\n const propertyIds: string[] = [];\n const componentNames: string[] = [];\n const crossRefs: CrossReference[] = [];\n const idLocations = new Map<string, { filePath: string; line: number }>();\n\n // Requirement ID: ### CODE-N: Title or ### CODE-N.P: Title\n const reqIdRegex = /^###\\s+([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?)\\s*:/;\n // AC ID: - CODE-N_AC-M or - [ ] CODE-N_AC-M or - [x] CODE-N.P_AC-M\n const acIdRegex = /^-\\s+(?:\\[[ x]\\]\\s+)?([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?_AC-\\d+)\\s/;\n // Property ID: - CODE_P-N [Name]\n const propIdRegex = /^-\\s+([A-Z][A-Z0-9]*_P-\\d+)\\s/;\n // Component name: ### CODE-ComponentName\n const componentRegex = /^###\\s+([A-Z][A-Z0-9]*-[A-Za-z][A-Za-z0-9]*(?:[A-Z][a-z0-9]*)*)\\s*$/;\n\n for (const [i, line] of lines.entries()) {\n const lineNum = i + 1;\n\n // Requirement IDs\n const reqMatch = reqIdRegex.exec(line);\n if (reqMatch?.[1]) {\n requirementIds.push(reqMatch[1]);\n idLocations.set(reqMatch[1], { filePath, line: lineNum });\n }\n\n // AC IDs\n const acMatch = acIdRegex.exec(line);\n if (acMatch?.[1]) {\n acIds.push(acMatch[1]);\n idLocations.set(acMatch[1], { filePath, line: lineNum });\n }\n\n // Property IDs\n const propMatch = propIdRegex.exec(line);\n if (propMatch?.[1]) {\n propertyIds.push(propMatch[1]);\n idLocations.set(propMatch[1], { filePath, line: lineNum });\n }\n\n // Component names (from DESIGN files)\n const compMatch = componentRegex.exec(line);\n if (compMatch?.[1]) {\n // Only count as component if it doesn't match requirement pattern\n if (!reqIdRegex.test(line)) {\n componentNames.push(compMatch[1]);\n idLocations.set(compMatch[1], { filePath, line: lineNum });\n }\n }\n\n // Cross-references (IMPLEMENTS:, VALIDATES:)\n for (const pattern of crossRefPatterns) {\n const patIdx = line.indexOf(pattern);\n if (patIdx !== -1) {\n const afterPattern = line.slice(patIdx + pattern.length);\n const ids = extractIdsFromText(afterPattern);\n if (ids.length > 0) {\n const type = pattern.toLowerCase().includes('implements') ? 'implements' : 'validates';\n crossRefs.push({ type, ids, filePath, line: i + 1 });\n }\n }\n }\n }\n\n return {\n filePath,\n code,\n requirementIds,\n acIds,\n propertyIds,\n componentNames,\n crossRefs,\n idLocations,\n };\n}\n\nfunction extractCodePrefix(filePath: string): string {\n const name = basename(filePath, '.md');\n // Extract CODE from patterns like REQ-CODE-feature, DESIGN-CODE-feature, FEAT-CODE-feature\n const match = /^(?:REQ|DESIGN|FEAT|EXAMPLES|API)-([A-Z][A-Z0-9]*)-/.exec(name);\n if (match?.[1]) return match[1];\n // Fallback: ARCHITECTURE.md has no code prefix\n return '';\n}\n\nfunction extractIdsFromText(text: string): string[] {\n const idRegex = /[A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?(?:_AC-\\d+)?|[A-Z][A-Z0-9]*_P-\\d+/g;\n const ids: string[] = [];\n let match = idRegex.exec(text);\n while (match !== null) {\n ids.push(match[0]);\n match = idRegex.exec(text);\n }\n return ids;\n}\n\n// @awa-impl: CHK-12_AC-1\nasync function collectSpecFiles(\n specGlobs: readonly string[],\n ignore: readonly string[]\n): Promise<string[]> {\n return collectFiles(specGlobs, ignore);\n}\n","// @awa-component: CHK-SpecSpecChecker\n// @awa-impl: CHK-5_AC-1\n// @awa-impl: CHK-7_AC-1\n// @awa-impl: CHK-15_AC-1\n\nimport type {\n CheckConfig,\n CheckResult,\n Finding,\n MarkerScanResult,\n SpecParseResult,\n} from './types.js';\n\n// @awa-impl: CHK-5_AC-1, CHK-7_AC-1\nexport function checkSpecAgainstSpec(\n specs: SpecParseResult,\n markers: MarkerScanResult,\n config: CheckConfig\n): CheckResult {\n const findings: Finding[] = [];\n\n // @awa-impl: CHK-5_AC-1\n // Check cross-references resolve to real IDs\n for (const specFile of specs.specFiles) {\n for (const crossRef of specFile.crossRefs) {\n for (const refId of crossRef.ids) {\n if (!specs.allIds.has(refId)) {\n findings.push({\n severity: 'error',\n code: 'broken-cross-ref',\n message: `Cross-reference '${refId}' (${crossRef.type}) not found in any spec file`,\n filePath: crossRef.filePath,\n line: crossRef.line,\n id: refId,\n });\n }\n }\n }\n }\n\n // @awa-impl: CHK-7_AC-1\n // Check for orphaned spec files (CODE not referenced by any other spec or code)\n // Skip when specOnly — orphaned-spec detection depends on code markers to be meaningful\n if (!config.specOnly) {\n const referencedCodes = new Set<string>();\n\n // Collect codes referenced in code markers\n for (const marker of markers.markers) {\n const codeMatch = /^([A-Z][A-Z0-9]*)[-_]/.exec(marker.id);\n if (codeMatch?.[1]) {\n referencedCodes.add(codeMatch[1]);\n }\n }\n\n // Collect codes referenced in cross-references\n for (const specFile of specs.specFiles) {\n for (const crossRef of specFile.crossRefs) {\n for (const refId of crossRef.ids) {\n const codeMatch = /^([A-Z][A-Z0-9]*)[-_]/.exec(refId);\n if (codeMatch?.[1]) {\n referencedCodes.add(codeMatch[1]);\n }\n }\n }\n }\n\n for (const specFile of specs.specFiles) {\n if (!specFile.code) continue; // Skip ARCHITECTURE.md etc.\n if (!referencedCodes.has(specFile.code)) {\n findings.push({\n severity: 'warning',\n code: 'orphaned-spec',\n message: `Spec file code '${specFile.code}' is not referenced by any other spec or code marker`,\n filePath: specFile.filePath,\n id: specFile.code,\n });\n }\n }\n }\n\n return { findings };\n}\n","// @awa-component: CHK-CheckCommand\n\n// @awa-impl: CHK-16_AC-1\nexport interface CheckConfig {\n readonly specGlobs: readonly string[];\n readonly codeGlobs: readonly string[];\n readonly specIgnore: readonly string[];\n readonly codeIgnore: readonly string[];\n readonly ignoreMarkers: readonly string[];\n readonly markers: readonly string[];\n readonly idPattern: string;\n readonly crossRefPatterns: readonly string[];\n readonly format: 'text' | 'json';\n readonly schemaDir: string;\n readonly schemaEnabled: boolean;\n readonly allowWarnings: boolean;\n readonly specOnly: boolean;\n}\n\nexport const DEFAULT_CHECK_CONFIG: CheckConfig = {\n specGlobs: [\n '.awa/specs/ARCHITECTURE.md',\n '.awa/specs/FEAT-*.md',\n '.awa/specs/REQ-*.md',\n '.awa/specs/DESIGN-*.md',\n '.awa/specs/EXAMPLES-*.md',\n '.awa/specs/API-*.tsp',\n '.awa/tasks/TASK-*.md',\n '.awa/plans/PLAN-*.md',\n '.awa/align/ALIGN-*.md',\n ],\n codeGlobs: [\n '**/*.{ts,js,tsx,jsx,mts,mjs,cjs,py,go,rs,java,kt,kts,cs,c,h,cpp,cc,cxx,hpp,hxx,swift,rb,php,scala,ex,exs,dart,lua,zig}',\n ],\n specIgnore: [],\n codeIgnore: [\n 'node_modules/**',\n 'dist/**',\n 'vendor/**',\n 'target/**',\n 'build/**',\n 'out/**',\n '.awa/**',\n ],\n ignoreMarkers: [],\n markers: ['@awa-impl', '@awa-test', '@awa-component'],\n idPattern: '([A-Z][A-Z0-9]*-\\\\d+(?:\\\\.\\\\d+)?(?:_AC-\\\\d+)?|[A-Z][A-Z0-9]*_P-\\\\d+)',\n crossRefPatterns: ['IMPLEMENTS:', 'VALIDATES:'],\n format: 'text',\n schemaDir: '.awa/.agent/schemas',\n schemaEnabled: true,\n allowWarnings: false,\n specOnly: false,\n};\n\nexport type FindingSeverity = 'error' | 'warning';\n\nexport type FindingCode =\n | 'orphaned-marker'\n | 'uncovered-ac'\n | 'uncovered-component'\n | 'unimplemented-ac'\n | 'broken-cross-ref'\n | 'invalid-id-format'\n | 'marker-trailing-text'\n | 'orphaned-spec'\n | 'schema-missing-section'\n | 'schema-wrong-level'\n | 'schema-missing-content'\n | 'schema-table-columns'\n | 'schema-prohibited'\n | 'schema-no-rule'\n | 'schema-line-limit';\n\nexport interface Finding {\n readonly severity: FindingSeverity;\n readonly code: FindingCode;\n readonly message: string;\n readonly filePath?: string;\n readonly line?: number;\n readonly id?: string;\n /** Path to the .schema.yaml file that defines the violated rule. */\n readonly ruleSource?: string;\n /** Concise representation of the violated rule. */\n readonly rule?: string;\n}\n\nexport type MarkerType = 'impl' | 'test' | 'component';\n\nexport interface CodeMarker {\n readonly type: MarkerType;\n readonly id: string;\n readonly filePath: string;\n readonly line: number;\n}\n\nexport interface MarkerScanResult {\n readonly markers: readonly CodeMarker[];\n readonly findings: readonly Finding[];\n}\n\nexport interface CrossReference {\n readonly type: 'implements' | 'validates';\n readonly ids: readonly string[];\n readonly filePath: string;\n readonly line: number;\n}\n\nexport interface SpecFile {\n readonly filePath: string;\n readonly code: string;\n readonly requirementIds: readonly string[];\n readonly acIds: readonly string[];\n readonly propertyIds: readonly string[];\n readonly componentNames: readonly string[];\n readonly crossRefs: readonly CrossReference[];\n /** Maps IDs parsed from this file to their line number. Populated by spec-parser. */\n readonly idLocations?: ReadonlyMap<string, { filePath: string; line: number }>;\n}\n\nexport interface SpecParseResult {\n readonly requirementIds: Set<string>;\n readonly acIds: Set<string>;\n readonly propertyIds: Set<string>;\n readonly componentNames: Set<string>;\n readonly allIds: Set<string>;\n readonly specFiles: readonly SpecFile[];\n /** Maps spec IDs (requirements, ACs, properties, components) to their source location. */\n readonly idLocations: ReadonlyMap<string, { filePath: string; line: number }>;\n}\n\nexport interface CheckResult {\n readonly findings: readonly Finding[];\n}\n\nexport interface RawCheckOptions {\n readonly specIgnore?: string[];\n readonly codeIgnore?: string[];\n readonly format?: string;\n readonly config?: string;\n readonly allowWarnings?: boolean;\n readonly specOnly?: boolean;\n}\n","// @awa-component: CHK-CheckCommand\n// @awa-impl: CHK-8_AC-1\n// @awa-impl: CHK-10_AC-1\n// @awa-impl: CHK-17_AC-1\n// @awa-impl: CHK-17_AC-2\n// @awa-impl: CHK-17_AC-3\n\nimport { checkCodeAgainstSpec } from '../core/check/code-spec-checker.js';\nimport { scanMarkers } from '../core/check/marker-scanner.js';\nimport { report } from '../core/check/reporter.js';\nimport { loadRules } from '../core/check/rule-loader.js';\nimport { checkSchemasAsync } from '../core/check/schema-checker.js';\nimport { parseSpecs } from '../core/check/spec-parser.js';\nimport { checkSpecAgainstSpec } from '../core/check/spec-spec-checker.js';\nimport type { CheckConfig, RawCheckOptions } from '../core/check/types.js';\nimport { DEFAULT_CHECK_CONFIG } from '../core/check/types.js';\nimport { configLoader } from '../core/config.js';\nimport type { FileConfig } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\n\n// @awa-impl: CHK-8_AC-1\nexport async function checkCommand(cliOptions: RawCheckOptions): Promise<number> {\n try {\n // Load config from file\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // Build check config from file [check] section + CLI overrides\n const config = buildCheckConfig(fileConfig, cliOptions);\n\n // Scan code markers (skip when --spec-only), parse specs, and load schema rules in parallel\n const emptyMarkers: import('../core/check/types.js').MarkerScanResult = {\n markers: [],\n findings: [],\n };\n const [markers, specs, ruleSets] = await Promise.all([\n config.specOnly ? Promise.resolve(emptyMarkers) : scanMarkers(config),\n parseSpecs(config),\n config.schemaEnabled ? loadRules(config.schemaDir) : Promise.resolve([]),\n ]);\n\n // Run checkers (code-spec and spec-spec are synchronous; schema is async)\n // When --spec-only, skip code-to-spec traceability checks entirely\n const codeSpecResult = config.specOnly\n ? { findings: [] as const }\n : checkCodeAgainstSpec(markers, specs, config);\n const specSpecResult = checkSpecAgainstSpec(specs, markers, config);\n const schemaResult =\n config.schemaEnabled && ruleSets.length > 0\n ? await checkSchemasAsync(specs.specFiles, ruleSets)\n : { findings: [] as const };\n\n // Combine findings\n const combinedFindings = [\n ...markers.findings,\n ...codeSpecResult.findings,\n ...specSpecResult.findings,\n ...schemaResult.findings,\n ];\n\n // Unless --allow-warnings, promote warnings to errors\n const allFindings = config.allowWarnings\n ? combinedFindings\n : combinedFindings.map((f) =>\n f.severity === 'warning' ? { ...f, severity: 'error' as const } : f\n );\n\n // Report results\n report(allFindings, config.format);\n\n // Exit code: 0 = clean, 1 = any errors present\n const hasErrors = allFindings.some((f) => f.severity === 'error');\n return hasErrors ? 1 : 0;\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n return 2;\n }\n}\n\n// @awa-impl: CHK-10_AC-1, CHK-16_AC-1\nfunction buildCheckConfig(fileConfig: FileConfig | null, cliOptions: RawCheckOptions): CheckConfig {\n const section = fileConfig?.check;\n\n const specGlobs = toStringArray(section?.['spec-globs']) ?? [...DEFAULT_CHECK_CONFIG.specGlobs];\n const codeGlobs = toStringArray(section?.['code-globs']) ?? [...DEFAULT_CHECK_CONFIG.codeGlobs];\n const markers = toStringArray(section?.markers) ?? [...DEFAULT_CHECK_CONFIG.markers];\n const crossRefPatterns = toStringArray(section?.['cross-ref-patterns']) ?? [\n ...DEFAULT_CHECK_CONFIG.crossRefPatterns,\n ];\n const idPattern =\n typeof section?.['id-pattern'] === 'string'\n ? section['id-pattern']\n : DEFAULT_CHECK_CONFIG.idPattern;\n\n // CLI --spec-ignore / --code-ignore append to their respective config lists\n const configSpecIgnore = toStringArray(section?.['spec-ignore']) ?? [\n ...DEFAULT_CHECK_CONFIG.specIgnore,\n ];\n const configCodeIgnore = toStringArray(section?.['code-ignore']) ?? [\n ...DEFAULT_CHECK_CONFIG.codeIgnore,\n ];\n const specIgnore = [...configSpecIgnore, ...(cliOptions.specIgnore ?? [])];\n const codeIgnore = [...configCodeIgnore, ...(cliOptions.codeIgnore ?? [])];\n\n const ignoreMarkers = toStringArray(section?.['ignore-markers']) ?? [\n ...DEFAULT_CHECK_CONFIG.ignoreMarkers,\n ];\n\n const format: 'text' | 'json' =\n cliOptions.format === 'json'\n ? 'json'\n : section?.format === 'json'\n ? 'json'\n : DEFAULT_CHECK_CONFIG.format;\n\n const schemaDir =\n typeof section?.['schema-dir'] === 'string'\n ? section['schema-dir']\n : DEFAULT_CHECK_CONFIG.schemaDir;\n\n const schemaEnabled =\n typeof section?.['schema-enabled'] === 'boolean'\n ? section['schema-enabled']\n : DEFAULT_CHECK_CONFIG.schemaEnabled;\n\n const allowWarnings =\n cliOptions.allowWarnings === true\n ? true\n : typeof section?.['allow-warnings'] === 'boolean'\n ? section['allow-warnings']\n : DEFAULT_CHECK_CONFIG.allowWarnings;\n\n const specOnly =\n cliOptions.specOnly === true\n ? true\n : typeof section?.['spec-only'] === 'boolean'\n ? section['spec-only']\n : DEFAULT_CHECK_CONFIG.specOnly;\n\n return {\n specGlobs,\n codeGlobs,\n specIgnore,\n codeIgnore,\n ignoreMarkers,\n markers,\n idPattern,\n crossRefPatterns,\n format,\n schemaDir,\n schemaEnabled,\n allowWarnings,\n specOnly,\n };\n}\n\nfunction toStringArray(value: unknown): string[] | null {\n if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {\n return value as string[];\n }\n return null;\n}\n","// @awa-component: DIFF-DiffCommand\n// @awa-component: JSON-DiffCommand\n// @awa-component: MULTI-DiffCommand\n// @awa-impl: DIFF-5_AC-1\n// @awa-impl: DIFF-5_AC-2\n// @awa-impl: DIFF-5_AC-3\n// @awa-impl: MULTI-6_AC-1\n// @awa-impl: MULTI-7_AC-1\n// @awa-impl: MULTI-12_AC-1\n\nimport { intro, outro } from '@clack/prompts';\nimport { batchRunner } from '../core/batch-runner.js';\nimport { configLoader } from '../core/config.js';\nimport { diffEngine } from '../core/differ.js';\nimport { featureResolver } from '../core/feature-resolver.js';\nimport { formatDiffSummary, serializeDiffResult, writeJsonOutput } from '../core/json-output.js';\nimport { buildMergedDir, resolveOverlays } from '../core/overlay.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport { DiffError, type RawCliOptions, type ResolvedOptions } from '../types/index.js';\nimport { FileWatcher } from '../utils/file-watcher.js';\nimport { pathExists, rmDir } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nasync function runDiff(\n diffOptions: {\n templatePath: string;\n targetPath: string;\n features: string[];\n listUnknown: boolean;\n },\n options: { json: boolean; summary: boolean },\n mergedDir: string | null\n): Promise<number> {\n try {\n // Perform diff\n const result = await diffEngine.diff(diffOptions);\n\n // @awa-impl: JSON-2_AC-1, JSON-8_AC-1\n if (options.json) {\n writeJsonOutput(serializeDiffResult(result));\n // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2\n return result.hasDifferences ? 1 : 0;\n }\n\n // @awa-impl: JSON-5_AC-1\n if (options.summary) {\n console.log(formatDiffSummary(result));\n return result.hasDifferences ? 1 : 0;\n }\n\n // Display diff output\n for (const file of result.files) {\n switch (file.status) {\n case 'modified':\n logger.info(`Modified: ${file.relativePath}`);\n if (file.unifiedDiff) {\n // Parse and display unified diff with colors\n const lines = file.unifiedDiff.split('\\n');\n for (const line of lines) {\n if (\n line.startsWith('diff --git') ||\n line.startsWith('index ') ||\n line.startsWith('--- ') ||\n line.startsWith('+++ ')\n ) {\n logger.diffLine(line, 'context');\n } else if (line.startsWith('+')) {\n logger.diffLine(line, 'add');\n } else if (line.startsWith('-')) {\n logger.diffLine(line, 'remove');\n } else if (line.startsWith('@@')) {\n logger.diffLine(line, 'context');\n } else {\n logger.diffLine(line, 'context');\n }\n }\n }\n break;\n case 'new':\n logger.info(`New file: ${file.relativePath}`);\n break;\n case 'extra':\n logger.warn(`Extra file (not in template): ${file.relativePath}`);\n break;\n case 'binary-differs':\n logger.warn(`binary files differ: ${file.relativePath}`);\n break;\n case 'delete-listed':\n logger.warn(`Delete listed: ${file.relativePath}`);\n break;\n case 'identical':\n // Skip identical files from output\n break;\n }\n }\n\n // Display summary\n logger.diffSummary(result);\n\n // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2\n return result.hasDifferences ? 1 : 0;\n } finally {\n // Clean up merged overlay temp directory\n if (mergedDir) {\n try {\n await rmDir(mergedDir);\n } catch {\n // Swallow cleanup errors — temp dir will be cleaned by OS eventually\n }\n }\n }\n}\n\nasync function prepareDiff(options: ResolvedOptions): Promise<{\n diffOptions: {\n templatePath: string;\n targetPath: string;\n features: string[];\n listUnknown: boolean;\n };\n template: { type: string; localPath: string; source: string };\n mergedDir: string | null;\n}> {\n // Validate target directory exists (now from options.output)\n if (!(await pathExists(options.output))) {\n throw new DiffError(`Target directory does not exist: ${options.output}`);\n }\n\n const targetPath = options.output;\n\n // Resolve template source\n const template = await templateResolver.resolve(options.template, options.refresh);\n\n const features = featureResolver.resolve({\n baseFeatures: [...options.features],\n presetNames: [...options.preset],\n removeFeatures: [...options.removeFeatures],\n presetDefinitions: options.presets,\n });\n\n // @awa-impl: OVL-7_AC-1\n // Build merged template dir if overlays are specified\n let mergedDir: string | null = null;\n let templatePath = template.localPath;\n if (options.overlay.length > 0) {\n const overlayDirs = await resolveOverlays([...options.overlay], options.refresh);\n mergedDir = await buildMergedDir(template.localPath, overlayDirs);\n templatePath = mergedDir;\n }\n\n return {\n diffOptions: {\n templatePath,\n targetPath,\n features,\n listUnknown: options.listUnknown,\n },\n template,\n mergedDir,\n };\n}\n\nexport async function diffCommand(cliOptions: RawCliOptions): Promise<number> {\n try {\n // Load configuration file\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // Batch mode: --all or --target\n if (cliOptions.all || cliOptions.target) {\n const mode = cliOptions.all ? 'all' : 'single';\n const targets = batchRunner.resolveTargets(cliOptions, fileConfig, mode, cliOptions.target);\n\n // @awa-impl: MULTI-12_AC-1\n // Exit code aggregation: 0 if all identical, 1 if any differ, 2 on error (first error short-circuits)\n let hasDifferences = false;\n for (const { targetName, options } of targets) {\n batchRunner.logForTarget(targetName, 'Starting diff...');\n const { diffOptions, mergedDir } = await prepareDiff(options);\n const exitCode = await runDiff(diffOptions, options, mergedDir);\n if (exitCode === 1) {\n hasDifferences = true;\n }\n batchRunner.logForTarget(targetName, 'Diff complete.');\n }\n\n outro('All targets diffed!');\n return hasDifferences ? 1 : 0;\n }\n\n // Standard single-target mode (backward compatible)\n const options = configLoader.merge(cliOptions, fileConfig);\n\n const silent = options.json || options.summary;\n\n // @awa-impl: JSON-6_AC-1\n // Suppress interactive output when --json or --summary is active\n if (!silent) {\n intro('awa CLI - Template Diff');\n }\n\n const { diffOptions, template, mergedDir } = await prepareDiff(options);\n\n // Validate watch mode: only local templates are supported\n if (cliOptions.watch && template.type !== 'local' && template.type !== 'bundled') {\n throw new DiffError('--watch is only supported with local template sources');\n }\n\n // Run diff once\n const result = await runDiff(diffOptions, options, mergedDir);\n\n if (!cliOptions.watch) {\n if (!silent) {\n outro('Diff complete!');\n }\n return result;\n }\n\n // Watch mode: re-run diff on template changes\n // Resolves only on SIGINT (Ctrl+C) — this is intentional for watch mode\n logger.info(`Watching for changes in ${template.localPath}...`);\n\n return new Promise<number>((resolve) => {\n let running = false;\n const watcher = new FileWatcher({\n directory: template.localPath,\n onChange: async () => {\n if (running) return;\n running = true;\n try {\n console.clear();\n logger.info(`[${new Date().toLocaleTimeString()}] Change detected, re-running diff...`);\n logger.info('---');\n await runDiff(diffOptions, options, null);\n } finally {\n running = false;\n }\n },\n });\n\n watcher.start();\n\n process.once('SIGINT', () => {\n watcher.stop();\n logger.info('\\nWatch mode stopped.');\n resolve(0);\n });\n });\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n\n // @awa-impl: DIFF-5_AC-3\n return 2;\n }\n}\n","// @awa-component: MULTI-BatchRunner\n// @awa-component: MULTI-Reporter\n// @awa-impl: MULTI-4_AC-1\n// @awa-impl: MULTI-4_AC-2\n// @awa-impl: MULTI-5_AC-1\n// @awa-impl: MULTI-8_AC-1\n// @awa-impl: MULTI-9_AC-1\n// @awa-impl: MULTI-11_AC-1\n\nimport {\n ConfigError,\n type FileConfig,\n type RawCliOptions,\n type ResolvedOptions,\n} from '../types/index.js';\nimport { logger } from '../utils/logger.js';\nimport { configLoader } from './config.js';\n\nexport interface BatchTargetResult {\n targetName: string;\n options: ResolvedOptions;\n}\n\nexport class BatchRunner {\n // Resolve all targets or a single named target from config\n resolveTargets(\n cli: RawCliOptions,\n fileConfig: FileConfig | null,\n mode: 'all' | 'single',\n targetName?: string\n ): BatchTargetResult[] {\n if (!fileConfig) {\n throw new ConfigError(\n 'No configuration file found. --all and --target require a config file with [targets.*] sections.',\n 'NO_TARGETS',\n null\n );\n }\n\n const targetNames = configLoader.getTargetNames(fileConfig);\n\n if (targetNames.length === 0) {\n throw new ConfigError(\n 'No targets defined in configuration. Add [targets.<name>] sections to .awa.toml.',\n 'NO_TARGETS',\n null\n );\n }\n\n const namesToProcess = mode === 'all' ? targetNames : [targetName as string];\n\n const results: BatchTargetResult[] = [];\n\n for (const name of namesToProcess) {\n const resolved = configLoader.resolveTarget(name, fileConfig);\n\n // Build CLI options for this target:\n // - When --all, ignore CLI positional output\n // - When --target, CLI positional overrides target output\n const targetCli: RawCliOptions = {\n ...cli,\n output: mode === 'all' ? undefined : cli.output,\n };\n\n let options: ResolvedOptions;\n try {\n options = configLoader.merge(targetCli, resolved);\n } catch (error) {\n // Re-throw MISSING_OUTPUT with target-specific message\n if (error instanceof ConfigError && error.code === 'MISSING_OUTPUT') {\n throw new ConfigError(\n `Target '${name}' has no output directory. Specify 'output' in [targets.${name}] or in the root config.`,\n 'MISSING_OUTPUT',\n null\n );\n }\n throw error;\n }\n\n results.push({ targetName: name, options });\n }\n\n return results;\n }\n\n // Log a message prefixed with target name\n logForTarget(targetName: string, message: string): void {\n logger.info(`[${targetName}] ${message}`);\n }\n\n warnForTarget(targetName: string, message: string): void {\n logger.warn(`[${targetName}] ${message}`);\n }\n\n errorForTarget(targetName: string, message: string): void {\n logger.error(`[${targetName}] ${message}`);\n }\n}\n\nexport const batchRunner = new BatchRunner();\n","// @awa-component: DIFF-DiffEngine\n// @awa-impl: DIFF-1_AC-1\n// @awa-impl: DIFF-1_AC-2\n// @awa-impl: DIFF-1_AC-3\n// @awa-impl: DIFF-2_AC-1\n// @awa-impl: DIFF-2_AC-2\n// @awa-impl: DIFF-2_AC-3\n// @awa-impl: DIFF-2_AC-4\n// @awa-impl: DIFF-2_AC-5\n// @awa-impl: DIFF-3_AC-1\n// @awa-impl: DIFF-3_AC-2\n// @awa-impl: DIFF-3_AC-3\n// @awa-impl: DIFF-4_AC-1\n// @awa-impl: DIFF-4_AC-2\n// @awa-impl: DIFF-5_AC-1\n// @awa-impl: DIFF-5_AC-2\n// @awa-impl: DIFF-5_AC-3\n// @awa-impl: DIFF-6_AC-1\n// @awa-impl: DIFF-6_AC-2\n// @awa-impl: DIFF-6_AC-3\n// @awa-impl: DIFF-8_AC-1\n// @awa-impl: DIFF-8_AC-2\n// @awa-impl: DIFF-8_AC-3\n// @awa-impl: DIFF-8_AC-4\n\nimport { tmpdir } from 'node:os';\nimport { join, relative } from 'node:path';\nimport { structuredPatch } from 'diff';\nimport { isBinaryFile as detectBinaryFile } from 'isbinaryfile';\nimport type { DiffOptions, DiffResult, FileDiff, GenerateOptions } from '../types/index.js';\nimport { ensureDir, pathExists, readBinaryFile, rmDir, walkDirectory } from '../utils/fs.js';\nimport { loadDeleteList, resolveDeleteList } from './delete-list.js';\nimport { fileGenerator } from './generator.js';\n\nexport class DiffEngine {\n // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2, DIFF-1_AC-3\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5\n // @awa-impl: DIFF-3_AC-1, DIFF-3_AC-2, DIFF-3_AC-3\n // @awa-impl: DIFF-4_AC-1, DIFF-4_AC-2\n // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2, DIFF-5_AC-3\n // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3\n async diff(options: DiffOptions): Promise<DiffResult> {\n const { templatePath, targetPath, features, listUnknown } = options;\n\n // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2\n const tempPath = await this.createTempDir();\n\n try {\n // Generate templates to temp directory\n const generateOptions: GenerateOptions = {\n templatePath,\n outputPath: tempPath,\n features,\n force: true,\n dryRun: false,\n delete: false,\n };\n\n await fileGenerator.generate(generateOptions);\n\n // Collect all files from both directories\n const generatedFiles = new Set<string>();\n const targetFiles = new Set<string>();\n\n // Walk generated directory (if exists - may be empty if template generates nothing)\n if (await pathExists(tempPath)) {\n for await (const file of walkDirectory(tempPath)) {\n const relPath = relative(tempPath, file);\n generatedFiles.add(relPath);\n }\n }\n\n // Walk target directory (if exists)\n if (await pathExists(targetPath)) {\n for await (const file of walkDirectory(targetPath)) {\n const relPath = relative(targetPath, file);\n targetFiles.add(relPath);\n }\n }\n\n // Compare files: iterate generated files first; optionally include target-only files when requested\n const files: FileDiff[] = [];\n\n for (const relPath of generatedFiles) {\n const generatedFilePath = join(tempPath, relPath);\n const targetFilePath = join(targetPath, relPath);\n\n if (targetFiles.has(relPath)) {\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5\n const fileDiff = await this.compareFiles(generatedFilePath, targetFilePath, relPath);\n files.push(fileDiff);\n } else {\n // @awa-impl: DIFF-3_AC-1\n files.push({\n relativePath: relPath,\n status: 'new',\n });\n }\n }\n\n if (listUnknown) {\n for (const relPath of targetFiles) {\n if (generatedFiles.has(relPath)) {\n continue;\n }\n\n // @awa-impl: DIFF-3_AC-2, DIFF-3_AC-3, DIFF-3_AC-4\n files.push({\n relativePath: relPath,\n status: 'extra',\n });\n }\n }\n\n // Check delete list for files that exist in target\n const deleteEntries = await loadDeleteList(templatePath);\n const deleteList = resolveDeleteList(deleteEntries, features ?? []);\n for (const relPath of deleteList) {\n if (targetFiles.has(relPath) && !generatedFiles.has(relPath)) {\n // Remove any existing 'extra' entry for this path (to avoid double-reporting)\n const existingIdx = files.findIndex(\n (f) => f.relativePath === relPath && f.status === 'extra'\n );\n if (existingIdx !== -1) {\n files.splice(existingIdx, 1);\n }\n files.push({\n relativePath: relPath,\n status: 'delete-listed',\n });\n }\n }\n\n // Calculate summary\n const identical = files.filter((f) => f.status === 'identical').length;\n const modified = files.filter((f) => f.status === 'modified').length;\n const newFiles = files.filter((f) => f.status === 'new').length;\n const extraFiles = files.filter((f) => f.status === 'extra').length;\n const binaryDiffers = files.filter((f) => f.status === 'binary-differs').length;\n const deleteListed = files.filter((f) => f.status === 'delete-listed').length;\n\n const hasDifferences =\n modified > 0 || newFiles > 0 || extraFiles > 0 || binaryDiffers > 0 || deleteListed > 0;\n\n return {\n files,\n identical,\n modified,\n newFiles,\n extraFiles,\n binaryDiffers,\n deleteListed,\n hasDifferences,\n };\n } finally {\n // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3\n await this.cleanupTempDir(tempPath);\n }\n }\n\n // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2\n async createTempDir(): Promise<string> {\n const systemTemp = tmpdir();\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n const tempPath = join(systemTemp, `awa-diff-${timestamp}-${random}`);\n\n await ensureDir(tempPath);\n return tempPath;\n }\n\n // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3\n async cleanupTempDir(tempPath: string): Promise<void> {\n try {\n if (await pathExists(tempPath)) {\n await rmDir(tempPath);\n }\n } catch (_error) {\n // Swallow cleanup errors - temp directory will be cleaned by OS eventually\n // This ensures cleanup errors don't mask the actual diff results\n }\n }\n\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5\n async compareFiles(\n generatedPath: string,\n targetPath: string,\n relativePath: string\n ): Promise<FileDiff> {\n // Read raw bytes for byte-for-byte comparison.\n const generatedBytes = await readBinaryFile(generatedPath);\n const targetBytes = await readBinaryFile(targetPath);\n\n // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-3\n if (generatedBytes.equals(targetBytes)) {\n return {\n relativePath,\n status: 'identical',\n };\n }\n\n // @awa-impl: DIFF-2_AC-5\n // If either side is binary, do not attempt a text diff.\n const isBinaryGenerated = await this.isBinaryFile(generatedPath);\n const isBinaryTarget = await this.isBinaryFile(targetPath);\n\n if (isBinaryGenerated || isBinaryTarget) {\n return {\n relativePath,\n status: 'binary-differs',\n };\n }\n\n // Text files: unified diff (diff library is text-based)\n const generatedContent = generatedBytes.toString('utf-8');\n const targetContent = targetBytes.toString('utf-8');\n\n // @awa-impl: DIFF-2_AC-4\n // Generate unified diff\n const patch = structuredPatch(\n `a/${relativePath}`,\n `b/${relativePath}`,\n targetContent,\n generatedContent,\n 'target',\n 'generated',\n {\n context: 3,\n }\n );\n\n // Format as git-style unified diff string (with file headers)\n const headerLines = [\n `diff --git a/${relativePath} b/${relativePath}`,\n `--- a/${relativePath}`,\n `+++ b/${relativePath}`,\n ];\n\n const hunkLines = patch.hunks.flatMap((hunk) => {\n const lines = [`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`];\n lines.push(...hunk.lines);\n return lines;\n });\n\n const unifiedDiff = [...headerLines, ...hunkLines].join('\\n');\n\n return {\n relativePath,\n status: 'modified',\n unifiedDiff,\n };\n }\n\n // @awa-impl: DIFF-2_AC-5\n async isBinaryFile(filePath: string): Promise<boolean> {\n try {\n return await detectBinaryFile(filePath);\n } catch {\n // If detection fails, assume text file\n return false;\n }\n }\n}\n\nexport const diffEngine = new DiffEngine();\n","// @awa-component: GEN-DeleteList\n// @awa-impl: GEN-12_AC-1\n// @awa-impl: GEN-12_AC-8\n\nimport { join } from 'node:path';\nimport { pathExists, readTextFile } from '../utils/fs.js';\n\nconst DELETE_LIST_FILENAME = '_delete.txt';\n\n/**\n * A delete list entry. When `features` is set, the path is only deleted\n * when NONE of those features are present in the active feature set\n * (stale tool cleanup). When `features` is absent, the path is always\n * deleted (legacy removal).\n */\nexport interface DeleteEntry {\n path: string;\n /** One or more feature names — keep (don't delete) if any is active. */\n features?: string[];\n}\n\n/**\n * Parse `_delete.txt` content into structured entries.\n *\n * Format:\n * - Blank lines and `#` comments are ignored.\n * - `# @feature <name> [<name2> ...]` starts a feature-gated section: subsequent\n * paths are deleted only when NONE of the listed features are active.\n * - Any other comment line clears the current feature section (returns to\n * always-delete behaviour).\n * - Path lines inherit the current section's feature tag (if any).\n */\nexport function parseDeleteList(content: string): DeleteEntry[] {\n const entries: DeleteEntry[] = [];\n let currentFeatures: string[] | undefined;\n\n for (const raw of content.split('\\n')) {\n const line = raw.trim();\n if (line.length === 0) continue;\n\n if (line.startsWith('#')) {\n const featureMatch = line.match(/^#\\s*@feature\\s+(.+)$/);\n if (featureMatch) {\n const featureSection = featureMatch[1];\n currentFeatures = featureSection ? featureSection.trim().split(/\\s+/) : undefined;\n } else {\n // Any other comment resets the feature section\n currentFeatures = undefined;\n }\n continue;\n }\n\n entries.push({ path: line, features: currentFeatures });\n }\n\n return entries;\n}\n\n/**\n * Resolve which paths from the delete list should actually be deleted,\n * given the currently active feature flags.\n *\n * - Entries without a feature tag are always included (legacy removals).\n * - Entries with feature tags are included only when NONE of those features are active\n * (stale tool output cleanup).\n */\nexport function resolveDeleteList(entries: DeleteEntry[], activeFeatures: string[]): string[] {\n const activeSet = new Set(activeFeatures);\n return entries\n .filter((e) => e.features === undefined || !e.features.some((f) => activeSet.has(f)))\n .map((e) => e.path);\n}\n\n/**\n * Load and parse `_delete.txt` from the template directory.\n * Returns empty array if the file does not exist.\n */\nexport async function loadDeleteList(templatePath: string): Promise<DeleteEntry[]> {\n const deleteListPath = join(templatePath, DELETE_LIST_FILENAME);\n\n if (!(await pathExists(deleteListPath))) {\n return [];\n }\n\n const content = await readTextFile(deleteListPath);\n return parseDeleteList(content);\n}\n","// @awa-component: GEN-FileGenerator\n// @awa-impl: GEN-1_AC-1\n// @awa-impl: GEN-1_AC-2\n// @awa-impl: GEN-1_AC-3\n// @awa-impl: GEN-2_AC-1\n// @awa-impl: GEN-2_AC-2\n// @awa-impl: GEN-2_AC-3\n// @awa-impl: GEN-3_AC-1\n// @awa-impl: GEN-3_AC-2\n// @awa-impl: GEN-3_AC-3\n// @awa-impl: GEN-8_AC-1\n// @awa-impl: GEN-8_AC-2\n// @awa-impl: GEN-8_AC-3\n// @awa-impl: GEN-11_AC-3\n// @awa-impl: GEN-6_AC-1\n// @awa-impl: GEN-6_AC-2\n// @awa-impl: GEN-12_AC-2\n// @awa-impl: GEN-12_AC-4\n// @awa-impl: GEN-12_AC-5\n// @awa-impl: GEN-12_AC-6\n// @awa-impl: GEN-12_AC-7\n// @awa-impl: CLI-6_AC-2\n// @awa-impl: CLI-12_AC-2\n// @awa-impl: TPL-9_AC-1\n// @awa-impl: TPL-9_AC-2\n\nimport { join, relative } from 'node:path';\nimport { PACKAGE_INFO } from '../_generated/package_info.js';\nimport {\n type ConflictItem,\n type FileAction,\n type GenerateOptions,\n GenerationError,\n type GenerationResult,\n} from '../types/index.js';\nimport { deleteFile, pathExists, readTextFile, walkDirectory, writeTextFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\nimport { loadDeleteList, resolveDeleteList } from './delete-list.js';\nimport { conflictResolver, deleteResolver } from './resolver.js';\nimport { templateEngine } from './template.js';\n\nexport class FileGenerator {\n // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3\n // @awa-impl: GEN-2_AC-1, GEN-2_AC-2, GEN-2_AC-3\n // @awa-impl: GEN-3_AC-1, GEN-3_AC-2, GEN-3_AC-3\n async generate(options: GenerateOptions): Promise<GenerationResult> {\n const { templatePath, outputPath, features, force, dryRun } = options;\n const enableDelete = options.delete;\n\n // Configure template engine\n templateEngine.configure(templatePath);\n\n const actions: FileAction[] = [];\n let created = 0;\n let overwritten = 0;\n let deleted = 0;\n let skippedEmpty = 0;\n let skippedUser = 0;\n let skippedEqual = 0;\n\n // Collect files to process\n interface FileToProcess {\n templateFile: string;\n outputFile: string;\n content: string;\n isNew: boolean;\n }\n\n const filesToProcess: FileToProcess[] = [];\n const conflicts: ConflictItem[] = [];\n\n try {\n // First pass: render all templates and categorize files\n for await (const templateFile of this.walkTemplates(templatePath)) {\n // Compute output path\n const outputFile = this.computeOutputPath(templateFile, templatePath, outputPath);\n\n // Render template\n const result = await templateEngine.render(templateFile, {\n features,\n version: PACKAGE_INFO.version,\n });\n\n // Handle empty output\n if (result.isEmpty && !result.isEmptyFileMarker) {\n // Skip empty files\n actions.push({\n type: 'skip-empty',\n sourcePath: templateFile,\n outputPath: outputFile,\n });\n skippedEmpty++;\n continue;\n }\n\n // Get final content (empty string if marker)\n const content = result.isEmptyFileMarker ? '' : result.content;\n\n // Check for conflicts\n const fileExists = await pathExists(outputFile);\n\n if (fileExists) {\n // Read existing content for comparison\n const existingContent = await readTextFile(outputFile);\n conflicts.push({\n outputPath: outputFile,\n sourcePath: templateFile,\n newContent: content,\n existingContent,\n });\n }\n\n filesToProcess.push({\n templateFile,\n outputFile,\n content,\n isNew: !fileExists,\n });\n }\n\n // Resolve all conflicts at once if there are any\n let resolution: { overwrite: string[]; skip: string[]; equal: string[] } = {\n overwrite: [],\n skip: [],\n equal: [],\n };\n if (conflicts.length > 0) {\n resolution = await conflictResolver.resolveBatch(conflicts, force, dryRun);\n }\n\n // Second pass: process files based on resolution\n for (const file of filesToProcess) {\n if (file.isNew) {\n // Create new file\n if (!dryRun) {\n await writeTextFile(file.outputFile, file.content);\n }\n actions.push({\n type: 'create',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n created++;\n logger.fileAction({\n type: 'create',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n } else if (resolution.overwrite.includes(file.outputFile)) {\n // Overwrite existing file\n if (!dryRun) {\n await writeTextFile(file.outputFile, file.content);\n }\n actions.push({\n type: 'overwrite',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n overwritten++;\n logger.fileAction({\n type: 'overwrite',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n } else if (resolution.equal.includes(file.outputFile)) {\n // Skip file — content is identical\n actions.push({\n type: 'skip-equal',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n skippedEqual++;\n logger.fileAction({\n type: 'skip-equal',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n } else if (resolution.skip.includes(file.outputFile)) {\n // Skip file — user declined overwrite\n actions.push({\n type: 'skip-user',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n skippedUser++;\n logger.fileAction({\n type: 'skip-user',\n sourcePath: file.templateFile,\n outputPath: file.outputFile,\n });\n }\n }\n\n // Process delete list (after file generation)\n const deleteEntries = await loadDeleteList(templatePath);\n if (deleteEntries.length > 0) {\n const deleteList = resolveDeleteList(deleteEntries, features);\n\n // Collect generated output paths to detect conflicts\n const generatedOutputPaths = new Set(filesToProcess.map((f) => f.outputFile));\n\n // Filter: only files that exist and aren't being generated\n const deleteCandidates: string[] = [];\n for (const relPath of deleteList) {\n const absPath = join(outputPath, relPath);\n if (generatedOutputPaths.has(absPath)) {\n logger.warn(\n `Delete list entry '${relPath}' conflicts with generated file — skipping deletion`\n );\n continue;\n }\n if (await pathExists(absPath)) {\n deleteCandidates.push(absPath);\n }\n }\n\n if (deleteCandidates.length > 0) {\n if (!enableDelete) {\n // --delete not passed: warn but do nothing\n for (const absPath of deleteCandidates) {\n logger.warn(\n `Would delete (pass --delete to enable): ${relative(outputPath, absPath)}`\n );\n }\n } else {\n const confirmed = await deleteResolver.resolveDeletes(deleteCandidates, force, dryRun);\n\n for (const absPath of confirmed) {\n if (!dryRun) {\n await deleteFile(absPath);\n }\n actions.push({ type: 'delete', outputPath: absPath });\n deleted++;\n logger.fileAction({ type: 'delete', outputPath: absPath });\n }\n }\n }\n }\n\n return {\n actions,\n created,\n overwritten,\n deleted,\n skipped: skippedEmpty + skippedUser + skippedEqual,\n skippedEmpty,\n skippedUser,\n skippedEqual,\n };\n } catch (error) {\n // @awa-impl: GEN-2_AC-3, GEN-11_AC-3\n if (error instanceof Error && 'code' in error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'EACCES' || code === 'EPERM') {\n throw new GenerationError(`Permission denied: ${error.message}`, 'PERMISSION_DENIED');\n }\n if (code === 'ENOSPC') {\n throw new GenerationError(`Disk full: ${error.message}`, 'DISK_FULL');\n }\n }\n throw error;\n }\n }\n\n // @awa-impl: GEN-8_AC-1, GEN-8_AC-2, GEN-8_AC-3\n // @awa-impl: TPL-9_AC-1, TPL-9_AC-2\n async *walkTemplates(dir: string): AsyncIterable<string> {\n // Use utility function that already handles underscore exclusion\n yield* walkDirectory(dir);\n }\n\n // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3\n computeOutputPath(templatePath: string, templateRoot: string, outputRoot: string): string {\n // Get relative path from template root\n const relativePath = relative(templateRoot, templatePath);\n\n // Join with output root to mirror structure\n return join(outputRoot, relativePath);\n }\n}\n\nexport const fileGenerator = new FileGenerator();\n","// @awa-component: GEN-ConflictResolver\n// @awa-component: GEN-DeleteResolver\n// @awa-impl: CLI-5_AC-2\n// @awa-impl: CLI-5_AC-3\n// @awa-impl: GEN-4_AC-1\n// @awa-impl: GEN-4_AC-2\n// @awa-impl: GEN-4_AC-3\n// @awa-impl: GEN-5_AC-1\n// @awa-impl: GEN-5_AC-2\n// @awa-impl: GEN-5_AC-3\n// @awa-impl: GEN-5_AC-4\n// @awa-impl: GEN-5_AC-5\n// @awa-impl: GEN-5_AC-6\n// @awa-impl: GEN-5_AC-7\n// @awa-impl: GEN-6_AC-3\n// @awa-impl: GEN-10_AC-3\n// @awa-impl: GEN-12_AC-3\n// @awa-impl: GEN-12_AC-4\n// @awa-impl: GEN-12_AC-5\n// @awa-impl: CLI-12_AC-3\n\nimport { MultiSelectPrompt } from '@clack/core';\nimport { isCancel, multiselect } from '@clack/prompts';\nimport chalk from 'chalk';\nimport type { BatchConflictResolution, ConflictItem } from '../types/index.js';\n\n// Unicode symbols (mirrors @clack/prompts internals)\nconst _unicode = process.platform !== 'win32';\nconst _s = (c: string, fb: string) => (_unicode ? c : fb);\nconst _CHECKED = _s('\\u25FC', '[+]'); // ◼\nconst _UNCHECKED_A = _s('\\u25FB', '[·]'); // ◻ active\nconst _UNCHECKED = _s('\\u25FB', '[ ]'); // ◻ inactive\nconst _BAR = _s('\\u2502', '|'); // │\nconst _BAR_END = _s('\\u2514', '-'); // └\n\ntype SelectOption = { value: string; label?: string; hint?: string };\n\nfunction _renderDeleteItem(opt: SelectOption, state: string): string {\n const label = opt.label ?? opt.value;\n const hint = opt.hint ? ` ${chalk.dim(`(${opt.hint})`)}` : '';\n switch (state) {\n case 'active':\n return `${chalk.cyan(_UNCHECKED_A)} ${label}${hint}`;\n case 'selected':\n return `${chalk.red(_CHECKED)} ${chalk.dim(label)}${hint}`;\n case 'active-selected':\n return `${chalk.red(_CHECKED)} ${label}${hint}`;\n case 'cancelled':\n return chalk.strikethrough(chalk.dim(label));\n case 'submitted':\n return chalk.dim(label);\n default:\n return `${chalk.dim(_UNCHECKED)} ${chalk.dim(label)}`;\n }\n}\n\n/** Like @clack/prompts `multiselect` but with red checkboxes for destructive operations. */\nasync function deleteMultiselect(opts: {\n message: string;\n options: SelectOption[];\n initialValues?: string[];\n required?: boolean;\n}): Promise<string[] | symbol> {\n const { message, options, initialValues, required = false } = opts;\n return new MultiSelectPrompt({\n options,\n initialValues,\n required,\n render() {\n const self = this as unknown as {\n state: string;\n options: SelectOption[];\n cursor: number;\n value: string[];\n };\n const header = `${chalk.gray(_BAR)}\\n${chalk.cyan(_BAR)} ${message}\\n`;\n const getState = (opt: SelectOption, idx: number): string => {\n const active = idx === self.cursor;\n const sel = self.value.includes(opt.value);\n if (active && sel) return 'active-selected';\n if (sel) return 'selected';\n if (active) return 'active';\n return 'inactive';\n };\n switch (self.state) {\n case 'submit':\n return (\n `${header}${chalk.gray(_BAR)} ` +\n (self.options\n .filter((o) => self.value.includes(o.value))\n .map((o) => _renderDeleteItem(o, 'submitted'))\n .join(chalk.dim(', ')) || chalk.dim('none'))\n );\n case 'cancel': {\n const cancelled = self.options\n .filter((o) => self.value.includes(o.value))\n .map((o) => _renderDeleteItem(o, 'cancelled'))\n .join(chalk.dim(', '));\n return `${header}${chalk.gray(_BAR)} ${cancelled.trim() ? `${cancelled}\\n${chalk.gray(_BAR)}` : chalk.dim('none')}`;\n }\n default:\n return (\n `${header}${chalk.cyan(_BAR)} ` +\n self.options\n .map((o, i) => _renderDeleteItem(o, getState(o, i)))\n .join(`\\n${chalk.cyan(_BAR)} `) +\n `\\n${chalk.cyan(_BAR_END)}\\n`\n );\n }\n },\n }).prompt() as Promise<string[] | symbol>;\n}\n\nexport class ConflictResolver {\n // @awa-impl: GEN-4_AC-1, GEN-4_AC-2, GEN-4_AC-3\n // @awa-impl: GEN-5_AC-1, GEN-5_AC-2, GEN-5_AC-3, GEN-5_AC-4, GEN-5_AC-5, GEN-5_AC-6, GEN-5_AC-7\n // @awa-impl: CLI-5_AC-2, CLI-5_AC-3\n // @awa-impl: GEN-6_AC-3\n async resolveBatch(\n conflicts: ConflictItem[],\n force: boolean,\n dryRun: boolean\n ): Promise<BatchConflictResolution> {\n // Separate identical-content files from different files\n const identicalPaths = conflicts\n .filter((c) => c.newContent === c.existingContent)\n .map((c) => c.outputPath);\n const differentFiles = conflicts.filter((c) => c.newContent !== c.existingContent);\n\n // In dry-run mode, never modify files (P7: Dry Run Immutable)\n if (dryRun) {\n return {\n overwrite: [],\n skip: differentFiles.map((c) => c.outputPath),\n equal: identicalPaths,\n };\n }\n\n // In force mode, always overwrite without prompting (P8: Force No Prompt)\n if (force) {\n return {\n overwrite: differentFiles.map((c) => c.outputPath),\n skip: [],\n equal: identicalPaths,\n };\n }\n\n // If all files are identical, skip them all\n if (differentFiles.length === 0) {\n return {\n overwrite: [],\n skip: [],\n equal: identicalPaths,\n };\n }\n\n // @awa-impl: GEN-5_AC-1, GEN-5_AC-2, GEN-5_AC-5, GEN-5_AC-6\n // Prompt user with multi-select (all selected by default)\n const selected = await multiselect({\n message: 'The following files already exist. Select files to overwrite:',\n options: differentFiles.map((c) => ({\n value: c.outputPath,\n label: c.outputPath,\n })),\n initialValues: differentFiles.map((c) => c.outputPath), // All selected by default (AC-5.6)\n required: false,\n });\n\n // @awa-impl: GEN-10_AC-3\n // Handle user cancellation (Ctrl+C)\n if (isCancel(selected)) {\n process.exit(1);\n }\n\n const selectedPaths = selected as string[];\n const allPaths = differentFiles.map((c) => c.outputPath);\n\n return {\n overwrite: selectedPaths,\n skip: allPaths.filter((p) => !selectedPaths.includes(p)),\n equal: identicalPaths,\n };\n }\n}\n\nexport const conflictResolver = new ConflictResolver();\n\nexport class DeleteResolver {\n /**\n * Prompt user to confirm which files to delete.\n * Returns the list of absolute paths confirmed for deletion.\n */\n async resolveDeletes(candidates: string[], force: boolean, dryRun: boolean): Promise<string[]> {\n if (candidates.length === 0) {\n return [];\n }\n\n // In dry-run mode, return all candidates (caller logs but won't delete)\n if (dryRun) {\n return candidates;\n }\n\n // In force mode, delete without prompting\n if (force) {\n return candidates;\n }\n\n // Prompt user with multi-select (all selected by default, red checkboxes)\n const selected = await deleteMultiselect({\n message:\n '⚠ WARNING: The selected files will be PERMANENTLY DELETED from disk.\\n' +\n ' Deselect any files you want to keep. Press Enter to confirm deletion:',\n options: candidates.map((p) => ({\n value: p,\n label: p,\n })),\n initialValues: candidates,\n required: false,\n });\n\n // Handle user cancellation (Ctrl+C)\n if (isCancel(selected)) {\n process.exit(1);\n }\n\n return selected as string[];\n }\n}\n\nexport const deleteResolver = new DeleteResolver();\n","// @awa-component: TPL-TemplateEngine\n// @awa-impl: TPL-4_AC-1\n// @awa-impl: TPL-4_AC-2\n// @awa-impl: TPL-4_AC-3\n// @awa-impl: TPL-4_AC-4\n// @awa-impl: TPL-5_AC-1\n// @awa-impl: TPL-5_AC-2\n// @awa-impl: TPL-5_AC-3\n// @awa-impl: TPL-6_AC-1\n// @awa-impl: TPL-6_AC-2\n// @awa-impl: TPL-7_AC-1\n// @awa-impl: TPL-7_AC-2\n// @awa-impl: TPL-8_AC-1\n// @awa-impl: TPL-8_AC-2\n// @awa-impl: TPL-8_AC-3\n// @awa-impl: TPL-8_AC-4\n// @awa-impl: TPL-11_AC-1\n// @awa-impl: TPL-11_AC-2\n\nimport { Eta } from 'eta';\nimport { type RenderResult, type TemplateContext, TemplateError } from '../types/index.js';\nimport { readTextFile } from '../utils/fs.js';\n\nconst EMPTY_FILE_MARKER = '<!-- AWA:EMPTY_FILE -->';\n\nexport class TemplateEngine {\n private eta: Eta | null = null;\n private templateDir: string | null = null;\n private compiledCache = new Map<string, unknown>();\n\n // @awa-impl: TPL-8_AC-1, TPL-8_AC-2, TPL-8_AC-3, TPL-8_AC-4\n configure(templateDir: string): void {\n this.templateDir = templateDir;\n this.compiledCache.clear();\n\n // @awa-impl: TPL-4_AC-1, TPL-4_AC-2, TPL-4_AC-3, TPL-4_AC-4\n // Configure Eta with partials support\n this.eta = new Eta({\n views: templateDir,\n cache: true, // Enable compilation caching\n autoEscape: false, // Don't escape HTML by default\n defaultExtension: '', // No automatic extension - use exact path as specified (AC-8.2)\n });\n }\n\n // @awa-impl: TPL-5_AC-1, TPL-5_AC-2, TPL-5_AC-3\n // @awa-impl: TPL-6_AC-1, TPL-6_AC-2\n // @awa-impl: TPL-7_AC-1, TPL-7_AC-2\n // @awa-impl: TPL-11_AC-1, TPL-11_AC-2\n async render(templatePath: string, context: TemplateContext): Promise<RenderResult> {\n if (!this.eta || !this.templateDir) {\n throw new TemplateError(\n 'Template engine not configured. Call configure() first.',\n 'RENDER_ERROR'\n );\n }\n\n try {\n // Read template content\n const templateContent = await readTextFile(templatePath);\n\n // Render with features context\n // The context is available as 'it' in templates\n const rendered = await this.eta.renderStringAsync(templateContent, {\n features: context.features,\n version: context.version ?? '',\n });\n\n // Check if output is empty or only whitespace\n const trimmed = rendered.trim();\n const isEmpty = trimmed.length === 0;\n\n // Check for empty file marker\n const isEmptyFileMarker = trimmed === EMPTY_FILE_MARKER;\n\n return {\n content: rendered,\n isEmpty,\n isEmptyFileMarker,\n };\n } catch (error) {\n throw new TemplateError(\n `Failed to render template ${templatePath}: ${error instanceof Error ? error.message : String(error)}`,\n 'RENDER_ERROR',\n templatePath\n );\n }\n }\n}\n\nexport const templateEngine = new TemplateEngine();\n","// @awa-component: FP-FeatureResolver\n// @awa-impl: FP-2_AC-3\n// @awa-impl: FP-4_AC-4\n// @awa-impl: FP-6_AC-1\n// @awa-impl: FP-6_AC-2\n// @awa-impl: FP-6_AC-3\n// @awa-impl: FP-6_AC-4\n// @awa-impl: FP-6_AC-5\n// @awa-impl: FP-7_AC-1\n// @awa-impl: FP-7_AC-2\n\nimport { ConfigError, type PresetDefinitions } from '../types/index.js';\n\nexport interface FeatureResolutionInput {\n baseFeatures: string[];\n presetNames: string[];\n removeFeatures: string[];\n presetDefinitions: PresetDefinitions;\n}\n\nexport class FeatureResolver {\n validatePresets(presetNames: string[], definitions: PresetDefinitions): void {\n for (const name of presetNames) {\n if (!definitions[name]) {\n throw new ConfigError(`Unknown preset: ${name}`, 'UNKNOWN_PRESET');\n }\n }\n }\n\n resolve(input: FeatureResolutionInput): string[] {\n const { baseFeatures, presetNames, removeFeatures, presetDefinitions } = input;\n\n this.validatePresets(presetNames, presetDefinitions);\n\n const finalFeatures: string[] = [];\n const seen = new Set<string>();\n\n const add = (feature: string) => {\n if (seen.has(feature)) return;\n seen.add(feature);\n finalFeatures.push(feature);\n };\n\n for (const feature of baseFeatures) add(feature);\n\n for (const presetName of presetNames) {\n for (const feature of presetDefinitions[presetName] ?? []) add(feature);\n }\n\n if (removeFeatures.length === 0) return finalFeatures;\n\n const removeSet = new Set(removeFeatures);\n return finalFeatures.filter((f) => !removeSet.has(f));\n }\n}\n\nexport const featureResolver = new FeatureResolver();\n","// @awa-component: JSON-JsonSerializer\n// @awa-impl: JSON-1_AC-1\n// @awa-impl: JSON-2_AC-1\n// @awa-impl: JSON-3_AC-1\n// @awa-impl: JSON-4_AC-1\n// @awa-impl: JSON-5_AC-1\n// @awa-impl: JSON-8_AC-1\n\nimport type {\n DiffFileJSON,\n DiffJSON,\n DiffResult,\n GenerationActionJSON,\n GenerationJSON,\n GenerationResult,\n} from '../types/index.js';\n\n// @awa-impl: JSON-1_AC-1, JSON-3_AC-1\nexport function serializeGenerationResult(result: GenerationResult): GenerationJSON {\n const actions: GenerationActionJSON[] = result.actions.map((action) => ({\n type: action.type,\n path: action.outputPath,\n }));\n\n return {\n actions,\n counts: {\n created: result.created,\n overwritten: result.overwritten,\n skipped: result.skipped,\n deleted: result.deleted,\n },\n };\n}\n\n// @awa-impl: JSON-2_AC-1, JSON-4_AC-1\nexport function serializeDiffResult(result: DiffResult): DiffJSON {\n const diffs: DiffFileJSON[] = result.files.map((file) => {\n const entry: DiffFileJSON = {\n path: file.relativePath,\n status: file.status,\n };\n if (file.unifiedDiff) {\n entry.diff = file.unifiedDiff;\n }\n return entry;\n });\n\n return {\n diffs,\n counts: {\n changed: result.modified,\n new: result.newFiles,\n matching: result.identical,\n deleted: result.deleteListed,\n },\n };\n}\n\n// @awa-impl: JSON-5_AC-1\nexport function formatGenerationSummary(result: GenerationResult): string {\n return `created: ${result.created}, overwritten: ${result.overwritten}, skipped: ${result.skipped}, deleted: ${result.deleted}`;\n}\n\n// @awa-impl: JSON-5_AC-1\nexport function formatDiffSummary(result: DiffResult): string {\n return `changed: ${result.modified}, new: ${result.newFiles}, matching: ${result.identical}, deleted: ${result.deleteListed}`;\n}\n\n// @awa-impl: JSON-8_AC-1\nexport function writeJsonOutput(data: GenerationJSON | DiffJSON): void {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n}\n","// @awa-component: OVL-OverlayResolver\n// @awa-component: OVL-MergedTemplateView\n// @awa-impl: OVL-1_AC-1\n// @awa-impl: OVL-2_AC-1\n// @awa-impl: OVL-3_AC-1\n// @awa-impl: OVL-4_AC-1\n// @awa-impl: OVL-5_AC-1\n// @awa-impl: OVL-6_AC-1\n\nimport { cp } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { ensureDir } from '../utils/fs.js';\nimport { templateResolver } from './template-resolver.js';\n\n/**\n * Resolve each overlay source string to a local directory path.\n * Delegates to TemplateResolver so local paths and Git sources are both handled.\n *\n * @awa-impl: OVL-1_AC-1, OVL-6_AC-1\n */\nexport async function resolveOverlays(overlays: string[], refresh: boolean): Promise<string[]> {\n const dirs: string[] = [];\n for (const source of overlays) {\n const resolved = await templateResolver.resolve(source, refresh);\n dirs.push(resolved.localPath);\n }\n return dirs;\n}\n\n/**\n * Build a temporary merged directory by copying baseDir then applying each\n * overlay in order. Later overlay files overwrite earlier ones at the same\n * relative path; base-only files are left intact; overlay-only files are added.\n *\n * Caller is responsible for cleaning up the returned temp directory.\n *\n * @awa-impl: OVL-2_AC-1, OVL-3_AC-1, OVL-4_AC-1, OVL-5_AC-1\n */\nexport async function buildMergedDir(baseDir: string, overlayDirs: string[]): Promise<string> {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n const tempPath = join(tmpdir(), `awa-overlay-${timestamp}-${random}`);\n\n await ensureDir(tempPath);\n\n // Copy base template files into the temp directory\n await cp(baseDir, tempPath, { recursive: true });\n\n // Apply overlays in order — later overlays win (force: true is the default for fs.cp)\n for (const overlayDir of overlayDirs) {\n await cp(overlayDir, tempPath, { recursive: true });\n }\n\n return tempPath;\n}\n","// @awa-component: TPL-TemplateResolver\n// @awa-impl: CLI-3_AC-2\n// @awa-impl: CLI-3_AC-3\n// @awa-impl: CLI-8_AC-2\n// @awa-impl: TPL-1_AC-1\n// @awa-impl: TPL-1_AC-2\n// @awa-impl: TPL-1_AC-3\n// @awa-impl: TPL-1_AC-4\n// @awa-impl: TPL-2_AC-1\n// @awa-impl: TPL-2_AC-2\n// @awa-impl: TPL-2_AC-3\n// @awa-impl: TPL-2_AC-4\n// @awa-impl: TPL-2_AC-5\n// @awa-impl: TPL-2_AC-6\n// @awa-impl: TPL-3_AC-1\n// @awa-impl: TPL-3_AC-2\n// @awa-impl: TPL-3_AC-3\n// @awa-impl: TPL-3_AC-4\n// @awa-impl: TPL-10_AC-1\n// @awa-impl: TPL-10_AC-2\n// @awa-impl: TPL-10_AC-3\n\nimport { createHash } from 'node:crypto';\nimport { rm } from 'node:fs/promises';\nimport { isAbsolute, join, resolve } from 'node:path';\nimport degit from 'degit';\nimport { type ResolvedTemplate, TemplateError, type TemplateSourceType } from '../types/index.js';\nimport { ensureDir, getCacheDir, getTemplateDir, pathExists } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nexport class TemplateResolver {\n // @awa-impl: CLI-3_AC-2, TPL-10_AC-1\n async resolve(source: string | null, refresh: boolean): Promise<ResolvedTemplate> {\n // If no source provided, use bundled templates\n if (!source) {\n const bundledPath = join(getTemplateDir(), 'awa');\n return {\n type: 'bundled',\n localPath: bundledPath,\n source: 'bundled',\n };\n }\n\n const type = this.detectType(source);\n\n // @awa-impl: TPL-1_AC-1, TPL-1_AC-2, TPL-1_AC-3, TPL-1_AC-4\n if (type === 'local') {\n // Resolve relative/absolute paths\n const localPath = isAbsolute(source) ? source : resolve(process.cwd(), source);\n\n // Check if path exists\n if (!(await pathExists(localPath))) {\n throw new TemplateError(\n `Template source not found: ${localPath}`,\n 'SOURCE_NOT_FOUND',\n source\n );\n }\n\n // Local templates are not cached\n return {\n type: 'local',\n localPath,\n source,\n };\n }\n\n // @awa-impl: TPL-2_AC-1, TPL-2_AC-2, TPL-2_AC-3, TPL-2_AC-4, TPL-2_AC-5, TPL-2_AC-6, TPL-3_AC-1, TPL-3_AC-2, TPL-3_AC-3, TPL-3_AC-4\n if (type === 'git') {\n const cachePath = this.getCachePath(source);\n\n // @awa-impl: CLI-8_AC-2, TPL-3_AC-2\n // Check if cached version exists\n const cacheExists = await pathExists(cachePath);\n\n if (cacheExists && !refresh) {\n // Use cached version\n logger.info(`Using cached template: ${source}`);\n return {\n type: 'git',\n localPath: cachePath,\n source,\n };\n }\n\n // Fetch from Git\n try {\n // Remove existing cache if refresh\n if (cacheExists && refresh) {\n logger.info(`Refreshing template: ${source}`);\n await rm(cachePath, { recursive: true, force: true });\n } else {\n logger.info(`Fetching template: ${source}`);\n }\n\n await ensureDir(cachePath);\n\n // Use degit for shallow fetch\n const emitter = degit(source, { cache: false, force: true });\n await emitter.clone(cachePath);\n\n return {\n type: 'git',\n localPath: cachePath,\n source,\n };\n } catch (error) {\n throw new TemplateError(\n `Failed to fetch Git template: ${error instanceof Error ? error.message : String(error)}`,\n 'FETCH_FAILED',\n source\n );\n }\n }\n\n throw new TemplateError(\n `Unable to resolve template source: ${source}`,\n 'SOURCE_NOT_FOUND',\n source\n );\n }\n\n // @awa-impl: TPL-2_AC-1, TPL-2_AC-2, TPL-2_AC-3, TPL-2_AC-4, TPL-2_AC-5, TPL-2_AC-6\n detectType(source: string): TemplateSourceType {\n // Check for local path indicators\n if (source.startsWith('.') || source.startsWith('/') || source.startsWith('~')) {\n return 'local';\n }\n\n // Check for Windows absolute paths\n if (/^[a-zA-Z]:/.test(source)) {\n return 'local';\n }\n\n // All other formats are treated as Git sources:\n // - GitHub shorthand: owner/repo\n // - Prefixed: github:owner/repo, gitlab:owner/repo, bitbucket:owner/repo\n // - HTTPS: https://github.com/owner/repo\n // - SSH: git@github.com:owner/repo\n // - With subdirs: owner/repo/path/to/templates\n // - With refs: owner/repo#branch\n return 'git';\n }\n\n // @awa-impl: TPL-3_AC-1\n getCachePath(source: string): string {\n // Create a stable cache path based on source hash\n const hash = createHash('sha256').update(source).digest('hex').substring(0, 16);\n const cacheDir = getCacheDir();\n return join(cacheDir, hash);\n }\n}\n\nexport const templateResolver = new TemplateResolver();\n","// @awa-component: DIFF-FileWatcher\n\nimport { type FSWatcher, watch } from 'node:fs';\nimport { Debouncer } from './debouncer.js';\n\nexport interface FileWatcherOptions {\n directory: string;\n debounceMs?: number;\n onChange: () => void;\n}\n\nexport class FileWatcher {\n private watcher: FSWatcher | null = null;\n private debouncer: Debouncer;\n private readonly directory: string;\n private readonly onChange: () => void;\n\n constructor(options: FileWatcherOptions) {\n this.directory = options.directory;\n this.debouncer = new Debouncer(options.debounceMs ?? 300);\n this.onChange = options.onChange;\n }\n\n start(): void {\n this.watcher = watch(this.directory, { recursive: true }, () => {\n this.debouncer.trigger(this.onChange);\n });\n }\n\n stop(): void {\n this.debouncer.cancel();\n if (this.watcher) {\n this.watcher.close();\n this.watcher = null;\n }\n }\n}\n","// @awa-component: DIFF-Debouncer\n\nexport class Debouncer {\n private timer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private readonly delayMs: number) {}\n\n trigger(callback: () => void): void {\n if (this.timer) {\n clearTimeout(this.timer);\n }\n this.timer = setTimeout(() => {\n this.timer = null;\n callback();\n }, this.delayMs);\n }\n\n cancel(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n","// @awa-component: DISC-FeaturesCommand\n// @awa-impl: DISC-4_AC-1\n// @awa-impl: DISC-5_AC-1\n\nimport { intro, outro } from '@clack/prompts';\nimport { configLoader } from '../core/config.js';\nimport { featuresReporter } from '../core/features/reporter.js';\nimport { featureScanner } from '../core/features/scanner.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport { logger } from '../utils/logger.js';\n\nexport interface FeaturesCommandOptions {\n template?: string;\n config?: string;\n refresh?: boolean;\n json?: boolean;\n}\n\n// @awa-impl: DISC-4_AC-1, DISC-5_AC-1\nexport async function featuresCommand(cliOptions: FeaturesCommandOptions): Promise<number> {\n try {\n if (!cliOptions.json) {\n intro('awa CLI - Feature Discovery');\n }\n\n // Load configuration file (for presets and default template)\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // Resolve template source — reuse same resolver as generate/diff\n const templateSource = cliOptions.template ?? fileConfig?.template ?? null;\n const refresh = cliOptions.refresh ?? fileConfig?.refresh ?? false;\n const template = await templateResolver.resolve(templateSource, refresh);\n\n // Scan template for feature flags\n const scanResult = await featureScanner.scan(template.localPath);\n\n // Retrieve preset definitions from config if available\n const presets = fileConfig?.presets;\n\n // Report results\n featuresReporter.report({\n scanResult,\n json: cliOptions.json ?? false,\n presets,\n });\n\n if (!cliOptions.json) {\n outro('Feature discovery complete!');\n }\n\n return 0;\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n return 1;\n }\n}\n","// @awa-component: DISC-Reporter\n// @awa-impl: DISC-6_AC-1\n// @awa-impl: DISC-7_AC-1\n\nimport chalk from 'chalk';\nimport type { PresetDefinitions } from '../../types/index.js';\nimport type { ScanResult } from './scanner.js';\n\n/** Options for rendering the features report. */\nexport interface ReportOptions {\n /** Scan results from the feature scanner. */\n scanResult: ScanResult;\n /** Whether to output JSON instead of a human-readable table. */\n json: boolean;\n /** Preset definitions from the user's .awa.toml, if available. */\n presets?: PresetDefinitions;\n}\n\n/** JSON output structure for --json mode. */\nexport interface FeaturesJsonOutput {\n features: Array<{\n name: string;\n files: string[];\n }>;\n presets?: Record<string, string[]>;\n filesScanned: number;\n}\n\nexport class FeaturesReporter {\n // @awa-impl: DISC-6_AC-1, DISC-7_AC-1\n /** Render the features report to stdout. */\n report(options: ReportOptions): void {\n const { scanResult, json, presets } = options;\n\n if (json) {\n this.reportJson(scanResult, presets);\n } else {\n this.reportTable(scanResult, presets);\n }\n }\n\n // @awa-impl: DISC-6_AC-1\n /** Build the JSON output object (also used by tests). */\n buildJsonOutput(scanResult: ScanResult, presets?: PresetDefinitions): FeaturesJsonOutput {\n const output: FeaturesJsonOutput = {\n features: scanResult.features.map((f) => ({\n name: f.name,\n files: f.files,\n })),\n filesScanned: scanResult.filesScanned,\n };\n\n if (presets && Object.keys(presets).length > 0) {\n output.presets = presets;\n }\n\n return output;\n }\n\n private reportJson(scanResult: ScanResult, presets?: PresetDefinitions): void {\n const output = this.buildJsonOutput(scanResult, presets);\n console.log(JSON.stringify(output, null, 2));\n }\n\n // @awa-impl: DISC-7_AC-1\n private reportTable(scanResult: ScanResult, presets?: PresetDefinitions): void {\n const { features, filesScanned } = scanResult;\n\n if (features.length === 0) {\n console.log(chalk.yellow('No feature flags found.'));\n console.log(chalk.dim(`(${filesScanned} files scanned)`));\n return;\n }\n\n console.log(chalk.bold(`Feature flags (${features.length} found):\\n`));\n\n for (const feature of features) {\n console.log(` ${chalk.cyan(feature.name)}`);\n for (const file of feature.files) {\n console.log(` ${chalk.dim(file)}`);\n }\n }\n\n console.log('');\n console.log(chalk.dim(`${filesScanned} files scanned`));\n\n // Show presets if available\n if (presets && Object.keys(presets).length > 0) {\n console.log('');\n console.log(chalk.bold('Presets (from .awa.toml):\\n'));\n for (const [name, flags] of Object.entries(presets)) {\n console.log(` ${chalk.green(name)}: ${flags.join(', ')}`);\n }\n }\n }\n}\n\nexport const featuresReporter = new FeaturesReporter();\n","// @awa-component: DISC-FeatureScanner\n// @awa-impl: DISC-1_AC-1\n// @awa-impl: DISC-2_AC-1\n// @awa-impl: DISC-3_AC-1\n\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\n\n/** A single feature flag discovered in a template. */\nexport interface DiscoveredFeature {\n /** The flag name (e.g. \"copilot\"). */\n name: string;\n /** Relative paths of template files that reference this flag. */\n files: string[];\n}\n\n/** Result of scanning a template directory for feature flags. */\nexport interface ScanResult {\n /** All discovered feature flags, sorted by name. */\n features: DiscoveredFeature[];\n /** Total number of template files scanned. */\n filesScanned: number;\n}\n\n// Matches: it.features.includes('name') or it.features.includes(\"name\")\n// Also matches: it.features.indexOf('name') or it.features.indexOf(\"name\")\nconst FEATURE_PATTERN = /it\\.features\\.(?:includes|indexOf)\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n/**\n * Recursively walk a directory yielding all file paths (including those\n * starting with underscore, since partials may reference feature flags).\n */\nasync function* walkAllFiles(dir: string): AsyncGenerator<string> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkAllFiles(fullPath);\n } else if (entry.isFile()) {\n yield fullPath;\n }\n }\n}\n\nexport class FeatureScanner {\n // @awa-impl: DISC-1_AC-1, DISC-2_AC-1\n /** Extract feature flag names from a single file's content. */\n extractFlags(content: string): string[] {\n const flags = new Set<string>();\n for (const match of content.matchAll(FEATURE_PATTERN)) {\n if (match[1]) {\n flags.add(match[1]);\n }\n }\n return [...flags];\n }\n\n // @awa-impl: DISC-1_AC-1, DISC-2_AC-1, DISC-3_AC-1\n /** Scan a template directory and return all discovered feature flags. */\n async scan(templatePath: string): Promise<ScanResult> {\n const flagToFiles = new Map<string, Set<string>>();\n let filesScanned = 0;\n\n for await (const filePath of walkAllFiles(templatePath)) {\n filesScanned++;\n try {\n const content = await readFile(filePath, 'utf-8');\n const flags = this.extractFlags(content);\n const relPath = relative(templatePath, filePath);\n for (const flag of flags) {\n const existing = flagToFiles.get(flag);\n if (existing) {\n existing.add(relPath);\n } else {\n flagToFiles.set(flag, new Set([relPath]));\n }\n }\n } catch {\n // Skip binary files or files that can't be read as UTF-8\n }\n }\n\n const features: DiscoveredFeature[] = [...flagToFiles.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, files]) => ({\n name,\n files: [...files].sort(),\n }));\n\n return { features, filesScanned };\n }\n}\n\nexport const featureScanner = new FeatureScanner();\n","// @awa-component: GEN-GenerateCommand\n// @awa-component: JSON-GenerateCommand\n// @awa-component: INIT-ConfigHint\n// @awa-component: MULTI-GenerateCommand\n// @awa-impl: INIT-5_AC-1\n// @awa-impl: MULTI-6_AC-1\n// @awa-impl: MULTI-10_AC-1\n// @awa-impl: CHK-1_AC-2\n// @awa-impl: CHK-1_AC-3\n// @awa-impl: CHK-5_AC-2\n// @awa-impl: CHK-5_AC-3\n\nimport { intro, isCancel, multiselect, outro } from '@clack/prompts';\nimport { batchRunner } from '../core/batch-runner.js';\nimport { configLoader } from '../core/config.js';\nimport { featureResolver } from '../core/feature-resolver.js';\nimport { fileGenerator } from '../core/generator.js';\nimport {\n formatGenerationSummary,\n serializeGenerationResult,\n writeJsonOutput,\n} from '../core/json-output.js';\nimport { buildMergedDir, resolveOverlays } from '../core/overlay.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport type { RawCliOptions, ResolvedOptions } from '../types/index.js';\nimport { rmDir } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\n/** Known AI tool feature flags for interactive selection. */\nconst TOOL_FEATURES = [\n { value: 'copilot', label: 'GitHub Copilot' },\n { value: 'claude', label: 'Claude Code' },\n { value: 'cursor', label: 'Cursor' },\n { value: 'windsurf', label: 'Windsurf' },\n { value: 'kilocode', label: 'Kilocode' },\n { value: 'opencode', label: 'OpenCode' },\n { value: 'gemini', label: 'Gemini CLI' },\n { value: 'roo', label: 'Roo Code' },\n { value: 'qwen', label: 'Qwen Code' },\n { value: 'codex', label: 'Codex CLI' },\n { value: 'agy', label: 'Antigravity (agy)' },\n { value: 'agents-md', label: 'AGENTS.md (cross-tool)' },\n] as const;\n\nconst TOOL_FEATURE_VALUES = new Set<string>(TOOL_FEATURES.map((t) => t.value));\n\nasync function runGenerate(options: ResolvedOptions, batchMode: boolean): Promise<void> {\n const silent = options.json || options.summary;\n\n // Resolve template source\n const template = await templateResolver.resolve(options.template, options.refresh);\n\n const features = featureResolver.resolve({\n baseFeatures: [...options.features],\n presetNames: [...options.preset],\n removeFeatures: [...options.removeFeatures],\n presetDefinitions: options.presets,\n });\n\n // @awa-impl: MTT-1_AC-1 // @awa-ignore\n // If no tool feature flag is present, prompt the user to select tools interactively\n // In batch mode (--all / --target), skip prompting\n // @awa-impl: JSON-6_AC-1\n if (!batchMode) {\n const hasToolFlag = features.some((f) => TOOL_FEATURE_VALUES.has(f));\n if (!hasToolFlag && !silent) {\n const selected = await multiselect({\n message: 'Select AI tools to generate for (space to toggle, enter to confirm):',\n options: TOOL_FEATURES.map((t) => ({ value: t.value, label: t.label })),\n required: true,\n });\n if (isCancel(selected)) {\n logger.info('Generation cancelled.');\n process.exit(0);\n }\n features.push(...(selected as string[]));\n }\n }\n\n // @awa-impl: JSON-7_AC-1\n // --json implies --dry-run for generate\n const effectiveDryRun = options.json || options.dryRun;\n\n // Display mode indicators\n if (!silent) {\n if (effectiveDryRun) {\n logger.info('Running in dry-run mode (no files will be modified)');\n }\n if (options.force) {\n logger.info('Force mode enabled (existing files will be overwritten)');\n }\n }\n\n // @awa-impl: OVL-2_AC-1\n // Build merged template dir if overlays are specified\n let mergedDir: string | null = null;\n let templatePath = template.localPath;\n if (options.overlay.length > 0) {\n const overlayDirs = await resolveOverlays([...options.overlay], options.refresh);\n mergedDir = await buildMergedDir(template.localPath, overlayDirs);\n templatePath = mergedDir;\n }\n\n try {\n // Generate files\n const result = await fileGenerator.generate({\n templatePath,\n outputPath: options.output,\n features,\n force: options.force,\n dryRun: effectiveDryRun,\n delete: options.delete,\n });\n\n // @awa-impl: JSON-1_AC-1, JSON-8_AC-1\n if (options.json) {\n writeJsonOutput(serializeGenerationResult(result));\n } else if (options.summary) {\n // @awa-impl: JSON-5_AC-1\n console.log(formatGenerationSummary(result));\n } else {\n // Display summary\n logger.summary(result);\n }\n } finally {\n // Clean up merged overlay temp directory\n if (mergedDir) {\n try {\n await rmDir(mergedDir);\n } catch {\n // Swallow cleanup errors — temp dir will be cleaned by OS eventually\n }\n }\n }\n}\n\nexport async function generateCommand(cliOptions: RawCliOptions): Promise<void> {\n try {\n // Load configuration file\n const fileConfig = await configLoader.load(cliOptions.config ?? null);\n\n // @awa-impl: INIT-5_AC-1\n // Non-blocking hint when no config file is present and --config was not provided\n if (!cliOptions.config && fileConfig === null) {\n logger.info('Tip: create .awa.toml to save your options for next time.');\n }\n\n // Batch mode: --all or --target\n if (cliOptions.all || cliOptions.target) {\n const mode = cliOptions.all ? 'all' : 'single';\n const targets = batchRunner.resolveTargets(cliOptions, fileConfig, mode, cliOptions.target);\n\n for (const { targetName, options } of targets) {\n batchRunner.logForTarget(targetName, 'Starting generation...');\n await runGenerate(options, true);\n batchRunner.logForTarget(targetName, 'Generation complete.');\n }\n\n outro('All targets generated!');\n return;\n }\n\n // Standard single-target mode (backward compatible)\n const options = configLoader.merge(cliOptions, fileConfig);\n\n const silent = options.json || options.summary;\n\n // @awa-impl: JSON-6_AC-1\n // Suppress interactive output when --json or --summary is active\n if (!silent) {\n intro('awa CLI - Template Generator');\n }\n\n await runGenerate(options, false);\n\n if (!silent) {\n outro('Generation complete!');\n }\n } catch (error) {\n // @awa-impl: JSON-8_AC-1\n // Error handling with proper exit codes — errors always go to stderr\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","// @awa-component: TTST-TestCommand\n// @awa-impl: TTST-7_AC-1\n\nimport { intro, outro } from '@clack/prompts';\nimport { configLoader } from '../core/config.js';\nimport { templateResolver } from '../core/template-resolver.js';\nimport { discoverFixtures } from '../core/template-test/fixture-loader.js';\nimport { report } from '../core/template-test/reporter.js';\nimport { runAll } from '../core/template-test/runner.js';\nimport type { RawTestOptions } from '../core/template-test/types.js';\nimport { logger } from '../utils/logger.js';\n\n// @awa-impl: TTST-7_AC-1\nexport async function testCommand(options: RawTestOptions): Promise<number> {\n try {\n intro('awa CLI - Template Test');\n\n // Load configuration file\n const fileConfig = await configLoader.load(options.config ?? null);\n const templateSource = options.template ?? fileConfig?.template ?? null;\n\n // Resolve template source\n const template = await templateResolver.resolve(templateSource, false);\n\n // Discover fixtures\n const fixtures = await discoverFixtures(template.localPath);\n\n if (fixtures.length === 0) {\n logger.warn('No test fixtures found in _tests/ directory');\n outro('No tests to run.');\n return 0;\n }\n\n logger.info(`Found ${fixtures.length} fixture(s)`);\n\n // Extract preset definitions from config\n const presetDefinitions = fileConfig?.presets ?? {};\n\n // Run all fixtures\n const result = await runAll(\n fixtures,\n template.localPath,\n { updateSnapshots: options.updateSnapshots },\n presetDefinitions\n );\n\n // Report results\n report(result);\n\n if (result.failed > 0) {\n outro(`${result.failed} fixture(s) failed.`);\n return 1;\n }\n\n outro('All tests passed!');\n return 0;\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n return 2;\n }\n}\n","// @awa-component: TTST-FixtureLoader\n// @awa-impl: TTST-1_AC-1\n// @awa-impl: TTST-2_AC-1\n\nimport { readdir } from 'node:fs/promises';\nimport { basename, extname, join } from 'node:path';\nimport { parse } from 'smol-toml';\nimport { readTextFile } from '../../utils/fs.js';\nimport type { TestFixture } from './types.js';\n\n// @awa-impl: TTST-1_AC-1\nexport async function discoverFixtures(templatePath: string): Promise<TestFixture[]> {\n const testsDir = join(templatePath, '_tests');\n\n let entries: string[];\n try {\n const dirEntries = await readdir(testsDir, { withFileTypes: true });\n entries = dirEntries\n .filter((e) => e.isFile() && extname(e.name) === '.toml')\n .map((e) => e.name)\n .sort();\n } catch {\n // _tests/ directory doesn't exist — no fixtures\n return [];\n }\n\n const fixtures: TestFixture[] = [];\n for (const filename of entries) {\n const filePath = join(testsDir, filename);\n const fixture = await parseFixture(filePath);\n fixtures.push(fixture);\n }\n\n return fixtures;\n}\n\n// @awa-impl: TTST-2_AC-1\nexport async function parseFixture(filePath: string): Promise<TestFixture> {\n const content = await readTextFile(filePath);\n const parsed = parse(content) as Record<string, unknown>;\n\n const name = basename(filePath, extname(filePath));\n\n const features = toStringArray(parsed.features) ?? [];\n const preset = toStringArray(parsed.preset) ?? [];\n const removeFeatures = toStringArray(parsed['remove-features']) ?? [];\n const expectedFiles = toStringArray(parsed['expected-files']) ?? [];\n\n return {\n name,\n features,\n preset,\n removeFeatures,\n expectedFiles,\n filePath,\n };\n}\n\nfunction toStringArray(value: unknown): string[] | null {\n if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {\n return value as string[];\n }\n return null;\n}\n","// @awa-component: TTST-Reporter\n// @awa-impl: TTST-6_AC-1\n\nimport chalk from 'chalk';\nimport type { FixtureResult, TestSuiteResult } from './types.js';\n\n// @awa-impl: TTST-6_AC-1\nexport function report(result: TestSuiteResult): void {\n console.log('');\n\n for (const fixture of result.results) {\n reportFixture(fixture);\n }\n\n // Summary\n console.log('');\n console.log(chalk.bold('Test Summary:'));\n console.log(` Total: ${result.total}`);\n console.log(chalk.green(` Passed: ${result.passed}`));\n if (result.failed > 0) {\n console.log(chalk.red(` Failed: ${result.failed}`));\n }\n console.log('');\n}\n\nfunction reportFixture(fixture: FixtureResult): void {\n const icon = fixture.passed ? chalk.green('✔') : chalk.red('✖');\n console.log(`${icon} ${fixture.name}`);\n\n if (fixture.error) {\n console.log(chalk.red(` Error: ${fixture.error}`));\n return;\n }\n\n // Report missing files\n const missingFiles = fixture.fileResults.filter((r) => !r.found);\n for (const missing of missingFiles) {\n console.log(chalk.red(` Missing file: ${missing.path}`));\n }\n\n // Report snapshot mismatches\n const snapshotFailures = fixture.snapshotResults.filter((r) => r.status !== 'match');\n for (const failure of snapshotFailures) {\n switch (failure.status) {\n case 'mismatch':\n console.log(chalk.yellow(` Snapshot mismatch: ${failure.path}`));\n break;\n case 'missing-snapshot':\n console.log(chalk.yellow(` Missing snapshot: ${failure.path}`));\n break;\n case 'extra-snapshot':\n console.log(chalk.yellow(` Extra snapshot (not in output): ${failure.path}`));\n break;\n }\n }\n}\n","// @awa-component: TTST-TestRunner\n// @awa-impl: TTST-3_AC-1\n// @awa-impl: TTST-4_AC-1\n// @awa-impl: TTST-5_AC-1\n// @awa-impl: TTST-8_AC-1\n\nimport { mkdir, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { pathExists } from '../../utils/fs.js';\nimport { featureResolver } from '../feature-resolver.js';\nimport { fileGenerator } from '../generator.js';\nimport { compareSnapshots, updateSnapshots } from './snapshot.js';\nimport type {\n FileAssertionResult,\n FixtureResult,\n SnapshotFileResult,\n TestFixture,\n TestRunOptions,\n TestSuiteResult,\n} from './types.js';\n\n// @awa-impl: TTST-3_AC-1\nexport async function runFixture(\n fixture: TestFixture,\n templatePath: string,\n options: TestRunOptions,\n presetDefinitions: Record<string, string[]> = {}\n): Promise<FixtureResult> {\n const tempDir = join(tmpdir(), `awa-test-${fixture.name}-${Date.now()}`);\n\n try {\n await mkdir(tempDir, { recursive: true });\n\n // Resolve features using presets and remove-features\n const features = featureResolver.resolve({\n baseFeatures: [...fixture.features],\n presetNames: [...fixture.preset],\n removeFeatures: [...fixture.removeFeatures],\n presetDefinitions,\n });\n\n // Render templates to temp dir\n await fileGenerator.generate({\n templatePath,\n outputPath: tempDir,\n features,\n force: true,\n dryRun: false,\n delete: false,\n });\n\n // @awa-impl: TTST-4_AC-1\n // Check expected files\n const fileResults: FileAssertionResult[] = [];\n for (const expectedFile of fixture.expectedFiles) {\n const fullPath = join(tempDir, expectedFile);\n const found = await pathExists(fullPath);\n fileResults.push({ path: expectedFile, found });\n }\n\n const missingFiles = fileResults.filter((r) => !r.found);\n\n // @awa-impl: TTST-5_AC-1\n // Snapshot comparison\n const snapshotDir = join(templatePath, '_tests', fixture.name);\n let snapshotResults: SnapshotFileResult[] = [];\n if (options.updateSnapshots) {\n await updateSnapshots(tempDir, snapshotDir);\n } else if (await pathExists(snapshotDir)) {\n snapshotResults = await compareSnapshots(tempDir, snapshotDir);\n }\n\n const snapshotFailures = snapshotResults.filter((r) => r.status !== 'match');\n\n const passed = missingFiles.length === 0 && snapshotFailures.length === 0;\n\n return {\n name: fixture.name,\n passed,\n fileResults,\n snapshotResults,\n };\n } catch (error) {\n return {\n name: fixture.name,\n passed: false,\n fileResults: [],\n snapshotResults: [],\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n // Clean up temp dir\n await rm(tempDir, { recursive: true, force: true }).catch(() => {});\n }\n}\n\nexport async function runAll(\n fixtures: TestFixture[],\n templatePath: string,\n options: TestRunOptions,\n presetDefinitions: Record<string, string[]> = {}\n): Promise<TestSuiteResult> {\n const results: FixtureResult[] = [];\n\n for (const fixture of fixtures) {\n const result = await runFixture(fixture, templatePath, options, presetDefinitions);\n results.push(result);\n }\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.filter((r) => !r.passed).length;\n\n return {\n results,\n total: results.length,\n passed,\n failed,\n };\n}\n","// @awa-component: TTST-TestRunner\n// @awa-impl: TTST-5_AC-1\n\nimport { mkdir, readdir, rm } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { pathExists, readTextFile, writeTextFile } from '../../utils/fs.js';\nimport type { SnapshotFileResult } from './types.js';\n\n/** Walk a directory recursively and yield relative file paths. */\nasync function walkRelative(dir: string, base: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const sub = await walkRelative(fullPath, base);\n results.push(...sub);\n } else if (entry.isFile()) {\n results.push(relative(base, fullPath));\n }\n }\n\n return results;\n}\n\n// @awa-impl: TTST-5_AC-1\nexport async function compareSnapshots(\n renderedDir: string,\n snapshotDir: string\n): Promise<SnapshotFileResult[]> {\n const results: SnapshotFileResult[] = [];\n\n const renderedFiles = await walkRelative(renderedDir, renderedDir);\n const snapshotFiles = await walkRelative(snapshotDir, snapshotDir);\n\n const snapshotSet = new Set(snapshotFiles);\n const renderedSet = new Set(renderedFiles);\n\n // Check rendered files against snapshots\n for (const file of renderedFiles) {\n const renderedPath = join(renderedDir, file);\n const snapshotPath = join(snapshotDir, file);\n\n if (!snapshotSet.has(file)) {\n results.push({ path: file, status: 'missing-snapshot' });\n continue;\n }\n\n const renderedContent = await readTextFile(renderedPath);\n const snapshotContent = await readTextFile(snapshotPath);\n\n results.push({\n path: file,\n status: renderedContent === snapshotContent ? 'match' : 'mismatch',\n });\n }\n\n // Check for extra snapshot files not in rendered output\n for (const file of snapshotFiles) {\n if (!renderedSet.has(file)) {\n results.push({ path: file, status: 'extra-snapshot' });\n }\n }\n\n return results;\n}\n\n// @awa-impl: TTST-5_AC-1\nexport async function updateSnapshots(renderedDir: string, snapshotDir: string): Promise<void> {\n // Remove existing snapshot directory\n if (await pathExists(snapshotDir)) {\n await rm(snapshotDir, { recursive: true, force: true });\n }\n\n await mkdir(snapshotDir, { recursive: true });\n\n // Copy rendered files to snapshot directory\n const files = await walkRelative(renderedDir, renderedDir);\n for (const file of files) {\n const srcPath = join(renderedDir, file);\n const destPath = join(snapshotDir, file);\n const content = await readTextFile(srcPath);\n await writeTextFile(destPath, content);\n }\n}\n","import chalk from 'chalk';\nimport { PACKAGE_INFO } from '../_generated/package_info.js';\nimport type { Logger } from './logger.js';\n\nexport interface UpdateCheckResult {\n current: string;\n latest: string;\n isOutdated: boolean;\n isMajorBump: boolean;\n}\n\n/**\n * Compare two semver version strings numerically (major.minor.patch only).\n * Returns a negative number if a < b, 0 if equal, positive if a > b.\n */\nexport function compareSemver(a: string, b: string): number {\n const partsA = a.split('.').map((s) => Number.parseInt(s, 10));\n const partsB = b.split('.').map((s) => Number.parseInt(s, 10));\n\n for (let i = 0; i < 3; i++) {\n const diff = (partsA[i] ?? 0) - (partsB[i] ?? 0);\n if (diff !== 0) return diff;\n }\n return 0;\n}\n\n/**\n * Check if a version bump is a major version bump.\n */\nexport function isMajorVersionBump(current: string, latest: string): boolean {\n const currentMajor = Number.parseInt(current.split('.')[0] ?? '0', 10);\n const latestMajor = Number.parseInt(latest.split('.')[0] ?? '0', 10);\n return latestMajor > currentMajor;\n}\n\n/**\n * Fetch the latest version from the npm registry.\n * Returns the update check result or null on any error.\n */\nexport async function checkForUpdate(): Promise<UpdateCheckResult | null> {\n try {\n const response = await fetch('https://registry.npmjs.org/@ncoderz/awa/latest', {\n signal: AbortSignal.timeout(5000),\n });\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n const latest = data.version;\n if (!latest || typeof latest !== 'string') return null;\n\n const current = PACKAGE_INFO.version;\n const isOutdated = compareSemver(current, latest) < 0;\n\n return {\n current,\n latest,\n isOutdated,\n isMajorBump: isOutdated && isMajorVersionBump(current, latest),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Print an update warning to the console using the logger.\n */\nexport function printUpdateWarning(log: Logger, result: UpdateCheckResult): void {\n if (!result.isOutdated) return;\n\n console.log('');\n if (result.isMajorBump) {\n log.warn(\n chalk.yellow(\n `New major version available: ${result.current} → ${result.latest} (breaking changes)`\n )\n );\n log.warn(chalk.dim(' See https://github.com/ncoderz/awa/releases for details'));\n } else {\n log.warn(chalk.yellow(`Update available: ${result.current} → ${result.latest}`));\n }\n log.warn(chalk.dim(' Run `npm install -g @ncoderz/awa` to update'));\n console.log('');\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst CACHE_DIR = join(homedir(), '.cache', 'awa');\nconst CACHE_FILE = join(CACHE_DIR, 'update-check.json');\nconst DEFAULT_INTERVAL_MS = 86_400_000; // 1 day\n\ninterface CacheData {\n timestamp: number;\n latestVersion: string;\n}\n\n/**\n * Determine whether a new update check should be performed.\n * Returns true if the cache is missing, corrupt, or stale.\n */\nexport async function shouldCheck(intervalMs: number = DEFAULT_INTERVAL_MS): Promise<boolean> {\n try {\n const raw = await readFile(CACHE_FILE, 'utf-8');\n const data = JSON.parse(raw) as CacheData;\n\n if (typeof data.timestamp !== 'number' || typeof data.latestVersion !== 'string') {\n return true;\n }\n\n return Date.now() - data.timestamp >= intervalMs;\n } catch {\n return true;\n }\n}\n\n/**\n * Write the latest version and current timestamp to the cache file.\n */\nexport async function writeCache(latestVersion: string): Promise<void> {\n try {\n await mkdir(dirname(CACHE_FILE), { recursive: true });\n\n const data: CacheData = {\n timestamp: Date.now(),\n latestVersion,\n };\n\n await writeFile(CACHE_FILE, JSON.stringify(data), 'utf-8');\n } catch {\n // Silently ignore write failures\n }\n}\n\n/**\n * Read the cached latest version. Returns null if cache is missing or corrupt.\n */\nexport async function readCachedVersion(): Promise<string | null> {\n try {\n const raw = await readFile(CACHE_FILE, 'utf-8');\n const data = JSON.parse(raw) as CacheData;\n if (typeof data.latestVersion === 'string') {\n return data.latestVersion;\n }\n return null;\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":["readFile","readFile","readFile","readFile","readFile","readFile","join","relative","join","join","join","chalk","join","relative","join","tmpdir","join","join","join","join","tmpdir","options","diffOptions","mergedDir","resolve","intro","outro","chalk","readFile","join","relative","intro","outro","intro","isCancel","multiselect","outro","multiselect","isCancel","options","outro","intro","intro","outro","readdir","basename","join","join","readdir","basename","toStringArray","chalk","report","mkdir","rm","tmpdir","join","readdir","rm","join","relative","readdir","join","relative","rm","join","tmpdir","mkdir","rm","intro","outro","report","chalk","chalk","mkdir","readFile","join","configLoader"]}