@ncoderz/awa 1.8.5 → 1.10.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 (106) hide show
  1. package/dist/{chunk-TTXSMGB5.js → chunk-PC3PMV3K.js} +6 -3
  2. package/dist/{chunk-TTXSMGB5.js.map → chunk-PC3PMV3K.js.map} +1 -1
  3. package/dist/index.js +179 -69
  4. package/dist/index.js.map +1 -1
  5. package/dist/{renumber-T46VEDEI.js → renumber-LG6FUVOP.js} +2 -2
  6. package/package.json +1 -1
  7. package/templates/awa/.agent/skills/awa-spec-deprecate/SKILL.md +3 -0
  8. package/templates/awa/.agent/skills/awa-spec-merge/SKILL.md +3 -0
  9. package/templates/awa/.agent/skills/awa-spec-tidy/SKILL.md +3 -0
  10. package/templates/awa/.agent/workflows/awa-spec-deprecate.md +3 -0
  11. package/templates/awa/.agent/workflows/awa-spec-merge.md +3 -0
  12. package/templates/awa/.agent/workflows/awa-spec-tidy.md +3 -0
  13. package/templates/awa/.agents/skills/awa-spec-deprecate/SKILL.md +3 -0
  14. package/templates/awa/.agents/skills/awa-spec-merge/SKILL.md +3 -0
  15. package/templates/awa/.agents/skills/awa-spec-tidy/SKILL.md +3 -0
  16. package/templates/awa/.awa/.agent/schemas/DEPRECATED.schema.yaml +42 -0
  17. package/templates/awa/.awa/.agent/schemas/DESIGN.schema.yaml +34 -1
  18. package/templates/awa/.claude/skills/awa-spec-deprecate/SKILL.md +3 -0
  19. package/templates/awa/.claude/skills/awa-spec-merge/SKILL.md +3 -0
  20. package/templates/awa/.claude/skills/awa-spec-tidy/SKILL.md +3 -0
  21. package/templates/awa/.codex/prompts/awa-spec-deprecate.md +3 -0
  22. package/templates/awa/.cursor/rules/awa-spec-deprecate.md +8 -0
  23. package/templates/awa/.gemini/commands/awa-spec-deprecate.md +3 -0
  24. package/templates/awa/.gemini/commands/awa-spec-merge.md +3 -0
  25. package/templates/awa/.gemini/commands/awa-spec-tidy.md +3 -0
  26. package/templates/awa/.gemini/skills/awa-spec-deprecate/SKILL.md +3 -0
  27. package/templates/awa/.gemini/skills/awa-spec-merge/SKILL.md +3 -0
  28. package/templates/awa/.gemini/skills/awa-spec-tidy/SKILL.md +3 -0
  29. package/templates/awa/.github/prompts/awa.spec-deprecate.prompt.md +8 -0
  30. package/templates/awa/.github/prompts/awa.spec-tidy.prompt.md +1 -1
  31. package/templates/awa/.github/skills/awa-spec-deprecate/SKILL.md +8 -0
  32. package/templates/awa/.github/skills/awa-spec-merge/SKILL.md +3 -0
  33. package/templates/awa/.github/skills/awa-spec-tidy/SKILL.md +3 -0
  34. package/templates/awa/.kilocode/skills/awa-spec-deprecate/SKILL.md +3 -0
  35. package/templates/awa/.kilocode/skills/awa-spec-merge/SKILL.md +3 -0
  36. package/templates/awa/.kilocode/skills/awa-spec-tidy/SKILL.md +3 -0
  37. package/templates/awa/.kilocode/workflows/awa-spec-deprecate.md +3 -0
  38. package/templates/awa/.kilocode/workflows/awa-spec-merge.md +3 -0
  39. package/templates/awa/.kilocode/{skills/spec-merge/SKILL.md → workflows/awa-spec-tidy.md} +1 -1
  40. package/templates/awa/.opencode/commands/awa-spec-deprecate.md +3 -0
  41. package/templates/awa/.opencode/commands/awa-spec-merge.md +3 -0
  42. package/templates/awa/.opencode/commands/{spec-merge.md → awa-spec-tidy.md} +1 -1
  43. package/templates/awa/.opencode/skills/awa-spec-deprecate/SKILL.md +3 -0
  44. package/templates/awa/.opencode/skills/awa-spec-merge/SKILL.md +3 -0
  45. package/templates/awa/.opencode/skills/awa-spec-tidy/SKILL.md +3 -0
  46. package/templates/awa/.qwen/commands/awa-spec-deprecate.md +3 -0
  47. package/templates/awa/.qwen/commands/awa-spec-merge.md +3 -0
  48. package/templates/awa/.qwen/commands/awa-spec-tidy.md +3 -0
  49. package/templates/awa/.qwen/skills/awa-spec-deprecate/SKILL.md +3 -0
  50. package/templates/awa/.qwen/skills/awa-spec-merge/SKILL.md +3 -0
  51. package/templates/awa/.qwen/skills/awa-spec-tidy/SKILL.md +3 -0
  52. package/templates/awa/.roo/skills/awa-spec-deprecate/SKILL.md +3 -0
  53. package/templates/awa/.roo/skills/awa-spec-merge/SKILL.md +3 -0
  54. package/templates/awa/.roo/skills/awa-spec-tidy/SKILL.md +3 -0
  55. package/templates/awa/.windsurf/skills/awa-spec-deprecate/SKILL.md +3 -0
  56. package/templates/awa/.windsurf/skills/awa-spec-merge/SKILL.md +3 -0
  57. package/templates/awa/.windsurf/skills/awa-spec-tidy/SKILL.md +3 -0
  58. package/templates/awa/_delete.txt +108 -0
  59. package/templates/awa/_partials/_cmd.awa-spec-deprecate.md +6 -0
  60. package/templates/awa/_partials/{_cmd.spec-tidy.md → _cmd.awa-spec-tidy.md} +1 -1
  61. package/templates/awa/_partials/_skill.awa-spec-deprecate.md +6 -0
  62. package/templates/awa/_partials/{_skill.spec-merge.md → _skill.awa-spec-merge.md} +1 -1
  63. package/templates/awa/_partials/{_skill.spec-tidy.md → _skill.awa-spec-tidy.md} +2 -2
  64. package/templates/awa/_partials/awa.core.md +7 -3
  65. package/templates/awa/_partials/awa.spec-deprecate.md +86 -0
  66. package/templates/awa/_partials/awa.usage.md +16 -7
  67. package/templates/awa/_tests/claude/.claude/skills/awa-spec-deprecate/SKILL.md +88 -0
  68. package/templates/awa/_tests/claude/.claude/skills/{spec-merge → awa-spec-merge}/SKILL.md +1 -1
  69. package/templates/awa/_tests/{copilot/.github/skills/spec-tidy → claude/.claude/skills/awa-spec-tidy}/SKILL.md +1 -1
  70. package/templates/awa/_tests/claude/.claude/skills/awa-usage/SKILL.md +14 -5
  71. package/templates/awa/_tests/copilot/.github/prompts/awa.spec-deprecate.prompt.md +88 -0
  72. package/templates/awa/_tests/copilot/.github/skills/awa-spec-deprecate/SKILL.md +88 -0
  73. package/templates/awa/_tests/copilot/.github/skills/{spec-merge → awa-spec-merge}/SKILL.md +1 -1
  74. package/templates/awa/_tests/{claude/.claude/skills/spec-tidy → copilot/.github/skills/awa-spec-tidy}/SKILL.md +1 -1
  75. package/templates/awa/_tests/copilot/.github/skills/awa-usage/SKILL.md +14 -5
  76. package/templates/awa/.agent/skills/spec-merge/SKILL.md +0 -3
  77. package/templates/awa/.agent/skills/spec-tidy/SKILL.md +0 -3
  78. package/templates/awa/.agent/workflows/spec-merge.md +0 -3
  79. package/templates/awa/.agent/workflows/spec-tidy.md +0 -3
  80. package/templates/awa/.agents/skills/spec-merge/SKILL.md +0 -3
  81. package/templates/awa/.agents/skills/spec-tidy/SKILL.md +0 -3
  82. package/templates/awa/.claude/skills/spec-merge/SKILL.md +0 -3
  83. package/templates/awa/.claude/skills/spec-tidy/SKILL.md +0 -3
  84. package/templates/awa/.gemini/commands/spec-merge.md +0 -3
  85. package/templates/awa/.gemini/commands/spec-tidy.md +0 -3
  86. package/templates/awa/.gemini/skills/spec-merge/SKILL.md +0 -3
  87. package/templates/awa/.gemini/skills/spec-tidy/SKILL.md +0 -3
  88. package/templates/awa/.github/skills/spec-merge/SKILL.md +0 -3
  89. package/templates/awa/.github/skills/spec-tidy/SKILL.md +0 -3
  90. package/templates/awa/.kilocode/skills/spec-tidy/SKILL.md +0 -3
  91. package/templates/awa/.kilocode/workflows/spec-merge.md +0 -3
  92. package/templates/awa/.kilocode/workflows/spec-tidy.md +0 -3
  93. package/templates/awa/.opencode/commands/spec-tidy.md +0 -3
  94. package/templates/awa/.opencode/skills/spec-merge/SKILL.md +0 -3
  95. package/templates/awa/.opencode/skills/spec-tidy/SKILL.md +0 -3
  96. package/templates/awa/.qwen/commands/spec-merge.md +0 -3
  97. package/templates/awa/.qwen/commands/spec-tidy.md +0 -3
  98. package/templates/awa/.qwen/skills/spec-merge/SKILL.md +0 -3
  99. package/templates/awa/.qwen/skills/spec-tidy/SKILL.md +0 -3
  100. package/templates/awa/.roo/skills/spec-merge/SKILL.md +0 -3
  101. package/templates/awa/.roo/skills/spec-tidy/SKILL.md +0 -3
  102. package/templates/awa/.windsurf/skills/spec-merge/SKILL.md +0 -3
  103. package/templates/awa/.windsurf/skills/spec-tidy/SKILL.md +0 -3
  104. /package/dist/{renumber-T46VEDEI.js.map → renumber-LG6FUVOP.js.map} +0 -0
  105. /package/templates/awa/_partials/{_cmd.spec-merge.md → _cmd.awa-spec-merge.md} +0 -0
  106. /package/templates/awa/_partials/{awa.spec.tidy.md → awa.spec-tidy.md} +0 -0
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  renumberCommand,
11
11
  scan,
12
12
  scanMarkers
13
- } from "./chunk-TTXSMGB5.js";
13
+ } from "./chunk-PC3PMV3K.js";
14
14
  import {
15
15
  ConfigError,
16
16
  DiffError,
@@ -36,7 +36,7 @@ import { Command, Option } from "commander";
36
36
  // src/_generated/package_info.ts
37
37
  var PACKAGE_INFO = {
38
38
  "name": "@ncoderz/awa",
39
- "version": "1.8.5",
39
+ "version": "1.10.0",
40
40
  "author": "Richard Sewell <richard.sewell@ncoderz.com>",
41
41
  "license": "BSD-3-Clause",
42
42
  "description": "awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage agent workflow files using templates."
@@ -71,7 +71,7 @@ function buildComponentAttribution(markers) {
71
71
  }
72
72
  return result;
73
73
  }
74
- function checkCodeAgainstSpec(markers, specs, config) {
74
+ function checkCodeAgainstSpec(markers, specs, config, deprecatedIds = /* @__PURE__ */ new Set()) {
75
75
  const findings = [];
76
76
  const idRegex = new RegExp(`^${config.idPattern}$`);
77
77
  for (const marker of markers.markers) {
@@ -92,6 +92,19 @@ function checkCodeAgainstSpec(markers, specs, config) {
92
92
  for (const marker of markers.markers) {
93
93
  if (marker.type === "component") {
94
94
  if (!specs.componentNames.has(marker.id)) {
95
+ if (deprecatedIds.has(marker.id)) {
96
+ if (config.deprecated) {
97
+ findings.push({
98
+ severity: "warning",
99
+ code: "deprecated-ref",
100
+ message: `Component marker '${marker.id}' references a deprecated ID`,
101
+ filePath: marker.filePath,
102
+ line: marker.line,
103
+ id: marker.id
104
+ });
105
+ }
106
+ continue;
107
+ }
95
108
  findings.push({
96
109
  severity: "error",
97
110
  code: "orphaned-marker",
@@ -103,6 +116,19 @@ function checkCodeAgainstSpec(markers, specs, config) {
103
116
  }
104
117
  } else {
105
118
  if (!specs.allIds.has(marker.id)) {
119
+ if (deprecatedIds.has(marker.id)) {
120
+ if (config.deprecated) {
121
+ findings.push({
122
+ severity: "warning",
123
+ code: "deprecated-ref",
124
+ message: `Marker '${marker.id}' references a deprecated ID`,
125
+ filePath: marker.filePath,
126
+ line: marker.line,
127
+ id: marker.id
128
+ });
129
+ }
130
+ continue;
131
+ }
106
132
  findings.push({
107
133
  severity: "error",
108
134
  code: "orphaned-marker",
@@ -116,6 +142,7 @@ function checkCodeAgainstSpec(markers, specs, config) {
116
142
  }
117
143
  const testedIds = new Set(markers.markers.filter((m) => m.type === "test").map((m) => m.id));
118
144
  for (const acId of specs.acIds) {
145
+ if (deprecatedIds.has(acId)) continue;
119
146
  if (!testedIds.has(acId)) {
120
147
  const loc = specs.idLocations.get(acId);
121
148
  const specFile = loc ? void 0 : specs.specFiles.find((sf) => sf.acIds.includes(acId));
@@ -133,6 +160,7 @@ function checkCodeAgainstSpec(markers, specs, config) {
133
160
  markers.markers.filter((m) => m.type === "component").map((m) => m.id)
134
161
  );
135
162
  for (const componentName of specs.componentNames) {
163
+ if (deprecatedIds.has(componentName)) continue;
136
164
  if (!implementedComponents.has(componentName)) {
137
165
  const loc = specs.idLocations.get(componentName);
138
166
  const specFile = loc ? void 0 : specs.specFiles.find((sf) => sf.componentNames.includes(componentName));
@@ -148,6 +176,7 @@ function checkCodeAgainstSpec(markers, specs, config) {
148
176
  }
149
177
  const implementedIds = new Set(markers.markers.filter((m) => m.type === "impl").map((m) => m.id));
150
178
  for (const acId of specs.acIds) {
179
+ if (deprecatedIds.has(acId)) continue;
151
180
  if (!implementedIds.has(acId)) {
152
181
  const loc = specs.idLocations.get(acId);
153
182
  const specFile = loc ? void 0 : specs.specFiles.find((sf) => sf.acIds.includes(acId));
@@ -162,6 +191,7 @@ function checkCodeAgainstSpec(markers, specs, config) {
162
191
  }
163
192
  }
164
193
  for (const propId of specs.propertyIds) {
194
+ if (deprecatedIds.has(propId)) continue;
165
195
  if (!testedIds.has(propId)) {
166
196
  const loc = specs.idLocations.get(propId);
167
197
  const specFile = loc ? void 0 : specs.specFiles.find((sf) => sf.propertyIds.includes(propId));
@@ -517,8 +547,37 @@ function replaceFeatureCodesSection(content, sectionStart, newSection) {
517
547
  return result.join("\n");
518
548
  }
519
549
 
550
+ // src/core/check/deprecated-parser.ts
551
+ import { readFile as readFile3 } from "fs/promises";
552
+ import { join } from "path";
553
+ var DEPRECATED_PATH = "deprecated/DEPRECATED.md";
554
+ async function parseDeprecated(specDir) {
555
+ const filePath = join(specDir, DEPRECATED_PATH);
556
+ let content;
557
+ try {
558
+ content = await readFile3(filePath, "utf-8");
559
+ } catch {
560
+ return { deprecatedIds: /* @__PURE__ */ new Set() };
561
+ }
562
+ const deprecatedIds = /* @__PURE__ */ new Set();
563
+ const idPattern = /[A-Z][A-Z0-9]*(?:-\d+(?:\.\d+)?(?:_AC-\d+)?|_P-\d+|-[A-Za-z][A-Za-z0-9]*)/g;
564
+ for (const line of content.split("\n")) {
565
+ const trimmed = line.trim();
566
+ if (trimmed === "" || /^#\s/.test(trimmed)) continue;
567
+ for (const segment of trimmed.split(",")) {
568
+ const match = segment.trim().match(idPattern);
569
+ if (match) {
570
+ for (const id of match) {
571
+ deprecatedIds.add(id);
572
+ }
573
+ }
574
+ }
575
+ }
576
+ return { deprecatedIds };
577
+ }
578
+
520
579
  // src/core/check/matrix-fixer.ts
521
- import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
580
+ import { readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
522
581
  import { basename as basename3 } from "path";
523
582
  async function fixMatrices(specs, crossRefPatterns) {
524
583
  const reqFileMaps = buildReqFileMaps(specs.specFiles);
@@ -593,7 +652,7 @@ async function fixDesignMatrix(filePath, reqFileMaps, crossRefPatterns, cachedCo
593
652
  content = cachedContent;
594
653
  } else {
595
654
  try {
596
- content = await readFile3(filePath, "utf-8");
655
+ content = await readFile4(filePath, "utf-8");
597
656
  } catch {
598
657
  return false;
599
658
  }
@@ -697,7 +756,7 @@ async function fixTaskMatrix(filePath, reqFileMaps, specs, crossRefPatterns, cac
697
756
  content = cachedContent;
698
757
  } else {
699
758
  try {
700
- content = await readFile3(filePath, "utf-8");
759
+ content = await readFile4(filePath, "utf-8");
701
760
  } catch {
702
761
  return false;
703
762
  }
@@ -944,12 +1003,31 @@ function printRuleContext(f) {
944
1003
  console.log(chalk.dim(` rule: ${parts.join(" \u2014 ")}`));
945
1004
  }
946
1005
 
1006
+ // src/core/check/reservation-checker.ts
1007
+ function checkReservations(specs, deprecatedIds) {
1008
+ const findings = [];
1009
+ for (const id of deprecatedIds) {
1010
+ if (specs.allIds.has(id)) {
1011
+ const loc = specs.idLocations.get(id);
1012
+ findings.push({
1013
+ severity: "error",
1014
+ code: "deprecated-id-conflict",
1015
+ message: `ID '${id}' is defined in active specs but is reserved by the deprecated file`,
1016
+ filePath: loc?.filePath,
1017
+ line: loc?.line,
1018
+ id
1019
+ });
1020
+ }
1021
+ }
1022
+ return { findings };
1023
+ }
1024
+
947
1025
  // src/core/check/rule-loader.ts
948
- import { readFile as readFile4 } from "fs/promises";
949
- import { join } from "path";
1026
+ import { readFile as readFile5 } from "fs/promises";
1027
+ import { join as join2 } from "path";
950
1028
  import { parse as parseYaml } from "yaml";
951
1029
  async function loadRules(schemaDir) {
952
- const pattern = join(schemaDir, "*.schema.yaml");
1030
+ const pattern = join2(schemaDir, "*.schema.yaml");
953
1031
  const files = await collectFiles([pattern], []);
954
1032
  const results = [];
955
1033
  for (const filePath of files) {
@@ -966,7 +1044,7 @@ function matchesTargetGlob(filePath, targetGlob) {
966
1044
  async function loadRuleFile(filePath) {
967
1045
  let content;
968
1046
  try {
969
- content = await readFile4(filePath, "utf-8");
1047
+ content = await readFile5(filePath, "utf-8");
970
1048
  } catch {
971
1049
  return null;
972
1050
  }
@@ -1158,7 +1236,7 @@ var RuleValidationError = class extends Error {
1158
1236
  };
1159
1237
 
1160
1238
  // src/core/check/schema-checker.ts
1161
- import { readFile as readFile5 } from "fs/promises";
1239
+ import { readFile as readFile6 } from "fs/promises";
1162
1240
  import remarkGfm from "remark-gfm";
1163
1241
  import remarkParse from "remark-parse";
1164
1242
  import { unified } from "unified";
@@ -1208,7 +1286,7 @@ async function checkSchemasAsync(specFiles, ruleSets) {
1208
1286
  content = spec2.content;
1209
1287
  } else {
1210
1288
  try {
1211
- content = await readFile5(spec2.filePath, "utf-8");
1289
+ content = await readFile6(spec2.filePath, "utf-8");
1212
1290
  } catch {
1213
1291
  continue;
1214
1292
  }
@@ -1654,12 +1732,25 @@ function collectAllCodeBlocks(section) {
1654
1732
  }
1655
1733
 
1656
1734
  // src/core/check/spec-spec-checker.ts
1657
- function checkSpecAgainstSpec(specs, markers, config) {
1735
+ function checkSpecAgainstSpec(specs, markers, config, deprecatedIds = /* @__PURE__ */ new Set()) {
1658
1736
  const findings = [];
1659
1737
  for (const specFile of specs.specFiles) {
1660
1738
  for (const crossRef of specFile.crossRefs) {
1661
1739
  for (const refId of crossRef.ids) {
1662
1740
  if (!specs.allIds.has(refId)) {
1741
+ if (deprecatedIds.has(refId)) {
1742
+ if (config.deprecated) {
1743
+ findings.push({
1744
+ severity: "warning",
1745
+ code: "deprecated-ref",
1746
+ message: `Cross-reference '${refId}' (${crossRef.type}) targets a deprecated ID`,
1747
+ filePath: crossRef.filePath,
1748
+ line: crossRef.line,
1749
+ id: refId
1750
+ });
1751
+ }
1752
+ continue;
1753
+ }
1663
1754
  findings.push({
1664
1755
  severity: "error",
1665
1756
  code: "broken-cross-ref",
@@ -1690,7 +1781,16 @@ function checkSpecAgainstSpec(specs, markers, config) {
1690
1781
  }
1691
1782
  }
1692
1783
  }
1784
+ const deprecatedReqIds = /* @__PURE__ */ new Set();
1785
+ for (const id of deprecatedIds) {
1786
+ if (/^[A-Z][A-Z0-9]*-\d+(?:\.\d+)?$/.test(id)) {
1787
+ deprecatedReqIds.add(id);
1788
+ }
1789
+ }
1693
1790
  for (const acId of reqAcIds) {
1791
+ if (deprecatedIds.has(acId)) continue;
1792
+ const parentMatch = /^([A-Z][A-Z0-9]*-\d+(?:\.\d+)?)_AC-\d+$/.exec(acId);
1793
+ if (parentMatch?.[1] && deprecatedReqIds.has(parentMatch[1])) continue;
1694
1794
  if (!implementedAcIds.has(acId)) {
1695
1795
  const loc = specs.idLocations.get(acId);
1696
1796
  findings.push({
@@ -1751,8 +1851,10 @@ async function checkCommand(cliOptions) {
1751
1851
  parseSpecs(config),
1752
1852
  config.schemaEnabled ? loadRules(config.schemaDir) : Promise.resolve([])
1753
1853
  ]);
1754
- const codeSpecResult = config.specOnly ? { findings: [] } : checkCodeAgainstSpec(markers, specs, config);
1755
- const specSpecResult = checkSpecAgainstSpec(specs, markers, config);
1854
+ const { deprecatedIds } = await parseDeprecated(".awa/specs");
1855
+ const codeSpecResult = config.specOnly ? { findings: [] } : checkCodeAgainstSpec(markers, specs, config, deprecatedIds);
1856
+ const specSpecResult = checkSpecAgainstSpec(specs, markers, config, deprecatedIds);
1857
+ const reservationResult = deprecatedIds.size > 0 ? checkReservations(specs, deprecatedIds) : { findings: [] };
1756
1858
  if (config.fix) {
1757
1859
  const fixResult = await fixMatrices(specs, config.crossRefPatterns);
1758
1860
  if (fixResult.filesFixed > 0) {
@@ -1773,6 +1875,7 @@ async function checkCommand(cliOptions) {
1773
1875
  ...markers.findings,
1774
1876
  ...codeSpecResult.findings,
1775
1877
  ...specSpecResult.findings,
1878
+ ...reservationResult.findings,
1776
1879
  ...schemaResult.findings
1777
1880
  ];
1778
1881
  const allFindings = config.allowWarnings ? combinedFindings : combinedFindings.map(
@@ -1823,6 +1926,7 @@ function buildCheckConfig(fileConfig, cliOptions) {
1823
1926
  const allowWarnings = cliOptions.allowWarnings === true ? true : typeof section?.["allow-warnings"] === "boolean" ? section["allow-warnings"] : DEFAULT_CHECK_CONFIG.allowWarnings;
1824
1927
  const specOnly = cliOptions.specOnly === true ? true : typeof section?.["spec-only"] === "boolean" ? section["spec-only"] : DEFAULT_CHECK_CONFIG.specOnly;
1825
1928
  const fix = cliOptions.fix === false ? false : DEFAULT_CHECK_CONFIG.fix;
1929
+ const deprecated = cliOptions.deprecated === true ? true : DEFAULT_CHECK_CONFIG.deprecated;
1826
1930
  const extraSpecGlobs = toStringArray(section?.["extra-spec-globs"]) ?? [
1827
1931
  ...DEFAULT_CHECK_CONFIG.extraSpecGlobs
1828
1932
  ];
@@ -1845,7 +1949,8 @@ function buildCheckConfig(fileConfig, cliOptions) {
1845
1949
  schemaEnabled,
1846
1950
  allowWarnings,
1847
1951
  specOnly,
1848
- fix
1952
+ fix,
1953
+ deprecated
1849
1954
  };
1850
1955
  }
1851
1956
  function toStringArray(value) {
@@ -2012,12 +2117,12 @@ var batchRunner = new BatchRunner();
2012
2117
 
2013
2118
  // src/core/differ.ts
2014
2119
  import { tmpdir } from "os";
2015
- import { join as join4, relative as relative2 } from "path";
2120
+ import { join as join5, relative as relative2 } from "path";
2016
2121
  import { structuredPatch } from "diff";
2017
2122
  import { isBinaryFile as detectBinaryFile } from "isbinaryfile";
2018
2123
 
2019
2124
  // src/core/delete-list.ts
2020
- import { join as join2 } from "path";
2125
+ import { join as join3 } from "path";
2021
2126
  var DELETE_LIST_FILENAME = "_delete.txt";
2022
2127
  function parseDeleteList(content) {
2023
2128
  const entries = [];
@@ -2044,7 +2149,7 @@ function resolveDeleteList(entries, activeFeatures) {
2044
2149
  return entries.filter((e) => e.features === void 0 || !e.features.some((f) => activeSet.has(f))).map((e) => e.path);
2045
2150
  }
2046
2151
  async function loadDeleteList(templatePath) {
2047
- const deleteListPath = join2(templatePath, DELETE_LIST_FILENAME);
2152
+ const deleteListPath = join3(templatePath, DELETE_LIST_FILENAME);
2048
2153
  if (!await pathExists(deleteListPath)) {
2049
2154
  return [];
2050
2155
  }
@@ -2053,7 +2158,7 @@ async function loadDeleteList(templatePath) {
2053
2158
  }
2054
2159
 
2055
2160
  // src/core/generator.ts
2056
- import { join as join3, relative } from "path";
2161
+ import { join as join4, relative } from "path";
2057
2162
 
2058
2163
  // src/core/resolver.ts
2059
2164
  import { MultiSelectPrompt } from "@clack/core";
@@ -2388,7 +2493,7 @@ var FileGenerator = class {
2388
2493
  const generatedOutputPaths = new Set(filesToProcess.map((f) => f.outputFile));
2389
2494
  const deleteCandidates = [];
2390
2495
  for (const relPath of deleteList) {
2391
- const absPath = join3(outputPath, relPath);
2496
+ const absPath = join4(outputPath, relPath);
2392
2497
  if (generatedOutputPaths.has(absPath)) {
2393
2498
  logger.warn(
2394
2499
  `Delete list entry '${relPath}' conflicts with generated file \u2014 skipping deletion`
@@ -2450,7 +2555,7 @@ var FileGenerator = class {
2450
2555
  // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3
2451
2556
  computeOutputPath(templatePath, templateRoot, outputRoot) {
2452
2557
  const relativePath = relative(templateRoot, templatePath);
2453
- return join3(outputRoot, relativePath);
2558
+ return join4(outputRoot, relativePath);
2454
2559
  }
2455
2560
  };
2456
2561
  var fileGenerator = new FileGenerator();
@@ -2492,8 +2597,8 @@ var DiffEngine = class {
2492
2597
  }
2493
2598
  const files = [];
2494
2599
  for (const relPath of generatedFiles) {
2495
- const generatedFilePath = join4(tempPath, relPath);
2496
- const targetFilePath = join4(targetPath, relPath);
2600
+ const generatedFilePath = join5(tempPath, relPath);
2601
+ const targetFilePath = join5(targetPath, relPath);
2497
2602
  if (targetFiles.has(relPath)) {
2498
2603
  const fileDiff = await this.compareFiles(generatedFilePath, targetFilePath, relPath);
2499
2604
  files.push(fileDiff);
@@ -2557,7 +2662,7 @@ var DiffEngine = class {
2557
2662
  const systemTemp = tmpdir();
2558
2663
  const timestamp = Date.now();
2559
2664
  const random = Math.random().toString(36).substring(2, 8);
2560
- const tempPath = join4(systemTemp, `awa-diff-${timestamp}-${random}`);
2665
+ const tempPath = join5(systemTemp, `awa-diff-${timestamp}-${random}`);
2561
2666
  await ensureDir(tempPath);
2562
2667
  return tempPath;
2563
2668
  }
@@ -2710,18 +2815,18 @@ function writeJsonOutput(data) {
2710
2815
  // src/core/overlay.ts
2711
2816
  import { cp } from "fs/promises";
2712
2817
  import { tmpdir as tmpdir2 } from "os";
2713
- import { join as join6 } from "path";
2818
+ import { join as join7 } from "path";
2714
2819
 
2715
2820
  // src/core/template-resolver.ts
2716
2821
  import { createHash } from "crypto";
2717
2822
  import { rm } from "fs/promises";
2718
- import { isAbsolute, join as join5, resolve } from "path";
2823
+ import { isAbsolute, join as join6, resolve } from "path";
2719
2824
  import degit from "degit";
2720
2825
  var TemplateResolver = class {
2721
2826
  // @awa-impl: CLI-3_AC-2, TPL-10_AC-1
2722
2827
  async resolve(source, refresh) {
2723
2828
  if (!source) {
2724
- const bundledPath = join5(getTemplateDir(), "awa");
2829
+ const bundledPath = join6(getTemplateDir(), "awa");
2725
2830
  return {
2726
2831
  type: "bundled",
2727
2832
  localPath: bundledPath,
@@ -2798,7 +2903,7 @@ var TemplateResolver = class {
2798
2903
  getCachePath(source) {
2799
2904
  const hash = createHash("sha256").update(source).digest("hex").substring(0, 16);
2800
2905
  const cacheDir = getCacheDir();
2801
- return join5(cacheDir, hash);
2906
+ return join6(cacheDir, hash);
2802
2907
  }
2803
2908
  };
2804
2909
  var templateResolver = new TemplateResolver();
@@ -2815,7 +2920,7 @@ async function resolveOverlays(overlays, refresh) {
2815
2920
  async function buildMergedDir(baseDir, overlayDirs) {
2816
2921
  const timestamp = Date.now();
2817
2922
  const random = Math.random().toString(36).substring(2, 8);
2818
- const tempPath = join6(tmpdir2(), `awa-overlay-${timestamp}-${random}`);
2923
+ const tempPath = join7(tmpdir2(), `awa-overlay-${timestamp}-${random}`);
2819
2924
  await ensureDir(tempPath);
2820
2925
  await cp(baseDir, tempPath, { recursive: true });
2821
2926
  for (const overlayDir of overlayDirs) {
@@ -3100,13 +3205,13 @@ var FeaturesReporter = class {
3100
3205
  var featuresReporter = new FeaturesReporter();
3101
3206
 
3102
3207
  // src/core/features/scanner.ts
3103
- import { readdir, readFile as readFile6 } from "fs/promises";
3104
- import { join as join7, relative as relative3 } from "path";
3208
+ import { readdir, readFile as readFile7 } from "fs/promises";
3209
+ import { join as join8, relative as relative3 } from "path";
3105
3210
  var FEATURE_PATTERN = /it\.features\.(?:includes|indexOf)\(\s*['"]([^'"]+)['"]\s*\)/g;
3106
3211
  async function* walkAllFiles(dir) {
3107
3212
  const entries = await readdir(dir, { withFileTypes: true });
3108
3213
  for (const entry of entries) {
3109
- const fullPath = join7(dir, entry.name);
3214
+ const fullPath = join8(dir, entry.name);
3110
3215
  if (entry.isDirectory()) {
3111
3216
  yield* walkAllFiles(fullPath);
3112
3217
  } else if (entry.isFile()) {
@@ -3134,7 +3239,7 @@ var FeatureScanner = class {
3134
3239
  for await (const filePath of walkAllFiles(templatePath)) {
3135
3240
  filesScanned++;
3136
3241
  try {
3137
- const content = await readFile6(filePath, "utf-8");
3242
+ const content = await readFile7(filePath, "utf-8");
3138
3243
  const flags = this.extractFlags(content);
3139
3244
  const relPath = relative3(templatePath, filePath);
3140
3245
  for (const flag of flags) {
@@ -3326,21 +3431,21 @@ async function generateCommand(cliOptions) {
3326
3431
  }
3327
3432
 
3328
3433
  // src/core/merge/content-merger.ts
3329
- import { readFile as readFile7, rename, writeFile as writeFile3 } from "fs/promises";
3330
- import { basename as basename4, dirname, extname, join as join8 } from "path";
3434
+ import { readFile as readFile8, rename, writeFile as writeFile3 } from "fs/promises";
3435
+ import { basename as basename4, dirname, extname, join as join9 } from "path";
3331
3436
  var MERGE_PREFIXES = ["FEAT", "REQ", "DESIGN", "API", "EXAMPLE", "TASK"];
3332
3437
  function resolveMovePath(sourceFilePath, prefix, sourceCode, targetCode, existingPaths, plannedPaths) {
3333
3438
  const dir = dirname(sourceFilePath);
3334
3439
  const name = basename4(sourceFilePath);
3335
3440
  const newName = name.replace(`${prefix}-${sourceCode}-`, `${prefix}-${targetCode}-`);
3336
- const newPath = join8(dir, newName);
3441
+ const newPath = join9(dir, newName);
3337
3442
  if (!existingPaths.has(newPath) && !plannedPaths.has(newPath)) {
3338
3443
  return newPath;
3339
3444
  }
3340
3445
  const ext = extname(newName);
3341
3446
  const stem = newName.slice(0, -ext.length);
3342
3447
  for (let i = 1; i < 1e3; i++) {
3343
- const indexed = join8(dir, `${stem}-${String(i).padStart(3, "0")}${ext}`);
3448
+ const indexed = join9(dir, `${stem}-${String(i).padStart(3, "0")}${ext}`);
3344
3449
  if (!existingPaths.has(indexed) && !plannedPaths.has(indexed)) {
3345
3450
  return indexed;
3346
3451
  }
@@ -3399,7 +3504,7 @@ async function executeMoves(sourceCode, targetCode, specFiles, dryRun) {
3399
3504
  docType: matchedPrefix
3400
3505
  });
3401
3506
  if (!dryRun) {
3402
- const content = await readFile7(sf.filePath, "utf-8");
3507
+ const content = await readFile8(sf.filePath, "utf-8");
3403
3508
  const updated = updateHeading(content, sourceCode, targetCode);
3404
3509
  await rename(sf.filePath, targetPath);
3405
3510
  if (updated !== content) {
@@ -3482,8 +3587,8 @@ function formatJson2(result) {
3482
3587
  }
3483
3588
 
3484
3589
  // src/core/merge/spec-mover.ts
3485
- import { readFile as readFile8, rename as rename2 } from "fs/promises";
3486
- import { basename as basename5, dirname as dirname2, join as join9 } from "path";
3590
+ import { readFile as readFile9, rename as rename2 } from "fs/promises";
3591
+ import { basename as basename5, dirname as dirname2, join as join10 } from "path";
3487
3592
 
3488
3593
  // src/core/merge/types.ts
3489
3594
  var MergeError = class extends Error {
@@ -3516,7 +3621,7 @@ function planRenames(sourceCode, targetCode, specFiles) {
3516
3621
  const oldSuffix = name.slice(oldPrefix.length);
3517
3622
  const newSuffix = targetFeature ? replaceFeaturePart(oldSuffix, targetFeature) : oldSuffix;
3518
3623
  const newName = `${prefix}-${targetCode}-${newSuffix}`;
3519
- const newPath = join9(dirname2(sf.filePath), newName);
3624
+ const newPath = join10(dirname2(sf.filePath), newName);
3520
3625
  renames.push({ oldPath: sf.filePath, newPath });
3521
3626
  break;
3522
3627
  }
@@ -3558,7 +3663,7 @@ function updateHeading2(content, sourceCode, targetCode) {
3558
3663
  async function executeRenames(renames, sourceCode, targetCode, dryRun) {
3559
3664
  if (dryRun) return renames;
3560
3665
  for (const r of renames) {
3561
- const content = await readFile8(r.oldPath, "utf-8");
3666
+ const content = await readFile9(r.oldPath, "utf-8");
3562
3667
  const updated = updateHeading2(content, sourceCode, targetCode);
3563
3668
  await rename2(r.oldPath, r.newPath);
3564
3669
  if (updated !== content) {
@@ -3574,7 +3679,7 @@ async function findStaleRefs(sourceCode, filePaths) {
3574
3679
  for (const filePath of filePaths) {
3575
3680
  let content;
3576
3681
  try {
3577
- content = await readFile8(filePath, "utf-8");
3682
+ content = await readFile9(filePath, "utf-8");
3578
3683
  } catch {
3579
3684
  continue;
3580
3685
  }
@@ -3787,7 +3892,7 @@ async function mergeCommand(options) {
3787
3892
  return 2;
3788
3893
  }
3789
3894
  if (options.renumber && !dryRun && !noChange) {
3790
- const { renumberCommand: renumberCommand2 } = await import("./renumber-T46VEDEI.js");
3895
+ const { renumberCommand: renumberCommand2 } = await import("./renumber-LG6FUVOP.js");
3791
3896
  await renumberCommand2({
3792
3897
  code: options.targetCode,
3793
3898
  dryRun: false,
@@ -3975,10 +4080,10 @@ import { intro as intro4, outro as outro4 } from "@clack/prompts";
3975
4080
 
3976
4081
  // src/core/template-test/fixture-loader.ts
3977
4082
  import { readdir as readdir2 } from "fs/promises";
3978
- import { basename as basename6, extname as extname2, join as join10 } from "path";
4083
+ import { basename as basename6, extname as extname2, join as join11 } from "path";
3979
4084
  import { parse } from "smol-toml";
3980
4085
  async function discoverFixtures(templatePath) {
3981
- const testsDir = join10(templatePath, "_tests");
4086
+ const testsDir = join11(templatePath, "_tests");
3982
4087
  let entries;
3983
4088
  try {
3984
4089
  const dirEntries = await readdir2(testsDir, { withFileTypes: true });
@@ -3988,7 +4093,7 @@ async function discoverFixtures(templatePath) {
3988
4093
  }
3989
4094
  const fixtures = [];
3990
4095
  for (const filename of entries) {
3991
- const filePath = join10(testsDir, filename);
4096
+ const filePath = join11(testsDir, filename);
3992
4097
  const fixture = await parseFixture(filePath);
3993
4098
  fixtures.push(fixture);
3994
4099
  }
@@ -4089,16 +4194,16 @@ function reportFixture(fixture) {
4089
4194
  // src/core/template-test/runner.ts
4090
4195
  import { mkdir as mkdir2, rm as rm3 } from "fs/promises";
4091
4196
  import { tmpdir as tmpdir3 } from "os";
4092
- import { join as join12 } from "path";
4197
+ import { join as join13 } from "path";
4093
4198
 
4094
4199
  // src/core/template-test/snapshot.ts
4095
4200
  import { mkdir, readdir as readdir3, rm as rm2 } from "fs/promises";
4096
- import { join as join11, relative as relative4 } from "path";
4201
+ import { join as join12, relative as relative4 } from "path";
4097
4202
  async function walkRelative(dir, base) {
4098
4203
  const results = [];
4099
4204
  const entries = await readdir3(dir, { withFileTypes: true });
4100
4205
  for (const entry of entries) {
4101
- const fullPath = join11(dir, entry.name);
4206
+ const fullPath = join12(dir, entry.name);
4102
4207
  if (entry.isDirectory()) {
4103
4208
  const sub = await walkRelative(fullPath, base);
4104
4209
  results.push(...sub);
@@ -4115,8 +4220,8 @@ async function compareSnapshots(renderedDir, snapshotDir) {
4115
4220
  const snapshotSet = new Set(snapshotFiles);
4116
4221
  const renderedSet = new Set(renderedFiles);
4117
4222
  for (const file of renderedFiles) {
4118
- const renderedPath = join11(renderedDir, file);
4119
- const snapshotPath = join11(snapshotDir, file);
4223
+ const renderedPath = join12(renderedDir, file);
4224
+ const snapshotPath = join12(snapshotDir, file);
4120
4225
  if (!snapshotSet.has(file)) {
4121
4226
  results.push({ path: file, status: "missing-snapshot" });
4122
4227
  continue;
@@ -4142,8 +4247,8 @@ async function updateSnapshots(renderedDir, snapshotDir) {
4142
4247
  await mkdir(snapshotDir, { recursive: true });
4143
4248
  const files = await walkRelative(renderedDir, renderedDir);
4144
4249
  for (const file of files) {
4145
- const srcPath = join11(renderedDir, file);
4146
- const destPath = join11(snapshotDir, file);
4250
+ const srcPath = join12(renderedDir, file);
4251
+ const destPath = join12(snapshotDir, file);
4147
4252
  const content = await readTextFile(srcPath);
4148
4253
  await writeTextFile(destPath, content);
4149
4254
  }
@@ -4151,7 +4256,7 @@ async function updateSnapshots(renderedDir, snapshotDir) {
4151
4256
 
4152
4257
  // src/core/template-test/runner.ts
4153
4258
  async function runFixture(fixture, templatePath, options, presetDefinitions = {}) {
4154
- const tempDir = join12(tmpdir3(), `awa-test-${fixture.name}-${Date.now()}`);
4259
+ const tempDir = join13(tmpdir3(), `awa-test-${fixture.name}-${Date.now()}`);
4155
4260
  try {
4156
4261
  await mkdir2(tempDir, { recursive: true });
4157
4262
  const features = featureResolver.resolve({
@@ -4170,12 +4275,12 @@ async function runFixture(fixture, templatePath, options, presetDefinitions = {}
4170
4275
  });
4171
4276
  const fileResults = [];
4172
4277
  for (const expectedFile of fixture.expectedFiles) {
4173
- const fullPath = join12(tempDir, expectedFile);
4278
+ const fullPath = join13(tempDir, expectedFile);
4174
4279
  const found = await pathExists(fullPath);
4175
4280
  fileResults.push({ path: expectedFile, found });
4176
4281
  }
4177
4282
  const missingFiles = fileResults.filter((r) => !r.found);
4178
- const snapshotDir = join12(templatePath, "_tests", fixture.name);
4283
+ const snapshotDir = join13(templatePath, "_tests", fixture.name);
4179
4284
  let snapshotResults = [];
4180
4285
  if (options.updateSnapshots) {
4181
4286
  await updateSnapshots(tempDir, snapshotDir);
@@ -4292,7 +4397,7 @@ async function testCommand(options) {
4292
4397
  }
4293
4398
 
4294
4399
  // src/core/trace/content-assembler.ts
4295
- import { readFile as readFile9 } from "fs/promises";
4400
+ import { readFile as readFile10 } from "fs/promises";
4296
4401
  var DEFAULT_BEFORE_CONTEXT = 5;
4297
4402
  var DEFAULT_AFTER_CONTEXT = 20;
4298
4403
  async function assembleContent(result, taskPath, contextOptions) {
@@ -4500,7 +4605,7 @@ async function cachedReadFile(cache, filePath) {
4500
4605
  if (cache.has(filePath)) return cache.get(filePath) ?? null;
4501
4606
  let content;
4502
4607
  try {
4503
- content = await readFile9(filePath, "utf-8");
4608
+ content = await readFile10(filePath, "utf-8");
4504
4609
  } catch {
4505
4610
  content = null;
4506
4611
  }
@@ -4850,7 +4955,7 @@ function pushToMap(map, key, value) {
4850
4955
  }
4851
4956
 
4852
4957
  // src/core/trace/input-resolver.ts
4853
- import { readFile as readFile10 } from "fs/promises";
4958
+ import { readFile as readFile11 } from "fs/promises";
4854
4959
  function resolveIds(ids, index) {
4855
4960
  const resolved = [];
4856
4961
  const warnings = [];
@@ -4866,7 +4971,7 @@ function resolveIds(ids, index) {
4866
4971
  async function resolveTaskFile(taskPath, index) {
4867
4972
  let content;
4868
4973
  try {
4869
- content = await readFile10(taskPath, "utf-8");
4974
+ content = await readFile11(taskPath, "utf-8");
4870
4975
  } catch {
4871
4976
  return { ids: [], warnings: [`Task file not found: ${taskPath}`] };
4872
4977
  }
@@ -4917,7 +5022,7 @@ async function resolveTaskFile(taskPath, index) {
4917
5022
  async function resolveSourceFile(filePath, index) {
4918
5023
  let content;
4919
5024
  try {
4920
- content = await readFile10(filePath, "utf-8");
5025
+ content = await readFile11(filePath, "utf-8");
4921
5026
  } catch {
4922
5027
  return { ids: [], warnings: [`Source file not found: ${filePath}`] };
4923
5028
  }
@@ -5390,15 +5495,15 @@ function printUpdateWarning(log, result) {
5390
5495
  }
5391
5496
 
5392
5497
  // src/utils/update-check-cache.ts
5393
- import { mkdir as mkdir3, readFile as readFile11, writeFile as writeFile4 } from "fs/promises";
5498
+ import { mkdir as mkdir3, readFile as readFile12, writeFile as writeFile4 } from "fs/promises";
5394
5499
  import { homedir } from "os";
5395
- import { dirname as dirname3, join as join13 } from "path";
5396
- var CACHE_DIR = join13(homedir(), ".cache", "awa");
5397
- var CACHE_FILE = join13(CACHE_DIR, "update-check.json");
5500
+ import { dirname as dirname3, join as join14 } from "path";
5501
+ var CACHE_DIR = join14(homedir(), ".cache", "awa");
5502
+ var CACHE_FILE = join14(CACHE_DIR, "update-check.json");
5398
5503
  var DEFAULT_INTERVAL_MS = 864e5;
5399
5504
  async function shouldCheck(intervalMs = DEFAULT_INTERVAL_MS) {
5400
5505
  try {
5401
- const raw = await readFile11(CACHE_FILE, "utf-8");
5506
+ const raw = await readFile12(CACHE_FILE, "utf-8");
5402
5507
  const data = JSON.parse(raw);
5403
5508
  if (typeof data.timestamp !== "number" || typeof data.latestVersion !== "string") {
5404
5509
  return true;
@@ -5513,6 +5618,10 @@ program.command("check").description(
5513
5618
  ).option(
5514
5619
  "--no-fix",
5515
5620
  "Skip regeneration of Requirements Traceability sections in DESIGN and TASK files"
5621
+ ).option(
5622
+ "--deprecated",
5623
+ "Surface warnings for code markers and cross-references targeting deprecated IDs",
5624
+ false
5516
5625
  ).action(async (options, command) => {
5517
5626
  const cliOptions = {
5518
5627
  config: cliProvidedOption(command, options, "config"),
@@ -5523,7 +5632,8 @@ program.command("check").description(
5523
5632
  summary: cliProvidedOption(command, options, "summary"),
5524
5633
  allowWarnings: cliProvidedOption(command, options, "allowWarnings"),
5525
5634
  specOnly: cliProvidedOption(command, options, "specOnly"),
5526
- fix: cliProvidedOption(command, options, "fix")
5635
+ fix: cliProvidedOption(command, options, "fix"),
5636
+ deprecated: cliProvidedOption(command, options, "deprecated")
5527
5637
  };
5528
5638
  const exitCode = await checkCommand(cliOptions);
5529
5639
  process.exit(exitCode);