eslint-plugin-traceability 1.11.0 → 1.11.2

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 (84) hide show
  1. package/CHANGELOG.md +3 -4
  2. package/README.md +1 -1
  3. package/lib/src/index.d.ts +12 -1
  4. package/lib/src/index.js +43 -6
  5. package/lib/src/maintenance/commands.js +2 -3
  6. package/lib/src/maintenance/flags.js +111 -25
  7. package/lib/src/maintenance/update.js +1 -14
  8. package/lib/src/rules/helpers/require-story-core.d.ts +67 -0
  9. package/lib/src/rules/helpers/require-story-core.js +142 -23
  10. package/lib/src/rules/helpers/require-story-helpers.d.ts +9 -88
  11. package/lib/src/rules/helpers/require-story-helpers.js +118 -166
  12. package/lib/src/rules/helpers/require-story-io.js +51 -31
  13. package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +12 -13
  14. package/lib/src/rules/helpers/valid-annotation-format-internal.js +21 -16
  15. package/lib/src/rules/helpers/valid-annotation-format-validators.d.ts +29 -3
  16. package/lib/src/rules/helpers/valid-annotation-format-validators.js +29 -3
  17. package/lib/src/rules/helpers/valid-annotation-options.d.ts +3 -0
  18. package/lib/src/rules/helpers/valid-annotation-options.js +64 -21
  19. package/lib/src/rules/helpers/valid-annotation-utils.d.ts +3 -3
  20. package/lib/src/rules/helpers/valid-annotation-utils.js +10 -10
  21. package/lib/src/rules/helpers/valid-req-reference-helpers.d.ts +11 -0
  22. package/lib/src/rules/helpers/valid-req-reference-helpers.js +362 -0
  23. package/lib/src/rules/prefer-implements-annotation.js +7 -7
  24. package/lib/src/rules/require-story-annotation.d.ts +2 -0
  25. package/lib/src/rules/require-story-annotation.js +1 -1
  26. package/lib/src/rules/valid-req-reference.d.ts +4 -0
  27. package/lib/src/rules/valid-req-reference.js +5 -349
  28. package/lib/src/rules/valid-story-reference.d.ts +1 -1
  29. package/lib/src/rules/valid-story-reference.js +17 -10
  30. package/lib/src/utils/annotation-checker.js +31 -7
  31. package/lib/src/utils/branch-annotation-helpers.d.ts +2 -2
  32. package/lib/src/utils/branch-annotation-helpers.js +4 -4
  33. package/lib/src/utils/reqAnnotationDetection.js +36 -22
  34. package/lib/tests/cli-error-handling.test.js +2 -1
  35. package/lib/tests/config/eslint-config-validation.test.d.ts +8 -0
  36. package/lib/tests/config/eslint-config-validation.test.js +81 -0
  37. package/lib/tests/config/flat-config-presets-integration.test.js +1 -3
  38. package/lib/tests/config/require-story-annotation-config.test.d.ts +9 -0
  39. package/lib/tests/config/require-story-annotation-config.test.js +9 -0
  40. package/lib/tests/fixtures/stale/example.js +1 -1
  41. package/lib/tests/fixtures/update/example.js +1 -1
  42. package/lib/tests/integration/cli-integration.test.js +9 -1
  43. package/lib/tests/integration/dogfooding-validation.test.d.ts +1 -0
  44. package/lib/tests/integration/dogfooding-validation.test.js +94 -0
  45. package/lib/tests/maintenance/batch.test.js +1 -0
  46. package/lib/tests/maintenance/cli.test.js +38 -0
  47. package/lib/tests/maintenance/detect-isolated.test.js +6 -5
  48. package/lib/tests/maintenance/detect.test.js +1 -0
  49. package/lib/tests/maintenance/index.test.js +1 -0
  50. package/lib/tests/maintenance/report.test.js +1 -0
  51. package/lib/tests/maintenance/update-isolated.test.js +1 -0
  52. package/lib/tests/maintenance/update.test.js +1 -0
  53. package/lib/tests/perf/maintenance-cli-large-workspace.test.js +18 -0
  54. package/lib/tests/perf/require-branch-annotation-large-file.test.d.ts +1 -0
  55. package/lib/tests/perf/require-branch-annotation-large-file.test.js +67 -0
  56. package/lib/tests/plugin-default-export-and-configs.test.js +2 -0
  57. package/lib/tests/plugin-setup-error.test.d.ts +1 -0
  58. package/lib/tests/plugin-setup-error.test.js +1 -0
  59. package/lib/tests/plugin-setup.test.js +12 -1
  60. package/lib/tests/rules/auto-fix-behavior-008.test.js +16 -0
  61. package/lib/tests/rules/error-reporting.test.js +1 -0
  62. package/lib/tests/rules/prefer-implements-annotation.test.js +8 -0
  63. package/lib/tests/rules/require-branch-annotation.test.js +34 -0
  64. package/lib/tests/rules/require-story-core-edgecases.test.js +1 -0
  65. package/lib/tests/rules/require-story-core.autofix.test.js +1 -0
  66. package/lib/tests/rules/require-story-core.test.js +1 -0
  67. package/lib/tests/rules/require-story-helpers-edgecases.test.d.ts +1 -0
  68. package/lib/tests/rules/require-story-helpers-edgecases.test.js +1 -0
  69. package/lib/tests/rules/require-story-helpers.test.js +4 -3
  70. package/lib/tests/rules/require-story-io-behavior.test.d.ts +1 -0
  71. package/lib/tests/rules/require-story-io-behavior.test.js +1 -0
  72. package/lib/tests/rules/require-story-io.edgecases.test.d.ts +1 -0
  73. package/lib/tests/rules/require-story-io.edgecases.test.js +1 -0
  74. package/lib/tests/rules/require-story-visitors-edgecases.test.d.ts +1 -0
  75. package/lib/tests/rules/require-story-visitors-edgecases.test.js +1 -0
  76. package/lib/tests/rules/valid-annotation-format-internal.test.d.ts +8 -0
  77. package/lib/tests/rules/valid-annotation-format-internal.test.js +47 -0
  78. package/lib/tests/rules/valid-story-reference.test.js +2 -0
  79. package/lib/tests/utils/annotation-checker.test.js +2 -1
  80. package/lib/tests/utils/branch-annotation-helpers.test.js +2 -1
  81. package/package.json +2 -2
  82. package/user-docs/api-reference.md +115 -8
  83. package/user-docs/examples.md +1 -1
  84. package/user-docs/migration-guide.md +35 -2
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createValidReqReferenceProgramVisitor = createValidReqReferenceProgramVisitor;
7
+ /* eslint-env node */
8
+ /**
9
+ * Helper utilities for the "valid-req-reference" rule.
10
+ *
11
+ * These helpers encapsulate the deep-validation logic for @req and
12
+ * @supports annotations so that the rule module can remain focused on
13
+ * wiring into ESLint. They are intentionally structured as a set of
14
+ * small, single-responsibility functions that can be reused and tested
15
+ * in isolation if needed.
16
+ *
17
+ * @supports docs/stories/010.0-DEV-DEEP-VALIDATION.story.md REQ-DEEP-PARSE REQ-DEEP-MATCH REQ-DEEP-CACHE
18
+ * @supports docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md REQ-SUPPORTS-VALIDATE REQ-MIXED-SUPPORT REQ-SCOPED-IDS
19
+ */
20
+ const fs_1 = __importDefault(require("fs"));
21
+ const path_1 = __importDefault(require("path"));
22
+ /**
23
+ * Token index configuration for @supports annotations.
24
+ * This clarifies the expected positions of the story path and first requirement ID
25
+ * and avoids hard-coded "magic number" indices in parsing logic.
26
+ * @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
27
+ */
28
+ const IMPLEMENTS_TOKENS = {
29
+ STORY_INDEX: 1,
30
+ FIRST_REQ_INDEX: 2,
31
+ };
32
+ /**
33
+ * Extract the story path from a JSDoc comment.
34
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
35
+ * @req REQ-DEEP-PARSE - Parse JSDoc comment lines to locate @story annotations
36
+ */
37
+ function extractStoryPath(comment) {
38
+ const rawLines = comment.value.split(/\r?\n/);
39
+ for (const rawLine of rawLines) {
40
+ const line = rawLine.trim().replace(/^\*+\s*/, "");
41
+ if (line.startsWith("@story")) {
42
+ const parts = line.split(/\s+/);
43
+ return parts[1] || null;
44
+ }
45
+ }
46
+ return null;
47
+ }
48
+ /**
49
+ * Validate and resolve the referenced story path.
50
+ * Performs traversal/absolute checks and resolves to a disk path.
51
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
52
+ * @req REQ-DEEP-CACHE - Validate and resolve referenced story file paths
53
+ */
54
+ function validateAndResolveStoryPath(opts) {
55
+ const { comment, context, storyPath, cwd } = opts;
56
+ if (storyPath.includes("..") || path_1.default.isAbsolute(storyPath)) {
57
+ context.report({
58
+ node: comment,
59
+ messageId: "invalidPath",
60
+ data: { storyPath },
61
+ });
62
+ return null;
63
+ }
64
+ const resolvedStoryPath = path_1.default.resolve(cwd, storyPath);
65
+ if (!resolvedStoryPath.startsWith(cwd + path_1.default.sep) &&
66
+ resolvedStoryPath !== cwd) {
67
+ context.report({
68
+ node: comment,
69
+ messageId: "invalidPath",
70
+ data: { storyPath },
71
+ });
72
+ return null;
73
+ }
74
+ return resolvedStoryPath;
75
+ }
76
+ /**
77
+ * Load and cache requirement IDs from a story file.
78
+ * Reads the story file, extracts requirement IDs, and updates the cache.
79
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
80
+ * @req REQ-DEEP-CACHE - Cache requirement IDs discovered in story files
81
+ * @req REQ-DEEP-PARSE - Parse story file contents to extract requirement identifiers
82
+ */
83
+ function loadAndCacheRequirements(opts) {
84
+ const { resolvedStoryPath, reqCache } = opts;
85
+ if (!reqCache.has(resolvedStoryPath)) {
86
+ try {
87
+ const content = fs_1.default.readFileSync(resolvedStoryPath, "utf8");
88
+ const found = new Set();
89
+ const regex = /REQ-[A-Z0-9-]+/g;
90
+ let match;
91
+ while ((match = regex.exec(content)) !== null) {
92
+ found.add(match[0]);
93
+ }
94
+ reqCache.set(resolvedStoryPath, found);
95
+ }
96
+ catch {
97
+ reqCache.set(resolvedStoryPath, new Set());
98
+ }
99
+ }
100
+ return reqCache.get(resolvedStoryPath);
101
+ }
102
+ /**
103
+ * Perform the final requirement existence check and report if missing.
104
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
105
+ * @req REQ-DEEP-MATCH - Verify that a referenced requirement ID exists in the story
106
+ */
107
+ function checkRequirementExists(opts) {
108
+ const { comment, context, reqId, storyPath, reqSet } = opts;
109
+ if (!reqSet.has(reqId)) {
110
+ context.report({
111
+ node: comment,
112
+ messageId: "reqMissing",
113
+ data: { reqId, storyPath },
114
+ });
115
+ }
116
+ }
117
+ /**
118
+ * Extract requirement ID from a @req line.
119
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
120
+ * @req REQ-DEEP-PARSE - Parse annotation lines to extract requirement IDs
121
+ */
122
+ function extractReqIdFromLine(line) {
123
+ const parts = line.split(/\s+/);
124
+ return parts[1];
125
+ }
126
+ /**
127
+ * Resolve story path and load requirements set for validation.
128
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
129
+ * @req REQ-DEEP-CACHE - Validate and resolve referenced story file paths
130
+ * @req REQ-DEEP-CACHE - Cache requirement IDs discovered in story files
131
+ */
132
+ function resolveStoryAndRequirements(opts) {
133
+ const { comment, context, storyPath, cwd, reqCache } = opts;
134
+ const resolvedStoryPath = validateAndResolveStoryPath({
135
+ comment,
136
+ context,
137
+ storyPath,
138
+ cwd,
139
+ });
140
+ if (!resolvedStoryPath) {
141
+ return { resolvedStoryPath: null, reqSet: null };
142
+ }
143
+ const reqSet = loadAndCacheRequirements({
144
+ resolvedStoryPath,
145
+ reqCache,
146
+ });
147
+ return { resolvedStoryPath, reqSet };
148
+ }
149
+ /**
150
+ * Validate a @req annotation line against the extracted story content.
151
+ * Performs path validation, file reading, caching, and requirement existence checks.
152
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
153
+ * @req REQ-DEEP-CACHE - Validate and resolve referenced story file paths
154
+ * @req REQ-DEEP-CACHE - Cache requirement IDs discovered in story files
155
+ * @req REQ-DEEP-MATCH - Verify that a referenced requirement ID exists in the story
156
+ * @req REQ-DEEP-PARSE - Parse story file contents to extract requirement identifiers
157
+ */
158
+ function validateReqLine(opts) {
159
+ const { comment, context, line, storyPath, cwd, reqCache } = opts;
160
+ const reqId = extractReqIdFromLine(line);
161
+ if (!reqId || !storyPath) {
162
+ return;
163
+ }
164
+ const { reqSet } = resolveStoryAndRequirements({
165
+ comment,
166
+ context,
167
+ storyPath,
168
+ cwd,
169
+ reqCache,
170
+ });
171
+ if (!reqSet) {
172
+ return;
173
+ }
174
+ checkRequirementExists({
175
+ comment,
176
+ context,
177
+ reqId,
178
+ storyPath,
179
+ reqSet,
180
+ });
181
+ }
182
+ /**
183
+ * Parse a @supports annotation line into its story path and requirement IDs.
184
+ * Expects the format: "@supports <storyPath> <REQ-ID-1> <REQ-ID-2> ..."
185
+ * Invalid formats (missing storyPath or reqIds) are ignored by this deep rule.
186
+ * @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
187
+ * @req REQ-SUPPORTS-VALIDATE - Support validation of @supports annotations
188
+ * @req REQ-MIXED-SUPPORT - Allow mixed @story/@req/@implements usage in the same comment
189
+ * @req REQ-SCOPED-IDS - Treat requirement IDs as scoped to the referenced story file
190
+ */
191
+ function parseImplementsLine(line) {
192
+ const parts = line.split(/\s+/);
193
+ const storyPath = parts[IMPLEMENTS_TOKENS.STORY_INDEX];
194
+ const reqIds = parts.slice(IMPLEMENTS_TOKENS.FIRST_REQ_INDEX);
195
+ if (!storyPath || reqIds.length === 0) {
196
+ return null;
197
+ }
198
+ return { storyPath, reqIds };
199
+ }
200
+ /**
201
+ * Validate an @supports annotation line against the referenced story content.
202
+ * Performs path validation, file reading, caching, and requirement existence checks
203
+ * for each requirement ID listed on the line.
204
+ * @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
205
+ * @req REQ-SUPPORTS-VALIDATE - Validate that all @supports requirement IDs exist
206
+ * @req REQ-MIXED-SUPPORT - Ensure @supports can coexist with @story/@req annotations
207
+ * @req REQ-SCOPED-IDS - Validate requirement IDs in the scope of their explicit story
208
+ */
209
+ function validateImplementsLine(opts) {
210
+ const { comment, context, line, cwd, reqCache } = opts;
211
+ const parsed = parseImplementsLine(line);
212
+ if (!parsed) {
213
+ return;
214
+ }
215
+ const { storyPath, reqIds } = parsed;
216
+ const { reqSet } = resolveStoryAndRequirements({
217
+ comment,
218
+ context,
219
+ storyPath,
220
+ cwd,
221
+ reqCache,
222
+ });
223
+ if (!reqSet) {
224
+ return;
225
+ }
226
+ for (const reqId of reqIds) {
227
+ checkRequirementExists({
228
+ comment,
229
+ context,
230
+ reqId,
231
+ storyPath,
232
+ reqSet,
233
+ });
234
+ }
235
+ }
236
+ /**
237
+ * Handle a single annotation line for story or requirement metadata.
238
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
239
+ * @req REQ-DEEP-PARSE - Parse annotation lines for @story, @req, and @supports tags
240
+ * @req REQ-DEEP-MATCH - Dispatch @req lines for validation against story requirements
241
+ * @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
242
+ * @req REQ-SUPPORTS-VALIDATE - Dispatch @supports lines for validation
243
+ * @req REQ-MIXED-SUPPORT - Support mixed annotation types without interfering with each other
244
+ */
245
+ function handleAnnotationLine(opts) {
246
+ const { line, comment, context, cwd, reqCache, storyPath } = opts;
247
+ if (line.startsWith("@story")) {
248
+ const newPath = extractStoryPath(comment);
249
+ return newPath || storyPath;
250
+ }
251
+ else if (line.startsWith("@req")) {
252
+ validateReqLine({ comment, context, line, storyPath, cwd, reqCache });
253
+ return storyPath;
254
+ }
255
+ else if (line.startsWith("@supports")) {
256
+ validateImplementsLine({ comment, context, line, cwd, reqCache });
257
+ return storyPath;
258
+ }
259
+ return storyPath;
260
+ }
261
+ /**
262
+ * Iterate over all raw lines in a comment and update storyPath as needed.
263
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
264
+ * @req REQ-DEEP-PARSE - Iterate comment lines to process @story/@req annotations
265
+ * @req REQ-DEEP-MATCH - Coordinate annotation handling across a comment block
266
+ */
267
+ function processCommentLines(opts) {
268
+ const { comment, context, cwd, reqCache, initialStoryPath } = opts;
269
+ let storyPath = initialStoryPath;
270
+ const rawLines = comment.value.split(/\r?\n/);
271
+ for (const rawLine of rawLines) {
272
+ const line = rawLine.trim().replace(/^\*+\s*/, "");
273
+ storyPath = handleAnnotationLine({
274
+ line,
275
+ comment,
276
+ context,
277
+ cwd,
278
+ reqCache,
279
+ storyPath,
280
+ });
281
+ }
282
+ return storyPath;
283
+ }
284
+ /**
285
+ * Handle JSDoc story and req annotations for a single comment block.
286
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
287
+ * @req REQ-DEEP-PARSE - Iterate comment lines to process @story/@req annotations
288
+ * @req REQ-DEEP-MATCH - Coordinate annotation handling across a comment block
289
+ * @req REQ-DEEP-CACHE - Maintain and reuse discovered story path across comments
290
+ */
291
+ function handleComment(opts) {
292
+ const { comment, context, cwd, reqCache, rawStoryPath } = opts;
293
+ return processCommentLines({
294
+ comment,
295
+ context,
296
+ cwd,
297
+ reqCache,
298
+ initialStoryPath: rawStoryPath,
299
+ });
300
+ }
301
+ /**
302
+ * Get all comments from source and drive comment-level handling.
303
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
304
+ * @req REQ-DEEP-PARSE - Collect all comments from the source code
305
+ * @req REQ-DEEP-MATCH - Drive comment-level handling for traceability checks
306
+ * @req REQ-DEEP-CACHE - Reuse story path and requirement cache across comments
307
+ */
308
+ function processAllComments(opts) {
309
+ const { sourceCode, context, cwd, reqCache } = opts;
310
+ let rawStoryPath = opts.initialStoryPath;
311
+ const comments = sourceCode.getAllComments() || [];
312
+ comments.forEach((comment) => {
313
+ rawStoryPath = handleComment({
314
+ comment,
315
+ context,
316
+ cwd,
317
+ reqCache,
318
+ rawStoryPath,
319
+ });
320
+ });
321
+ }
322
+ /**
323
+ * Create a Program listener that iterates comments and validates annotations.
324
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
325
+ * @req REQ-DEEP-CACHE - Initialize and share a requirement cache for the program
326
+ * @req REQ-DEEP-CACHE - Derive the working directory context for path resolution
327
+ */
328
+ function programListener(context) {
329
+ const sourceCode = context.getSourceCode();
330
+ const cwd = process.cwd();
331
+ const reqCache = new Map();
332
+ let rawStoryPath = null;
333
+ /**
334
+ * Program visitor that walks all comments to validate story/requirement references.
335
+ * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
336
+ * @req REQ-DEEP-PARSE - Collect all comments from the source code
337
+ * @req REQ-DEEP-MATCH - Drive comment-level handling for traceability checks
338
+ * @req REQ-DEEP-CACHE - Reuse story path and requirement cache across comments
339
+ * @req REQ-DEEP-CACHE - Ensure validation respects project-relative paths
340
+ */
341
+ return function Program() {
342
+ processAllComments({
343
+ sourceCode,
344
+ context,
345
+ cwd,
346
+ reqCache,
347
+ initialStoryPath: rawStoryPath,
348
+ });
349
+ };
350
+ }
351
+ /**
352
+ * Factory used by the valid-req-reference rule to construct its Program
353
+ * visitor. Keeping this in a helper module allows the rule entrypoint
354
+ * itself to remain small and focused on meta configuration while the
355
+ * heavier deep-validation logic is encapsulated here.
356
+ *
357
+ * @supports docs/stories/010.0-DEV-DEEP-VALIDATION.story.md REQ-DEEP-PARSE REQ-DEEP-MATCH REQ-DEEP-CACHE
358
+ * @supports docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md REQ-SUPPORTS-VALIDATE REQ-MIXED-SUPPORT REQ-SCOPED-IDS
359
+ */
360
+ function createValidReqReferenceProgramVisitor(context) {
361
+ return programListener(context);
362
+ }
@@ -100,15 +100,15 @@ function applyImplementsReplacement(context, comment, details) {
100
100
  * preserving the original comment formatting.
101
101
  *
102
102
  * The fixer is intentionally conservative and only activates when:
103
- * - There is exactly one distinct `@story` path.
104
- * - Exactly one `@story` line is present.
105
- * - At least one `@req` line is present.
106
- * - Each `@req` line has the simple form `@req <REQ-ID>` (no extra tokens).
103
+ * This rule requires that there is exactly one distinct `@story` path.
104
+ * It also requires that exactly one `@story` line is present.
105
+ * It requires that at least one `@req` line is present.
106
+ * It also requires that each `@req` line has the simple form `@req <REQ-ID>` (no extra tokens).
107
107
  *
108
108
  * When applicable, the fix:
109
- * - Removes the original `@story` and `@req` lines.
110
- * - Inserts a single `@supports` line in their place, preserving the
111
- * original leading comment prefix (indentation and `*` markers).
109
+ * It removes the original `@story` and `@req` lines.
110
+ * It then inserts a single `@supports` line in their place, preserving the
111
+ * original leading comment prefix (indentation and `*` markers).
112
112
  *
113
113
  * More complex patterns remain diagnostics-only with no fix to avoid
114
114
  * producing invalid or ambiguous output.
@@ -3,6 +3,8 @@
3
3
  *
4
4
  * This file implements the ESLint rule that requires @story annotations
5
5
  * on functions and methods according to configured scope and export priority.
6
+ * Example: see docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md for function annotations,
7
+ * and docs/stories/008.0-DEV-AUTO-FIX.story.md for auto-fix behavior.
6
8
  *
7
9
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
8
10
  * @story docs/stories/008.0-DEV-AUTO-FIX.story.md
@@ -33,7 +33,7 @@ const rule = {
33
33
  */
34
34
  fixable: "code",
35
35
  messages: {
36
- missingStory: "Function '{{name}}' must have an explicit @story annotation. Add a JSDoc or line comment with @story that points to the implementing story file (for example, docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md).",
36
+ missingStory: "Function '{{name}}' must have an explicit @story annotation. Add a JSDoc or line comment with @story that points to the implementing story file, such as docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md.",
37
37
  },
38
38
  schema: [
39
39
  {
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Rule to validate @req annotation references refer to existing requirements in story files.
3
+ * Uses shared helpers from the valid-req-reference-helpers module.
4
+ */
1
5
  import type { Rule } from "eslint";
2
6
  declare const _default: Rule.RuleModule;
3
7
  export default _default;