safeword 0.62.0 → 0.63.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 (100) hide show
  1. package/dist/{architecture-WFRA4ITA.js → architecture-T4RR7Q5J.js} +2 -2
  2. package/dist/{check-FH7FC7IG.js → check-MUL6YRIO.js} +7 -7
  3. package/dist/{chunk-XTLCJKGE.js → chunk-6BEAVNR2.js} +56 -16
  4. package/dist/chunk-6BEAVNR2.js.map +1 -0
  5. package/dist/{chunk-G7IU3XBI.js → chunk-7F523R3I.js} +643 -457
  6. package/dist/chunk-7F523R3I.js.map +1 -0
  7. package/dist/{chunk-D4UGNHLW.js → chunk-CYITXCZO.js} +2 -2
  8. package/dist/{chunk-HWOJR33A.js → chunk-DN67MPYH.js} +61 -22
  9. package/dist/chunk-DN67MPYH.js.map +1 -0
  10. package/dist/{chunk-HI7ANNQI.js → chunk-FTMQT2V3.js} +7 -1
  11. package/dist/chunk-FTMQT2V3.js.map +1 -0
  12. package/dist/{chunk-ILTC7KBQ.js → chunk-IDTVO3BJ.js} +11 -1
  13. package/dist/chunk-IDTVO3BJ.js.map +1 -0
  14. package/dist/{chunk-AA3G2VTE.js → chunk-OE6HYAWU.js} +2 -2
  15. package/dist/{chunk-2IK7L4EZ.js → chunk-ZBFYIJNE.js} +62 -12
  16. package/dist/chunk-ZBFYIJNE.js.map +1 -0
  17. package/dist/cli.js +33 -21
  18. package/dist/cli.js.map +1 -1
  19. package/dist/{codify-BXBG5XPK.js → codify-SPIWSH2R.js} +4 -4
  20. package/dist/{diff-LLE62QKI.js → diff-BZOC4JXC.js} +3 -3
  21. package/dist/index.d.ts +14 -0
  22. package/dist/{lint-gherkin-FLJEH3EJ.js → lint-gherkin-RKLOOSNO.js} +4 -2
  23. package/dist/{lint-gherkin-FLJEH3EJ.js.map → lint-gherkin-RKLOOSNO.js.map} +1 -1
  24. package/dist/{reset-NBZGOP4I.js → reset-646VL6X4.js} +3 -3
  25. package/dist/{retro-ART3JCCW.js → retro-GGVK4BYL.js} +3 -3
  26. package/dist/retro-GGVK4BYL.js.map +1 -0
  27. package/dist/{self-report-XLBFP2NT.js → self-report-MZ2CP23A.js} +4 -2
  28. package/dist/{self-report-AQZKGDAS.js → self-report-SMDJD2UO.js} +2 -2
  29. package/dist/{setup-46AW3EOX.js → setup-Q4Y7Y6PN.js} +21 -8
  30. package/dist/{setup-46AW3EOX.js.map → setup-Q4Y7Y6PN.js.map} +1 -1
  31. package/dist/{sync-learnings-BVNUNLPD.js → sync-learnings-THGNXZCT.js} +2 -2
  32. package/dist/{sync-tickets-4TOJBDHW.js → sync-tickets-P2FFD7DH.js} +3 -3
  33. package/dist/{sync-tracker-U4TKFX4R.js → sync-tracker-SV6AEV2O.js} +3 -3
  34. package/dist/{ticket-new-PIHZGZGG.js → ticket-new-K4X2ZO6V.js} +2 -2
  35. package/dist/{upgrade-JELXQM56.js → upgrade-R52BFPBM.js} +15 -13
  36. package/dist/upgrade-R52BFPBM.js.map +1 -0
  37. package/package.json +1 -1
  38. package/templates/agents/safeword-retro-filer.md +50 -0
  39. package/templates/agents/safeword-retro-filer.toml +47 -0
  40. package/templates/codex/config.toml +9 -0
  41. package/templates/commands/self-review.md +4 -2
  42. package/templates/commands/verify.md +2 -304
  43. package/templates/cucumber/cucumber.mjs +42 -2
  44. package/templates/doc-templates/ticket-template.md +1 -1
  45. package/templates/guides/self-report-filing.md +31 -21
  46. package/templates/hooks/codex/post-tool-quality.ts +56 -0
  47. package/templates/hooks/codex/post-tool-skill-nudge.ts +2 -17
  48. package/templates/hooks/codex/pre-tool-quality-helpers.ts +24 -0
  49. package/templates/hooks/codex/pre-tool-quality.ts +21 -19
  50. package/templates/hooks/codex/stop.ts +21 -5
  51. package/templates/hooks/cursor/before-shell-execution.ts +23 -6
  52. package/templates/hooks/cursor/gate-adapter.ts +9 -103
  53. package/templates/hooks/cursor/stop.ts +17 -4
  54. package/templates/hooks/lib/bash-ledger-writes.ts +216 -0
  55. package/templates/hooks/lib/cursor-run-identity.ts +114 -10
  56. package/templates/hooks/lib/jtbd.ts +1 -1
  57. package/templates/hooks/lib/lint-config.ts +48 -1
  58. package/templates/hooks/lib/lint.ts +42 -4
  59. package/templates/hooks/lib/phase-provenance.ts +263 -0
  60. package/templates/hooks/lib/retro-draft-spool.ts +43 -3
  61. package/templates/hooks/lib/retro-filing-gate.ts +192 -0
  62. package/templates/hooks/lib/retro-nudge.ts +4 -4
  63. package/templates/hooks/lib/self-report.ts +16 -0
  64. package/templates/hooks/lib/shell-segments.ts +116 -0
  65. package/templates/hooks/post-tool-quality.ts +59 -7
  66. package/templates/hooks/pre-tool-quality.ts +46 -5
  67. package/templates/hooks/prompt-retro-nudge.ts +9 -6
  68. package/templates/hooks/stop-quality.ts +1 -1
  69. package/templates/hooks/stop-retro-filing.ts +62 -0
  70. package/templates/hooks/write-review-stamp.ts +76 -12
  71. package/templates/skills/audit/SKILL.md +25 -24
  72. package/templates/skills/bdd/DISCOVERY.md +1 -0
  73. package/templates/skills/bdd/SCENARIOS.md +30 -0
  74. package/templates/skills/bdd/SKILL.md +3 -3
  75. package/templates/skills/bdd/TDD.md +2 -2
  76. package/templates/skills/self-review/SKILL.md +3 -2
  77. package/templates/skills/ticket-system/SKILL.md +2 -1
  78. package/templates/skills/verify/SKILL.md +13 -7
  79. package/templates/spec-template.md +4 -0
  80. package/dist/chunk-2IK7L4EZ.js.map +0 -1
  81. package/dist/chunk-G7IU3XBI.js.map +0 -1
  82. package/dist/chunk-HI7ANNQI.js.map +0 -1
  83. package/dist/chunk-HWOJR33A.js.map +0 -1
  84. package/dist/chunk-ILTC7KBQ.js.map +0 -1
  85. package/dist/chunk-XTLCJKGE.js.map +0 -1
  86. package/dist/retro-ART3JCCW.js.map +0 -1
  87. package/dist/upgrade-JELXQM56.js.map +0 -1
  88. /package/dist/{architecture-WFRA4ITA.js.map → architecture-T4RR7Q5J.js.map} +0 -0
  89. /package/dist/{check-FH7FC7IG.js.map → check-MUL6YRIO.js.map} +0 -0
  90. /package/dist/{chunk-D4UGNHLW.js.map → chunk-CYITXCZO.js.map} +0 -0
  91. /package/dist/{chunk-AA3G2VTE.js.map → chunk-OE6HYAWU.js.map} +0 -0
  92. /package/dist/{codify-BXBG5XPK.js.map → codify-SPIWSH2R.js.map} +0 -0
  93. /package/dist/{diff-LLE62QKI.js.map → diff-BZOC4JXC.js.map} +0 -0
  94. /package/dist/{reset-NBZGOP4I.js.map → reset-646VL6X4.js.map} +0 -0
  95. /package/dist/{self-report-XLBFP2NT.js.map → self-report-MZ2CP23A.js.map} +0 -0
  96. /package/dist/{self-report-AQZKGDAS.js.map → self-report-SMDJD2UO.js.map} +0 -0
  97. /package/dist/{sync-learnings-BVNUNLPD.js.map → sync-learnings-THGNXZCT.js.map} +0 -0
  98. /package/dist/{sync-tickets-4TOJBDHW.js.map → sync-tickets-P2FFD7DH.js.map} +0 -0
  99. /package/dist/{sync-tracker-U4TKFX4R.js.map → sync-tracker-SV6AEV2O.js.map} +0 -0
  100. /package/dist/{ticket-new-PIHZGZGG.js.map → ticket-new-K4X2ZO6V.js.map} +0 -0
@@ -2,7 +2,7 @@ import {
2
2
  GENERATED_ARCHITECTURE_FILENAME,
3
3
  isArchitectureDocumentEnforcementEnabled,
4
4
  resolveGeneratedArchitecturePath
5
- } from "./chunk-HI7ANNQI.js";
5
+ } from "./chunk-FTMQT2V3.js";
6
6
  import {
7
7
  exists,
8
8
  isDirectory,
@@ -976,4 +976,4 @@ function architectureCheck(cwd) {
976
976
  export {
977
977
  architecture
978
978
  };
979
- //# sourceMappingURL=architecture-WFRA4ITA.js.map
979
+ //# sourceMappingURL=architecture-T4RR7Q5J.js.map
@@ -4,22 +4,22 @@ import {
4
4
  import {
5
5
  checkHealth,
6
6
  reportHealthSummary
7
- } from "./chunk-2IK7L4EZ.js";
8
- import "./chunk-HWOJR33A.js";
9
- import "./chunk-XTLCJKGE.js";
7
+ } from "./chunk-ZBFYIJNE.js";
8
+ import "./chunk-DN67MPYH.js";
9
+ import "./chunk-6BEAVNR2.js";
10
10
  import {
11
11
  fetchRegistryLatestVersion,
12
12
  isNewerVersion
13
13
  } from "./chunk-LRYWFRPD.js";
14
- import "./chunk-G7IU3XBI.js";
14
+ import "./chunk-7F523R3I.js";
15
15
  import {
16
16
  detectPackageManager
17
17
  } from "./chunk-OY7F4YNQ.js";
18
18
  import {
19
19
  syncTickets
20
- } from "./chunk-D4UGNHLW.js";
20
+ } from "./chunk-CYITXCZO.js";
21
21
  import "./chunk-NHXVS5FL.js";
22
- import "./chunk-HI7ANNQI.js";
22
+ import "./chunk-FTMQT2V3.js";
23
23
  import "./chunk-CXGL65PS.js";
24
24
  import "./chunk-HSC7TELY.js";
25
25
  import "./chunk-2KELQTLE.js";
@@ -125,4 +125,4 @@ async function check(options) {
125
125
  export {
126
126
  check
127
127
  };
128
- //# sourceMappingURL=check-FH7FC7IG.js.map
128
+ //# sourceMappingURL=check-MUL6YRIO.js.map
@@ -1,3 +1,7 @@
1
+ import {
2
+ resolveConfiguredLaneDirectory
3
+ } from "./chunk-FTMQT2V3.js";
4
+
1
5
  // src/utils/feature-source.ts
2
6
  import { existsSync, readdirSync } from "fs";
3
7
  import nodePath from "path";
@@ -16,12 +20,17 @@ function collectExecutableFeatureFiles(cwd, fileName) {
16
20
  );
17
21
  }
18
22
  function collectExecutableFeatureDirectories(cwd) {
19
- return [
23
+ const directories = [
20
24
  nodePath.join(cwd, "features"),
21
25
  ...WORKSPACE_FEATURE_ROOTS.flatMap(
22
26
  (root) => collectWorkspaceFeatureDirectories(nodePath.join(cwd, root))
23
27
  )
24
28
  ];
29
+ const configured = resolveConfiguredLaneDirectory(cwd, "features");
30
+ if (configured !== void 0 && !directories.includes(configured)) {
31
+ directories.push(configured);
32
+ }
33
+ return directories;
25
34
  }
26
35
  function collectWorkspaceFeatureDirectories(workspaceDirectory) {
27
36
  if (!existsSync(workspaceDirectory)) return [];
@@ -69,15 +78,15 @@ function parseFeatureScenarios(featureContent) {
69
78
  const featureName = feature.name || "Feature";
70
79
  return collectFeatureChildren(feature.children, featureName, featureTags);
71
80
  }
72
- function parseFeatureAcReferences(featureContent) {
73
- const references = /* @__PURE__ */ new Set();
81
+ function parseFeatureLineageReferences(featureContent) {
82
+ const byKind = { ac: /* @__PURE__ */ new Set(), rule: /* @__PURE__ */ new Set() };
74
83
  for (const scenario of parseFeatureScenarios(featureContent)) {
75
84
  for (const tag of scenario.tags) {
76
- const ref = parseAcReferenceFromTag(tag);
77
- if (ref !== void 0) references.add(ref);
85
+ const ref = parseLineageReferenceFromTag(tag);
86
+ if (ref !== void 0) byKind[ref.kind].add(ref.reference);
78
87
  }
79
88
  }
80
- return [...references];
89
+ return { ac: [...byKind.ac], rule: [...byKind.rule] };
81
90
  }
82
91
  function findGherkinLintIssues(featureContent, options = {}) {
83
92
  const issues = findTextLintIssues(featureContent, options.filePath);
@@ -103,14 +112,16 @@ function findGherkinLintIssues(featureContent, options = {}) {
103
112
  }
104
113
  function findFeatureLineageIssues(featureContent) {
105
114
  return parseFeatureScenarios(featureContent).flatMap((scenario) => {
106
- const references = uniqueAcReferences(scenario.tags);
115
+ const references = uniqueLineageReferences(scenario.tags);
107
116
  if (references.length === 0) {
108
- return [`Scenario "${scenario.title}" is missing lineage; add exactly one @<jtbd>.AC# tag.`];
117
+ return [
118
+ `Scenario "${scenario.title}" is missing lineage; add exactly one @<jtbd>.AC# or @<jtbd>.R# tag.`
119
+ ];
109
120
  }
110
121
  if (references.length > 1) {
111
122
  const tagList = references.map((reference) => `@${reference}`).join(", ");
112
123
  return [
113
- `Scenario "${scenario.title}" has multiple lineage tags after inheritance (${tagList}); keep exactly one @<jtbd>.AC# tag.`
124
+ `Scenario "${scenario.title}" has multiple lineage tags after inheritance (${tagList}); keep exactly one @<jtbd>.AC# or @<jtbd>.R# tag.`
114
125
  ];
115
126
  }
116
127
  return [];
@@ -278,7 +289,10 @@ function findDocumentLintIssues(feature) {
278
289
  for (const child of feature.children) {
279
290
  if (child.scenario) scenarios.push(child.scenario);
280
291
  if (child.rule) {
281
- issues.push(...findDuplicateTagIssues(child.rule.tags, `Rule "${child.rule.name}"`));
292
+ issues.push(
293
+ ...findDuplicateTagIssues(child.rule.tags, `Rule "${child.rule.name}"`),
294
+ ...findRuleNameTagIssues(child.rule)
295
+ );
282
296
  for (const ruleChild of child.rule.children) {
283
297
  if (ruleChild.scenario) scenarios.push(ruleChild.scenario);
284
298
  }
@@ -390,6 +404,19 @@ function collectPlaceholders(text, variables) {
390
404
  }
391
405
  }
392
406
  }
407
+ function findRuleNameTagIssues(rule) {
408
+ const ruleReference = rule.tags.map((tag) => parseLineageReferenceFromTag(tag.name)).find((reference) => reference?.kind === "rule");
409
+ if (ruleReference === void 0) return [];
410
+ const nameToken = rule.name.trim().split(/[\s—–]+/, 1)[0] ?? "";
411
+ if (nameToken === ruleReference.reference) return [];
412
+ return [
413
+ issue(
414
+ "rule-name-tag-mismatch",
415
+ `Rule "${rule.name}" is tagged @${ruleReference.reference} but its name starts with a different id; make the name's first token match the tag.`,
416
+ rule.location.line
417
+ )
418
+ ];
419
+ }
393
420
  function findDuplicateTagIssues(tags, owner) {
394
421
  const seen = /* @__PURE__ */ new Set();
395
422
  const issues = [];
@@ -439,11 +466,23 @@ function parseAcReferenceFromTag(tag) {
439
466
  if (!match) return void 0;
440
467
  return `${match[1] ?? ""}.AC${match[2] ?? ""}`;
441
468
  }
442
- function uniqueAcReferences(tags) {
469
+ function parseRuleReferenceFromTag(tag) {
470
+ const match = /^@?(\S+)\.R(\d+)$/.exec(tag.trim());
471
+ if (!match) return void 0;
472
+ return `${match[1] ?? ""}.R${match[2] ?? ""}`;
473
+ }
474
+ function parseLineageReferenceFromTag(tag) {
475
+ const acReference = parseAcReferenceFromTag(tag);
476
+ if (acReference !== void 0) return { kind: "ac", reference: acReference };
477
+ const ruleReference = parseRuleReferenceFromTag(tag);
478
+ if (ruleReference !== void 0) return { kind: "rule", reference: ruleReference };
479
+ return void 0;
480
+ }
481
+ function uniqueLineageReferences(tags) {
443
482
  const references = /* @__PURE__ */ new Set();
444
483
  for (const tag of tags) {
445
- const ref = parseAcReferenceFromTag(tag);
446
- if (ref !== void 0) references.add(ref);
484
+ const ref = parseLineageReferenceFromTag(tag);
485
+ if (ref !== void 0) references.add(ref.reference);
447
486
  }
448
487
  return [...references];
449
488
  }
@@ -457,8 +496,9 @@ export {
457
496
  collectExecutableFeatureFiles,
458
497
  FeatureParseError,
459
498
  parseFeatureScenarios,
460
- parseFeatureAcReferences,
499
+ parseFeatureLineageReferences,
461
500
  findGherkinLintIssues,
462
- findFeatureLineageIssues
501
+ findFeatureLineageIssues,
502
+ parseLineageReferenceFromTag
463
503
  };
464
- //# sourceMappingURL=chunk-XTLCJKGE.js.map
504
+ //# sourceMappingURL=chunk-6BEAVNR2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/feature-source.ts","../src/utils/gherkin-feature.ts"],"sourcesContent":["import { existsSync, readdirSync } from 'node:fs';\nimport nodePath from 'node:path';\n\nimport { resolveConfiguredLaneDirectory } from './configured-paths.js';\n\nconst WORKSPACE_FEATURE_ROOTS = ['packages', 'apps', 'libs', 'modules'] as const;\n\n/** Ticket folder `ID-slug` -> `slug`; legacy `ID` -> `ID`. */\nfunction slugFromTicketFolder(ticketFolder: string): string {\n const dashIndex = ticketFolder.indexOf('-');\n return dashIndex === -1 ? ticketFolder : ticketFolder.slice(dashIndex + 1);\n}\n\n/**\n * Find the executable `.feature` file for a ticket by slug. The search mirrors\n * the Cucumber lane: all feature files under root `features/`, then under each\n * direct workspace package's `features/` directory in stable order.\n */\nexport function findFeatureSourcePath(cwd: string, ticketFolder: string): string | undefined {\n const fileName = `${slugFromTicketFolder(ticketFolder)}.feature`;\n return collectExecutableFeatureFiles(cwd, fileName)[0];\n}\n\nexport function collectExecutableFeatureFiles(cwd: string, fileName?: string): string[] {\n return collectExecutableFeatureDirectories(cwd).flatMap(directory =>\n findFeatureFiles(directory, fileName),\n );\n}\n\nfunction collectExecutableFeatureDirectories(cwd: string): string[] {\n const directories = [\n nodePath.join(cwd, 'features'),\n ...WORKSPACE_FEATURE_ROOTS.flatMap(root =>\n collectWorkspaceFeatureDirectories(nodePath.join(cwd, root)),\n ),\n ];\n\n // paths.features AUGMENTS the defaults (ticket 56JCFZ) — relocated/host\n // lanes become readable without abandoning root features/.\n const configured = resolveConfiguredLaneDirectory(cwd, 'features');\n if (configured !== undefined && !directories.includes(configured)) {\n directories.push(configured);\n }\n return directories;\n}\n\nfunction collectWorkspaceFeatureDirectories(workspaceDirectory: string): string[] {\n if (!existsSync(workspaceDirectory)) return [];\n return readdirSync(workspaceDirectory, { withFileTypes: true })\n .filter(entry => entry.isDirectory())\n .map(entry => nodePath.join(workspaceDirectory, entry.name, 'features'));\n}\n\nfunction findFeatureFiles(directory: string, fileName?: string): string[] {\n let entries;\n try {\n entries = readdirSync(directory, { withFileTypes: true });\n } catch {\n return [];\n }\n\n const matches: string[] = [];\n for (const entry of entries) {\n const absolute = nodePath.join(directory, entry.name);\n if (entry.isDirectory()) {\n matches.push(...findFeatureFiles(absolute, fileName));\n } else if (entry.isFile() && isMatchingFeatureFile(entry.name, fileName)) {\n matches.push(absolute);\n }\n }\n return matches.toSorted((a, b) => a.localeCompare(b));\n}\n\nfunction isMatchingFeatureFile(entryName: string, fileName: string | undefined): boolean {\n if (!entryName.endsWith('.feature')) return false;\n return fileName === undefined || entryName === fileName;\n}\n","import { AstBuilder, GherkinClassicTokenMatcher, Parser } from '@cucumber/gherkin';\nimport {\n type DataTable,\n type DocString as GherkinDocumentString,\n type Examples,\n type Feature,\n type FeatureChild,\n IdGenerator,\n type RuleChild,\n type Scenario,\n type Step,\n type TableRow,\n type Tag,\n} from '@cucumber/messages';\n\nimport type { ParsedScenario } from './test-skeleton.js';\n\nexport interface ParsedFeatureScenario extends ParsedScenario {\n /** Effective tags after applying Feature/Rule/Scenario inheritance. */\n tags: string[];\n}\n\nexport class FeatureParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'FeatureParseError';\n }\n}\n\nexport interface GherkinLintIssue {\n line?: number;\n message: string;\n rule: string;\n}\n\nexport function parseFeatureScenarios(featureContent: string): ParsedFeatureScenario[] {\n const document = parseFeature(featureContent);\n const feature = document.feature;\n if (feature === undefined) return [];\n\n const featureTags = feature.tags.map(tag => tag.name);\n const featureName = feature.name || 'Feature';\n return collectFeatureChildren(feature.children, featureName, featureTags);\n}\n\nexport function parseFeatureAcReferences(featureContent: string): string[] {\n return parseFeatureLineageReferences(featureContent).ac;\n}\n\nexport function parseFeatureRuleReferences(featureContent: string): string[] {\n return parseFeatureLineageReferences(featureContent).rule;\n}\n\n/**\n * The AC and numbered-Rule lineage references a feature's scenarios carry,\n * split by kind, from a single `parseFeatureScenarios` pass. Callers that need\n * both kinds (coverage) read them off one AST build instead of parsing twice.\n */\nexport function parseFeatureLineageReferences(featureContent: string): {\n ac: string[];\n rule: string[];\n} {\n const byKind: Record<LineageKind, Set<string>> = { ac: new Set(), rule: new Set() };\n for (const scenario of parseFeatureScenarios(featureContent)) {\n for (const tag of scenario.tags) {\n const ref = parseLineageReferenceFromTag(tag);\n if (ref !== undefined) byKind[ref.kind].add(ref.reference);\n }\n }\n return { ac: [...byKind.ac], rule: [...byKind.rule] };\n}\n\nexport function findGherkinLintIssues(\n featureContent: string,\n options: { filePath?: string } = {},\n): GherkinLintIssue[] {\n const issues = findTextLintIssues(featureContent, options.filePath);\n if (featureContent.trim() === '') {\n return [...issues, issue('no-empty-file', 'Feature file is empty.')];\n }\n\n try {\n const document = parseFeature(featureContent);\n const feature = document.feature;\n if (feature === undefined) {\n return [...issues, issue('no-feature', 'Feature file has no Feature.')];\n }\n return [...issues, ...findDocumentLintIssues(feature)];\n } catch (error: unknown) {\n if (error instanceof FeatureParseError) {\n return [\n ...issues,\n issue('parse', `Invalid Gherkin syntax: ${error.message}`, parseErrorLine(error.message)),\n ];\n }\n throw error;\n }\n}\n\nexport function findFeatureLineageIssues(featureContent: string): string[] {\n return parseFeatureScenarios(featureContent).flatMap(scenario => {\n const references = uniqueLineageReferences(scenario.tags);\n if (references.length === 0) {\n return [\n `Scenario \"${scenario.title}\" is missing lineage; add exactly one @<jtbd>.AC# or @<jtbd>.R# tag.`,\n ];\n }\n if (references.length > 1) {\n const tagList = references.map(reference => `@${reference}`).join(', ');\n return [\n `Scenario \"${scenario.title}\" has multiple lineage tags after inheritance (${tagList}); keep exactly one @<jtbd>.AC# or @<jtbd>.R# tag.`,\n ];\n }\n return [];\n });\n}\n\nfunction parseFeature(featureContent: string) {\n const parser = new Parser(new AstBuilder(IdGenerator.uuid()), new GherkinClassicTokenMatcher());\n try {\n return parser.parse(featureContent);\n } catch (error: unknown) {\n throw new FeatureParseError(formatParseError(error));\n }\n}\n\nfunction collectFeatureChildren(\n children: readonly FeatureChild[],\n featureName: string,\n inheritedTags: readonly string[],\n): ParsedFeatureScenario[] {\n const scenarios: ParsedFeatureScenario[] = [];\n let featureBackgroundSteps: readonly Step[] = [];\n for (const child of children) {\n if (child.background) {\n featureBackgroundSteps = child.background.steps;\n }\n if (child.scenario) {\n scenarios.push(\n ...toParsedScenarios(child.scenario, featureName, inheritedTags, featureBackgroundSteps),\n );\n }\n if (child.rule) {\n const ruleTags = [...inheritedTags, ...child.rule.tags.map(tag => tag.name)];\n scenarios.push(\n ...collectRuleChildren(\n child.rule.children,\n child.rule.name,\n ruleTags,\n featureBackgroundSteps,\n ),\n );\n }\n }\n return scenarios;\n}\n\nfunction collectRuleChildren(\n children: readonly RuleChild[],\n ruleName: string,\n inheritedTags: readonly string[],\n featureBackgroundSteps: readonly Step[],\n): ParsedFeatureScenario[] {\n const scenarios: ParsedFeatureScenario[] = [];\n let ruleBackgroundSteps: readonly Step[] = [];\n for (const child of children) {\n if (child.background) {\n ruleBackgroundSteps = child.background.steps;\n }\n if (child.scenario) {\n scenarios.push(\n ...toParsedScenarios(child.scenario, ruleName, inheritedTags, [\n ...featureBackgroundSteps,\n ...ruleBackgroundSteps,\n ]),\n );\n }\n }\n return scenarios;\n}\n\nfunction toParsedScenarios(\n scenario: Scenario,\n rule: string,\n inheritedTags: readonly string[],\n inheritedSteps: readonly Step[],\n): ParsedFeatureScenario[] {\n if (scenario.examples.length === 0)\n return [toParsedScenario(scenario, rule, inheritedTags, inheritedSteps)];\n return scenario.examples.flatMap(example =>\n toParsedExampleScenarios(scenario, rule, inheritedTags, inheritedSteps, example),\n );\n}\n\nfunction toParsedScenario(\n scenario: Scenario,\n rule: string,\n inheritedTags: readonly string[],\n inheritedSteps: readonly Step[],\n row?: ExampleRow,\n): ParsedFeatureScenario {\n const title = row === undefined ? scenario.name : exampleTitle(scenario.name, row);\n return {\n rule,\n title,\n steps: [...inheritedSteps, ...scenario.steps].flatMap(step => renderStep(step, row)),\n tags: [...inheritedTags, ...scenario.tags.map(tag => tag.name), ...(row?.tags ?? [])],\n };\n}\n\ninterface ExampleRow {\n cells: Map<string, string>;\n summary: string;\n tags: string[];\n}\n\nfunction toParsedExampleScenarios(\n scenario: Scenario,\n rule: string,\n inheritedTags: readonly string[],\n inheritedSteps: readonly Step[],\n example: Examples,\n): ParsedFeatureScenario[] {\n const headers = example.tableHeader?.cells.map(cell => cell.value) ?? [];\n return example.tableBody.map(row =>\n toParsedScenario(scenario, rule, inheritedTags, inheritedSteps, {\n cells: rowCells(headers, row),\n summary: rowSummary(headers, row),\n tags: example.tags.map(tag => tag.name),\n }),\n );\n}\n\nfunction renderStep(step: Step, row: ExampleRow | undefined): string[] {\n return [\n interpolate(`${step.keyword.trim()} ${step.text}`.trim(), row),\n ...renderStepArgument(step, row),\n ];\n}\n\nfunction renderStepArgument(step: Step, row: ExampleRow | undefined): string[] {\n if (step.dataTable) return renderDataTable(step.dataTable, row);\n if (step.docString) return renderDocumentString(step.docString, row);\n return [];\n}\n\nfunction renderDataTable(dataTable: DataTable, row: ExampleRow | undefined): string[] {\n return dataTable.rows.map(\n tableRow => `| ${tableRow.cells.map(cell => interpolate(cell.value, row)).join(' | ')} |`,\n );\n}\n\nfunction renderDocumentString(\n documentString: GherkinDocumentString,\n row: ExampleRow | undefined,\n): string[] {\n const opener =\n documentString.mediaType === undefined\n ? documentString.delimiter\n : `${documentString.delimiter}${documentString.mediaType}`;\n return [\n opener,\n ...interpolate(documentString.content, row).split('\\n'),\n documentString.delimiter,\n ];\n}\n\nfunction rowCells(headers: readonly string[], row: TableRow): Map<string, string> {\n return new Map(headers.map((header, index) => [header, row.cells[index]?.value ?? '']));\n}\n\nfunction rowSummary(headers: readonly string[], row: TableRow): string {\n return headers.map((header, index) => `${header}=${row.cells[index]?.value ?? ''}`).join(', ');\n}\n\nfunction exampleTitle(title: string, row: ExampleRow): string {\n const interpolated = interpolate(title, row);\n return row.summary === '' ? interpolated : `${interpolated} (${row.summary})`;\n}\n\nfunction interpolate(text: string, row: ExampleRow | undefined): string {\n if (row === undefined) return text;\n let interpolated = text;\n for (const [key, value] of row.cells) {\n interpolated = interpolated.split(`<${key}>`).join(value);\n }\n return interpolated;\n}\n\nfunction findTextLintIssues(content: string, filePath: string | undefined): GherkinLintIssue[] {\n const issues: GherkinLintIssue[] = [];\n if (filePath !== undefined) {\n const fileName = filePath.split(/[\\\\/]/).pop() ?? filePath;\n if (!isKebabCaseFeatureFileName(fileName)) {\n issues.push(\n issue(\n 'file-name',\n `Feature file name should be kebab-case, e.g. \"${kebabFileName(fileName)}\".`,\n ),\n );\n }\n }\n if (content !== '' && !content.endsWith('\\n')) {\n issues.push(issue('new-line-at-eof', 'Feature file should end with a newline.'));\n }\n\n let isPreviousBlank = false;\n for (const [index, line] of content.split('\\n').entries()) {\n const lineNumber = index + 1;\n if (/[ \\t]$/.test(line)) {\n issues.push(issue('no-trailing-spaces', 'Line has trailing whitespace.', lineNumber));\n }\n const isBlank = line.trim() === '';\n if (isBlank && isPreviousBlank) {\n issues.push(\n issue('no-multiple-empty-lines', 'Avoid multiple consecutive blank lines.', lineNumber),\n );\n }\n isPreviousBlank = isBlank;\n }\n return issues;\n}\n\nfunction findDocumentLintIssues(feature: Feature): GherkinLintIssue[] {\n const issues: GherkinLintIssue[] = [];\n if (feature.name.trim() === '') {\n issues.push(issue('no-unnamed-features', 'Feature must have a name.', feature.location.line));\n }\n issues.push(...findDuplicateTagIssues(feature.tags, 'Feature'));\n\n const scenarios: Scenario[] = [];\n for (const child of feature.children) {\n if (child.scenario) scenarios.push(child.scenario);\n if (child.rule) {\n issues.push(\n ...findDuplicateTagIssues(child.rule.tags, `Rule \"${child.rule.name}\"`),\n ...findRuleNameTagIssues(child.rule),\n );\n for (const ruleChild of child.rule.children) {\n if (ruleChild.scenario) scenarios.push(ruleChild.scenario);\n }\n }\n }\n\n if (scenarios.length === 0) {\n issues.push(\n issue('no-files-without-scenarios', 'Feature file must contain at least one scenario.'),\n );\n }\n issues.push(...findScenarioLintIssues(scenarios));\n return issues;\n}\n\nfunction findScenarioLintIssues(scenarios: readonly Scenario[]): GherkinLintIssue[] {\n const issues: GherkinLintIssue[] = [];\n const firstLineByName = new Map<string, number>();\n for (const scenario of scenarios) {\n const name = scenario.name.trim();\n if (name === '') {\n issues.push(\n issue('no-unnamed-scenarios', 'Scenario must have a name.', scenario.location.line),\n );\n } else if (firstLineByName.has(name)) {\n issues.push(\n issue(\n 'no-dupe-scenario-names',\n `Scenario name \"${name}\" is duplicated in this feature.`,\n scenario.location.line,\n ),\n );\n } else {\n firstLineByName.set(name, scenario.location.line);\n }\n\n if (scenario.keyword.toLowerCase().includes('outline') && scenario.examples.length === 0) {\n issues.push(\n issue(\n 'no-scenario-outlines-without-examples',\n 'Scenario Outline must include Examples.',\n scenario.location.line,\n ),\n );\n }\n issues.push(\n ...findScenarioOutlineVariableIssues(scenario),\n ...findDuplicateTagIssues(scenario.tags, `Scenario \"${scenario.name}\"`),\n ...scenario.examples.flatMap(example =>\n findDuplicateTagIssues(example.tags, `Examples \"${example.name}\"`),\n ),\n );\n }\n return issues;\n}\n\nfunction findScenarioOutlineVariableIssues(scenario: Scenario): GherkinLintIssue[] {\n if (!scenario.keyword.toLowerCase().includes('outline') || scenario.examples.length === 0) {\n return [];\n }\n\n const usedVariables = collectScenarioOutlineVariables(scenario);\n return scenario.examples.flatMap(example =>\n findExamplesVariableIssues(scenario, example, usedVariables),\n );\n}\n\nfunction findExamplesVariableIssues(\n scenario: Scenario,\n example: Examples,\n usedVariables: ReadonlySet<string>,\n): GherkinLintIssue[] {\n const headers = example.tableHeader?.cells.map(cell => cell.value.trim()).filter(Boolean) ?? [];\n const headerSet = new Set(headers);\n const exampleName = example.name || 'Examples';\n\n const missing = [...usedVariables]\n .filter(variable => !headerSet.has(variable))\n .map(variable =>\n issue(\n 'no-unused-variables',\n `Scenario Outline \"${scenario.name}\" uses <${variable}> but Examples \"${exampleName}\" has no \"${variable}\" column.`,\n example.location.line,\n ),\n );\n\n const unused = headers\n .filter(header => !usedVariables.has(header))\n .map(header =>\n issue(\n 'no-unused-variables',\n `Examples \"${exampleName}\" defines <${header}> but Scenario Outline \"${scenario.name}\" never uses it.`,\n example.tableHeader?.location.line ?? example.location.line,\n ),\n );\n\n return [...missing, ...unused];\n}\n\nfunction collectScenarioOutlineVariables(scenario: Scenario): Set<string> {\n const variables = new Set<string>();\n collectPlaceholders(scenario.name, variables);\n collectPlaceholders(scenario.description, variables);\n for (const step of scenario.steps) {\n collectPlaceholders(step.text, variables);\n if (step.docString) collectPlaceholders(step.docString.content, variables);\n if (step.dataTable) {\n for (const row of step.dataTable.rows) {\n for (const cell of row.cells) {\n collectPlaceholders(cell.value, variables);\n }\n }\n }\n }\n return variables;\n}\n\nfunction collectPlaceholders(text: string, variables: Set<string>): void {\n let start = -1;\n for (let index = 0; index < text.length; index += 1) {\n const character = text[index];\n if (character === '<') {\n start = index + 1;\n } else if (character === '>' && start !== -1) {\n const variable = text.slice(start, index).trim();\n if (variable) variables.add(variable);\n start = -1;\n }\n }\n}\n\n/**\n * A Rule block carrying a rule lineage tag must repeat that id as its name's\n * first token (the tag is authoritative; the name token is the human-readable\n * copy). Unnumbered grouping blocks carry no rule tag and are exempt.\n */\nfunction findRuleNameTagIssues(rule: {\n name: string;\n tags: readonly Tag[];\n location: { line: number };\n}): GherkinLintIssue[] {\n const ruleReference = rule.tags\n .map(tag => parseLineageReferenceFromTag(tag.name))\n .find(reference => reference?.kind === 'rule');\n if (ruleReference === undefined) return [];\n\n // The id ends at the first whitespace or dash separator. Split on em/en dash\n // too so a name glued as `demo.DEV1.R1—foo` still yields the id, not a false\n // mismatch; a plain `-` stays part of the token (kebab slugs contain it).\n const nameToken = rule.name.trim().split(/[\\s—–]+/, 1)[0] ?? '';\n if (nameToken === ruleReference.reference) return [];\n return [\n issue(\n 'rule-name-tag-mismatch',\n `Rule \"${rule.name}\" is tagged @${ruleReference.reference} but its name starts with a different id; make the name's first token match the tag.`,\n rule.location.line,\n ),\n ];\n}\n\nfunction findDuplicateTagIssues(tags: readonly Tag[], owner: string): GherkinLintIssue[] {\n const seen = new Set<string>();\n const issues: GherkinLintIssue[] = [];\n for (const tag of tags) {\n if (seen.has(tag.name)) {\n issues.push(\n issue('no-duplicate-tags', `${owner} has duplicate tag ${tag.name}.`, tag.location.line),\n );\n }\n seen.add(tag.name);\n }\n return issues;\n}\n\nfunction issue(rule: string, message: string, line?: number): GherkinLintIssue {\n return line === undefined ? { rule, message } : { rule, message, line };\n}\n\nfunction kebabFileName(fileName: string): string {\n const stem = fileName.endsWith('.feature') ? fileName.slice(0, -'.feature'.length) : fileName;\n return [\n stem\n .replaceAll('_', '-')\n .replaceAll(/[^a-zA-Z0-9]+/gu, '-')\n .replaceAll(/^-|-$/gu, '')\n .toLowerCase(),\n '.feature',\n ].join('');\n}\n\nfunction isKebabCaseFeatureFileName(fileName: string): boolean {\n if (!fileName.endsWith('.feature')) return false;\n const stem = fileName.slice(0, -'.feature'.length);\n if (stem === '') return false;\n return stem.split('-').every(segment => isLowercaseAlphaNumeric(segment));\n}\n\nfunction isLowercaseAlphaNumeric(segment: string): boolean {\n if (segment === '') return false;\n for (const character of segment) {\n const code = character.codePointAt(0);\n if (code === undefined) return false;\n const isDigit = code >= 48 && code <= 57;\n const isLowercaseLetter = code >= 97 && code <= 122;\n if (!isDigit && !isLowercaseLetter) return false;\n }\n return true;\n}\n\nfunction parseErrorLine(message: string): number | undefined {\n const match = /\\((\\d+):\\d+\\)/.exec(message);\n return match?.[1] === undefined ? undefined : Number(match[1]);\n}\n\ntype LineageKind = 'ac' | 'rule';\n\nexport interface LineageReference {\n kind: LineageKind;\n reference: string;\n}\n\nfunction parseAcReferenceFromTag(tag: string): string | undefined {\n const match = /^@?(\\S+?)\\.AC(\\d+)(?:\\.|$)/.exec(tag.trim());\n if (!match) return undefined;\n return `${match[1] ?? ''}.AC${match[2] ?? ''}`;\n}\n\nfunction parseRuleReferenceFromTag(tag: string): string | undefined {\n // Anchor on the *terminal* `.R<n>` (greedy prefix) so the parsed id matches\n // the spec-side declaration, which keeps the whole heading token\n // (`scenario-coverage.ts` `isRuleId` = `/\\.R\\d+$/`). A lazy first-match would\n // read `@feat.R1.R2` as `feat.R1` while the spec declares `feat.R1.R2`,\n // splitting one corpus into a spurious uncovered+orphan pair. Rule tags carry\n // no `.<scenario_name>` tail (unlike AC titles), so terminal anchoring is safe.\n const match = /^@?(\\S+)\\.R(\\d+)$/.exec(tag.trim());\n if (!match) return undefined;\n return `${match[1] ?? ''}.R${match[2] ?? ''}`;\n}\n\n/** Parse a tag's lineage reference. An AC match wins over a rule-shaped prefix\n * so persona codes like `R` stay unambiguous: `@feat.R1.AC1` is AC1 of JTBD\n * `feat.R1`, never rule `feat.R1`. */\nexport function parseLineageReferenceFromTag(tag: string): LineageReference | undefined {\n const acReference = parseAcReferenceFromTag(tag);\n if (acReference !== undefined) return { kind: 'ac', reference: acReference };\n const ruleReference = parseRuleReferenceFromTag(tag);\n if (ruleReference !== undefined) return { kind: 'rule', reference: ruleReference };\n return undefined;\n}\n\nfunction uniqueLineageReferences(tags: readonly string[]): string[] {\n const references = new Set<string>();\n for (const tag of tags) {\n const ref = parseLineageReferenceFromTag(tag);\n if (ref !== undefined) references.add(ref.reference);\n }\n return [...references];\n}\n\nfunction formatParseError(error: unknown): string {\n if (error instanceof Error) return error.message.replaceAll('\\n', ' ');\n return String(error);\n}\n"],"mappings":"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","names":[]}