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.
- package/dist/{architecture-WFRA4ITA.js → architecture-T4RR7Q5J.js} +2 -2
- package/dist/{check-FH7FC7IG.js → check-MUL6YRIO.js} +7 -7
- package/dist/{chunk-XTLCJKGE.js → chunk-6BEAVNR2.js} +56 -16
- package/dist/chunk-6BEAVNR2.js.map +1 -0
- package/dist/{chunk-G7IU3XBI.js → chunk-7F523R3I.js} +643 -457
- package/dist/chunk-7F523R3I.js.map +1 -0
- package/dist/{chunk-D4UGNHLW.js → chunk-CYITXCZO.js} +2 -2
- package/dist/{chunk-HWOJR33A.js → chunk-DN67MPYH.js} +61 -22
- package/dist/chunk-DN67MPYH.js.map +1 -0
- package/dist/{chunk-HI7ANNQI.js → chunk-FTMQT2V3.js} +7 -1
- package/dist/chunk-FTMQT2V3.js.map +1 -0
- package/dist/{chunk-ILTC7KBQ.js → chunk-IDTVO3BJ.js} +11 -1
- package/dist/chunk-IDTVO3BJ.js.map +1 -0
- package/dist/{chunk-AA3G2VTE.js → chunk-OE6HYAWU.js} +2 -2
- package/dist/{chunk-2IK7L4EZ.js → chunk-ZBFYIJNE.js} +62 -12
- package/dist/chunk-ZBFYIJNE.js.map +1 -0
- package/dist/cli.js +33 -21
- package/dist/cli.js.map +1 -1
- package/dist/{codify-BXBG5XPK.js → codify-SPIWSH2R.js} +4 -4
- package/dist/{diff-LLE62QKI.js → diff-BZOC4JXC.js} +3 -3
- package/dist/index.d.ts +14 -0
- package/dist/{lint-gherkin-FLJEH3EJ.js → lint-gherkin-RKLOOSNO.js} +4 -2
- package/dist/{lint-gherkin-FLJEH3EJ.js.map → lint-gherkin-RKLOOSNO.js.map} +1 -1
- package/dist/{reset-NBZGOP4I.js → reset-646VL6X4.js} +3 -3
- package/dist/{retro-ART3JCCW.js → retro-GGVK4BYL.js} +3 -3
- package/dist/retro-GGVK4BYL.js.map +1 -0
- package/dist/{self-report-XLBFP2NT.js → self-report-MZ2CP23A.js} +4 -2
- package/dist/{self-report-AQZKGDAS.js → self-report-SMDJD2UO.js} +2 -2
- package/dist/{setup-46AW3EOX.js → setup-Q4Y7Y6PN.js} +21 -8
- package/dist/{setup-46AW3EOX.js.map → setup-Q4Y7Y6PN.js.map} +1 -1
- package/dist/{sync-learnings-BVNUNLPD.js → sync-learnings-THGNXZCT.js} +2 -2
- package/dist/{sync-tickets-4TOJBDHW.js → sync-tickets-P2FFD7DH.js} +3 -3
- package/dist/{sync-tracker-U4TKFX4R.js → sync-tracker-SV6AEV2O.js} +3 -3
- package/dist/{ticket-new-PIHZGZGG.js → ticket-new-K4X2ZO6V.js} +2 -2
- package/dist/{upgrade-JELXQM56.js → upgrade-R52BFPBM.js} +15 -13
- package/dist/upgrade-R52BFPBM.js.map +1 -0
- package/package.json +1 -1
- package/templates/agents/safeword-retro-filer.md +50 -0
- package/templates/agents/safeword-retro-filer.toml +47 -0
- package/templates/codex/config.toml +9 -0
- package/templates/commands/self-review.md +4 -2
- package/templates/commands/verify.md +2 -304
- package/templates/cucumber/cucumber.mjs +42 -2
- package/templates/doc-templates/ticket-template.md +1 -1
- package/templates/guides/self-report-filing.md +31 -21
- package/templates/hooks/codex/post-tool-quality.ts +56 -0
- package/templates/hooks/codex/post-tool-skill-nudge.ts +2 -17
- package/templates/hooks/codex/pre-tool-quality-helpers.ts +24 -0
- package/templates/hooks/codex/pre-tool-quality.ts +21 -19
- package/templates/hooks/codex/stop.ts +21 -5
- package/templates/hooks/cursor/before-shell-execution.ts +23 -6
- package/templates/hooks/cursor/gate-adapter.ts +9 -103
- package/templates/hooks/cursor/stop.ts +17 -4
- package/templates/hooks/lib/bash-ledger-writes.ts +216 -0
- package/templates/hooks/lib/cursor-run-identity.ts +114 -10
- package/templates/hooks/lib/jtbd.ts +1 -1
- package/templates/hooks/lib/lint-config.ts +48 -1
- package/templates/hooks/lib/lint.ts +42 -4
- package/templates/hooks/lib/phase-provenance.ts +263 -0
- package/templates/hooks/lib/retro-draft-spool.ts +43 -3
- package/templates/hooks/lib/retro-filing-gate.ts +192 -0
- package/templates/hooks/lib/retro-nudge.ts +4 -4
- package/templates/hooks/lib/self-report.ts +16 -0
- package/templates/hooks/lib/shell-segments.ts +116 -0
- package/templates/hooks/post-tool-quality.ts +59 -7
- package/templates/hooks/pre-tool-quality.ts +46 -5
- package/templates/hooks/prompt-retro-nudge.ts +9 -6
- package/templates/hooks/stop-quality.ts +1 -1
- package/templates/hooks/stop-retro-filing.ts +62 -0
- package/templates/hooks/write-review-stamp.ts +76 -12
- package/templates/skills/audit/SKILL.md +25 -24
- package/templates/skills/bdd/DISCOVERY.md +1 -0
- package/templates/skills/bdd/SCENARIOS.md +30 -0
- package/templates/skills/bdd/SKILL.md +3 -3
- package/templates/skills/bdd/TDD.md +2 -2
- package/templates/skills/self-review/SKILL.md +3 -2
- package/templates/skills/ticket-system/SKILL.md +2 -1
- package/templates/skills/verify/SKILL.md +13 -7
- package/templates/spec-template.md +4 -0
- package/dist/chunk-2IK7L4EZ.js.map +0 -1
- package/dist/chunk-G7IU3XBI.js.map +0 -1
- package/dist/chunk-HI7ANNQI.js.map +0 -1
- package/dist/chunk-HWOJR33A.js.map +0 -1
- package/dist/chunk-ILTC7KBQ.js.map +0 -1
- package/dist/chunk-XTLCJKGE.js.map +0 -1
- package/dist/retro-ART3JCCW.js.map +0 -1
- package/dist/upgrade-JELXQM56.js.map +0 -1
- /package/dist/{architecture-WFRA4ITA.js.map → architecture-T4RR7Q5J.js.map} +0 -0
- /package/dist/{check-FH7FC7IG.js.map → check-MUL6YRIO.js.map} +0 -0
- /package/dist/{chunk-D4UGNHLW.js.map → chunk-CYITXCZO.js.map} +0 -0
- /package/dist/{chunk-AA3G2VTE.js.map → chunk-OE6HYAWU.js.map} +0 -0
- /package/dist/{codify-BXBG5XPK.js.map → codify-SPIWSH2R.js.map} +0 -0
- /package/dist/{diff-LLE62QKI.js.map → diff-BZOC4JXC.js.map} +0 -0
- /package/dist/{reset-NBZGOP4I.js.map → reset-646VL6X4.js.map} +0 -0
- /package/dist/{self-report-XLBFP2NT.js.map → self-report-MZ2CP23A.js.map} +0 -0
- /package/dist/{self-report-AQZKGDAS.js.map → self-report-SMDJD2UO.js.map} +0 -0
- /package/dist/{sync-learnings-BVNUNLPD.js.map → sync-learnings-THGNXZCT.js.map} +0 -0
- /package/dist/{sync-tickets-4TOJBDHW.js.map → sync-tickets-P2FFD7DH.js.map} +0 -0
- /package/dist/{sync-tracker-U4TKFX4R.js.map → sync-tracker-SV6AEV2O.js.map} +0 -0
- /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-
|
|
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-
|
|
979
|
+
//# sourceMappingURL=architecture-T4RR7Q5J.js.map
|
|
@@ -4,22 +4,22 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
checkHealth,
|
|
6
6
|
reportHealthSummary
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
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-
|
|
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-
|
|
20
|
+
} from "./chunk-CYITXCZO.js";
|
|
21
21
|
import "./chunk-NHXVS5FL.js";
|
|
22
|
-
import "./chunk-
|
|
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-
|
|
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
|
-
|
|
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
|
|
73
|
-
const
|
|
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 =
|
|
77
|
-
if (ref !== void 0)
|
|
85
|
+
const ref = parseLineageReferenceFromTag(tag);
|
|
86
|
+
if (ref !== void 0) byKind[ref.kind].add(ref.reference);
|
|
78
87
|
}
|
|
79
88
|
}
|
|
80
|
-
return [...
|
|
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 =
|
|
115
|
+
const references = uniqueLineageReferences(scenario.tags);
|
|
107
116
|
if (references.length === 0) {
|
|
108
|
-
return [
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
-
|
|
499
|
+
parseFeatureLineageReferences,
|
|
461
500
|
findGherkinLintIssues,
|
|
462
|
-
findFeatureLineageIssues
|
|
501
|
+
findFeatureLineageIssues,
|
|
502
|
+
parseLineageReferenceFromTag
|
|
463
503
|
};
|
|
464
|
-
//# sourceMappingURL=chunk-
|
|
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":[]}
|