@ncoderz/awa 1.8.4 → 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 (112) hide show
  1. package/dist/{chunk-GOIBZQFJ.js → chunk-4NC73OUR.js} +13 -1
  2. package/dist/chunk-4NC73OUR.js.map +1 -0
  3. package/dist/{chunk-2VUVSW6T.js → chunk-PC3PMV3K.js} +7 -4
  4. package/dist/{chunk-2VUVSW6T.js.map → chunk-PC3PMV3K.js.map} +1 -1
  5. package/dist/{config-SJLBJX77.js → config-EP5JOR5X.js} +2 -2
  6. package/dist/index.js +221 -99
  7. package/dist/index.js.map +1 -1
  8. package/dist/renumber-LG6FUVOP.js +9 -0
  9. package/package.json +1 -1
  10. package/templates/awa/.agent/skills/awa-spec-deprecate/SKILL.md +3 -0
  11. package/templates/awa/.agent/skills/awa-spec-merge/SKILL.md +3 -0
  12. package/templates/awa/.agent/skills/awa-spec-tidy/SKILL.md +3 -0
  13. package/templates/awa/.agent/workflows/awa-spec-deprecate.md +3 -0
  14. package/templates/awa/.agent/workflows/awa-spec-merge.md +3 -0
  15. package/templates/awa/.agent/workflows/awa-spec-tidy.md +3 -0
  16. package/templates/awa/.agents/skills/awa-spec-deprecate/SKILL.md +3 -0
  17. package/templates/awa/.agents/skills/awa-spec-merge/SKILL.md +3 -0
  18. package/templates/awa/.agents/skills/awa-spec-tidy/SKILL.md +3 -0
  19. package/templates/awa/.awa/.agent/schemas/DEPRECATED.schema.yaml +42 -0
  20. package/templates/awa/.claude/skills/awa-spec-deprecate/SKILL.md +3 -0
  21. package/templates/awa/.claude/skills/awa-spec-merge/SKILL.md +3 -0
  22. package/templates/awa/.claude/skills/awa-spec-tidy/SKILL.md +3 -0
  23. package/templates/awa/.codex/prompts/awa-spec-deprecate.md +3 -0
  24. package/templates/awa/.cursor/rules/awa-spec-deprecate.md +8 -0
  25. package/templates/awa/.gemini/commands/awa-spec-deprecate.md +3 -0
  26. package/templates/awa/.gemini/commands/awa-spec-merge.md +3 -0
  27. package/templates/awa/.gemini/commands/awa-spec-tidy.md +3 -0
  28. package/templates/awa/.gemini/skills/awa-spec-deprecate/SKILL.md +3 -0
  29. package/templates/awa/.gemini/skills/awa-spec-merge/SKILL.md +3 -0
  30. package/templates/awa/.gemini/skills/awa-spec-tidy/SKILL.md +3 -0
  31. package/templates/awa/.github/prompts/awa.spec-deprecate.prompt.md +8 -0
  32. package/templates/awa/.github/prompts/awa.spec-tidy.prompt.md +1 -1
  33. package/templates/awa/.github/skills/awa-spec-deprecate/SKILL.md +8 -0
  34. package/templates/awa/.github/skills/awa-spec-merge/SKILL.md +3 -0
  35. package/templates/awa/.github/skills/awa-spec-tidy/SKILL.md +3 -0
  36. package/templates/awa/.kilocode/skills/awa-spec-deprecate/SKILL.md +3 -0
  37. package/templates/awa/.kilocode/skills/awa-spec-merge/SKILL.md +3 -0
  38. package/templates/awa/.kilocode/skills/awa-spec-tidy/SKILL.md +3 -0
  39. package/templates/awa/.kilocode/workflows/awa-spec-deprecate.md +3 -0
  40. package/templates/awa/.kilocode/workflows/awa-spec-merge.md +3 -0
  41. package/templates/awa/.kilocode/{skills/spec-merge/SKILL.md → workflows/awa-spec-tidy.md} +1 -1
  42. package/templates/awa/.opencode/commands/awa-spec-deprecate.md +3 -0
  43. package/templates/awa/.opencode/commands/awa-spec-merge.md +3 -0
  44. package/templates/awa/.opencode/commands/{spec-merge.md → awa-spec-tidy.md} +1 -1
  45. package/templates/awa/.opencode/skills/awa-spec-deprecate/SKILL.md +3 -0
  46. package/templates/awa/.opencode/skills/awa-spec-merge/SKILL.md +3 -0
  47. package/templates/awa/.opencode/skills/awa-spec-tidy/SKILL.md +3 -0
  48. package/templates/awa/.qwen/commands/awa-spec-deprecate.md +3 -0
  49. package/templates/awa/.qwen/commands/awa-spec-merge.md +3 -0
  50. package/templates/awa/.qwen/commands/awa-spec-tidy.md +3 -0
  51. package/templates/awa/.qwen/skills/awa-spec-deprecate/SKILL.md +3 -0
  52. package/templates/awa/.qwen/skills/awa-spec-merge/SKILL.md +3 -0
  53. package/templates/awa/.qwen/skills/awa-spec-tidy/SKILL.md +3 -0
  54. package/templates/awa/.roo/skills/awa-spec-deprecate/SKILL.md +3 -0
  55. package/templates/awa/.roo/skills/awa-spec-merge/SKILL.md +3 -0
  56. package/templates/awa/.roo/skills/awa-spec-tidy/SKILL.md +3 -0
  57. package/templates/awa/.windsurf/skills/awa-spec-deprecate/SKILL.md +3 -0
  58. package/templates/awa/.windsurf/skills/awa-spec-merge/SKILL.md +3 -0
  59. package/templates/awa/.windsurf/skills/awa-spec-tidy/SKILL.md +3 -0
  60. package/templates/awa/_delete.txt +108 -0
  61. package/templates/awa/_partials/_cmd.awa-spec-deprecate.md +6 -0
  62. package/templates/awa/_partials/{_cmd.spec-tidy.md → _cmd.awa-spec-tidy.md} +1 -1
  63. package/templates/awa/_partials/_skill.awa-spec-deprecate.md +6 -0
  64. package/templates/awa/_partials/{_skill.spec-merge.md → _skill.awa-spec-merge.md} +1 -1
  65. package/templates/awa/_partials/{_skill.spec-tidy.md → _skill.awa-spec-tidy.md} +2 -2
  66. package/templates/awa/_partials/awa.code.md +5 -4
  67. package/templates/awa/_partials/awa.core.md +10 -6
  68. package/templates/awa/_partials/awa.spec-deprecate.md +86 -0
  69. package/templates/awa/_partials/awa.usage.md +16 -7
  70. package/templates/awa/_tests/claude/.claude/skills/awa-spec-deprecate/SKILL.md +88 -0
  71. package/templates/awa/_tests/claude/.claude/skills/{spec-merge → awa-spec-merge}/SKILL.md +1 -1
  72. package/templates/awa/_tests/{copilot/.github/skills/spec-tidy → claude/.claude/skills/awa-spec-tidy}/SKILL.md +1 -1
  73. package/templates/awa/_tests/claude/.claude/skills/awa-usage/SKILL.md +14 -5
  74. package/templates/awa/_tests/copilot/.github/prompts/awa.spec-deprecate.prompt.md +88 -0
  75. package/templates/awa/_tests/copilot/.github/skills/awa-spec-deprecate/SKILL.md +88 -0
  76. package/templates/awa/_tests/copilot/.github/skills/{spec-merge → awa-spec-merge}/SKILL.md +1 -1
  77. package/templates/awa/_tests/{claude/.claude/skills/spec-tidy → copilot/.github/skills/awa-spec-tidy}/SKILL.md +1 -1
  78. package/templates/awa/_tests/copilot/.github/skills/awa-usage/SKILL.md +14 -5
  79. package/dist/chunk-GOIBZQFJ.js.map +0 -1
  80. package/dist/renumber-TGDI47IS.js +0 -9
  81. package/templates/awa/.agent/skills/spec-merge/SKILL.md +0 -3
  82. package/templates/awa/.agent/skills/spec-tidy/SKILL.md +0 -3
  83. package/templates/awa/.agent/workflows/spec-merge.md +0 -3
  84. package/templates/awa/.agent/workflows/spec-tidy.md +0 -3
  85. package/templates/awa/.agents/skills/spec-merge/SKILL.md +0 -3
  86. package/templates/awa/.agents/skills/spec-tidy/SKILL.md +0 -3
  87. package/templates/awa/.claude/skills/spec-merge/SKILL.md +0 -3
  88. package/templates/awa/.claude/skills/spec-tidy/SKILL.md +0 -3
  89. package/templates/awa/.gemini/commands/spec-merge.md +0 -3
  90. package/templates/awa/.gemini/commands/spec-tidy.md +0 -3
  91. package/templates/awa/.gemini/skills/spec-merge/SKILL.md +0 -3
  92. package/templates/awa/.gemini/skills/spec-tidy/SKILL.md +0 -3
  93. package/templates/awa/.github/skills/spec-merge/SKILL.md +0 -3
  94. package/templates/awa/.github/skills/spec-tidy/SKILL.md +0 -3
  95. package/templates/awa/.kilocode/skills/spec-tidy/SKILL.md +0 -3
  96. package/templates/awa/.kilocode/workflows/spec-merge.md +0 -3
  97. package/templates/awa/.kilocode/workflows/spec-tidy.md +0 -3
  98. package/templates/awa/.opencode/commands/spec-tidy.md +0 -3
  99. package/templates/awa/.opencode/skills/spec-merge/SKILL.md +0 -3
  100. package/templates/awa/.opencode/skills/spec-tidy/SKILL.md +0 -3
  101. package/templates/awa/.qwen/commands/spec-merge.md +0 -3
  102. package/templates/awa/.qwen/commands/spec-tidy.md +0 -3
  103. package/templates/awa/.qwen/skills/spec-merge/SKILL.md +0 -3
  104. package/templates/awa/.qwen/skills/spec-tidy/SKILL.md +0 -3
  105. package/templates/awa/.roo/skills/spec-merge/SKILL.md +0 -3
  106. package/templates/awa/.roo/skills/spec-tidy/SKILL.md +0 -3
  107. package/templates/awa/.windsurf/skills/spec-merge/SKILL.md +0 -3
  108. package/templates/awa/.windsurf/skills/spec-tidy/SKILL.md +0 -3
  109. /package/dist/{config-SJLBJX77.js.map → config-EP5JOR5X.js.map} +0 -0
  110. /package/dist/{renumber-TGDI47IS.js.map → renumber-LG6FUVOP.js.map} +0 -0
  111. /package/templates/awa/_partials/{_cmd.spec-merge.md → _cmd.awa-spec-merge.md} +0 -0
  112. /package/templates/awa/_partials/{awa.spec.tidy.md → awa.spec-tidy.md} +0 -0
@@ -631,6 +631,18 @@ var ConfigLoader = class {
631
631
  }
632
632
  return target;
633
633
  }
634
+ // @awa-component: MULTI-TargetResolver
635
+ // @awa-impl: CFG-1_AC-1, CFG-1_AC-2, CFG-1_AC-3, CFG-1_AC-4
636
+ // @awa-impl: CFG-2_AC-1, CFG-2_AC-2, CFG-2_AC-3
637
+ // @awa-impl: CFG-3_AC-1, CFG-3_AC-2, CFG-3_AC-3, CFG-3_AC-4, CFG-3_AC-5, CFG-3_AC-6, CFG-3_AC-7, CFG-3_AC-8, CFG-3_AC-9, CFG-3_AC-10
638
+ // @awa-impl: CFG-4_AC-1, CFG-4_AC-2, CFG-4_AC-3, CFG-4_AC-4
639
+ // @awa-impl: CFG-5_AC-1, CFG-6_AC-1, CFG-6_AC-2
640
+ // @awa-impl: CFG-7_AC-1, CFG-7_AC-2, CFG-7_AC-3, CFG-7_AC-4
641
+ // @awa-impl: CFG-9_AC-1, CFG-9_AC-2, CFG-9_AC-3
642
+ // @awa-impl: CFG-11_AC-1, CFG-11_AC-2, CFG-11_AC-3
643
+ // @awa-impl: CLI-1_AC-4, CLI-2_AC-2, CLI-2_AC-3, CLI-2_AC-4, CLI-4_AC-3, CLI-7_AC-2
644
+ // @awa-impl: CLI-31_AC-1, OVL-8_AC-1
645
+ // @awa-impl: MULTI-1_AC-1, MULTI-2_AC-1, MULTI-3_AC-1, MULTI-5_AC-2
634
646
  // Resolve a target by merging target config with root config (target overrides root via nullish coalescing)
635
647
  resolveTarget(targetName, fileConfig) {
636
648
  const targets = fileConfig.targets;
@@ -689,4 +701,4 @@ export {
689
701
  ConfigLoader,
690
702
  configLoader
691
703
  };
692
- //# sourceMappingURL=chunk-GOIBZQFJ.js.map
704
+ //# sourceMappingURL=chunk-4NC73OUR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/config.ts","../src/types/index.ts","../src/utils/fs.ts","../src/utils/logger.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\n\nimport { parse } from 'smol-toml';\n\nimport {\n ConfigError,\n type FileConfig,\n type PresetDefinitions,\n type RawCliOptions,\n type ResolvedOptions,\n type TargetConfig,\n type UpdateCheckConfig,\n} from '../types/index.js';\nimport { pathExists, readTextFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst DEFAULT_CONFIG_PATH = '.awa.toml';\n\n// @awa-component: CFG-ConfigLoader\n// @awa-impl: CFG-1_AC-1, CFG-1_AC-2, CFG-1_AC-3, CFG-1_AC-4\n// @awa-impl: CFG-2_AC-1, CFG-2_AC-2, CFG-2_AC-3\n// @awa-impl: CFG-3_AC-1, CFG-3_AC-2, CFG-3_AC-3, CFG-3_AC-4, CFG-3_AC-5, CFG-3_AC-6, CFG-3_AC-7, CFG-3_AC-8, CFG-3_AC-9, CFG-3_AC-10\n// @awa-impl: CFG-4_AC-1, CFG-4_AC-2, CFG-4_AC-3, CFG-4_AC-4\n// @awa-impl: CFG-5_AC-1, CFG-6_AC-1, CFG-6_AC-2\n// @awa-impl: CFG-7_AC-1, CFG-7_AC-2, CFG-7_AC-3, CFG-7_AC-4\n// @awa-impl: CFG-9_AC-1, CFG-9_AC-2, CFG-9_AC-3\n// @awa-impl: CFG-11_AC-1, CFG-11_AC-2, CFG-11_AC-3\n// @awa-impl: CLI-1_AC-4, CLI-2_AC-2, CLI-2_AC-3, CLI-2_AC-4, CLI-4_AC-3, CLI-7_AC-2\n// @awa-impl: MULTI-1_AC-1, MULTI-2_AC-1, MULTI-3_AC-1, MULTI-5_AC-2\nexport class ConfigLoader {\n private isLocalTemplateSource(source: string): boolean {\n if (source.startsWith('.') || source.startsWith('/') || source.startsWith('~')) {\n return true;\n }\n return /^[a-zA-Z]:/.test(source);\n }\n\n private resolvePathFromConfigDir(value: string, configDir: string): string {\n if (isAbsolute(value) || value.startsWith('~')) {\n return value;\n }\n return resolve(configDir, value);\n }\n\n private normalizeConfigPaths(config: FileConfig, configPath: string): FileConfig {\n const configDir = dirname(configPath);\n\n if (config.output !== undefined) {\n config.output = this.resolvePathFromConfigDir(config.output, configDir);\n }\n\n if (config.template !== undefined && this.isLocalTemplateSource(config.template)) {\n config.template = this.resolvePathFromConfigDir(config.template, configDir);\n }\n\n if (config.overlay !== undefined) {\n config.overlay = config.overlay.map((overlaySource) =>\n this.isLocalTemplateSource(overlaySource)\n ? this.resolvePathFromConfigDir(overlaySource, configDir)\n : overlaySource,\n );\n }\n\n if (config.targets !== undefined) {\n for (const target of Object.values(config.targets)) {\n if (target.output !== undefined) {\n target.output = this.resolvePathFromConfigDir(target.output, configDir);\n }\n\n if (target.template !== undefined && this.isLocalTemplateSource(target.template)) {\n target.template = this.resolvePathFromConfigDir(target.template, configDir);\n }\n }\n }\n\n return config;\n }\n\n private async discoverConfigPath(startDir: string): Promise<string | null> {\n const homeDir = resolve(homedir());\n let currentDir = resolve(startDir);\n\n while (true) {\n const candidatePath = join(currentDir, DEFAULT_CONFIG_PATH);\n if (await pathExists(candidatePath)) {\n return candidatePath;\n }\n\n const gitMarker = join(currentDir, '.git');\n if (await pathExists(gitMarker)) {\n return null;\n }\n\n const parentDir = dirname(currentDir);\n if (parentDir === currentDir || currentDir === homeDir) {\n return null;\n }\n\n currentDir = parentDir;\n }\n }\n\n // @awa-impl: CFG-1_AC-1, CFG-1_AC-2, CFG-1_AC-3, CFG-1_AC-4\n async load(configPath: string | null): Promise<FileConfig | null> {\n let pathToLoad: string | null;\n\n if (configPath) {\n pathToLoad = isAbsolute(configPath) ? configPath : resolve(process.cwd(), configPath);\n const exists = await pathExists(pathToLoad);\n if (!exists) {\n throw new ConfigError(\n `Configuration file not found: ${configPath}`,\n 'FILE_NOT_FOUND',\n configPath,\n );\n }\n } else {\n pathToLoad = await this.discoverConfigPath(process.cwd());\n }\n\n // No config found via auto-discovery\n if (!pathToLoad) {\n return null;\n }\n\n // If explicit path provided but doesn't exist, error\n if (configPath && !(await pathExists(pathToLoad))) {\n throw new ConfigError(\n `Configuration file not found: ${configPath}`,\n 'FILE_NOT_FOUND',\n configPath,\n );\n }\n\n // Read and parse TOML\n try {\n const content = await readTextFile(pathToLoad);\n const parsed = parse(content) as Record<string, unknown>;\n\n // Validate and extract known options\n const config: FileConfig = {};\n\n if (parsed.output !== undefined) {\n if (typeof parsed.output !== 'string') {\n throw new ConfigError(\n `Invalid type for 'output': expected string, got ${typeof parsed.output}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.output = parsed.output;\n }\n\n if (parsed.template !== undefined) {\n if (typeof parsed.template !== 'string') {\n throw new ConfigError(\n `Invalid type for 'template': expected string, got ${typeof parsed.template}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.template = parsed.template;\n }\n\n if (parsed.features !== undefined) {\n if (\n !Array.isArray(parsed.features) ||\n !parsed.features.every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'features': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.features = parsed.features;\n }\n\n if (parsed.preset !== undefined) {\n if (!Array.isArray(parsed.preset) || !parsed.preset.every((p) => typeof p === 'string')) {\n throw new ConfigError(\n `Invalid type for 'preset': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.preset = parsed.preset;\n }\n\n if (parsed['remove-features'] !== undefined) {\n if (\n !Array.isArray(parsed['remove-features']) ||\n !parsed['remove-features'].every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'remove-features': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config['remove-features'] = parsed['remove-features'];\n }\n\n if (parsed.force !== undefined) {\n if (typeof parsed.force !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'force': expected boolean, got ${typeof parsed.force}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.force = parsed.force;\n }\n\n if (parsed['dry-run'] !== undefined) {\n if (typeof parsed['dry-run'] !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'dry-run': expected boolean, got ${typeof parsed['dry-run']}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config['dry-run'] = parsed['dry-run'];\n }\n\n if (parsed.delete !== undefined) {\n if (typeof parsed.delete !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'delete': expected boolean, got ${typeof parsed.delete}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.delete = parsed.delete;\n }\n\n if (parsed.refresh !== undefined) {\n if (typeof parsed.refresh !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'refresh': expected boolean, got ${typeof parsed.refresh}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.refresh = parsed.refresh;\n }\n\n if (parsed.presets !== undefined) {\n if (\n parsed.presets === null ||\n typeof parsed.presets !== 'object' ||\n Array.isArray(parsed.presets)\n ) {\n throw new ConfigError(\n `Invalid type for 'presets': expected table of string arrays`,\n 'INVALID_PRESET',\n pathToLoad,\n );\n }\n\n const defs: PresetDefinitions = {};\n for (const [presetName, value] of Object.entries(\n parsed.presets as Record<string, unknown>,\n )) {\n if (!Array.isArray(value) || !value.every((v) => typeof v === 'string')) {\n throw new ConfigError(\n `Invalid preset '${presetName}': expected array of strings`,\n 'INVALID_PRESET',\n pathToLoad,\n );\n }\n defs[presetName] = value as string[];\n }\n\n config.presets = defs;\n }\n\n if (parsed['list-unknown'] !== undefined) {\n if (typeof parsed['list-unknown'] !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'list-unknown': expected boolean, got ${typeof parsed['list-unknown']}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config['list-unknown'] = parsed['list-unknown'];\n }\n\n // @awa-impl: CLI-31_AC-1\n // Pass through [check] table as-is for check command to process\n if (parsed.check !== undefined) {\n if (\n parsed.check === null ||\n typeof parsed.check !== 'object' ||\n Array.isArray(parsed.check)\n ) {\n throw new ConfigError(\n `Invalid type for 'check': expected table`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.check = parsed.check as Record<string, unknown>;\n }\n\n // @awa-impl: OVL-8_AC-1\n if (parsed.overlay !== undefined) {\n if (!Array.isArray(parsed.overlay) || !parsed.overlay.every((o) => typeof o === 'string')) {\n throw new ConfigError(\n `Invalid type for 'overlay': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n config.overlay = parsed.overlay;\n }\n\n if (parsed['update-check'] !== undefined) {\n if (\n parsed['update-check'] === null ||\n typeof parsed['update-check'] !== 'object' ||\n Array.isArray(parsed['update-check'])\n ) {\n throw new ConfigError(\n `Invalid type for 'update-check': expected table`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n\n const raw = parsed['update-check'] as Record<string, unknown>;\n const updateCheckConfig: UpdateCheckConfig = {};\n\n if (raw.enabled !== undefined) {\n if (typeof raw.enabled !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'update-check.enabled': expected boolean, got ${typeof raw.enabled}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n updateCheckConfig.enabled = raw.enabled;\n }\n\n if (raw.interval !== undefined) {\n if (typeof raw.interval !== 'number') {\n throw new ConfigError(\n `Invalid type for 'update-check.interval': expected number, got ${typeof raw.interval}`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n updateCheckConfig.interval = raw.interval;\n }\n\n config['update-check'] = updateCheckConfig;\n }\n\n // Parse [targets.*] sections\n if (parsed.targets !== undefined) {\n if (\n parsed.targets === null ||\n typeof parsed.targets !== 'object' ||\n Array.isArray(parsed.targets)\n ) {\n throw new ConfigError(\n `Invalid type for 'targets': expected table of target sections`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n\n const targets: Record<string, TargetConfig> = {};\n for (const [targetName, targetValue] of Object.entries(\n parsed.targets as Record<string, unknown>,\n )) {\n if (\n targetValue === null ||\n typeof targetValue !== 'object' ||\n Array.isArray(targetValue)\n ) {\n throw new ConfigError(\n `Invalid target '${targetName}': expected table`,\n 'INVALID_TYPE',\n pathToLoad,\n );\n }\n targets[targetName] = this.parseTargetSection(\n targetValue as Record<string, unknown>,\n targetName,\n pathToLoad,\n );\n }\n config.targets = targets;\n }\n\n // Warn about unknown options\n const knownKeys = new Set([\n 'output',\n 'template',\n 'features',\n 'preset',\n 'remove-features',\n 'presets',\n 'force',\n 'dry-run',\n 'delete',\n 'refresh',\n 'list-unknown',\n 'check',\n 'targets',\n 'overlay',\n 'update-check',\n ]);\n for (const key of Object.keys(parsed)) {\n if (!knownKeys.has(key)) {\n logger.warn(`Unknown configuration option: '${key}'`);\n }\n }\n\n return this.normalizeConfigPaths(config, pathToLoad);\n } catch (error) {\n if (error instanceof ConfigError) {\n throw error;\n }\n\n // TOML parsing error\n throw new ConfigError(\n `Failed to parse TOML configuration: ${error instanceof Error ? error.message : String(error)}`,\n 'PARSE_ERROR',\n pathToLoad,\n );\n }\n }\n\n // @awa-impl: CFG-4_AC-1, CFG-4_AC-2, CFG-4_AC-3, CFG-4_AC-4\n // @awa-impl: CLI-2_AC-2, CLI-2_AC-3, CLI-2_AC-4\n merge(cli: RawCliOptions, file: FileConfig | null): ResolvedOptions {\n // CLI arguments override file config values\n // Output can come from CLI (positional argument) or config file\n\n // @awa-impl: CLI-2_AC-2, CLI-2_AC-3\n const output = cli.output ?? file?.output;\n\n // @awa-impl: CLI-1_AC-4, CLI-2_AC-4\n if (!output) {\n throw new ConfigError(\n 'Output directory is required. Provide it as a positional argument or in the config file.',\n 'MISSING_OUTPUT',\n null,\n );\n }\n\n const template = cli.template ?? file?.template ?? null;\n\n // Features: CLI completely replaces config (no merge)\n const features = cli.features ?? file?.features ?? [];\n\n const preset = cli.preset ?? file?.preset ?? [];\n const removeFeatures = cli.removeFeatures ?? file?.['remove-features'] ?? [];\n const presets = file?.presets ?? {};\n\n const force = cli.force ?? file?.force ?? false;\n const dryRun = cli.dryRun ?? file?.['dry-run'] ?? false;\n const enableDelete = cli.delete ?? file?.delete ?? false;\n const refresh = cli.refresh ?? file?.refresh ?? false;\n const listUnknown = cli.listUnknown ?? file?.['list-unknown'] ?? false;\n const overlay = cli.overlay ?? file?.overlay ?? [];\n const json = cli.json ?? false;\n const summary = cli.summary ?? false;\n\n return {\n output,\n template,\n features,\n preset,\n removeFeatures,\n force,\n dryRun,\n delete: enableDelete,\n refresh,\n presets,\n listUnknown,\n overlay,\n json,\n summary,\n };\n }\n\n // Parse a [targets.<name>] section, validating allowed keys and types\n private parseTargetSection(\n section: Record<string, unknown>,\n targetName: string,\n configPath: string,\n ): TargetConfig {\n const target: TargetConfig = {};\n const allowedKeys = new Set(['output', 'template', 'features', 'preset', 'remove-features']);\n\n for (const key of Object.keys(section)) {\n if (!allowedKeys.has(key)) {\n logger.warn(`Unknown option in target '${targetName}': '${key}'`);\n }\n }\n\n if (section.output !== undefined) {\n if (typeof section.output !== 'string') {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.output': expected string, got ${typeof section.output}`,\n 'INVALID_TYPE',\n configPath,\n );\n }\n target.output = section.output;\n }\n\n if (section.template !== undefined) {\n if (typeof section.template !== 'string') {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.template': expected string, got ${typeof section.template}`,\n 'INVALID_TYPE',\n configPath,\n );\n }\n target.template = section.template;\n }\n\n if (section.features !== undefined) {\n if (\n !Array.isArray(section.features) ||\n !section.features.every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.features': expected array of strings`,\n 'INVALID_TYPE',\n configPath,\n );\n }\n target.features = section.features;\n }\n\n if (section.preset !== undefined) {\n if (!Array.isArray(section.preset) || !section.preset.every((p) => typeof p === 'string')) {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.preset': expected array of strings`,\n 'INVALID_TYPE',\n configPath,\n );\n }\n target.preset = section.preset;\n }\n\n if (section['remove-features'] !== undefined) {\n if (\n !Array.isArray(section['remove-features']) ||\n !section['remove-features'].every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.remove-features': expected array of strings`,\n 'INVALID_TYPE',\n configPath,\n );\n }\n target['remove-features'] = section['remove-features'];\n }\n\n return target;\n }\n\n // @awa-component: MULTI-TargetResolver\n // @awa-impl: CFG-1_AC-1, CFG-1_AC-2, CFG-1_AC-3, CFG-1_AC-4\n // @awa-impl: CFG-2_AC-1, CFG-2_AC-2, CFG-2_AC-3\n // @awa-impl: CFG-3_AC-1, CFG-3_AC-2, CFG-3_AC-3, CFG-3_AC-4, CFG-3_AC-5, CFG-3_AC-6, CFG-3_AC-7, CFG-3_AC-8, CFG-3_AC-9, CFG-3_AC-10\n // @awa-impl: CFG-4_AC-1, CFG-4_AC-2, CFG-4_AC-3, CFG-4_AC-4\n // @awa-impl: CFG-5_AC-1, CFG-6_AC-1, CFG-6_AC-2\n // @awa-impl: CFG-7_AC-1, CFG-7_AC-2, CFG-7_AC-3, CFG-7_AC-4\n // @awa-impl: CFG-9_AC-1, CFG-9_AC-2, CFG-9_AC-3\n // @awa-impl: CFG-11_AC-1, CFG-11_AC-2, CFG-11_AC-3\n // @awa-impl: CLI-1_AC-4, CLI-2_AC-2, CLI-2_AC-3, CLI-2_AC-4, CLI-4_AC-3, CLI-7_AC-2\n // @awa-impl: CLI-31_AC-1, OVL-8_AC-1\n // @awa-impl: MULTI-1_AC-1, MULTI-2_AC-1, MULTI-3_AC-1, MULTI-5_AC-2\n // Resolve a target by merging target config with root config (target overrides root via nullish coalescing)\n resolveTarget(targetName: string, fileConfig: FileConfig): FileConfig {\n const targets = fileConfig.targets;\n if (!targets || Object.keys(targets).length === 0) {\n throw new ConfigError(\n 'No targets defined in configuration. Add [targets.<name>] sections to .awa.toml.',\n 'NO_TARGETS',\n null,\n );\n }\n\n const target = targets[targetName];\n if (!target) {\n throw new ConfigError(\n `Unknown target: '${targetName}'. Available targets: ${Object.keys(targets).join(', ')}`,\n 'UNKNOWN_TARGET',\n null,\n );\n }\n\n // Merge: target fields override root (nullish coalescing — target value ?? root value)\n return {\n ...fileConfig,\n output: target.output ?? fileConfig.output,\n template: target.template ?? fileConfig.template,\n features: target.features ?? fileConfig.features,\n preset: target.preset ?? fileConfig.preset,\n 'remove-features': target['remove-features'] ?? fileConfig['remove-features'],\n targets: undefined, // Don't propagate targets into resolved config\n };\n }\n\n // Get all target names from config\n getTargetNames(fileConfig: FileConfig | null): string[] {\n if (!fileConfig?.targets) {\n return [];\n }\n return Object.keys(fileConfig.targets);\n }\n}\n\nexport const configLoader = new ConfigLoader();\n","// @awa-component: GEN-CoreTypes\n\n// Custom error classes for diff operations\nexport class DiffError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DiffError';\n }\n}\n\n// RawCliOptions - CLI argument parser output\nexport interface RawCliOptions {\n output?: string; // Optional positional argument (required if not in config)\n template?: string;\n features?: string[];\n preset?: string[];\n removeFeatures?: string[];\n force?: boolean;\n dryRun?: boolean;\n delete?: boolean;\n config?: string;\n refresh?: boolean;\n listUnknown?: boolean;\n all?: boolean;\n allTargets?: boolean;\n target?: string;\n watch?: boolean;\n overlay?: string[];\n json?: boolean;\n summary?: boolean;\n}\n\n// PresetDefinitions - Named feature bundles\nexport interface PresetDefinitions {\n [presetName: string]: string[];\n}\n\n// TargetConfig - Per-target configuration (generation-related fields only, no boolean flags)\nexport interface TargetConfig {\n output?: string;\n template?: string;\n features?: string[];\n preset?: string[];\n 'remove-features'?: string[];\n}\n\n// UpdateCheckConfig - Update check configuration\nexport interface UpdateCheckConfig {\n enabled?: boolean;\n interval?: number;\n}\n\n// FileConfig - TOML configuration file structure\nexport interface FileConfig {\n output?: string;\n template?: string;\n features?: string[];\n preset?: string[];\n 'remove-features'?: string[];\n force?: boolean;\n 'dry-run'?: boolean;\n delete?: boolean;\n refresh?: boolean;\n presets?: PresetDefinitions;\n 'list-unknown'?: boolean;\n check?: Record<string, unknown>;\n targets?: Record<string, TargetConfig>;\n overlay?: string[];\n 'update-check'?: UpdateCheckConfig;\n}\n\n// ResolvedOptions - Fully resolved configuration with defaults applied\nexport interface ResolvedOptions {\n readonly output: string;\n readonly template: string | null;\n readonly features: readonly string[];\n readonly preset: readonly string[];\n readonly removeFeatures: readonly string[];\n readonly force: boolean;\n readonly dryRun: boolean;\n readonly delete: boolean;\n readonly refresh: boolean;\n readonly presets: PresetDefinitions;\n readonly listUnknown: boolean;\n readonly overlay: readonly string[];\n readonly json: boolean;\n readonly summary: boolean;\n}\n\n// TemplateSourceType - Template source type detection\nexport type TemplateSourceType = 'local' | 'git' | 'bundled';\n\n// ResolvedTemplate - Template source resolution result\nexport interface ResolvedTemplate {\n type: TemplateSourceType;\n localPath: string;\n source: string;\n}\n\n// TemplateContext - Context passed to template engine\nexport interface TemplateContext {\n features: string[];\n version?: string;\n}\n\n// RenderResult - Template rendering output\nexport interface RenderResult {\n content: string;\n isEmpty: boolean;\n isEmptyFileMarker: boolean;\n}\n\n// FileAction - Tagged union for file operations\nexport type FileAction =\n | { type: 'create'; sourcePath: string; outputPath: string }\n | { type: 'overwrite'; sourcePath: string; outputPath: string }\n | { type: 'skip-user'; sourcePath: string; outputPath: string }\n | { type: 'skip-empty'; sourcePath: string; outputPath: string }\n | { type: 'skip-equal'; sourcePath: string; outputPath: string }\n | { type: 'delete'; outputPath: string };\n\n// GenerationResult - Aggregated generation outcome\nexport interface GenerationResult {\n readonly actions: readonly FileAction[];\n readonly created: number;\n readonly overwritten: number;\n readonly deleted: number;\n readonly skipped: number;\n readonly skippedEmpty: number;\n readonly skippedUser: number;\n readonly skippedEqual: number;\n}\n\n// GenerateOptions - File generation parameters\nexport interface GenerateOptions {\n templatePath: string;\n outputPath: string;\n features: string[];\n force: boolean;\n dryRun: boolean;\n delete: boolean;\n}\n\n// ConflictChoice - User choice for conflict resolution\nexport type ConflictChoice = 'overwrite' | 'skip';\n\n// ConflictItem - Individual file conflict for batch resolution\nexport interface ConflictItem {\n outputPath: string;\n sourcePath: string;\n newContent: string;\n existingContent: string;\n}\n\n// BatchConflictResolution - Result of batch conflict resolution\nexport interface BatchConflictResolution {\n overwrite: string[]; // List of output paths to overwrite\n skip: string[]; // List of output paths to skip\n equal: string[]; // List of output paths skipped because content is identical\n}\n\n// TemplateFile - Template file metadata\nexport interface TemplateFile {\n path: string;\n absolutePath: string;\n isPartial: boolean;\n}\n\n// DiffOptions - Diff operation parameters\nexport interface DiffOptions {\n templatePath: string;\n targetPath: string;\n features: string[];\n listUnknown: boolean;\n}\n\n// FileDiffStatus - File comparison status\nexport type FileDiffStatus =\n | 'identical'\n | 'modified'\n | 'new'\n | 'extra'\n | 'binary-differs'\n | 'delete-listed';\n\n// FileDiff - Comparison result for a single file\nexport interface FileDiff {\n relativePath: string;\n status: FileDiffStatus;\n unifiedDiff?: string; // Present only for 'modified' text files\n}\n\n// DiffResult - Aggregated diff outcome\nexport interface DiffResult {\n files: FileDiff[];\n identical: number;\n modified: number;\n newFiles: number;\n extraFiles: number;\n binaryDiffers: number;\n deleteListed: number;\n hasDifferences: boolean;\n}\n\n// CachedTemplate - Cached Git template metadata\nexport interface CachedTemplate {\n source: string;\n localPath: string;\n fetchedAt: Date;\n ref?: string;\n}\n\n// JSON output types for --json flag\n// @awa-impl: JSON-3_AC-1\nexport interface GenerationActionJSON {\n type: string;\n path: string;\n}\n\nexport interface GenerationJSON {\n actions: GenerationActionJSON[];\n counts: {\n created: number;\n overwritten: number;\n skipped: number;\n deleted: number;\n };\n}\n\n// @awa-impl: JSON-4_AC-1\nexport interface DiffFileJSON {\n path: string;\n status: string;\n diff?: string;\n}\n\nexport interface DiffJSON {\n diffs: DiffFileJSON[];\n counts: {\n changed: number;\n new: number;\n matching: number;\n deleted: number;\n };\n}\n\n// Custom error types\nexport class ConfigError extends Error {\n constructor(\n message: string,\n public code:\n | 'FILE_NOT_FOUND'\n | 'PARSE_ERROR'\n | 'INVALID_TYPE'\n | 'MISSING_OUTPUT'\n | 'INVALID_PRESET'\n | 'UNKNOWN_PRESET'\n | 'UNKNOWN_TARGET'\n | 'NO_TARGETS',\n public filePath?: string | null,\n ) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\nexport class TemplateError extends Error {\n constructor(\n message: string,\n public code: 'SOURCE_NOT_FOUND' | 'FETCH_FAILED' | 'RENDER_ERROR',\n public source?: string,\n ) {\n super(message);\n this.name = 'TemplateError';\n }\n}\n\nexport class GenerationError extends Error {\n constructor(\n message: string,\n public code: 'PERMISSION_DENIED' | 'DISK_FULL',\n ) {\n super(message);\n this.name = 'GenerationError';\n }\n}\n","// @awa-component: GEN-FileSystem\n// @awa-impl: GEN-1_AC-1, GEN-1_AC-2\n\nimport { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await mkdir(dirPath, { recursive: true });\n}\n\nexport async function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function isDirectory(path: string): Promise<boolean> {\n try {\n const stats = await stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function readTextFile(path: string): Promise<string> {\n return readFile(path, 'utf-8');\n}\n\nexport async function readBinaryFile(path: string): Promise<Buffer> {\n return readFile(path);\n}\n\nexport async function writeTextFile(path: string, content: string): Promise<void> {\n await ensureDir(dirname(path));\n await writeFile(path, content, 'utf-8');\n}\n\nexport async function* walkDirectory(dir: string): AsyncGenerator<string> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip directories starting with underscore\n if (entry.name.startsWith('_')) {\n continue;\n }\n yield* walkDirectory(fullPath);\n } else if (entry.isFile()) {\n // Skip files starting with underscore\n if (entry.name.startsWith('_')) {\n continue;\n }\n yield fullPath;\n }\n }\n}\n\nexport function getCacheDir(): string {\n return join(homedir(), '.cache', 'awa', 'templates');\n}\n\nexport function getTemplateDir(): string {\n // In built dist, we need to go up from dist/index.js to project root\n // In development, we're in src/utils/fs.ts\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n\n // Check if we're in dist/ or src/\n if (currentDir.includes('/dist')) {\n // In dist: go up one level to project root\n return join(dirname(currentDir), 'templates');\n }\n\n // In src: go up two levels to project root\n return join(currentDir, '..', '..', 'templates');\n}\n\nexport async function rmDir(dirPath: string): Promise<void> {\n await rm(dirPath, { recursive: true, force: true });\n}\n\nexport async function deleteFile(filePath: string): Promise<void> {\n await rm(filePath, { force: true });\n}\n","// @awa-component: GEN-Logger\n// @awa-impl: CLI-6_AC-3\n// @awa-impl: GEN-6_AC-4\n// @awa-impl: GEN-7_AC-1\n// @awa-impl: GEN-7_AC-2\n// @awa-impl: GEN-7_AC-3\n// @awa-impl: GEN-7_AC-4\n// @awa-impl: GEN-9_AC-1\n// @awa-impl: GEN-9_AC-2\n// @awa-impl: GEN-9_AC-3\n// @awa-impl: GEN-9_AC-4\n// @awa-impl: GEN-9_AC-5\n// @awa-impl: GEN-9_AC-6\n// @awa-impl: GEN-9_AC-7\n// @awa-impl: GEN-9_AC-8\n// @awa-impl: GEN-11_AC-1\n// @awa-impl: GEN-11_AC-2\n// @awa-impl: GEN-11_AC-4\n// @awa-impl: TPL-7_AC-3\n\nimport chalk from 'chalk';\n\nimport type { DiffResult, FileAction, GenerationResult } from '../types/index.js';\n\nexport class Logger {\n info(message: string): void {\n console.log(chalk.blue('ℹ'), message);\n }\n\n success(message: string): void {\n console.log(chalk.green('✔'), message);\n }\n\n warn(message: string): void {\n console.warn(chalk.yellow('⚠'), message);\n }\n\n error(message: string): void {\n console.error(chalk.red('✖'), message);\n }\n\n fileAction(action: FileAction): void {\n const { type, outputPath } = action;\n\n switch (type) {\n case 'create':\n console.log(chalk.green(' + '), chalk.dim(outputPath));\n break;\n case 'overwrite':\n console.log(chalk.yellow(' ~ '), chalk.dim(outputPath));\n break;\n case 'skip-user':\n console.log(chalk.blue(' - '), chalk.dim(outputPath), chalk.dim('(skipped)'));\n break;\n case 'skip-empty':\n console.log(chalk.dim(' · '), chalk.dim(outputPath), chalk.dim('(empty)'));\n break;\n case 'skip-equal':\n console.log(chalk.dim(' = '), chalk.dim(outputPath), chalk.dim('(unchanged)'));\n break;\n case 'delete':\n console.log(chalk.red(' ✖ '), chalk.dim(outputPath), chalk.red('(deleted)'));\n break;\n }\n }\n\n // @awa-impl: GEN-9_AC-1, GEN-9_AC-2, GEN-9_AC-3, GEN-9_AC-4, GEN-9_AC-5, GEN-9_AC-6\n summary(result: GenerationResult): void {\n console.log('');\n console.log(chalk.bold('Summary:'));\n\n // @awa-impl: GEN-9_AC-6\n // Check if no files were created, overwritten, or deleted\n if (result.created === 0 && result.overwritten === 0 && result.deleted === 0) {\n console.log(chalk.yellow(' ⚠ No files were created, overwritten, or deleted'));\n }\n\n if (result.created > 0) {\n console.log(chalk.green(` Created: ${result.created}`));\n }\n\n if (result.overwritten > 0) {\n console.log(chalk.yellow(` Overwritten: ${result.overwritten}`));\n }\n\n if (result.deleted > 0) {\n console.log(chalk.red(` Deleted: ${result.deleted}`));\n }\n\n if (result.skippedEqual > 0) {\n console.log(chalk.dim(` Skipped (equal): ${result.skippedEqual}`));\n }\n\n if (result.skippedUser > 0) {\n console.log(chalk.blue(` Skipped (user): ${result.skippedUser}`));\n }\n\n console.log('');\n }\n\n // @awa-impl: DIFF-4_AC-3\n diffLine(line: string, type: 'add' | 'remove' | 'context'): void {\n switch (type) {\n case 'add':\n console.log(chalk.green(line));\n break;\n case 'remove':\n console.log(chalk.red(line));\n break;\n case 'context':\n console.log(chalk.dim(line));\n break;\n }\n }\n\n // @awa-impl: DIFF-4_AC-4, DIFF-4_AC-5\n diffSummary(result: DiffResult): void {\n console.log('');\n\n const filesCompared =\n result.identical +\n result.modified +\n result.newFiles +\n result.extraFiles +\n result.binaryDiffers +\n result.deleteListed;\n const differences =\n result.modified +\n result.newFiles +\n result.extraFiles +\n result.binaryDiffers +\n result.deleteListed;\n\n // @awa-impl: DIFF-4_AC-5\n console.log(chalk.bold(`${filesCompared} files compared, ${differences} differences`));\n\n if (!result.hasDifferences) {\n // @awa-impl: DIFF-4_AC-4\n console.log(chalk.green('✔ No differences found'));\n }\n\n // @awa-impl: DIFF-4_AC-5\n console.log(chalk.bold('Summary:'));\n console.log(chalk.dim(` Identical: ${result.identical}`));\n\n if (result.modified > 0) {\n console.log(chalk.yellow(` Modified: ${result.modified}`));\n }\n\n if (result.newFiles > 0) {\n console.log(chalk.green(` New: ${result.newFiles}`));\n }\n\n if (result.extraFiles > 0) {\n console.log(chalk.red(` Extra: ${result.extraFiles}`));\n }\n\n if (result.binaryDiffers > 0) {\n console.log(chalk.red(` Binary differs: ${result.binaryDiffers}`));\n }\n\n if (result.deleteListed > 0) {\n console.log(chalk.red(` Delete listed: ${result.deleteListed}`));\n }\n\n console.log('');\n }\n}\n\nexport const logger = new Logger();\n"],"mappings":"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","names":["homedir","dirname","join","dirname","homedir","join"]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  configLoader,
4
4
  logger
5
- } from "./chunk-GOIBZQFJ.js";
5
+ } from "./chunk-4NC73OUR.js";
6
6
 
7
7
  // src/commands/renumber.ts
8
8
  import { readFile as readFile4 } from "fs/promises";
@@ -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-2VUVSW6T.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"]}
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  ConfigLoader,
4
4
  configLoader
5
- } from "./chunk-GOIBZQFJ.js";
5
+ } from "./chunk-4NC73OUR.js";
6
6
  export {
7
7
  ConfigLoader,
8
8
  configLoader
9
9
  };
10
- //# sourceMappingURL=config-SJLBJX77.js.map
10
+ //# sourceMappingURL=config-EP5JOR5X.js.map