eslint-plugin-traceability 1.21.1 → 1.22.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 (57) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/README.md +3 -4
  3. package/lib/src/maintenance/batch.js +0 -2
  4. package/lib/src/maintenance/cli.js +8 -11
  5. package/lib/src/maintenance/commands.d.ts +2 -2
  6. package/lib/src/maintenance/commands.js +2 -3
  7. package/lib/src/maintenance/detect.js +7 -8
  8. package/lib/src/maintenance/report.js +2 -3
  9. package/lib/src/maintenance/storyParser.d.ts +16 -0
  10. package/lib/src/maintenance/storyParser.js +167 -0
  11. package/lib/src/maintenance/update.js +0 -1
  12. package/lib/src/rules/helpers/pattern-validators.d.ts +42 -0
  13. package/lib/src/rules/helpers/pattern-validators.js +65 -0
  14. package/lib/src/rules/helpers/prefer-implements-inline.d.ts +16 -0
  15. package/lib/src/rules/helpers/prefer-implements-inline.js +146 -0
  16. package/lib/src/rules/helpers/require-story-comment-detection.d.ts +47 -0
  17. package/lib/src/rules/helpers/require-story-comment-detection.js +141 -0
  18. package/lib/src/rules/helpers/require-story-core.d.ts +6 -6
  19. package/lib/src/rules/helpers/require-story-core.js +10 -11
  20. package/lib/src/rules/helpers/require-story-helpers.d.ts +5 -63
  21. package/lib/src/rules/helpers/require-story-helpers.js +29 -337
  22. package/lib/src/rules/helpers/require-story-name-extraction.d.ts +35 -0
  23. package/lib/src/rules/helpers/require-story-name-extraction.js +107 -0
  24. package/lib/src/rules/helpers/require-story-node-utils.d.ts +43 -0
  25. package/lib/src/rules/helpers/require-story-node-utils.js +115 -0
  26. package/lib/src/rules/helpers/valid-annotation-format-internal.js +11 -3
  27. package/lib/src/rules/helpers/valid-annotation-options.d.ts +0 -10
  28. package/lib/src/rules/helpers/valid-annotation-options.js +22 -92
  29. package/lib/src/rules/helpers/valid-req-reference-helpers.js +0 -1
  30. package/lib/src/rules/no-redundant-annotation.js +4 -238
  31. package/lib/src/rules/prefer-implements-annotation.d.ts +12 -0
  32. package/lib/src/rules/prefer-implements-annotation.js +9 -164
  33. package/lib/src/rules/require-traceability.d.ts +8 -0
  34. package/lib/src/rules/require-traceability.js +8 -0
  35. package/lib/src/utils/annotation-checker.d.ts +3 -2
  36. package/lib/src/utils/annotation-checker.js +3 -2
  37. package/lib/src/utils/branch-annotation-catch-helpers.d.ts +22 -0
  38. package/lib/src/utils/branch-annotation-catch-helpers.js +70 -0
  39. package/lib/src/utils/branch-annotation-helpers.js +11 -187
  40. package/lib/src/utils/branch-annotation-if-helpers.d.ts +1 -0
  41. package/lib/src/utils/branch-annotation-if-helpers.js +59 -0
  42. package/lib/src/utils/branch-annotation-indent-helpers.d.ts +1 -1
  43. package/lib/src/utils/branch-annotation-switch-helpers.d.ts +8 -2
  44. package/lib/src/utils/branch-annotation-switch-helpers.js +10 -4
  45. package/lib/src/utils/branch-validation.d.ts +9 -0
  46. package/lib/src/utils/branch-validation.js +58 -0
  47. package/lib/src/utils/comment-text-helpers.d.ts +31 -0
  48. package/lib/src/utils/comment-text-helpers.js +54 -0
  49. package/lib/src/utils/redundancy-detector.d.ts +85 -0
  50. package/lib/src/utils/redundancy-detector.js +235 -0
  51. package/lib/tests/maintenance/storyParser.test.d.ts +8 -0
  52. package/lib/tests/maintenance/storyParser.test.js +505 -0
  53. package/lib/tests/rules/no-redundant-annotation.test.js +1 -0
  54. package/lib/tests/rules/require-story-helpers.test.js +3 -2
  55. package/lib/tests/rules/valid-req-reference.test.js +2 -0
  56. package/package.json +18 -10
  57. package/user-docs/api-reference.md +2 -2
package/CHANGELOG.md CHANGED
@@ -1,9 +1,14 @@
1
- ## [1.21.1](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.21.0...v1.21.1) (2025-12-21)
1
+ # [1.22.0](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.21.1...v1.22.0) (2026-01-10)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * **rules:** harden valid-annotation-format parsing ([7c914f1](https://github.com/voder-ai/eslint-plugin-traceability/commit/7c914f100b93923bec63f97dfa122e1c4686ecff))
6
+ * move voder-ai to optionalDependencies to allow CI without GitHub Packages access ([1a674cb](https://github.com/voder-ai/eslint-plugin-traceability/commit/1a674cb65d5223c75710910817393667435bfcd8))
7
+
8
+
9
+ ### Features
10
+
11
+ * **ci:** add post-deployment verification step ([00d3d21](https://github.com/voder-ai/eslint-plugin-traceability/commit/00d3d214f21e18bfc26e3de4fbcb0bd9f0aa8f28))
7
12
 
8
13
  # Changelog
9
14
 
package/README.md CHANGED
@@ -122,7 +122,6 @@ Traceability annotations are typically placed immediately adjacent to the code t
122
122
  - **Function-level (`traceability/require-story-annotation`, `traceability/require-req-annotation`)**
123
123
 
124
124
  Function-level rules support both before-function and inside-body placement, controlled by the same `annotationPlacement` option described above:
125
-
126
125
  - `"before"` – Annotations are written as JSDoc blocks immediately preceding the function, or as line comments placed directly before the function declaration or expression.
127
126
  - `"inside"` – Annotations are expected to appear on the first comment-only lines inside function and method bodies; comments before the function are ignored for block-bodied functions in this mode, while TypeScript declarations and signature-only nodes still rely on before-node annotations.
128
127
 
@@ -130,7 +129,7 @@ Traceability annotations are typically placed immediately adjacent to the code t
130
129
 
131
130
  For full configuration details and migration guidance between placement styles, see:
132
131
 
133
- - `traceability/require-branch-annotation` rule docs: [docs/rules/require-branch-annotation.md](docs/rules/require-branch-annotation.md)
132
+ - `traceability/require-branch-annotation` rule docs: [docs/rules/require-branch-annotation.md](https://github.com/voder-ai/eslint-plugin-traceability/blob/main/docs/rules/require-branch-annotation.md)
134
133
  - Migration guide: [user-docs/migration-guide.md](user-docs/migration-guide.md)
135
134
 
136
135
  ### Available Rules
@@ -281,7 +280,7 @@ Removing "duplicate" annotations would break the verification workflow by forcin
281
280
 
282
281
  ## Verification Workflow Guide
283
282
 
284
- For detailed verification workflows, examples, and best practices, see the [Verification Workflow Guide](docs/verification-workflow-guide.md).
283
+ For detailed verification workflows, examples, and best practices, see the [Verification Workflow Guide](https://github.com/voder-ai/eslint-plugin-traceability/blob/main/docs/verification-workflow-guide.md).
285
284
 
286
285
  ## API Reference
287
286
 
@@ -430,4 +429,4 @@ For the canonical, user-facing security policy (including how to report vulnerab
430
429
  - Contribution guide: <https://github.com/voder-ai/eslint-plugin-traceability/blob/main/CONTRIBUTING.md>
431
430
  - Issue tracker: <https://github.com/voder-ai/eslint-plugin-traceability/issues>
432
431
  - Changelog: [CHANGELOG.md](CHANGELOG.md)
433
- - Versioning and Releases: This project uses semantic-release for automated versioning. The authoritative list of published versions and release notes is on GitHub Releases: <https://github.com/voder-ai/eslint-plugin-traceability/releases>
432
+ - Versioning and Releases: This project uses semantic-release for automated versioning. The authoritative list of published versions and release notes is on GitHub Releases: <https://github.com/voder-ai/eslint-plugin-traceability/releases>
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.batchUpdateAnnotations = batchUpdateAnnotations;
4
4
  exports.verifyAnnotations = verifyAnnotations;
5
- /* eslint-disable traceability/valid-annotation-format */
6
5
  const update_1 = require("./update");
7
6
  const detect_1 = require("./detect");
8
7
  /**
@@ -16,7 +15,6 @@ const detect_1 = require("./detect");
16
15
  */
17
16
  function batchUpdateAnnotations(codebasePath, mappings) {
18
17
  let totalUpdated = 0;
19
- // @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md // @req REQ-MAINT-BATCH - Perform batch updates
20
18
  for (const { oldPath, newPath } of mappings) {
21
19
  totalUpdated += (0, update_1.updateAnnotationReferences)(codebasePath, oldPath, newPath);
22
20
  }
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- /* eslint-disable traceability/valid-annotation-format */
4
3
  Object.defineProperty(exports, "__esModule", { value: true });
5
4
  exports.runMaintenanceCli = runMaintenanceCli;
6
5
  const commands_1 = require("./commands");
@@ -20,7 +19,6 @@ function runMaintenanceCli(rawArgv) {
20
19
  const { subcommand: command } = initialNormalized;
21
20
  if (!command || command === "-h" || command === "--help") {
22
21
  // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
23
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Branch to show usage when no command or help flag is provided; handle help requests safely and provide discoverable usage output
24
22
  printHelp();
25
23
  return commands_1.EXIT_OK;
26
24
  }
@@ -29,35 +27,34 @@ function runMaintenanceCli(rawArgv) {
29
27
  const normalized = initialNormalized;
30
28
  try {
31
29
  // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
32
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Catch unexpected errors and surface concise diagnostics without crashing
33
30
  switch (command) {
34
31
  case "detect":
35
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT - Branch to dispatch to detection handler when 'detect' is requested; dispatch to detection handler
32
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
36
33
  return (0, commands_1.handleDetect)(normalized);
37
34
  case "verify":
38
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-VERIFY - Branch to dispatch to verification handler when 'verify' is requested; dispatch to verification handler
35
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-VERIFY
39
36
  return (0, commands_1.handleVerify)(normalized);
40
37
  case "report":
41
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-REPORT - Branch to dispatch to reporting handler when 'report' is requested; dispatch to reporting handler
38
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-REPORT
42
39
  return (0, commands_1.handleReport)(normalized);
43
40
  case "update": {
44
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-UPDATE - Branch to dispatch to update handler when 'update' is requested; dispatch to update handler
41
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-UPDATE
45
42
  const result = (0, commands_1.handleUpdate)(normalized);
46
43
  if (result === commands_1.EXIT_USAGE) {
47
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Print help on usage errors from update; help branch for update usage errors
44
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
48
45
  printHelp();
49
46
  }
50
47
  return result;
51
48
  }
52
49
  default:
53
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Branch for unknown commands to emit diagnostics and safe usage guidance; handle unknown commands safely with diagnostics
50
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
54
51
  console.error(`Unknown command: ${command}`);
55
52
  printHelp();
56
53
  return commands_1.EXIT_USAGE;
57
54
  }
58
55
  }
59
56
  catch (error) {
60
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Catch-all error branch to prevent crashes and provide concise diagnostics; catch unexpected errors and surface concise diagnostics without crashing
57
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
61
58
  const message = error instanceof Error
62
59
  ? error.message
63
60
  : "Unknown error in maintenance CLI";
@@ -71,7 +68,7 @@ function runMaintenanceCli(rawArgv) {
71
68
  * @req REQ-MAINT-SAFE - Provide discoverable CLI usage information
72
69
  */
73
70
  function printHelp() {
74
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Help branch ensures users can discover maintenance CLI usage safely; provide discoverable CLI usage information
71
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
75
72
  console.log(`traceability-maint - Traceability annotation maintenance tools
76
73
 
77
74
  Usage:
@@ -3,7 +3,7 @@ export declare const EXIT_OK = 0;
3
3
  export declare const EXIT_STALE = 1;
4
4
  export declare const EXIT_USAGE = 2;
5
5
  /**
6
- * Handle the `detect` subcommand for stale @story annotations.
6
+ * Handle the `detect` subcommand for stale story annotations.
7
7
  * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
8
8
  * @req REQ-MAINT-DETECT - CLI surface for detection of stale annotations
9
9
  * @req REQ-MAINT-SAFE - Return specific exit codes for stale vs clean states
@@ -27,7 +27,7 @@ export declare function handleVerify(normalized: NormalizedCliArgs): number;
27
27
  */
28
28
  export declare function handleReport(normalized: NormalizedCliArgs): number;
29
29
  /**
30
- * Handle the `update` subcommand to rewrite @story annotation references.
30
+ * Handle the `update` subcommand to rewrite story annotation references.
31
31
  * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
32
32
  * @req REQ-MAINT-UPDATE - CLI surface for updating annotation references
33
33
  * @req REQ-MAINT-SAFE - Provide dry-run mode and explicit parameter checks
@@ -5,7 +5,6 @@ exports.handleDetect = handleDetect;
5
5
  exports.handleVerify = handleVerify;
6
6
  exports.handleReport = handleReport;
7
7
  exports.handleUpdate = handleUpdate;
8
- /* eslint-disable traceability/valid-annotation-format */
9
8
  /**
10
9
  * Subcommand handlers for the traceability-maint CLI.
11
10
  *
@@ -25,7 +24,7 @@ exports.EXIT_OK = 0;
25
24
  exports.EXIT_STALE = 1;
26
25
  exports.EXIT_USAGE = 2;
27
26
  /**
28
- * Handle the `detect` subcommand for stale @story annotations.
27
+ * Handle the `detect` subcommand for stale story annotations.
29
28
  * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
30
29
  * @req REQ-MAINT-DETECT - CLI surface for detection of stale annotations
31
30
  * @req REQ-MAINT-SAFE - Return specific exit codes for stale vs clean states
@@ -96,7 +95,7 @@ function handleReport(normalized) {
96
95
  return exports.EXIT_OK;
97
96
  }
98
97
  /**
99
- * Handle the `update` subcommand to rewrite @story annotation references.
98
+ * Handle the `update` subcommand to rewrite story annotation references.
100
99
  * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
101
100
  * @req REQ-MAINT-UPDATE - CLI surface for updating annotation references
102
101
  * @req REQ-MAINT-SAFE - Provide dry-run mode and explicit parameter checks
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.detectStaleAnnotations = detectStaleAnnotations;
37
- /* eslint-disable traceability/valid-annotation-format */
38
37
  const fs = __importStar(require("fs"));
39
38
  const path = __importStar(require("path"));
40
39
  const utils_1 = require("./utils");
@@ -85,7 +84,7 @@ function processFileForStaleAnnotations(file, workspaceRoot, cwd, stale) {
85
84
  }
86
85
  catch {
87
86
  // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
88
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Swallow file read failures without aborting detection
87
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
89
88
  return;
90
89
  }
91
90
  const regex = /@story\s+([^\s]+)/g;
@@ -116,7 +115,7 @@ function handleStoryMatch(storyPath, workspaceRoot, cwd, stale) {
116
115
  const inProjectCandidates = getInProjectCandidates(storyProjectCandidate, storyCodebaseCandidate, workspaceRoot);
117
116
  // If both candidates are out-of-project, do not mark as stale and skip FS checks
118
117
  if (inProjectCandidates.length === 0) {
119
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT - No in-project candidates means nothing to check or mark stale
118
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
120
119
  return;
121
120
  }
122
121
  // @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
@@ -142,7 +141,7 @@ function getInProjectCandidates(storyProjectCandidate, storyCodebaseCandidate, w
142
141
  }
143
142
  catch {
144
143
  // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
145
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Treat boundary enforcement failures as out-of-project
144
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
146
145
  projectBoundary = {
147
146
  isWithinProject: false,
148
147
  candidate: storyProjectCandidate,
@@ -154,7 +153,7 @@ function getInProjectCandidates(storyProjectCandidate, storyCodebaseCandidate, w
154
153
  }
155
154
  catch {
156
155
  // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
157
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Treat boundary enforcement failures as out-of-project
156
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
158
157
  codebaseBoundary = {
159
158
  isWithinProject: false,
160
159
  candidate: storyCodebaseCandidate,
@@ -162,11 +161,11 @@ function getInProjectCandidates(storyProjectCandidate, storyCodebaseCandidate, w
162
161
  }
163
162
  const inProjectCandidates = [];
164
163
  if (projectBoundary.isWithinProject) {
165
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT - Collect project-relative in-project candidate
164
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
166
165
  inProjectCandidates.push(projectBoundary.candidate);
167
166
  }
168
167
  if (codebaseBoundary.isWithinProject) {
169
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT - Collect workspace-root-relative in-project candidate
168
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT
170
169
  inProjectCandidates.push(codebaseBoundary.candidate);
171
170
  }
172
171
  return inProjectCandidates;
@@ -183,7 +182,7 @@ function anyInProjectCandidateExists(inProjectCandidates) {
183
182
  (p) => {
184
183
  const exists = fs.existsSync(p);
185
184
  if (!exists) {
186
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - Safely handle non-existent candidate without throwing
185
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
187
186
  }
188
187
  return exists;
189
188
  });
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateMaintenanceReport = generateMaintenanceReport;
4
- /* eslint-disable traceability/valid-annotation-format */
5
4
  const detect_1 = require("./detect");
6
5
  /**
7
6
  * Generate a report of maintenance operations performed
@@ -13,8 +12,8 @@ const detect_1 = require("./detect");
13
12
  */
14
13
  function generateMaintenanceReport(codebasePath) {
15
14
  const staleAnnotations = (0, detect_1.detectStaleAnnotations)(codebasePath);
16
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE - When no stale annotations are found, return empty string to indicate no actions required
17
- // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-REPORT - When stale annotations exist, produce a newline-separated report
15
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
16
+ // @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-REPORT
18
17
  if (staleAnnotations.length === 0) {
19
18
  return "";
20
19
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Extract requirement IDs from story file content
3
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
4
+ * @req REQ-DEEP-PARSE - Parse story file content to identify available requirements
5
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
6
+ * @req REQ-DEEP-SECTION - Handle requirements in different story file sections
7
+ */
8
+ export declare function extractRequirementsFromStoryFile(filePath: string): Set<string>;
9
+ /**
10
+ * Extract requirement IDs from story file content string
11
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
12
+ * @req REQ-DEEP-PARSE - Parse story file content to identify available requirements
13
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
14
+ * @req REQ-DEEP-SECTION - Handle requirements in different story file sections
15
+ */
16
+ export declare function extractRequirementsFromContent(content: string): Set<string>;
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.extractRequirementsFromStoryFile = extractRequirementsFromStoryFile;
37
+ exports.extractRequirementsFromContent = extractRequirementsFromContent;
38
+ /**
39
+ * Parser for extracting requirements from story files
40
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
41
+ * @req REQ-DEEP-PARSE - Parse story file content to identify available requirements
42
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
43
+ * @req REQ-DEEP-SECTION - Handle requirements in different story file sections
44
+ */
45
+ const fs = __importStar(require("fs"));
46
+ /**
47
+ * Extract requirement IDs from story file content
48
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
49
+ * @req REQ-DEEP-PARSE - Parse story file content to identify available requirements
50
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
51
+ * @req REQ-DEEP-SECTION - Handle requirements in different story file sections
52
+ */
53
+ function extractRequirementsFromStoryFile(filePath) {
54
+ try {
55
+ const content = fs.readFileSync(filePath, "utf8");
56
+ return extractRequirementsFromContent(content);
57
+ }
58
+ catch {
59
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
60
+ // @req REQ-DEEP-PARSE - Handle file read errors gracefully
61
+ return new Set();
62
+ }
63
+ }
64
+ /**
65
+ * Extract requirement IDs from story file content string
66
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
67
+ * @req REQ-DEEP-PARSE - Parse story file content to identify available requirements
68
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
69
+ * @req REQ-DEEP-SECTION - Handle requirements in different story file sections
70
+ */
71
+ function extractRequirementsFromContent(content) {
72
+ const requirements = new Set();
73
+ // Strategy 1: Extract from structured sections (## Requirements, ## Acceptance Criteria)
74
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
75
+ // @req REQ-DEEP-SECTION - Handle requirements in different story file sections
76
+ const sectionRequirements = extractFromSections(content);
77
+ sectionRequirements.forEach((req) => requirements.add(req));
78
+ // Strategy 2: Fallback to regex-based extraction for REQ-XXX-YYY patterns anywhere in file
79
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
80
+ // @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
81
+ const regexRequirements = extractWithRegex(content);
82
+ regexRequirements.forEach((req) => requirements.add(req));
83
+ return requirements;
84
+ }
85
+ /**
86
+ * Extract requirements from structured markdown sections
87
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
88
+ * @req REQ-DEEP-SECTION - Handle requirements in different story file sections
89
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
90
+ */
91
+ function extractFromSections(content) {
92
+ const requirements = new Set();
93
+ const lines = content.split("\n");
94
+ let inRequirementsSection = false;
95
+ let inAcceptanceCriteriaSection = false;
96
+ for (const line of lines) {
97
+ // Detect section headers
98
+ if (line.match(/^##\s+Requirements/i)) {
99
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
100
+ // @req REQ-DEEP-SECTION - Parse ## Requirements sections
101
+ inRequirementsSection = true;
102
+ inAcceptanceCriteriaSection = false;
103
+ continue;
104
+ }
105
+ else if (line.match(/^##\s+Acceptance\s+Criteria/i)) {
106
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
107
+ // @req REQ-DEEP-SECTION - Parse ## Acceptance Criteria sections
108
+ inAcceptanceCriteriaSection = true;
109
+ inRequirementsSection = false;
110
+ continue;
111
+ }
112
+ else if (line.match(/^##\s+/)) {
113
+ // New section that's not Requirements or Acceptance Criteria
114
+ inRequirementsSection = false;
115
+ inAcceptanceCriteriaSection = false;
116
+ continue;
117
+ }
118
+ // Extract requirements from active sections
119
+ if (inRequirementsSection || inAcceptanceCriteriaSection) {
120
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
121
+ // @req REQ-DEEP-FORMAT - Extract requirement IDs from list items
122
+ const reqIds = extractReqIdsFromLine(line);
123
+ reqIds.forEach((req) => requirements.add(req));
124
+ }
125
+ }
126
+ return requirements;
127
+ }
128
+ /**
129
+ * Extract requirement IDs from a single line
130
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
131
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
132
+ */
133
+ function extractReqIdsFromLine(line) {
134
+ const requirements = [];
135
+ // Pattern 1: - **REQ-XXX-YYY**: Description
136
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
137
+ // @req REQ-DEEP-FORMAT - Extract from bold requirement format
138
+ const boldPattern = /\*\*(REQ-[A-Z0-9-]+)\*\*/g;
139
+ let match;
140
+ while ((match = boldPattern.exec(line)) !== null) {
141
+ requirements.push(match[1]);
142
+ }
143
+ // Pattern 2: REQ-XXX-YYY anywhere in the line (not already captured)
144
+ // @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
145
+ // @req REQ-DEEP-FORMAT - Extract from plain text mentions
146
+ const plainPattern = /\b(REQ-[A-Z0-9-]+)\b/g;
147
+ while ((match = plainPattern.exec(line)) !== null) {
148
+ if (!requirements.includes(match[1])) {
149
+ requirements.push(match[1]);
150
+ }
151
+ }
152
+ return requirements;
153
+ }
154
+ /**
155
+ * Extract requirements using regex fallback (for content outside structured sections)
156
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
157
+ * @req REQ-DEEP-FORMAT - Support finding requirement IDs in multiple markdown contexts
158
+ */
159
+ function extractWithRegex(content) {
160
+ const requirements = new Set();
161
+ const regex = /\b(REQ-[A-Z0-9-]+)\b/g;
162
+ let match;
163
+ while ((match = regex.exec(content)) !== null) {
164
+ requirements.add(match[1]);
165
+ }
166
+ return requirements;
167
+ }
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.updateAnnotationReferences = updateAnnotationReferences;
37
- /* eslint-disable traceability/valid-annotation-format */
38
37
  const fs = __importStar(require("fs"));
39
38
  const utils_1 = require("./utils");
40
39
  /**
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Pattern validation helpers for valid-annotation-format options.
3
+ *
4
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
5
+ * @req REQ-REGEX-VALIDATION - Validate that configured patterns are valid regular expressions
6
+ */
7
+ /**
8
+ * Build an error message for an invalid regex pattern.
9
+ *
10
+ * @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-REGEX-VALIDATION
11
+ */
12
+ export declare function buildInvalidRegexError(field: string, pattern: string): string;
13
+ /**
14
+ * Arguments for the resolvePattern helper.
15
+ */
16
+ export interface ResolvePatternArgs {
17
+ nestedPattern: string | undefined;
18
+ nestedFieldName: string;
19
+ flatPattern: string | undefined;
20
+ flatFieldName: string;
21
+ defaultPattern: RegExp;
22
+ errors?: string[];
23
+ }
24
+ /**
25
+ * Resolve a user-configured regex pattern, handling both nested and flat
26
+ * configuration shapes and accumulating validation errors.
27
+ *
28
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
29
+ * @req REQ-PATTERN-CONFIG
30
+ * @req REQ-REGEX-VALIDATION
31
+ * @req REQ-BACKWARD-COMPAT
32
+ */
33
+ export declare function resolvePattern({ nestedPattern, nestedFieldName, flatPattern, flatFieldName, defaultPattern, errors, }: ResolvePatternArgs): RegExp;
34
+ /**
35
+ * Resolve an example string, preferring nested over flat configuration,
36
+ * and falling back to the provided default when necessary.
37
+ *
38
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
39
+ * @req REQ-EXAMPLE-MESSAGES
40
+ * @req REQ-BACKWARD-COMPAT
41
+ */
42
+ export declare function resolveExample(nestedExample: string | undefined, flatExample: string | undefined, defaultExample: string): string;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Pattern validation helpers for valid-annotation-format options.
4
+ *
5
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
6
+ * @req REQ-REGEX-VALIDATION - Validate that configured patterns are valid regular expressions
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.buildInvalidRegexError = buildInvalidRegexError;
10
+ exports.resolvePattern = resolvePattern;
11
+ exports.resolveExample = resolveExample;
12
+ /**
13
+ * Build an error message for an invalid regex pattern.
14
+ *
15
+ * @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-REGEX-VALIDATION
16
+ */
17
+ function buildInvalidRegexError(field, pattern) {
18
+ return `Invalid regular expression for option "${field}": "${pattern}"`;
19
+ }
20
+ /**
21
+ * Resolve a user-configured regex pattern, handling both nested and flat
22
+ * configuration shapes and accumulating validation errors.
23
+ *
24
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
25
+ * @req REQ-PATTERN-CONFIG
26
+ * @req REQ-REGEX-VALIDATION
27
+ * @req REQ-BACKWARD-COMPAT
28
+ */
29
+ function resolvePattern({ nestedPattern, nestedFieldName, flatPattern, flatFieldName, defaultPattern, errors, }) {
30
+ const effective = typeof nestedPattern === "string"
31
+ ? { value: nestedPattern, field: nestedFieldName }
32
+ : typeof flatPattern === "string"
33
+ ? { value: flatPattern, field: flatFieldName }
34
+ : null;
35
+ if (!effective) {
36
+ return defaultPattern;
37
+ }
38
+ try {
39
+ return new RegExp(effective.value);
40
+ }
41
+ catch {
42
+ const error = buildInvalidRegexError(effective.field, effective.value);
43
+ if (errors) {
44
+ errors.push(error);
45
+ }
46
+ return defaultPattern;
47
+ }
48
+ }
49
+ /**
50
+ * Resolve an example string, preferring nested over flat configuration,
51
+ * and falling back to the provided default when necessary.
52
+ *
53
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
54
+ * @req REQ-EXAMPLE-MESSAGES
55
+ * @req REQ-BACKWARD-COMPAT
56
+ */
57
+ function resolveExample(nestedExample, flatExample, defaultExample) {
58
+ if (typeof nestedExample === "string" && nestedExample.trim()) {
59
+ return nestedExample;
60
+ }
61
+ if (typeof flatExample === "string" && flatExample.trim()) {
62
+ return flatExample;
63
+ }
64
+ return defaultExample;
65
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Inline comment processing for prefer-implements-annotation rule.
3
+ * Handles migration of inline comment story and requirement patterns to supports format.
4
+ *
5
+ * @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
6
+ * @req REQ-MIGRATE-INLINE
7
+ */
8
+ import type { Rule } from "eslint";
9
+ export type LineComment = {
10
+ type: "Line";
11
+ } & any;
12
+ /**
13
+ * Scan sequences of Line comments for inline legacy story and requirement patterns
14
+ * and report diagnostics with optional auto-fixes.
15
+ */
16
+ export declare function processInlineComments(context: Rule.RuleContext, lineComments: LineComment[]): void;