@ncoderz/awa 1.8.5 → 1.9.0

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.
Files changed (105) hide show
  1. package/dist/{chunk-TTXSMGB5.js → chunk-PC3PMV3K.js} +6 -3
  2. package/dist/{chunk-TTXSMGB5.js.map → chunk-PC3PMV3K.js.map} +1 -1
  3. package/dist/index.js +179 -69
  4. package/dist/index.js.map +1 -1
  5. package/dist/{renumber-T46VEDEI.js → renumber-LG6FUVOP.js} +2 -2
  6. package/package.json +1 -1
  7. package/templates/awa/.agent/skills/awa-spec-deprecate/SKILL.md +3 -0
  8. package/templates/awa/.agent/skills/awa-spec-merge/SKILL.md +3 -0
  9. package/templates/awa/.agent/skills/awa-spec-tidy/SKILL.md +3 -0
  10. package/templates/awa/.agent/workflows/awa-spec-deprecate.md +3 -0
  11. package/templates/awa/.agent/workflows/awa-spec-merge.md +3 -0
  12. package/templates/awa/.agent/workflows/awa-spec-tidy.md +3 -0
  13. package/templates/awa/.agents/skills/awa-spec-deprecate/SKILL.md +3 -0
  14. package/templates/awa/.agents/skills/awa-spec-merge/SKILL.md +3 -0
  15. package/templates/awa/.agents/skills/awa-spec-tidy/SKILL.md +3 -0
  16. package/templates/awa/.awa/.agent/schemas/DEPRECATED.schema.yaml +42 -0
  17. package/templates/awa/.claude/skills/awa-spec-deprecate/SKILL.md +3 -0
  18. package/templates/awa/.claude/skills/awa-spec-merge/SKILL.md +3 -0
  19. package/templates/awa/.claude/skills/awa-spec-tidy/SKILL.md +3 -0
  20. package/templates/awa/.codex/prompts/awa-spec-deprecate.md +3 -0
  21. package/templates/awa/.cursor/rules/awa-spec-deprecate.md +8 -0
  22. package/templates/awa/.gemini/commands/awa-spec-deprecate.md +3 -0
  23. package/templates/awa/.gemini/commands/awa-spec-merge.md +3 -0
  24. package/templates/awa/.gemini/commands/awa-spec-tidy.md +3 -0
  25. package/templates/awa/.gemini/skills/awa-spec-deprecate/SKILL.md +3 -0
  26. package/templates/awa/.gemini/skills/awa-spec-merge/SKILL.md +3 -0
  27. package/templates/awa/.gemini/skills/awa-spec-tidy/SKILL.md +3 -0
  28. package/templates/awa/.github/prompts/awa.spec-deprecate.prompt.md +8 -0
  29. package/templates/awa/.github/prompts/awa.spec-tidy.prompt.md +1 -1
  30. package/templates/awa/.github/skills/awa-spec-deprecate/SKILL.md +8 -0
  31. package/templates/awa/.github/skills/awa-spec-merge/SKILL.md +3 -0
  32. package/templates/awa/.github/skills/awa-spec-tidy/SKILL.md +3 -0
  33. package/templates/awa/.kilocode/skills/awa-spec-deprecate/SKILL.md +3 -0
  34. package/templates/awa/.kilocode/skills/awa-spec-merge/SKILL.md +3 -0
  35. package/templates/awa/.kilocode/skills/awa-spec-tidy/SKILL.md +3 -0
  36. package/templates/awa/.kilocode/workflows/awa-spec-deprecate.md +3 -0
  37. package/templates/awa/.kilocode/workflows/awa-spec-merge.md +3 -0
  38. package/templates/awa/.kilocode/{skills/spec-merge/SKILL.md → workflows/awa-spec-tidy.md} +1 -1
  39. package/templates/awa/.opencode/commands/awa-spec-deprecate.md +3 -0
  40. package/templates/awa/.opencode/commands/awa-spec-merge.md +3 -0
  41. package/templates/awa/.opencode/commands/{spec-merge.md → awa-spec-tidy.md} +1 -1
  42. package/templates/awa/.opencode/skills/awa-spec-deprecate/SKILL.md +3 -0
  43. package/templates/awa/.opencode/skills/awa-spec-merge/SKILL.md +3 -0
  44. package/templates/awa/.opencode/skills/awa-spec-tidy/SKILL.md +3 -0
  45. package/templates/awa/.qwen/commands/awa-spec-deprecate.md +3 -0
  46. package/templates/awa/.qwen/commands/awa-spec-merge.md +3 -0
  47. package/templates/awa/.qwen/commands/awa-spec-tidy.md +3 -0
  48. package/templates/awa/.qwen/skills/awa-spec-deprecate/SKILL.md +3 -0
  49. package/templates/awa/.qwen/skills/awa-spec-merge/SKILL.md +3 -0
  50. package/templates/awa/.qwen/skills/awa-spec-tidy/SKILL.md +3 -0
  51. package/templates/awa/.roo/skills/awa-spec-deprecate/SKILL.md +3 -0
  52. package/templates/awa/.roo/skills/awa-spec-merge/SKILL.md +3 -0
  53. package/templates/awa/.roo/skills/awa-spec-tidy/SKILL.md +3 -0
  54. package/templates/awa/.windsurf/skills/awa-spec-deprecate/SKILL.md +3 -0
  55. package/templates/awa/.windsurf/skills/awa-spec-merge/SKILL.md +3 -0
  56. package/templates/awa/.windsurf/skills/awa-spec-tidy/SKILL.md +3 -0
  57. package/templates/awa/_delete.txt +108 -0
  58. package/templates/awa/_partials/_cmd.awa-spec-deprecate.md +6 -0
  59. package/templates/awa/_partials/{_cmd.spec-tidy.md → _cmd.awa-spec-tidy.md} +1 -1
  60. package/templates/awa/_partials/_skill.awa-spec-deprecate.md +6 -0
  61. package/templates/awa/_partials/{_skill.spec-merge.md → _skill.awa-spec-merge.md} +1 -1
  62. package/templates/awa/_partials/{_skill.spec-tidy.md → _skill.awa-spec-tidy.md} +2 -2
  63. package/templates/awa/_partials/awa.core.md +7 -3
  64. package/templates/awa/_partials/awa.spec-deprecate.md +86 -0
  65. package/templates/awa/_partials/awa.usage.md +16 -7
  66. package/templates/awa/_tests/claude/.claude/skills/awa-spec-deprecate/SKILL.md +88 -0
  67. package/templates/awa/_tests/claude/.claude/skills/{spec-merge → awa-spec-merge}/SKILL.md +1 -1
  68. package/templates/awa/_tests/{copilot/.github/skills/spec-tidy → claude/.claude/skills/awa-spec-tidy}/SKILL.md +1 -1
  69. package/templates/awa/_tests/claude/.claude/skills/awa-usage/SKILL.md +14 -5
  70. package/templates/awa/_tests/copilot/.github/prompts/awa.spec-deprecate.prompt.md +88 -0
  71. package/templates/awa/_tests/copilot/.github/skills/awa-spec-deprecate/SKILL.md +88 -0
  72. package/templates/awa/_tests/copilot/.github/skills/{spec-merge → awa-spec-merge}/SKILL.md +1 -1
  73. package/templates/awa/_tests/{claude/.claude/skills/spec-tidy → copilot/.github/skills/awa-spec-tidy}/SKILL.md +1 -1
  74. package/templates/awa/_tests/copilot/.github/skills/awa-usage/SKILL.md +14 -5
  75. package/templates/awa/.agent/skills/spec-merge/SKILL.md +0 -3
  76. package/templates/awa/.agent/skills/spec-tidy/SKILL.md +0 -3
  77. package/templates/awa/.agent/workflows/spec-merge.md +0 -3
  78. package/templates/awa/.agent/workflows/spec-tidy.md +0 -3
  79. package/templates/awa/.agents/skills/spec-merge/SKILL.md +0 -3
  80. package/templates/awa/.agents/skills/spec-tidy/SKILL.md +0 -3
  81. package/templates/awa/.claude/skills/spec-merge/SKILL.md +0 -3
  82. package/templates/awa/.claude/skills/spec-tidy/SKILL.md +0 -3
  83. package/templates/awa/.gemini/commands/spec-merge.md +0 -3
  84. package/templates/awa/.gemini/commands/spec-tidy.md +0 -3
  85. package/templates/awa/.gemini/skills/spec-merge/SKILL.md +0 -3
  86. package/templates/awa/.gemini/skills/spec-tidy/SKILL.md +0 -3
  87. package/templates/awa/.github/skills/spec-merge/SKILL.md +0 -3
  88. package/templates/awa/.github/skills/spec-tidy/SKILL.md +0 -3
  89. package/templates/awa/.kilocode/skills/spec-tidy/SKILL.md +0 -3
  90. package/templates/awa/.kilocode/workflows/spec-merge.md +0 -3
  91. package/templates/awa/.kilocode/workflows/spec-tidy.md +0 -3
  92. package/templates/awa/.opencode/commands/spec-tidy.md +0 -3
  93. package/templates/awa/.opencode/skills/spec-merge/SKILL.md +0 -3
  94. package/templates/awa/.opencode/skills/spec-tidy/SKILL.md +0 -3
  95. package/templates/awa/.qwen/commands/spec-merge.md +0 -3
  96. package/templates/awa/.qwen/commands/spec-tidy.md +0 -3
  97. package/templates/awa/.qwen/skills/spec-merge/SKILL.md +0 -3
  98. package/templates/awa/.qwen/skills/spec-tidy/SKILL.md +0 -3
  99. package/templates/awa/.roo/skills/spec-merge/SKILL.md +0 -3
  100. package/templates/awa/.roo/skills/spec-tidy/SKILL.md +0 -3
  101. package/templates/awa/.windsurf/skills/spec-merge/SKILL.md +0 -3
  102. package/templates/awa/.windsurf/skills/spec-tidy/SKILL.md +0 -3
  103. /package/dist/{renumber-T46VEDEI.js.map → renumber-LG6FUVOP.js.map} +0 -0
  104. /package/templates/awa/_partials/{_cmd.spec-merge.md → _cmd.awa-spec-merge.md} +0 -0
  105. /package/templates/awa/_partials/{awa.spec.tidy.md → awa.spec-tidy.md} +0 -0
@@ -667,7 +667,8 @@ var DEFAULT_CHECK_CONFIG = {
667
667
  ".awa/specs/API-*.tsp",
668
668
  ".awa/tasks/TASK-*.md",
669
669
  ".awa/plans/PLAN-*.md",
670
- ".awa/align/ALIGN-*.md"
670
+ ".awa/align/ALIGN-*.md",
671
+ ".awa/specs/deprecated/DEPRECATED.md"
671
672
  ],
672
673
  codeGlobs: [
673
674
  "**/*.{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}"
@@ -693,7 +694,8 @@ var DEFAULT_CHECK_CONFIG = {
693
694
  schemaEnabled: true,
694
695
  allowWarnings: false,
695
696
  specOnly: false,
696
- fix: true
697
+ fix: true,
698
+ deprecated: false
697
699
  };
698
700
 
699
701
  // src/core/trace/scanner.ts
@@ -724,6 +726,7 @@ function buildScanConfig(fileConfig, overrides) {
724
726
  allowWarnings: true,
725
727
  specOnly: false,
726
728
  fix: true,
729
+ deprecated: false,
727
730
  ...overrides
728
731
  };
729
732
  }
@@ -892,4 +895,4 @@ export {
892
895
  propagate,
893
896
  renumberCommand
894
897
  };
895
- //# sourceMappingURL=chunk-TTXSMGB5.js.map
898
+ //# sourceMappingURL=chunk-PC3PMV3K.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/renumber.ts","../src/core/renumber/malformed-detector.ts","../src/core/spec-file-utils.ts","../src/core/renumber/types.ts","../src/core/renumber/map-builder.ts","../src/core/renumber/propagator.ts","../src/core/check/glob.ts","../src/core/renumber/reporter.ts","../src/core/check/marker-scanner.ts","../src/core/check/spec-parser.ts","../src/core/check/types.ts","../src/core/trace/scanner.ts"],"sourcesContent":["// @awa-component: RENUM-RenumberCommand\n// @awa-impl: RENUM-8_AC-1, RENUM-8_AC-2\n// @awa-impl: RENUM-9_AC-1, RENUM-9_AC-2, RENUM-9_AC-3, RENUM-9_AC-4\n// @awa-impl: RENUM-10_AC-1\n\nimport { readFile } from 'node:fs/promises';\n\nimport { correctMalformed, detectMalformed } from '../core/renumber/malformed-detector.js';\nimport { buildRenumberMap } from '../core/renumber/map-builder.js';\nimport { propagate } from '../core/renumber/propagator.js';\nimport { formatJson, formatText } from '../core/renumber/reporter.js';\nimport type { RenumberCommandOptions, RenumberResult } from '../core/renumber/types.js';\nimport { RenumberError } from '../core/renumber/types.js';\nimport { scan } from '../core/trace/scanner.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Execute the `awa renumber` command.\n * Returns exit code: 0 = no changes needed, 1 = changes applied/previewed, 2 = error.\n */\n// @awa-impl: RENUM-10_AC-1\nexport async function renumberCommand(options: RenumberCommandOptions): Promise<number> {\n try {\n // @awa-impl: RENUM-9_AC-3\n if (!options.code && !options.all) {\n logger.error('No feature code or --all specified');\n return 2;\n }\n\n const { markers, specs, config } = await scan(options.config);\n\n // Determine which codes to renumber\n // @awa-impl: RENUM-8_AC-1\n let codes: string[];\n if (options.all) {\n codes = discoverFeatureCodes(specs.specFiles);\n if (codes.length === 0) {\n logger.warn('No feature codes discovered from REQ files');\n return 0;\n }\n } else {\n codes = [options.code as string];\n }\n\n const dryRun = options.dryRun === true;\n const fixMalformed = options.expandUnambiguousIds === true;\n const results: RenumberResult[] = [];\n let hasChanges = false;\n\n // @awa-impl: RENUM-8_AC-2\n for (const code of codes) {\n try {\n const result = await runRenumberPipeline(\n code,\n specs,\n markers,\n config,\n dryRun,\n fixMalformed,\n );\n results.push(result);\n if (!result.noChange) {\n hasChanges = true;\n }\n } catch (err) {\n if (err instanceof RenumberError && err.errorCode === 'CODE_NOT_FOUND') {\n // @awa-impl: RENUM-9_AC-4\n logger.error(err.message);\n return 2;\n }\n throw err;\n }\n }\n\n // Output results\n if (options.json) {\n // JSON mode: output array if --all, single object otherwise\n if (results.length === 1) {\n const first = results[0] as RenumberResult;\n process.stdout.write(`${formatJson(first)}\\n`);\n } else {\n const jsonArray = results.map((r) => JSON.parse(formatJson(r)));\n process.stdout.write(`${JSON.stringify(jsonArray, null, 2)}\\n`);\n }\n } else {\n for (const result of results) {\n const text = formatText(result, dryRun);\n logger.info(text);\n }\n }\n\n // @awa-impl: RENUM-10_AC-1\n return hasChanges ? 1 : 0;\n } catch (err) {\n if (err instanceof RenumberError) {\n logger.error(err.message);\n return 2;\n }\n if (err instanceof Error) {\n logger.error(err.message);\n } else {\n logger.error(String(err));\n }\n return 2;\n }\n}\n\n/**\n * Run the renumber pipeline for a single feature code.\n */\n// @awa-impl: RENUM-9_AC-1\nasync function runRenumberPipeline(\n code: string,\n specs: import('../core/check/types.js').SpecParseResult,\n markers: import('../core/check/types.js').MarkerScanResult,\n config: import('../core/check/types.js').CheckConfig,\n dryRun: boolean,\n fixMalformed: boolean,\n): Promise<RenumberResult> {\n // Build renumber map\n const { map, noChange } = buildRenumberMap(code, specs);\n\n if (noChange) {\n return {\n code,\n map,\n affectedFiles: [],\n totalReplacements: 0,\n malformedWarnings: [],\n malformedCorrections: [],\n noChange: true,\n };\n }\n\n // Detect malformed IDs from spec and code files\n const fileContents = await collectFileContents(specs, markers, code);\n const allWarnings = detectMalformed(code, fileContents);\n\n // Optionally correct unambiguous malformed IDs before propagation\n let malformedWarnings: readonly import('../core/renumber/types.js').MalformedWarning[];\n let malformedCorrections: readonly import('../core/renumber/types.js').MalformedCorrection[];\n\n if (fixMalformed && allWarnings.length > 0) {\n const result = await correctMalformed(code, allWarnings, fileContents, dryRun);\n malformedCorrections = result.corrections;\n malformedWarnings = result.remainingWarnings;\n } else {\n malformedWarnings = allWarnings;\n malformedCorrections = [];\n }\n\n // Propagate changes (after corrections so corrected IDs get renumbered)\n const { affectedFiles, totalReplacements } = await propagate(map, specs, markers, config, dryRun);\n\n return {\n code,\n map,\n affectedFiles,\n totalReplacements,\n malformedWarnings,\n malformedCorrections,\n noChange: false,\n };\n}\n\n/**\n * Discover all feature codes from REQ files.\n */\nfunction discoverFeatureCodes(\n specFiles: readonly import('../core/check/types.js').SpecFile[],\n): string[] {\n const codes = new Set<string>();\n for (const sf of specFiles) {\n if (sf.code && /^REQ-/.test(sf.filePath.split('/').pop() ?? '')) {\n codes.add(sf.code);\n }\n }\n return [...codes].sort();\n}\n\n/**\n * Collect file contents for malformed detection.\n * Reads spec files and code files that have markers for the given code.\n */\nasync function collectFileContents(\n specs: import('../core/check/types.js').SpecParseResult,\n markers: import('../core/check/types.js').MarkerScanResult,\n code: string,\n): Promise<Map<string, string>> {\n const paths = new Set<string>();\n\n // Add spec files\n for (const sf of specs.specFiles) {\n paths.add(sf.filePath);\n }\n\n // Add code files with markers starting with the code prefix\n for (const m of markers.markers) {\n if (m.id.startsWith(`${code}-`) || m.id.startsWith(`${code}_`)) {\n paths.add(m.filePath);\n }\n }\n\n const contents = new Map<string, string>();\n for (const p of paths) {\n try {\n const content = await readFile(p, 'utf-8');\n contents.set(p, content);\n } catch {\n // Skip unreadable files\n }\n }\n\n return contents;\n}\n","// @awa-component: RENUM-MalformedDetector\n// @awa-impl: RENUM-12_AC-1, RENUM-12_AC-2, RENUM-12_AC-3\n\nimport { writeFile } from 'node:fs/promises';\n\nimport type { MalformedCorrection, MalformedWarning } from './types.js';\n\n/**\n * Standard ID patterns that are considered valid.\n * - CODE-N (requirement)\n * - CODE-N.P (subrequirement)\n * - CODE-N_AC-M or CODE-N.P_AC-M (acceptance criterion)\n * - CODE_P-N (property)\n * - CODE-ComponentName (component — PascalCase name after code)\n */\nconst VALID_ID_RE = /^[A-Z][A-Z0-9]*(?:-\\d+(?:\\.\\d+)?(?:_AC-\\d+)?|_P-\\d+|-[A-Z][a-zA-Z0-9]*)$/;\n\n/**\n * Patterns that can be unambiguously expanded into valid IDs:\n *\n * - Slash ranges on ACs: CODE-N_AC-M/P or CODE-N.S_AC-M/P\n * e.g. ARC-36_AC-8/9 → ARC-36_AC-8, ARC-36_AC-9\n *\n * - Dot-dot ranges on ACs: CODE-N_AC-M..P or CODE-N.S_AC-M..P\n * e.g. ARC-18_AC-14..16 → ARC-18_AC-14, ARC-18_AC-15, ARC-18_AC-16\n */\n\n/** Slash range on ACs: e.g. ARC-36_AC-8/9 */\nconst SLASH_RANGE_RE = /^([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?_AC-)(\\d+)\\/(\\d+)$/;\n\n/** Dot-dot range on ACs: e.g. ARC-18_AC-14..16 */\nconst DOT_DOT_AC_RANGE_RE = /^([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?_AC-)(\\d+)\\.\\.(\\d+)$/;\n\n/**\n * Detect tokens that start with the feature code prefix but do not conform\n * to standard ID formats. Reports each as a warning with location.\n */\n// @awa-impl: RENUM-12_AC-1, RENUM-12_AC-2\nexport function detectMalformed(\n code: string,\n fileContents: ReadonlyMap<string, string>,\n): readonly MalformedWarning[] {\n const warnings: MalformedWarning[] = [];\n\n // Match tokens that structurally resemble IDs:\n // CODE-<Uppercase-or-digit>... (requirement-like or component-like)\n // CODE_P-... (property-like)\n // Tokens like CODE-lowercase (e.g. CLI-provided) are natural language, not IDs.\n const esc = escapeRegex(code);\n const tokenRegex = new RegExp(\n `(?<![A-Za-z0-9_.-])(?:${esc}-[A-Z0-9][A-Za-z0-9_./-]*|${esc}_P-[A-Za-z0-9_./-]+)`,\n 'g',\n );\n\n for (const [filePath, content] of fileContents) {\n const lines = content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] as string;\n let match: RegExpExecArray | null;\n while ((match = tokenRegex.exec(line)) !== null) {\n const token = match[0];\n // @awa-impl: RENUM-12_AC-3\n if (!VALID_ID_RE.test(token)) {\n warnings.push({ filePath, line: i + 1, token });\n }\n }\n }\n }\n\n return warnings;\n}\n\n/**\n * Attempt to expand a single malformed token into its corrected replacement string.\n * Returns the replacement string if unambiguous, or `undefined` if the pattern\n * is ambiguous and should remain as a warning only.\n *\n * Correctable patterns:\n * - Slash ranges: CODE-N_AC-M/P → \"CODE-N_AC-M, CODE-N_AC-P\"\n * - Dot-dot AC ranges: CODE-N_AC-M..P → \"CODE-N_AC-M, CODE-N_AC-M+1, ..., CODE-N_AC-P\"\n *\n * Ambiguous / ignored patterns (return undefined):\n * - Trailing periods (e.g. ARC_P-206.) — likely end of sentence\n * - Letter suffixes (e.g. ARC-18_AC-7a)\n * - Full-ID ranges (e.g. ARC-20..ARC-25)\n * - Component + period (e.g. ARC-ChunkedTransferManager.)\n */\nexport function expandMalformedToken(token: string): string | undefined {\n // Try slash range: CODE-N_AC-M/P\n const slashMatch = SLASH_RANGE_RE.exec(token);\n if (slashMatch) {\n const [, prefix, startStr, endStr] = slashMatch as RegExpExecArray &\n [string, string, string, string];\n return `${prefix}${startStr}, ${prefix}${endStr}`;\n }\n\n // Try dot-dot AC range: CODE-N_AC-M..P\n const dotDotMatch = DOT_DOT_AC_RANGE_RE.exec(token);\n if (dotDotMatch) {\n const [, prefix, startStr, endStr] = dotDotMatch as RegExpExecArray &\n [string, string, string, string];\n const start = Number(startStr);\n const end = Number(endStr);\n if (end <= start) return undefined; // Invalid range\n const ids: string[] = [];\n for (let n = start; n <= end; n++) {\n ids.push(`${prefix}${n}`);\n }\n return ids.join(', ');\n }\n\n // All other patterns are ambiguous — do not correct\n return undefined;\n}\n\n/**\n * Apply malformed ID corrections to file contents.\n * Only corrects tokens for which `expandMalformedToken` returns a value.\n * Returns the list of corrections applied and the updated file contents map.\n *\n * When `dryRun` is true, files are not written to disk but corrections are\n * still computed and returned for preview.\n */\nexport async function correctMalformed(\n _code: string,\n warnings: readonly MalformedWarning[],\n fileContents: ReadonlyMap<string, string>,\n dryRun: boolean,\n): Promise<{\n corrections: readonly MalformedCorrection[];\n remainingWarnings: readonly MalformedWarning[];\n}> {\n const corrections: MalformedCorrection[] = [];\n const remainingWarnings: MalformedWarning[] = [];\n\n // Group warnings by file for efficient batch replacement\n const warningsByFile = new Map<string, MalformedWarning[]>();\n for (const w of warnings) {\n const existing = warningsByFile.get(w.filePath) ?? [];\n existing.push(w);\n warningsByFile.set(w.filePath, existing);\n }\n\n // Track files that need writing\n const modifiedFiles = new Map<string, string>();\n\n for (const [filePath, fileWarnings] of warningsByFile) {\n const original = fileContents.get(filePath);\n if (original === undefined) {\n // Cannot correct — keep as warnings\n remainingWarnings.push(...fileWarnings);\n continue;\n }\n\n let content: string = original;\n\n for (const w of fileWarnings) {\n const replacement = expandMalformedToken(w.token);\n if (replacement === undefined) {\n remainingWarnings.push(w);\n continue;\n }\n\n // Replace the token in content (whole-token match to avoid partial substitution)\n const escaped = escapeRegex(w.token);\n const regex = new RegExp(`(?<![A-Za-z0-9_.-])${escaped}(?![A-Za-z0-9_.-])`, 'g');\n const updated: string = content.replace(regex, replacement);\n if (updated !== content) {\n content = updated;\n corrections.push({\n filePath: w.filePath,\n line: w.line,\n token: w.token,\n replacement,\n });\n } else {\n // Token not found in content (unexpected) — keep as warning\n remainingWarnings.push(w);\n }\n }\n\n if (content !== original) {\n modifiedFiles.set(filePath, content);\n }\n }\n\n // Write modified files unless dry-run\n if (!dryRun) {\n for (const [filePath, content] of modifiedFiles) {\n await writeFile(filePath, content, 'utf-8');\n }\n }\n\n return { corrections, remainingWarnings };\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","// @awa-impl: RENUM-1_AC-1\n// @awa-impl: RCOD-1_AC-1\n\nimport { basename } from 'node:path';\n\nimport type { SpecFile } from './check/types.js';\n\n/**\n * Find all spec files matching a feature code and file type prefix.\n * Returns files sorted alphabetically by basename for deterministic ordering.\n */\nexport function findSpecFiles(\n specFiles: readonly SpecFile[],\n code: string,\n prefix: string,\n): SpecFile[] {\n return specFiles\n .filter((sf) => {\n const name = basename(sf.filePath);\n return name.startsWith(`${prefix}-${code}-`);\n })\n .sort((a, b) => basename(a.filePath).localeCompare(basename(b.filePath)));\n}\n\n/**\n * Find the first spec file matching a feature code and file type prefix.\n * Convenience wrapper over findSpecFiles for cases needing a single match.\n */\nexport function findSpecFile(\n specFiles: readonly SpecFile[],\n code: string,\n prefix: string,\n): SpecFile | undefined {\n return findSpecFiles(specFiles, code, prefix)[0];\n}\n\n/** Known spec file prefixes that carry a feature code. */\nexport const SPEC_PREFIXES = ['FEAT', 'REQ', 'DESIGN', 'EXAMPLE', 'API', 'TASK'] as const;\n\n/**\n * Check whether at least one spec file exists for the given feature code.\n */\nexport function hasAnySpecFile(specFiles: readonly SpecFile[], code: string): boolean {\n return specFiles.some((sf) => {\n const name = basename(sf.filePath);\n return SPEC_PREFIXES.some((prefix) => name.startsWith(`${prefix}-${code}-`));\n });\n}\n","// Types shared across the renumber module.\n// Components are declared in their respective implementation files.\n\n/**\n * Mapping from old ID strings to new ID strings for one feature code.\n */\nexport interface RenumberMap {\n readonly code: string;\n readonly entries: ReadonlyMap<string, string>;\n}\n\n/**\n * A file touched by propagation with per-line replacement details.\n */\nexport interface AffectedFile {\n readonly filePath: string;\n readonly replacements: readonly Replacement[];\n}\n\n/**\n * A single ID replacement within a file.\n */\nexport interface Replacement {\n readonly line: number;\n readonly oldId: string;\n readonly newId: string;\n}\n\n/**\n * Aggregated output of the renumber pipeline for one feature code.\n */\nexport interface RenumberResult {\n readonly code: string;\n readonly map: RenumberMap;\n readonly affectedFiles: readonly AffectedFile[];\n readonly totalReplacements: number;\n readonly malformedWarnings: readonly MalformedWarning[];\n readonly malformedCorrections: readonly MalformedCorrection[];\n readonly noChange: boolean;\n}\n\n/**\n * CLI options passed to the renumber command.\n */\nexport interface RenumberCommandOptions {\n readonly code?: string;\n readonly all?: boolean;\n readonly dryRun?: boolean;\n readonly json?: boolean;\n readonly config?: string;\n readonly expandUnambiguousIds?: boolean;\n}\n\n/**\n * Warning about a malformed ID token.\n */\nexport interface MalformedWarning {\n readonly filePath: string;\n readonly line: number;\n readonly token: string;\n}\n\n/**\n * A correction applied to a malformed ID token.\n */\nexport interface MalformedCorrection {\n readonly filePath: string;\n readonly line: number;\n readonly token: string;\n readonly replacement: string;\n}\n\n/**\n * Result of map building.\n */\nexport interface MapBuildResult {\n readonly map: RenumberMap;\n readonly noChange: boolean;\n}\n\n/**\n * Result of propagation.\n */\nexport interface PropagationResult {\n readonly affectedFiles: readonly AffectedFile[];\n readonly totalReplacements: number;\n}\n\n// --- Error types ---\n\nexport type RenumberErrorCode = 'CODE_NOT_FOUND' | 'NO_ARGS' | 'WRITE_FAILED';\n\nexport class RenumberError extends Error {\n readonly errorCode: RenumberErrorCode;\n\n constructor(errorCode: RenumberErrorCode, message: string) {\n super(message);\n this.name = 'RenumberError';\n this.errorCode = errorCode;\n }\n}\n","// @awa-component: RENUM-MapBuilder\n// @awa-impl: RENUM-1_AC-1, RENUM-1_AC-2, RENUM-1_AC-3\n// @awa-impl: RENUM-2_AC-1, RENUM-2_AC-2\n// @awa-impl: RENUM-3_AC-1, RENUM-3_AC-2\n// @awa-impl: RENUM-4_AC-1, RENUM-4_AC-2\n\nimport type { SpecFile, SpecParseResult } from '../check/types.js';\nimport { findSpecFiles } from '../spec-file-utils.js';\nimport type { MapBuildResult, RenumberMap } from './types.js';\nimport { RenumberError } from './types.js';\n\n/**\n * Build a renumber map by walking ALL REQ and DESIGN files in document order.\n * Files are sorted alphabetically by basename. Requirements and properties are\n * numbered globally across all files for the feature code.\n */\n// @awa-impl: RENUM-1_AC-1\nexport function buildRenumberMap(code: string, specs: SpecParseResult): MapBuildResult {\n const reqFiles = findSpecFiles(specs.specFiles, code, 'REQ');\n if (reqFiles.length === 0) {\n throw new RenumberError('CODE_NOT_FOUND', `No REQ file found for feature code: ${code}`);\n }\n\n const entries = new Map<string, string>();\n\n // Walk ALL REQ files in alphabetical order for requirements, subrequirements, and ACs\n buildRequirementEntries(code, reqFiles, entries);\n\n // Walk ALL DESIGN files in alphabetical order for properties\n // @awa-impl: RENUM-4_AC-1, RENUM-4_AC-2\n const designFiles = findSpecFiles(specs.specFiles, code, 'DESIGN');\n if (designFiles.length > 0) {\n buildPropertyEntries(code, designFiles, entries);\n }\n // If no DESIGN file exists, skip property renumbering without error (RENUM-4_AC-2)\n\n // Remove identity mappings (old === new)\n for (const [oldId, newId] of entries) {\n if (oldId === newId) {\n entries.delete(oldId);\n }\n }\n\n // @awa-impl: RENUM-1_AC-3\n const noChange = entries.size === 0;\n\n const map: RenumberMap = { code, entries };\n return { map, noChange };\n}\n\n/**\n * Build renumber entries for requirements, subrequirements, and ACs from all REQ files.\n * Files are processed in the order given (already sorted alphabetically).\n * IDs are numbered globally across all files.\n */\n// @awa-impl: RENUM-1_AC-2, RENUM-2_AC-1, RENUM-2_AC-2, RENUM-3_AC-1, RENUM-3_AC-2\nfunction buildRequirementEntries(\n code: string,\n reqFiles: readonly SpecFile[],\n entries: Map<string, string>,\n): void {\n // Collect all requirements and subrequirements across files in order\n const topLevelReqs: string[] = [];\n const subReqsByParent = new Map<string, string[]>();\n const allAcIds: string[] = [];\n\n for (const reqFile of reqFiles) {\n for (const id of reqFile.requirementIds) {\n if (id.includes('.')) {\n const dotIdx = id.lastIndexOf('.');\n const parent = id.slice(0, dotIdx);\n const subs = subReqsByParent.get(parent) ?? [];\n subs.push(id);\n subReqsByParent.set(parent, subs);\n } else {\n topLevelReqs.push(id);\n }\n }\n for (const acId of reqFile.acIds) {\n allAcIds.push(acId);\n }\n }\n\n // Build old→new mapping for top-level requirements\n const reqNumberMap = new Map<string, number>(); // old req ID → new number\n for (let i = 0; i < topLevelReqs.length; i++) {\n const oldId = topLevelReqs[i] as string;\n const newNum = i + 1;\n const newId = `${code}-${newNum}`;\n entries.set(oldId, newId);\n reqNumberMap.set(oldId, newNum);\n }\n\n // Build old→new mapping for subrequirements within each parent\n for (const oldParentId of topLevelReqs) {\n const subs = subReqsByParent.get(oldParentId);\n if (!subs) continue;\n\n const newParentNum = reqNumberMap.get(oldParentId);\n if (newParentNum === undefined) continue;\n\n for (let j = 0; j < subs.length; j++) {\n const oldSubId = subs[j] as string;\n const newSubNum = j + 1;\n const newSubId = `${code}-${newParentNum}.${newSubNum}`;\n entries.set(oldSubId, newSubId);\n }\n }\n\n // Build AC mapping: group ACs by their parent (req or subreq)\n const acsByParent = new Map<string, string[]>();\n for (const acId of allAcIds) {\n const parent = acId.split('_AC-')[0] as string;\n const acs = acsByParent.get(parent) ?? [];\n acs.push(acId);\n acsByParent.set(parent, acs);\n }\n\n // Renumber ACs within each parent\n for (const [oldParentId, acs] of acsByParent) {\n // Determine the new parent ID\n const newParentId = entries.get(oldParentId) ?? oldParentId;\n\n for (let k = 0; k < acs.length; k++) {\n const oldAcId = acs[k] as string;\n const newAcNum = k + 1;\n const newAcId = `${newParentId}_AC-${newAcNum}`;\n entries.set(oldAcId, newAcId);\n }\n }\n}\n\n/**\n * Build renumber entries for properties from all DESIGN files.\n * Files are processed in the order given (already sorted alphabetically).\n * Properties are numbered globally across all files.\n */\nfunction buildPropertyEntries(\n code: string,\n designFiles: readonly SpecFile[],\n entries: Map<string, string>,\n): void {\n let counter = 0;\n for (const designFile of designFiles) {\n for (const oldId of designFile.propertyIds) {\n counter++;\n const newId = `${code}_P-${counter}`;\n entries.set(oldId, newId);\n }\n }\n}\n","// @awa-component: RENUM-Propagator\n// @awa-impl: RENUM-5_AC-1, RENUM-5_AC-2, RENUM-5_AC-3\n// @awa-impl: RENUM-6_AC-1, RENUM-6_AC-2\n\nimport { readFile, writeFile } from 'node:fs/promises';\n\nimport { collectFiles } from '../check/glob.js';\nimport type { CheckConfig, MarkerScanResult, SpecParseResult } from '../check/types.js';\nimport type { AffectedFile, PropagationResult, RenumberMap, Replacement } from './types.js';\nimport { RenumberError } from './types.js';\n\n/**\n * Apply the renumber map across all spec files and code files.\n * Uses two-pass placeholder replacement to avoid swap collisions.\n */\nexport async function propagate(\n map: RenumberMap,\n specs: SpecParseResult,\n markers: MarkerScanResult,\n config: CheckConfig,\n dryRun: boolean,\n): Promise<PropagationResult> {\n if (map.entries.size === 0) {\n return { affectedFiles: [], totalReplacements: 0 };\n }\n\n // Collect all file paths that need scanning\n const filePaths = await collectFilePaths(map, specs, markers, config);\n\n const affectedFiles: AffectedFile[] = [];\n let totalReplacements = 0;\n\n for (const filePath of filePaths) {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n continue; // Skip unreadable files\n }\n\n const result = applyReplacements(content, map);\n if (result.replacements.length === 0) continue;\n\n affectedFiles.push({ filePath, replacements: result.replacements });\n totalReplacements += result.replacements.length;\n\n if (!dryRun) {\n try {\n await writeFile(filePath, result.newContent, 'utf-8');\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new RenumberError('WRITE_FAILED', `Failed to write ${filePath}: ${msg}`);\n }\n }\n }\n\n return { affectedFiles, totalReplacements };\n}\n\n/**\n * Collect unique file paths that may contain IDs needing replacement.\n * Includes all spec files (any may reference the code's IDs in matrices,\n * prose, or cross-references), extra spec files from extraSpecGlobs,\n * and code files with relevant markers.\n */\n// @awa-impl: RENUM-5_AC-1, RENUM-5_AC-2, RENUM-5_AC-3\nasync function collectFilePaths(\n map: RenumberMap,\n specs: SpecParseResult,\n markers: MarkerScanResult,\n config: CheckConfig,\n): Promise<string[]> {\n const paths = new Set<string>();\n const code = map.code;\n\n // Include all spec files — any may contain IDs in matrices, prose, or cross-refs.\n // The replacement pass efficiently skips files with no matches.\n // @awa-impl: RENUM-5_AC-1, RENUM-5_AC-3\n for (const specFile of specs.specFiles) {\n paths.add(specFile.filePath);\n }\n\n // Include extra spec files from extraSpecGlobs (custom files in .awa/ not matched by specGlobs)\n const combinedIgnore = [...config.specIgnore, ...config.extraSpecIgnore];\n const extraFiles = await collectFiles(config.extraSpecGlobs, combinedIgnore);\n for (const filePath of extraFiles) {\n paths.add(filePath);\n }\n\n // Add code/test files that have markers referencing affected IDs\n // @awa-impl: RENUM-5_AC-2\n const affectedIds = new Set(map.entries.keys());\n for (const marker of markers.markers) {\n if (affectedIds.has(marker.id) || hasCodePrefix(marker.id, code)) {\n paths.add(marker.filePath);\n }\n }\n\n return [...paths];\n}\n\n/**\n * Apply two-pass placeholder replacement to file content.\n * Pass 1: Replace old IDs with unique placeholders.\n * Pass 2: Replace placeholders with new IDs.\n * Uses whole-ID boundary matching to avoid partial replacements.\n */\n// @awa-impl: RENUM-6_AC-1, RENUM-6_AC-2\nfunction applyReplacements(\n content: string,\n map: RenumberMap,\n): { newContent: string; replacements: Replacement[] } {\n const replacements: Replacement[] = [];\n const lines = content.split('\\n');\n\n // Build sorted entries: replace longer IDs first to avoid partial matches\n const sortedEntries = [...map.entries].sort(([a], [b]) => b.length - a.length);\n\n // Build placeholder map: old ID → placeholder → new ID\n const placeholders = new Map<string, string>();\n const placeholderToNew = new Map<string, string>();\n for (const [oldId, newId] of sortedEntries) {\n const placeholder = `__RENUM_${placeholders.size}__`;\n placeholders.set(oldId, placeholder);\n placeholderToNew.set(placeholder, newId);\n }\n\n // Single pass per line: replace old IDs with placeholders, then placeholders with new IDs.\n // This avoids holding separate pass1Lines and pass2Lines arrays (reduces from 4× to 2× memory).\n for (let idx = 0; idx < lines.length; idx++) {\n let modified = lines[idx] as string;\n const origLine = modified;\n\n // Phase 1: Replace old IDs with placeholders and track replacements\n for (const [oldId, placeholder] of placeholders) {\n const regex = buildWholeIdRegex(oldId);\n // Count matches on original line for tracking\n const trackRegex = buildWholeIdRegex(oldId);\n while (trackRegex.exec(origLine) !== null) {\n replacements.push({\n line: idx + 1,\n oldId,\n newId: map.entries.get(oldId) ?? oldId,\n });\n }\n modified = modified.replace(regex, placeholder);\n }\n\n // Phase 2: Replace placeholders with new IDs\n for (const [placeholder, newId] of placeholderToNew) {\n modified = modified.replaceAll(placeholder, newId);\n }\n\n lines[idx] = modified;\n }\n\n // Deduplicate replacements per line (same oldId on same line counted once)\n const seen = new Set<string>();\n const dedupedReplacements = replacements.filter((r) => {\n const key = `${r.line}:${r.oldId}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n return { newContent: lines.join('\\n'), replacements: dedupedReplacements };\n}\n\n/**\n * Build a regex that matches a whole ID with boundary assertions.\n * Prevents partial matches within unrelated tokens.\n */\nfunction buildWholeIdRegex(id: string): RegExp {\n const escaped = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Word boundary won't work across hyphens/underscores, so use lookahead/lookbehind\n // Match the ID when not preceded or followed by alphanumeric, hyphen, underscore, or dot\n return new RegExp(`(?<![A-Za-z0-9_.-])${escaped}(?![A-Za-z0-9_.-])`, 'g');\n}\n\n/**\n * Check if an ID starts with the given feature code prefix.\n */\nfunction hasCodePrefix(id: string, code: string): boolean {\n return id.startsWith(`${code}-`) || id.startsWith(`${code}_`);\n}\n","// @awa-component: CLI-MarkerScanner\n// @awa-impl: CLI-28_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 // Pre-compile ignore patterns to RegExp objects to avoid re-creating them on every callback invocation\n const compiledIgnore = ignore.map((ig) => {\n const regex = ig\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<GLOBSTAR>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<GLOBSTAR>>/g, '.*');\n return new RegExp(`(^|/)${regex}($|/)`);\n });\n\n for (const pattern of globs) {\n for await (const filePath of glob(pattern, {\n exclude: (p) => dirPrefixes.includes(p) || compiledIgnore.some((re) => re.test(p)),\n })) {\n // Post-filter: fs.glob exclude only receives directory names,\n // so we must also filter the yielded file paths\n if (!compiledIgnore.some((re) => re.test(filePath))) {\n files.push(filePath);\n }\n }\n }\n\n return [...new Set(files)];\n}\n","// @awa-component: RENUM-Reporter\n// @awa-impl: RENUM-7_AC-1\n// @awa-impl: RENUM-11_AC-1\n\nimport type { RenumberResult } from './types.js';\n\n/**\n * Format renumber results as human-readable text.\n * In dry-run mode, prefixes output with a banner.\n */\n// @awa-impl: RENUM-7_AC-1\nexport function formatText(result: RenumberResult, dryRun: boolean): string {\n const lines: string[] = [];\n\n if (dryRun) {\n lines.push('DRY RUN — no files were modified\\n');\n }\n\n if (result.noChange) {\n lines.push(`${result.code}: no changes needed (IDs already sequential)`);\n return lines.join('\\n');\n }\n\n // Renumber map table\n lines.push(`${result.code}: ${result.map.entries.size} ID(s) renumbered\\n`);\n lines.push(' Old ID → New ID');\n lines.push(` ${'─'.repeat(40)}`);\n for (const [oldId, newId] of result.map.entries) {\n lines.push(` ${oldId} → ${newId}`);\n }\n\n // Affected files\n if (result.affectedFiles.length > 0) {\n lines.push('');\n lines.push(\n ` ${result.totalReplacements} replacement(s) in ${result.affectedFiles.length} file(s):`,\n );\n for (const file of result.affectedFiles) {\n lines.push(` ${file.filePath} (${file.replacements.length})`);\n }\n }\n\n // Malformed corrections\n if (result.malformedCorrections.length > 0) {\n lines.push('');\n lines.push(' Malformed ID corrections:');\n for (const c of result.malformedCorrections) {\n lines.push(` ${c.filePath}:${c.line} — ${c.token} → ${c.replacement}`);\n }\n }\n\n // Malformed warnings\n if (result.malformedWarnings.length > 0) {\n lines.push('');\n lines.push(' Malformed ID warnings:');\n for (const w of result.malformedWarnings) {\n lines.push(` ${w.filePath}:${w.line} — ${w.token}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format renumber results as JSON for CI consumption.\n */\n// @awa-impl: RENUM-11_AC-1\nexport function formatJson(result: RenumberResult): string {\n const output = {\n code: result.code,\n noChange: result.noChange,\n map: Object.fromEntries(result.map.entries),\n affectedFiles: result.affectedFiles.map((f) => ({\n filePath: f.filePath,\n replacements: f.replacements.map((r) => ({\n line: r.line,\n oldId: r.oldId,\n newId: r.newId,\n })),\n })),\n totalReplacements: result.totalReplacements,\n malformedCorrections: result.malformedCorrections.map((c) => ({\n filePath: c.filePath,\n line: c.line,\n token: c.token,\n replacement: c.replacement,\n })),\n malformedWarnings: result.malformedWarnings.map((w) => ({\n filePath: w.filePath,\n line: w.line,\n token: w.token,\n })),\n };\n\n return JSON.stringify(output, null, 2);\n}\n","// @awa-component: CLI-MarkerScanner\n// @awa-impl: CLI-16_AC-1\n// @awa-impl: CLI-26_AC-1\n// @awa-impl: CLI-28_AC-1\n\nimport { readFile } from 'node:fs/promises';\n\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: CLI-16_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: CLI-26_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+)?(?:[-_][A-Za-z0-9]+)*)/;\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: CLI-28_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: CLI-SpecParser\n// @awa-impl: CLI-17_AC-1\n// @awa-impl: CLI-27_AC-1\n\nimport { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\n\nimport { collectFiles } from './glob.js';\nimport type { CheckConfig, CrossReference, SpecFile, SpecParseResult } from './types.js';\n\n// @awa-impl: CLI-17_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 const componentImplements = new Map<string, string[]>();\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 // Track current component for building componentImplements map\n let currentComponent: string | null = null;\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 currentComponent = compMatch[1];\n }\n }\n\n // Any H2 or H1 heading resets the current component context\n if (/^#{1,2}\\s/.test(line) && !compMatch) {\n currentComponent = null;\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 // Build componentImplements map for IMPLEMENTS lines\n if (type === 'implements' && currentComponent) {\n const existing = componentImplements.get(currentComponent) ?? [];\n existing.push(...ids);\n componentImplements.set(currentComponent, existing);\n }\n }\n }\n }\n }\n\n return {\n filePath,\n code,\n requirementIds,\n acIds,\n propertyIds,\n componentNames,\n crossRefs,\n idLocations,\n componentImplements,\n content,\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|EXAMPLE|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: CLI-27_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: CLI-CheckCommand\n\n// @awa-impl: CLI-31_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 extraSpecGlobs: readonly string[];\n readonly extraSpecIgnore: 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 readonly fix: 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/EXAMPLE-*.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 extraSpecGlobs: ['.awa/**/*'],\n extraSpecIgnore: ['.awa/.agent/**'],\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 fix: true,\n};\n\nexport type FindingSeverity = 'error' | 'warning';\n\nexport type FindingCode =\n | 'orphaned-marker'\n | 'uncovered-ac'\n | 'uncovered-component'\n | 'uncovered-property'\n | 'unimplemented-ac'\n | 'unlinked-ac'\n | 'impl-not-in-implements'\n | 'implements-not-in-impl'\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 /** Maps component names to their IMPLEMENTS AC IDs. Populated for DESIGN files. */\n readonly componentImplements?: ReadonlyMap<string, readonly string[]>;\n /** Raw file content, cached by spec-parser to avoid re-reads in downstream phases. */\n readonly content?: string;\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 json?: boolean;\n readonly summary?: boolean;\n readonly config?: string;\n readonly allowWarnings?: boolean;\n readonly specOnly?: boolean;\n readonly fix?: boolean;\n}\n","// @awa-component: TRC-SharedScanner\n// @awa-impl: TRC-1_AC-1\n\nimport type { FileConfig } from '../../types/index.js';\nimport { scanMarkers } from '../check/marker-scanner.js';\nimport { parseSpecs } from '../check/spec-parser.js';\nimport type { CheckConfig, MarkerScanResult, SpecParseResult } from '../check/types.js';\nimport { DEFAULT_CHECK_CONFIG } from '../check/types.js';\nimport { configLoader } from '../config.js';\n\n/** Results from scanning markers and specs in parallel. */\nexport interface ScanResults {\n readonly markers: MarkerScanResult;\n readonly specs: SpecParseResult;\n readonly config: CheckConfig;\n}\n\n/**\n * Build a CheckConfig from file config + optional overrides.\n * Shared by trace, coverage, impact, and graph commands.\n */\nexport function buildScanConfig(\n fileConfig: FileConfig | null,\n overrides?: Partial<CheckConfig>,\n): CheckConfig {\n const section = fileConfig?.check;\n\n return {\n specGlobs: toStringArray(section?.['spec-globs']) ?? [...DEFAULT_CHECK_CONFIG.specGlobs],\n codeGlobs: toStringArray(section?.['code-globs']) ?? [...DEFAULT_CHECK_CONFIG.codeGlobs],\n specIgnore: toStringArray(section?.['spec-ignore']) ?? [...DEFAULT_CHECK_CONFIG.specIgnore],\n codeIgnore: toStringArray(section?.['code-ignore']) ?? [...DEFAULT_CHECK_CONFIG.codeIgnore],\n extraSpecGlobs: toStringArray(section?.['extra-spec-globs']) ?? [\n ...DEFAULT_CHECK_CONFIG.extraSpecGlobs,\n ],\n extraSpecIgnore: toStringArray(section?.['extra-spec-ignore']) ?? [\n ...DEFAULT_CHECK_CONFIG.extraSpecIgnore,\n ],\n ignoreMarkers: toStringArray(section?.['ignore-markers']) ?? [\n ...DEFAULT_CHECK_CONFIG.ignoreMarkers,\n ],\n markers: toStringArray(section?.markers) ?? [...DEFAULT_CHECK_CONFIG.markers],\n idPattern:\n typeof section?.['id-pattern'] === 'string'\n ? section['id-pattern']\n : DEFAULT_CHECK_CONFIG.idPattern,\n crossRefPatterns: toStringArray(section?.['cross-ref-patterns']) ?? [\n ...DEFAULT_CHECK_CONFIG.crossRefPatterns,\n ],\n format: DEFAULT_CHECK_CONFIG.format,\n schemaDir: DEFAULT_CHECK_CONFIG.schemaDir,\n schemaEnabled: false,\n allowWarnings: true,\n specOnly: false,\n fix: true,\n ...overrides,\n };\n}\n\n/**\n * Load config, scan markers and parse specs in parallel.\n * Shared by trace, coverage, impact, and graph commands.\n */\nexport async function scan(configPath?: string): Promise<ScanResults> {\n const fileConfig = await configLoader.load(configPath ?? null);\n const config = buildScanConfig(fileConfig);\n\n const [markers, specs] = await Promise.all([scanMarkers(config), parseSpecs(config)]);\n\n return { markers, specs, config };\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"],"mappings":"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","names":["readFile","writeFile","writeFile","readFile","readFile","readFile","basename","readFile","basename","readFile"]}
1
+ {"version":3,"sources":["../src/commands/renumber.ts","../src/core/renumber/malformed-detector.ts","../src/core/spec-file-utils.ts","../src/core/renumber/types.ts","../src/core/renumber/map-builder.ts","../src/core/renumber/propagator.ts","../src/core/check/glob.ts","../src/core/renumber/reporter.ts","../src/core/check/marker-scanner.ts","../src/core/check/spec-parser.ts","../src/core/check/types.ts","../src/core/trace/scanner.ts"],"sourcesContent":["// @awa-component: RENUM-RenumberCommand\n// @awa-impl: RENUM-8_AC-1, RENUM-8_AC-2\n// @awa-impl: RENUM-9_AC-1, RENUM-9_AC-2, RENUM-9_AC-3, RENUM-9_AC-4\n// @awa-impl: RENUM-10_AC-1\n\nimport { readFile } from 'node:fs/promises';\n\nimport { correctMalformed, detectMalformed } from '../core/renumber/malformed-detector.js';\nimport { buildRenumberMap } from '../core/renumber/map-builder.js';\nimport { propagate } from '../core/renumber/propagator.js';\nimport { formatJson, formatText } from '../core/renumber/reporter.js';\nimport type { RenumberCommandOptions, RenumberResult } from '../core/renumber/types.js';\nimport { RenumberError } from '../core/renumber/types.js';\nimport { scan } from '../core/trace/scanner.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Execute the `awa renumber` command.\n * Returns exit code: 0 = no changes needed, 1 = changes applied/previewed, 2 = error.\n */\n// @awa-impl: RENUM-10_AC-1\nexport async function renumberCommand(options: RenumberCommandOptions): Promise<number> {\n try {\n // @awa-impl: RENUM-9_AC-3\n if (!options.code && !options.all) {\n logger.error('No feature code or --all specified');\n return 2;\n }\n\n const { markers, specs, config } = await scan(options.config);\n\n // Determine which codes to renumber\n // @awa-impl: RENUM-8_AC-1\n let codes: string[];\n if (options.all) {\n codes = discoverFeatureCodes(specs.specFiles);\n if (codes.length === 0) {\n logger.warn('No feature codes discovered from REQ files');\n return 0;\n }\n } else {\n codes = [options.code as string];\n }\n\n const dryRun = options.dryRun === true;\n const fixMalformed = options.expandUnambiguousIds === true;\n const results: RenumberResult[] = [];\n let hasChanges = false;\n\n // @awa-impl: RENUM-8_AC-2\n for (const code of codes) {\n try {\n const result = await runRenumberPipeline(\n code,\n specs,\n markers,\n config,\n dryRun,\n fixMalformed,\n );\n results.push(result);\n if (!result.noChange) {\n hasChanges = true;\n }\n } catch (err) {\n if (err instanceof RenumberError && err.errorCode === 'CODE_NOT_FOUND') {\n // @awa-impl: RENUM-9_AC-4\n logger.error(err.message);\n return 2;\n }\n throw err;\n }\n }\n\n // Output results\n if (options.json) {\n // JSON mode: output array if --all, single object otherwise\n if (results.length === 1) {\n const first = results[0] as RenumberResult;\n process.stdout.write(`${formatJson(first)}\\n`);\n } else {\n const jsonArray = results.map((r) => JSON.parse(formatJson(r)));\n process.stdout.write(`${JSON.stringify(jsonArray, null, 2)}\\n`);\n }\n } else {\n for (const result of results) {\n const text = formatText(result, dryRun);\n logger.info(text);\n }\n }\n\n // @awa-impl: RENUM-10_AC-1\n return hasChanges ? 1 : 0;\n } catch (err) {\n if (err instanceof RenumberError) {\n logger.error(err.message);\n return 2;\n }\n if (err instanceof Error) {\n logger.error(err.message);\n } else {\n logger.error(String(err));\n }\n return 2;\n }\n}\n\n/**\n * Run the renumber pipeline for a single feature code.\n */\n// @awa-impl: RENUM-9_AC-1\nasync function runRenumberPipeline(\n code: string,\n specs: import('../core/check/types.js').SpecParseResult,\n markers: import('../core/check/types.js').MarkerScanResult,\n config: import('../core/check/types.js').CheckConfig,\n dryRun: boolean,\n fixMalformed: boolean,\n): Promise<RenumberResult> {\n // Build renumber map\n const { map, noChange } = buildRenumberMap(code, specs);\n\n if (noChange) {\n return {\n code,\n map,\n affectedFiles: [],\n totalReplacements: 0,\n malformedWarnings: [],\n malformedCorrections: [],\n noChange: true,\n };\n }\n\n // Detect malformed IDs from spec and code files\n const fileContents = await collectFileContents(specs, markers, code);\n const allWarnings = detectMalformed(code, fileContents);\n\n // Optionally correct unambiguous malformed IDs before propagation\n let malformedWarnings: readonly import('../core/renumber/types.js').MalformedWarning[];\n let malformedCorrections: readonly import('../core/renumber/types.js').MalformedCorrection[];\n\n if (fixMalformed && allWarnings.length > 0) {\n const result = await correctMalformed(code, allWarnings, fileContents, dryRun);\n malformedCorrections = result.corrections;\n malformedWarnings = result.remainingWarnings;\n } else {\n malformedWarnings = allWarnings;\n malformedCorrections = [];\n }\n\n // Propagate changes (after corrections so corrected IDs get renumbered)\n const { affectedFiles, totalReplacements } = await propagate(map, specs, markers, config, dryRun);\n\n return {\n code,\n map,\n affectedFiles,\n totalReplacements,\n malformedWarnings,\n malformedCorrections,\n noChange: false,\n };\n}\n\n/**\n * Discover all feature codes from REQ files.\n */\nfunction discoverFeatureCodes(\n specFiles: readonly import('../core/check/types.js').SpecFile[],\n): string[] {\n const codes = new Set<string>();\n for (const sf of specFiles) {\n if (sf.code && /^REQ-/.test(sf.filePath.split('/').pop() ?? '')) {\n codes.add(sf.code);\n }\n }\n return [...codes].sort();\n}\n\n/**\n * Collect file contents for malformed detection.\n * Reads spec files and code files that have markers for the given code.\n */\nasync function collectFileContents(\n specs: import('../core/check/types.js').SpecParseResult,\n markers: import('../core/check/types.js').MarkerScanResult,\n code: string,\n): Promise<Map<string, string>> {\n const paths = new Set<string>();\n\n // Add spec files\n for (const sf of specs.specFiles) {\n paths.add(sf.filePath);\n }\n\n // Add code files with markers starting with the code prefix\n for (const m of markers.markers) {\n if (m.id.startsWith(`${code}-`) || m.id.startsWith(`${code}_`)) {\n paths.add(m.filePath);\n }\n }\n\n const contents = new Map<string, string>();\n for (const p of paths) {\n try {\n const content = await readFile(p, 'utf-8');\n contents.set(p, content);\n } catch {\n // Skip unreadable files\n }\n }\n\n return contents;\n}\n","// @awa-component: RENUM-MalformedDetector\n// @awa-impl: RENUM-12_AC-1, RENUM-12_AC-2, RENUM-12_AC-3\n\nimport { writeFile } from 'node:fs/promises';\n\nimport type { MalformedCorrection, MalformedWarning } from './types.js';\n\n/**\n * Standard ID patterns that are considered valid.\n * - CODE-N (requirement)\n * - CODE-N.P (subrequirement)\n * - CODE-N_AC-M or CODE-N.P_AC-M (acceptance criterion)\n * - CODE_P-N (property)\n * - CODE-ComponentName (component — PascalCase name after code)\n */\nconst VALID_ID_RE = /^[A-Z][A-Z0-9]*(?:-\\d+(?:\\.\\d+)?(?:_AC-\\d+)?|_P-\\d+|-[A-Z][a-zA-Z0-9]*)$/;\n\n/**\n * Patterns that can be unambiguously expanded into valid IDs:\n *\n * - Slash ranges on ACs: CODE-N_AC-M/P or CODE-N.S_AC-M/P\n * e.g. ARC-36_AC-8/9 → ARC-36_AC-8, ARC-36_AC-9\n *\n * - Dot-dot ranges on ACs: CODE-N_AC-M..P or CODE-N.S_AC-M..P\n * e.g. ARC-18_AC-14..16 → ARC-18_AC-14, ARC-18_AC-15, ARC-18_AC-16\n */\n\n/** Slash range on ACs: e.g. ARC-36_AC-8/9 */\nconst SLASH_RANGE_RE = /^([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?_AC-)(\\d+)\\/(\\d+)$/;\n\n/** Dot-dot range on ACs: e.g. ARC-18_AC-14..16 */\nconst DOT_DOT_AC_RANGE_RE = /^([A-Z][A-Z0-9]*-\\d+(?:\\.\\d+)?_AC-)(\\d+)\\.\\.(\\d+)$/;\n\n/**\n * Detect tokens that start with the feature code prefix but do not conform\n * to standard ID formats. Reports each as a warning with location.\n */\n// @awa-impl: RENUM-12_AC-1, RENUM-12_AC-2\nexport function detectMalformed(\n code: string,\n fileContents: ReadonlyMap<string, string>,\n): readonly MalformedWarning[] {\n const warnings: MalformedWarning[] = [];\n\n // Match tokens that structurally resemble IDs:\n // CODE-<Uppercase-or-digit>... (requirement-like or component-like)\n // CODE_P-... (property-like)\n // Tokens like CODE-lowercase (e.g. CLI-provided) are natural language, not IDs.\n const esc = escapeRegex(code);\n const tokenRegex = new RegExp(\n `(?<![A-Za-z0-9_.-])(?:${esc}-[A-Z0-9][A-Za-z0-9_./-]*|${esc}_P-[A-Za-z0-9_./-]+)`,\n 'g',\n );\n\n for (const [filePath, content] of fileContents) {\n const lines = content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] as string;\n let match: RegExpExecArray | null;\n while ((match = tokenRegex.exec(line)) !== null) {\n const token = match[0];\n // @awa-impl: RENUM-12_AC-3\n if (!VALID_ID_RE.test(token)) {\n warnings.push({ filePath, line: i + 1, token });\n }\n }\n }\n }\n\n return warnings;\n}\n\n/**\n * Attempt to expand a single malformed token into its corrected replacement string.\n * Returns the replacement string if unambiguous, or `undefined` if the pattern\n * is ambiguous and should remain as a warning only.\n *\n * Correctable patterns:\n * - Slash ranges: CODE-N_AC-M/P → \"CODE-N_AC-M, CODE-N_AC-P\"\n * - Dot-dot AC ranges: CODE-N_AC-M..P → \"CODE-N_AC-M, CODE-N_AC-M+1, ..., CODE-N_AC-P\"\n *\n * Ambiguous / ignored patterns (return undefined):\n * - Trailing periods (e.g. ARC_P-206.) — likely end of sentence\n * - Letter suffixes (e.g. ARC-18_AC-7a)\n * - Full-ID ranges (e.g. ARC-20..ARC-25)\n * - Component + period (e.g. ARC-ChunkedTransferManager.)\n */\nexport function expandMalformedToken(token: string): string | undefined {\n // Try slash range: CODE-N_AC-M/P\n const slashMatch = SLASH_RANGE_RE.exec(token);\n if (slashMatch) {\n const [, prefix, startStr, endStr] = slashMatch as RegExpExecArray &\n [string, string, string, string];\n return `${prefix}${startStr}, ${prefix}${endStr}`;\n }\n\n // Try dot-dot AC range: CODE-N_AC-M..P\n const dotDotMatch = DOT_DOT_AC_RANGE_RE.exec(token);\n if (dotDotMatch) {\n const [, prefix, startStr, endStr] = dotDotMatch as RegExpExecArray &\n [string, string, string, string];\n const start = Number(startStr);\n const end = Number(endStr);\n if (end <= start) return undefined; // Invalid range\n const ids: string[] = [];\n for (let n = start; n <= end; n++) {\n ids.push(`${prefix}${n}`);\n }\n return ids.join(', ');\n }\n\n // All other patterns are ambiguous — do not correct\n return undefined;\n}\n\n/**\n * Apply malformed ID corrections to file contents.\n * Only corrects tokens for which `expandMalformedToken` returns a value.\n * Returns the list of corrections applied and the updated file contents map.\n *\n * When `dryRun` is true, files are not written to disk but corrections are\n * still computed and returned for preview.\n */\nexport async function correctMalformed(\n _code: string,\n warnings: readonly MalformedWarning[],\n fileContents: ReadonlyMap<string, string>,\n dryRun: boolean,\n): Promise<{\n corrections: readonly MalformedCorrection[];\n remainingWarnings: readonly MalformedWarning[];\n}> {\n const corrections: MalformedCorrection[] = [];\n const remainingWarnings: MalformedWarning[] = [];\n\n // Group warnings by file for efficient batch replacement\n const warningsByFile = new Map<string, MalformedWarning[]>();\n for (const w of warnings) {\n const existing = warningsByFile.get(w.filePath) ?? [];\n existing.push(w);\n warningsByFile.set(w.filePath, existing);\n }\n\n // Track files that need writing\n const modifiedFiles = new Map<string, string>();\n\n for (const [filePath, fileWarnings] of warningsByFile) {\n const original = fileContents.get(filePath);\n if (original === undefined) {\n // Cannot correct — keep as warnings\n remainingWarnings.push(...fileWarnings);\n continue;\n }\n\n let content: string = original;\n\n for (const w of fileWarnings) {\n const replacement = expandMalformedToken(w.token);\n if (replacement === undefined) {\n remainingWarnings.push(w);\n continue;\n }\n\n // Replace the token in content (whole-token match to avoid partial substitution)\n const escaped = escapeRegex(w.token);\n const regex = new RegExp(`(?<![A-Za-z0-9_.-])${escaped}(?![A-Za-z0-9_.-])`, 'g');\n const updated: string = content.replace(regex, replacement);\n if (updated !== content) {\n content = updated;\n corrections.push({\n filePath: w.filePath,\n line: w.line,\n token: w.token,\n replacement,\n });\n } else {\n // Token not found in content (unexpected) — keep as warning\n remainingWarnings.push(w);\n }\n }\n\n if (content !== original) {\n modifiedFiles.set(filePath, content);\n }\n }\n\n // Write modified files unless dry-run\n if (!dryRun) {\n for (const [filePath, content] of modifiedFiles) {\n await writeFile(filePath, content, 'utf-8');\n }\n }\n\n return { corrections, remainingWarnings };\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","// @awa-impl: RENUM-1_AC-1\n// @awa-impl: RCOD-1_AC-1\n\nimport { basename } from 'node:path';\n\nimport type { SpecFile } from './check/types.js';\n\n/**\n * Find all spec files matching a feature code and file type prefix.\n * Returns files sorted alphabetically by basename for deterministic ordering.\n */\nexport function findSpecFiles(\n specFiles: readonly SpecFile[],\n code: string,\n prefix: string,\n): SpecFile[] {\n return specFiles\n .filter((sf) => {\n const name = basename(sf.filePath);\n return name.startsWith(`${prefix}-${code}-`);\n })\n .sort((a, b) => basename(a.filePath).localeCompare(basename(b.filePath)));\n}\n\n/**\n * Find the first spec file matching a feature code and file type prefix.\n * Convenience wrapper over findSpecFiles for cases needing a single match.\n */\nexport function findSpecFile(\n specFiles: readonly SpecFile[],\n code: string,\n prefix: string,\n): SpecFile | undefined {\n return findSpecFiles(specFiles, code, prefix)[0];\n}\n\n/** Known spec file prefixes that carry a feature code. */\nexport const SPEC_PREFIXES = ['FEAT', 'REQ', 'DESIGN', 'EXAMPLE', 'API', 'TASK'] as const;\n\n/**\n * Check whether at least one spec file exists for the given feature code.\n */\nexport function hasAnySpecFile(specFiles: readonly SpecFile[], code: string): boolean {\n return specFiles.some((sf) => {\n const name = basename(sf.filePath);\n return SPEC_PREFIXES.some((prefix) => name.startsWith(`${prefix}-${code}-`));\n });\n}\n","// Types shared across the renumber module.\n// Components are declared in their respective implementation files.\n\n/**\n * Mapping from old ID strings to new ID strings for one feature code.\n */\nexport interface RenumberMap {\n readonly code: string;\n readonly entries: ReadonlyMap<string, string>;\n}\n\n/**\n * A file touched by propagation with per-line replacement details.\n */\nexport interface AffectedFile {\n readonly filePath: string;\n readonly replacements: readonly Replacement[];\n}\n\n/**\n * A single ID replacement within a file.\n */\nexport interface Replacement {\n readonly line: number;\n readonly oldId: string;\n readonly newId: string;\n}\n\n/**\n * Aggregated output of the renumber pipeline for one feature code.\n */\nexport interface RenumberResult {\n readonly code: string;\n readonly map: RenumberMap;\n readonly affectedFiles: readonly AffectedFile[];\n readonly totalReplacements: number;\n readonly malformedWarnings: readonly MalformedWarning[];\n readonly malformedCorrections: readonly MalformedCorrection[];\n readonly noChange: boolean;\n}\n\n/**\n * CLI options passed to the renumber command.\n */\nexport interface RenumberCommandOptions {\n readonly code?: string;\n readonly all?: boolean;\n readonly dryRun?: boolean;\n readonly json?: boolean;\n readonly config?: string;\n readonly expandUnambiguousIds?: boolean;\n}\n\n/**\n * Warning about a malformed ID token.\n */\nexport interface MalformedWarning {\n readonly filePath: string;\n readonly line: number;\n readonly token: string;\n}\n\n/**\n * A correction applied to a malformed ID token.\n */\nexport interface MalformedCorrection {\n readonly filePath: string;\n readonly line: number;\n readonly token: string;\n readonly replacement: string;\n}\n\n/**\n * Result of map building.\n */\nexport interface MapBuildResult {\n readonly map: RenumberMap;\n readonly noChange: boolean;\n}\n\n/**\n * Result of propagation.\n */\nexport interface PropagationResult {\n readonly affectedFiles: readonly AffectedFile[];\n readonly totalReplacements: number;\n}\n\n// --- Error types ---\n\nexport type RenumberErrorCode = 'CODE_NOT_FOUND' | 'NO_ARGS' | 'WRITE_FAILED';\n\nexport class RenumberError extends Error {\n readonly errorCode: RenumberErrorCode;\n\n constructor(errorCode: RenumberErrorCode, message: string) {\n super(message);\n this.name = 'RenumberError';\n this.errorCode = errorCode;\n }\n}\n","// @awa-component: RENUM-MapBuilder\n// @awa-impl: RENUM-1_AC-1, RENUM-1_AC-2, RENUM-1_AC-3\n// @awa-impl: RENUM-2_AC-1, RENUM-2_AC-2\n// @awa-impl: RENUM-3_AC-1, RENUM-3_AC-2\n// @awa-impl: RENUM-4_AC-1, RENUM-4_AC-2\n\nimport type { SpecFile, SpecParseResult } from '../check/types.js';\nimport { findSpecFiles } from '../spec-file-utils.js';\nimport type { MapBuildResult, RenumberMap } from './types.js';\nimport { RenumberError } from './types.js';\n\n/**\n * Build a renumber map by walking ALL REQ and DESIGN files in document order.\n * Files are sorted alphabetically by basename. Requirements and properties are\n * numbered globally across all files for the feature code.\n */\n// @awa-impl: RENUM-1_AC-1\nexport function buildRenumberMap(code: string, specs: SpecParseResult): MapBuildResult {\n const reqFiles = findSpecFiles(specs.specFiles, code, 'REQ');\n if (reqFiles.length === 0) {\n throw new RenumberError('CODE_NOT_FOUND', `No REQ file found for feature code: ${code}`);\n }\n\n const entries = new Map<string, string>();\n\n // Walk ALL REQ files in alphabetical order for requirements, subrequirements, and ACs\n buildRequirementEntries(code, reqFiles, entries);\n\n // Walk ALL DESIGN files in alphabetical order for properties\n // @awa-impl: RENUM-4_AC-1, RENUM-4_AC-2\n const designFiles = findSpecFiles(specs.specFiles, code, 'DESIGN');\n if (designFiles.length > 0) {\n buildPropertyEntries(code, designFiles, entries);\n }\n // If no DESIGN file exists, skip property renumbering without error (RENUM-4_AC-2)\n\n // Remove identity mappings (old === new)\n for (const [oldId, newId] of entries) {\n if (oldId === newId) {\n entries.delete(oldId);\n }\n }\n\n // @awa-impl: RENUM-1_AC-3\n const noChange = entries.size === 0;\n\n const map: RenumberMap = { code, entries };\n return { map, noChange };\n}\n\n/**\n * Build renumber entries for requirements, subrequirements, and ACs from all REQ files.\n * Files are processed in the order given (already sorted alphabetically).\n * IDs are numbered globally across all files.\n */\n// @awa-impl: RENUM-1_AC-2, RENUM-2_AC-1, RENUM-2_AC-2, RENUM-3_AC-1, RENUM-3_AC-2\nfunction buildRequirementEntries(\n code: string,\n reqFiles: readonly SpecFile[],\n entries: Map<string, string>,\n): void {\n // Collect all requirements and subrequirements across files in order\n const topLevelReqs: string[] = [];\n const subReqsByParent = new Map<string, string[]>();\n const allAcIds: string[] = [];\n\n for (const reqFile of reqFiles) {\n for (const id of reqFile.requirementIds) {\n if (id.includes('.')) {\n const dotIdx = id.lastIndexOf('.');\n const parent = id.slice(0, dotIdx);\n const subs = subReqsByParent.get(parent) ?? [];\n subs.push(id);\n subReqsByParent.set(parent, subs);\n } else {\n topLevelReqs.push(id);\n }\n }\n for (const acId of reqFile.acIds) {\n allAcIds.push(acId);\n }\n }\n\n // Build old→new mapping for top-level requirements\n const reqNumberMap = new Map<string, number>(); // old req ID → new number\n for (let i = 0; i < topLevelReqs.length; i++) {\n const oldId = topLevelReqs[i] as string;\n const newNum = i + 1;\n const newId = `${code}-${newNum}`;\n entries.set(oldId, newId);\n reqNumberMap.set(oldId, newNum);\n }\n\n // Build old→new mapping for subrequirements within each parent\n for (const oldParentId of topLevelReqs) {\n const subs = subReqsByParent.get(oldParentId);\n if (!subs) continue;\n\n const newParentNum = reqNumberMap.get(oldParentId);\n if (newParentNum === undefined) continue;\n\n for (let j = 0; j < subs.length; j++) {\n const oldSubId = subs[j] as string;\n const newSubNum = j + 1;\n const newSubId = `${code}-${newParentNum}.${newSubNum}`;\n entries.set(oldSubId, newSubId);\n }\n }\n\n // Build AC mapping: group ACs by their parent (req or subreq)\n const acsByParent = new Map<string, string[]>();\n for (const acId of allAcIds) {\n const parent = acId.split('_AC-')[0] as string;\n const acs = acsByParent.get(parent) ?? [];\n acs.push(acId);\n acsByParent.set(parent, acs);\n }\n\n // Renumber ACs within each parent\n for (const [oldParentId, acs] of acsByParent) {\n // Determine the new parent ID\n const newParentId = entries.get(oldParentId) ?? oldParentId;\n\n for (let k = 0; k < acs.length; k++) {\n const oldAcId = acs[k] as string;\n const newAcNum = k + 1;\n const newAcId = `${newParentId}_AC-${newAcNum}`;\n entries.set(oldAcId, newAcId);\n }\n }\n}\n\n/**\n * Build renumber entries for properties from all DESIGN files.\n * Files are processed in the order given (already sorted alphabetically).\n * Properties are numbered globally across all files.\n */\nfunction buildPropertyEntries(\n code: string,\n designFiles: readonly SpecFile[],\n entries: Map<string, string>,\n): void {\n let counter = 0;\n for (const designFile of designFiles) {\n for (const oldId of designFile.propertyIds) {\n counter++;\n const newId = `${code}_P-${counter}`;\n entries.set(oldId, newId);\n }\n }\n}\n","// @awa-component: RENUM-Propagator\n// @awa-impl: RENUM-5_AC-1, RENUM-5_AC-2, RENUM-5_AC-3\n// @awa-impl: RENUM-6_AC-1, RENUM-6_AC-2\n\nimport { readFile, writeFile } from 'node:fs/promises';\n\nimport { collectFiles } from '../check/glob.js';\nimport type { CheckConfig, MarkerScanResult, SpecParseResult } from '../check/types.js';\nimport type { AffectedFile, PropagationResult, RenumberMap, Replacement } from './types.js';\nimport { RenumberError } from './types.js';\n\n/**\n * Apply the renumber map across all spec files and code files.\n * Uses two-pass placeholder replacement to avoid swap collisions.\n */\nexport async function propagate(\n map: RenumberMap,\n specs: SpecParseResult,\n markers: MarkerScanResult,\n config: CheckConfig,\n dryRun: boolean,\n): Promise<PropagationResult> {\n if (map.entries.size === 0) {\n return { affectedFiles: [], totalReplacements: 0 };\n }\n\n // Collect all file paths that need scanning\n const filePaths = await collectFilePaths(map, specs, markers, config);\n\n const affectedFiles: AffectedFile[] = [];\n let totalReplacements = 0;\n\n for (const filePath of filePaths) {\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n continue; // Skip unreadable files\n }\n\n const result = applyReplacements(content, map);\n if (result.replacements.length === 0) continue;\n\n affectedFiles.push({ filePath, replacements: result.replacements });\n totalReplacements += result.replacements.length;\n\n if (!dryRun) {\n try {\n await writeFile(filePath, result.newContent, 'utf-8');\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new RenumberError('WRITE_FAILED', `Failed to write ${filePath}: ${msg}`);\n }\n }\n }\n\n return { affectedFiles, totalReplacements };\n}\n\n/**\n * Collect unique file paths that may contain IDs needing replacement.\n * Includes all spec files (any may reference the code's IDs in matrices,\n * prose, or cross-references), extra spec files from extraSpecGlobs,\n * and code files with relevant markers.\n */\n// @awa-impl: RENUM-5_AC-1, RENUM-5_AC-2, RENUM-5_AC-3\nasync function collectFilePaths(\n map: RenumberMap,\n specs: SpecParseResult,\n markers: MarkerScanResult,\n config: CheckConfig,\n): Promise<string[]> {\n const paths = new Set<string>();\n const code = map.code;\n\n // Include all spec files — any may contain IDs in matrices, prose, or cross-refs.\n // The replacement pass efficiently skips files with no matches.\n // @awa-impl: RENUM-5_AC-1, RENUM-5_AC-3\n for (const specFile of specs.specFiles) {\n paths.add(specFile.filePath);\n }\n\n // Include extra spec files from extraSpecGlobs (custom files in .awa/ not matched by specGlobs)\n const combinedIgnore = [...config.specIgnore, ...config.extraSpecIgnore];\n const extraFiles = await collectFiles(config.extraSpecGlobs, combinedIgnore);\n for (const filePath of extraFiles) {\n paths.add(filePath);\n }\n\n // Add code/test files that have markers referencing affected IDs\n // @awa-impl: RENUM-5_AC-2\n const affectedIds = new Set(map.entries.keys());\n for (const marker of markers.markers) {\n if (affectedIds.has(marker.id) || hasCodePrefix(marker.id, code)) {\n paths.add(marker.filePath);\n }\n }\n\n return [...paths];\n}\n\n/**\n * Apply two-pass placeholder replacement to file content.\n * Pass 1: Replace old IDs with unique placeholders.\n * Pass 2: Replace placeholders with new IDs.\n * Uses whole-ID boundary matching to avoid partial replacements.\n */\n// @awa-impl: RENUM-6_AC-1, RENUM-6_AC-2\nfunction applyReplacements(\n content: string,\n map: RenumberMap,\n): { newContent: string; replacements: Replacement[] } {\n const replacements: Replacement[] = [];\n const lines = content.split('\\n');\n\n // Build sorted entries: replace longer IDs first to avoid partial matches\n const sortedEntries = [...map.entries].sort(([a], [b]) => b.length - a.length);\n\n // Build placeholder map: old ID → placeholder → new ID\n const placeholders = new Map<string, string>();\n const placeholderToNew = new Map<string, string>();\n for (const [oldId, newId] of sortedEntries) {\n const placeholder = `__RENUM_${placeholders.size}__`;\n placeholders.set(oldId, placeholder);\n placeholderToNew.set(placeholder, newId);\n }\n\n // Single pass per line: replace old IDs with placeholders, then placeholders with new IDs.\n // This avoids holding separate pass1Lines and pass2Lines arrays (reduces from 4× to 2× memory).\n for (let idx = 0; idx < lines.length; idx++) {\n let modified = lines[idx] as string;\n const origLine = modified;\n\n // Phase 1: Replace old IDs with placeholders and track replacements\n for (const [oldId, placeholder] of placeholders) {\n const regex = buildWholeIdRegex(oldId);\n // Count matches on original line for tracking\n const trackRegex = buildWholeIdRegex(oldId);\n while (trackRegex.exec(origLine) !== null) {\n replacements.push({\n line: idx + 1,\n oldId,\n newId: map.entries.get(oldId) ?? oldId,\n });\n }\n modified = modified.replace(regex, placeholder);\n }\n\n // Phase 2: Replace placeholders with new IDs\n for (const [placeholder, newId] of placeholderToNew) {\n modified = modified.replaceAll(placeholder, newId);\n }\n\n lines[idx] = modified;\n }\n\n // Deduplicate replacements per line (same oldId on same line counted once)\n const seen = new Set<string>();\n const dedupedReplacements = replacements.filter((r) => {\n const key = `${r.line}:${r.oldId}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n return { newContent: lines.join('\\n'), replacements: dedupedReplacements };\n}\n\n/**\n * Build a regex that matches a whole ID with boundary assertions.\n * Prevents partial matches within unrelated tokens.\n */\nfunction buildWholeIdRegex(id: string): RegExp {\n const escaped = id.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Word boundary won't work across hyphens/underscores, so use lookahead/lookbehind\n // Match the ID when not preceded or followed by alphanumeric, hyphen, underscore, or dot\n return new RegExp(`(?<![A-Za-z0-9_.-])${escaped}(?![A-Za-z0-9_.-])`, 'g');\n}\n\n/**\n * Check if an ID starts with the given feature code prefix.\n */\nfunction hasCodePrefix(id: string, code: string): boolean {\n return id.startsWith(`${code}-`) || id.startsWith(`${code}_`);\n}\n","// @awa-component: CLI-MarkerScanner\n// @awa-impl: CLI-28_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 // Pre-compile ignore patterns to RegExp objects to avoid re-creating them on every callback invocation\n const compiledIgnore = ignore.map((ig) => {\n const regex = ig\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<GLOBSTAR>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<GLOBSTAR>>/g, '.*');\n return new RegExp(`(^|/)${regex}($|/)`);\n });\n\n for (const pattern of globs) {\n for await (const filePath of glob(pattern, {\n exclude: (p) => dirPrefixes.includes(p) || compiledIgnore.some((re) => re.test(p)),\n })) {\n // Post-filter: fs.glob exclude only receives directory names,\n // so we must also filter the yielded file paths\n if (!compiledIgnore.some((re) => re.test(filePath))) {\n files.push(filePath);\n }\n }\n }\n\n return [...new Set(files)];\n}\n","// @awa-component: RENUM-Reporter\n// @awa-impl: RENUM-7_AC-1\n// @awa-impl: RENUM-11_AC-1\n\nimport type { RenumberResult } from './types.js';\n\n/**\n * Format renumber results as human-readable text.\n * In dry-run mode, prefixes output with a banner.\n */\n// @awa-impl: RENUM-7_AC-1\nexport function formatText(result: RenumberResult, dryRun: boolean): string {\n const lines: string[] = [];\n\n if (dryRun) {\n lines.push('DRY RUN — no files were modified\\n');\n }\n\n if (result.noChange) {\n lines.push(`${result.code}: no changes needed (IDs already sequential)`);\n return lines.join('\\n');\n }\n\n // Renumber map table\n lines.push(`${result.code}: ${result.map.entries.size} ID(s) renumbered\\n`);\n lines.push(' Old ID → New ID');\n lines.push(` ${'─'.repeat(40)}`);\n for (const [oldId, newId] of result.map.entries) {\n lines.push(` ${oldId} → ${newId}`);\n }\n\n // Affected files\n if (result.affectedFiles.length > 0) {\n lines.push('');\n lines.push(\n ` ${result.totalReplacements} replacement(s) in ${result.affectedFiles.length} file(s):`,\n );\n for (const file of result.affectedFiles) {\n lines.push(` ${file.filePath} (${file.replacements.length})`);\n }\n }\n\n // Malformed corrections\n if (result.malformedCorrections.length > 0) {\n lines.push('');\n lines.push(' Malformed ID corrections:');\n for (const c of result.malformedCorrections) {\n lines.push(` ${c.filePath}:${c.line} — ${c.token} → ${c.replacement}`);\n }\n }\n\n // Malformed warnings\n if (result.malformedWarnings.length > 0) {\n lines.push('');\n lines.push(' Malformed ID warnings:');\n for (const w of result.malformedWarnings) {\n lines.push(` ${w.filePath}:${w.line} — ${w.token}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format renumber results as JSON for CI consumption.\n */\n// @awa-impl: RENUM-11_AC-1\nexport function formatJson(result: RenumberResult): string {\n const output = {\n code: result.code,\n noChange: result.noChange,\n map: Object.fromEntries(result.map.entries),\n affectedFiles: result.affectedFiles.map((f) => ({\n filePath: f.filePath,\n replacements: f.replacements.map((r) => ({\n line: r.line,\n oldId: r.oldId,\n newId: r.newId,\n })),\n })),\n totalReplacements: result.totalReplacements,\n malformedCorrections: result.malformedCorrections.map((c) => ({\n filePath: c.filePath,\n line: c.line,\n token: c.token,\n replacement: c.replacement,\n })),\n malformedWarnings: result.malformedWarnings.map((w) => ({\n filePath: w.filePath,\n line: w.line,\n token: w.token,\n })),\n };\n\n return JSON.stringify(output, null, 2);\n}\n","// @awa-component: CLI-MarkerScanner\n// @awa-impl: CLI-16_AC-1\n// @awa-impl: CLI-26_AC-1\n// @awa-impl: CLI-28_AC-1\n\nimport { readFile } from 'node:fs/promises';\n\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: CLI-16_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: CLI-26_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+)?(?:[-_][A-Za-z0-9]+)*)/;\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: CLI-28_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: CLI-SpecParser\n// @awa-impl: CLI-17_AC-1\n// @awa-impl: CLI-27_AC-1\n\nimport { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\n\nimport { collectFiles } from './glob.js';\nimport type { CheckConfig, CrossReference, SpecFile, SpecParseResult } from './types.js';\n\n// @awa-impl: CLI-17_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 const componentImplements = new Map<string, string[]>();\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 // Track current component for building componentImplements map\n let currentComponent: string | null = null;\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 currentComponent = compMatch[1];\n }\n }\n\n // Any H2 or H1 heading resets the current component context\n if (/^#{1,2}\\s/.test(line) && !compMatch) {\n currentComponent = null;\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 // Build componentImplements map for IMPLEMENTS lines\n if (type === 'implements' && currentComponent) {\n const existing = componentImplements.get(currentComponent) ?? [];\n existing.push(...ids);\n componentImplements.set(currentComponent, existing);\n }\n }\n }\n }\n }\n\n return {\n filePath,\n code,\n requirementIds,\n acIds,\n propertyIds,\n componentNames,\n crossRefs,\n idLocations,\n componentImplements,\n content,\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|EXAMPLE|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: CLI-27_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: CLI-CheckCommand\n\n// @awa-impl: CLI-31_AC-1\n\n// @awa-component: DEP-SchemaValidation\n// @awa-impl: DEP-7_AC-1\n// @awa-impl: DEP-7_AC-2\n\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 extraSpecGlobs: readonly string[];\n readonly extraSpecIgnore: 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 readonly fix: boolean;\n readonly deprecated: 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/EXAMPLE-*.md',\n '.awa/specs/API-*.tsp',\n '.awa/tasks/TASK-*.md',\n '.awa/plans/PLAN-*.md',\n '.awa/align/ALIGN-*.md',\n '.awa/specs/deprecated/DEPRECATED.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 extraSpecGlobs: ['.awa/**/*'],\n extraSpecIgnore: ['.awa/.agent/**'],\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 fix: true,\n deprecated: false,\n};\n\nexport type FindingSeverity = 'error' | 'warning';\n\nexport type FindingCode =\n | 'orphaned-marker'\n | 'uncovered-ac'\n | 'uncovered-component'\n | 'uncovered-property'\n | 'unimplemented-ac'\n | 'unlinked-ac'\n | 'impl-not-in-implements'\n | 'implements-not-in-impl'\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 | 'deprecated-ref'\n | 'deprecated-id-conflict';\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 /** Maps component names to their IMPLEMENTS AC IDs. Populated for DESIGN files. */\n readonly componentImplements?: ReadonlyMap<string, readonly string[]>;\n /** Raw file content, cached by spec-parser to avoid re-reads in downstream phases. */\n readonly content?: string;\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 DeprecatedResult {\n readonly deprecatedIds: ReadonlySet<string>;\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 json?: boolean;\n readonly summary?: boolean;\n readonly config?: string;\n readonly allowWarnings?: boolean;\n readonly specOnly?: boolean;\n readonly fix?: boolean;\n readonly deprecated?: boolean;\n}\n","// @awa-component: TRC-SharedScanner\n// @awa-impl: TRC-1_AC-1\n\nimport type { FileConfig } from '../../types/index.js';\nimport { scanMarkers } from '../check/marker-scanner.js';\nimport { parseSpecs } from '../check/spec-parser.js';\nimport type { CheckConfig, MarkerScanResult, SpecParseResult } from '../check/types.js';\nimport { DEFAULT_CHECK_CONFIG } from '../check/types.js';\nimport { configLoader } from '../config.js';\n\n/** Results from scanning markers and specs in parallel. */\nexport interface ScanResults {\n readonly markers: MarkerScanResult;\n readonly specs: SpecParseResult;\n readonly config: CheckConfig;\n}\n\n/**\n * Build a CheckConfig from file config + optional overrides.\n * Shared by trace, coverage, impact, and graph commands.\n */\nexport function buildScanConfig(\n fileConfig: FileConfig | null,\n overrides?: Partial<CheckConfig>,\n): CheckConfig {\n const section = fileConfig?.check;\n\n return {\n specGlobs: toStringArray(section?.['spec-globs']) ?? [...DEFAULT_CHECK_CONFIG.specGlobs],\n codeGlobs: toStringArray(section?.['code-globs']) ?? [...DEFAULT_CHECK_CONFIG.codeGlobs],\n specIgnore: toStringArray(section?.['spec-ignore']) ?? [...DEFAULT_CHECK_CONFIG.specIgnore],\n codeIgnore: toStringArray(section?.['code-ignore']) ?? [...DEFAULT_CHECK_CONFIG.codeIgnore],\n extraSpecGlobs: toStringArray(section?.['extra-spec-globs']) ?? [\n ...DEFAULT_CHECK_CONFIG.extraSpecGlobs,\n ],\n extraSpecIgnore: toStringArray(section?.['extra-spec-ignore']) ?? [\n ...DEFAULT_CHECK_CONFIG.extraSpecIgnore,\n ],\n ignoreMarkers: toStringArray(section?.['ignore-markers']) ?? [\n ...DEFAULT_CHECK_CONFIG.ignoreMarkers,\n ],\n markers: toStringArray(section?.markers) ?? [...DEFAULT_CHECK_CONFIG.markers],\n idPattern:\n typeof section?.['id-pattern'] === 'string'\n ? section['id-pattern']\n : DEFAULT_CHECK_CONFIG.idPattern,\n crossRefPatterns: toStringArray(section?.['cross-ref-patterns']) ?? [\n ...DEFAULT_CHECK_CONFIG.crossRefPatterns,\n ],\n format: DEFAULT_CHECK_CONFIG.format,\n schemaDir: DEFAULT_CHECK_CONFIG.schemaDir,\n schemaEnabled: false,\n allowWarnings: true,\n specOnly: false,\n fix: true,\n deprecated: false,\n ...overrides,\n };\n}\n\n/**\n * Load config, scan markers and parse specs in parallel.\n * Shared by trace, coverage, impact, and graph commands.\n */\nexport async function scan(configPath?: string): Promise<ScanResults> {\n const fileConfig = await configLoader.load(configPath ?? null);\n const config = buildScanConfig(fileConfig);\n\n const [markers, specs] = await Promise.all([scanMarkers(config), parseSpecs(config)]);\n\n return { markers, specs, config };\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"],"mappings":"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","names":["readFile","writeFile","writeFile","readFile","readFile","readFile","basename","readFile","basename","readFile"]}