@rsaglobaltech/specgate 0.8.1

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 (494) hide show
  1. package/CHANGELOG.md +1016 -0
  2. package/README.md +148 -0
  3. package/bin/specgate.js +2 -0
  4. package/bin/specgate.ts +383 -0
  5. package/dist/bin/specgate.js +342 -0
  6. package/dist/bin/specgate.js.map +1 -0
  7. package/dist/packages/core/src/application/AddRequirementUseCase.js +24 -0
  8. package/dist/packages/core/src/application/AddRequirementUseCase.js.map +1 -0
  9. package/dist/packages/core/src/application/ArchiveChangeUseCase.js +185 -0
  10. package/dist/packages/core/src/application/ArchiveChangeUseCase.js.map +1 -0
  11. package/dist/packages/core/src/application/CheckAgainstLockUseCase.js +134 -0
  12. package/dist/packages/core/src/application/CheckAgainstLockUseCase.js.map +1 -0
  13. package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js +25 -0
  14. package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js.map +1 -0
  15. package/dist/packages/core/src/application/GeneratePlanUseCase.js +135 -0
  16. package/dist/packages/core/src/application/GeneratePlanUseCase.js.map +1 -0
  17. package/dist/packages/core/src/application/LinkRequirementUseCase.js +25 -0
  18. package/dist/packages/core/src/application/LinkRequirementUseCase.js.map +1 -0
  19. package/dist/packages/core/src/application/RemovePackUseCase.js +28 -0
  20. package/dist/packages/core/src/application/RemovePackUseCase.js.map +1 -0
  21. package/dist/packages/core/src/application/UpdateRequirementStatusUseCase.js +37 -0
  22. package/dist/packages/core/src/application/UpdateRequirementStatusUseCase.js.map +1 -0
  23. package/dist/packages/core/src/application/ValidateChangeUseCase.js +86 -0
  24. package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -0
  25. package/dist/packages/core/src/application/ValidateProjectUseCase.js +101 -0
  26. package/dist/packages/core/src/application/ValidateProjectUseCase.js.map +1 -0
  27. package/dist/packages/core/src/application/ports/IDomainPackRepository.js +3 -0
  28. package/dist/packages/core/src/application/ports/IDomainPackRepository.js.map +1 -0
  29. package/dist/packages/core/src/application/ports/IHarnessConfigRepository.js +3 -0
  30. package/dist/packages/core/src/application/ports/IHarnessConfigRepository.js.map +1 -0
  31. package/dist/packages/core/src/application/ports/ILockfileRepository.js +3 -0
  32. package/dist/packages/core/src/application/ports/ILockfileRepository.js.map +1 -0
  33. package/dist/packages/core/src/application/ports/IManifestRepository.js +3 -0
  34. package/dist/packages/core/src/application/ports/IManifestRepository.js.map +1 -0
  35. package/dist/packages/core/src/application/ports/IProjectRepository.js +3 -0
  36. package/dist/packages/core/src/application/ports/IProjectRepository.js.map +1 -0
  37. package/dist/packages/core/src/application/ports/IRequirementGraphRepository.js +3 -0
  38. package/dist/packages/core/src/application/ports/IRequirementGraphRepository.js.map +1 -0
  39. package/dist/packages/core/src/application/ports/ITraceabilityRepository.js +3 -0
  40. package/dist/packages/core/src/application/ports/ITraceabilityRepository.js.map +1 -0
  41. package/dist/packages/core/src/domain/AgentPrompt.js +79 -0
  42. package/dist/packages/core/src/domain/AgentPrompt.js.map +1 -0
  43. package/dist/packages/core/src/domain/ArchivePlan.js +26 -0
  44. package/dist/packages/core/src/domain/ArchivePlan.js.map +1 -0
  45. package/dist/packages/core/src/domain/AuthoringScope.js +48 -0
  46. package/dist/packages/core/src/domain/AuthoringScope.js.map +1 -0
  47. package/dist/packages/core/src/domain/ChangeTemplates.js +133 -0
  48. package/dist/packages/core/src/domain/ChangeTemplates.js.map +1 -0
  49. package/dist/packages/core/src/domain/CucumberMessages.js +256 -0
  50. package/dist/packages/core/src/domain/CucumberMessages.js.map +1 -0
  51. package/dist/packages/core/src/domain/DeclaredArtifacts.js +117 -0
  52. package/dist/packages/core/src/domain/DeclaredArtifacts.js.map +1 -0
  53. package/dist/packages/core/src/domain/DeltaSpec.js +219 -0
  54. package/dist/packages/core/src/domain/DeltaSpec.js.map +1 -0
  55. package/dist/packages/core/src/domain/Diagnostic.js +75 -0
  56. package/dist/packages/core/src/domain/Diagnostic.js.map +1 -0
  57. package/dist/packages/core/src/domain/DomainPack.js +62 -0
  58. package/dist/packages/core/src/domain/DomainPack.js.map +1 -0
  59. package/dist/packages/core/src/domain/EmptyAttempt.js +60 -0
  60. package/dist/packages/core/src/domain/EmptyAttempt.js.map +1 -0
  61. package/dist/packages/core/src/domain/FileChangeSet.js +37 -0
  62. package/dist/packages/core/src/domain/FileChangeSet.js.map +1 -0
  63. package/dist/packages/core/src/domain/Gherkin.js +272 -0
  64. package/dist/packages/core/src/domain/Gherkin.js.map +1 -0
  65. package/dist/packages/core/src/domain/GherkinDialects.js +97 -0
  66. package/dist/packages/core/src/domain/GherkinDialects.js.map +1 -0
  67. package/dist/packages/core/src/domain/GherkinQuality.js +160 -0
  68. package/dist/packages/core/src/domain/GherkinQuality.js.map +1 -0
  69. package/dist/packages/core/src/domain/GherkinTags.js +119 -0
  70. package/dist/packages/core/src/domain/GherkinTags.js.map +1 -0
  71. package/dist/packages/core/src/domain/GitSafety.js +77 -0
  72. package/dist/packages/core/src/domain/GitSafety.js.map +1 -0
  73. package/dist/packages/core/src/domain/HarnessConfig.js +58 -0
  74. package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -0
  75. package/dist/packages/core/src/domain/HarnessReport.js +162 -0
  76. package/dist/packages/core/src/domain/HarnessReport.js.map +1 -0
  77. package/dist/packages/core/src/domain/HarnessRun.js +154 -0
  78. package/dist/packages/core/src/domain/HarnessRun.js.map +1 -0
  79. package/dist/packages/core/src/domain/InboundChange.js +127 -0
  80. package/dist/packages/core/src/domain/InboundChange.js.map +1 -0
  81. package/dist/packages/core/src/domain/Language.js +112 -0
  82. package/dist/packages/core/src/domain/Language.js.map +1 -0
  83. package/dist/packages/core/src/domain/Lockfile.js +64 -0
  84. package/dist/packages/core/src/domain/Lockfile.js.map +1 -0
  85. package/dist/packages/core/src/domain/PackContribution.js +106 -0
  86. package/dist/packages/core/src/domain/PackContribution.js.map +1 -0
  87. package/dist/packages/core/src/domain/PackDelta.js +298 -0
  88. package/dist/packages/core/src/domain/PackDelta.js.map +1 -0
  89. package/dist/packages/core/src/domain/PackSpec.js +481 -0
  90. package/dist/packages/core/src/domain/PackSpec.js.map +1 -0
  91. package/dist/packages/core/src/domain/ProfileMatch.js +87 -0
  92. package/dist/packages/core/src/domain/ProfileMatch.js.map +1 -0
  93. package/dist/packages/core/src/domain/Reconciliation.js +72 -0
  94. package/dist/packages/core/src/domain/Reconciliation.js.map +1 -0
  95. package/dist/packages/core/src/domain/RequirementGraph.js +197 -0
  96. package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -0
  97. package/dist/packages/core/src/domain/RequirementPlan.js +85 -0
  98. package/dist/packages/core/src/domain/RequirementPlan.js.map +1 -0
  99. package/dist/packages/core/src/domain/RequirementReadiness.js +115 -0
  100. package/dist/packages/core/src/domain/RequirementReadiness.js.map +1 -0
  101. package/dist/packages/core/src/domain/RequirementSyntax.js +91 -0
  102. package/dist/packages/core/src/domain/RequirementSyntax.js.map +1 -0
  103. package/dist/packages/core/src/domain/ResumeState.js +115 -0
  104. package/dist/packages/core/src/domain/ResumeState.js.map +1 -0
  105. package/dist/packages/core/src/domain/RunBudget.js +103 -0
  106. package/dist/packages/core/src/domain/RunBudget.js.map +1 -0
  107. package/dist/packages/core/src/domain/SpecDiff.js +48 -0
  108. package/dist/packages/core/src/domain/SpecDiff.js.map +1 -0
  109. package/dist/packages/core/src/domain/SpecParser.js +406 -0
  110. package/dist/packages/core/src/domain/SpecParser.js.map +1 -0
  111. package/dist/packages/core/src/domain/SpecopsManifest.js +90 -0
  112. package/dist/packages/core/src/domain/SpecopsManifest.js.map +1 -0
  113. package/dist/packages/core/src/domain/TraceabilityFormat.js +317 -0
  114. package/dist/packages/core/src/domain/TraceabilityFormat.js.map +1 -0
  115. package/dist/packages/core/src/domain/TraceabilityMatrix.js +200 -0
  116. package/dist/packages/core/src/domain/TraceabilityMatrix.js.map +1 -0
  117. package/dist/packages/core/src/domain/TraceabilityMerge.js +180 -0
  118. package/dist/packages/core/src/domain/TraceabilityMerge.js.map +1 -0
  119. package/dist/packages/core/src/domain/ValidationReport.js +53 -0
  120. package/dist/packages/core/src/domain/ValidationReport.js.map +1 -0
  121. package/dist/packages/core/src/domain/ValueAnnotations.js +138 -0
  122. package/dist/packages/core/src/domain/ValueAnnotations.js.map +1 -0
  123. package/dist/packages/core/src/domain/WriteScope.js +155 -0
  124. package/dist/packages/core/src/domain/WriteScope.js.map +1 -0
  125. package/dist/packages/core/src/domain/YamlLite.js +226 -0
  126. package/dist/packages/core/src/domain/YamlLite.js.map +1 -0
  127. package/dist/packages/core/src/index.js +120 -0
  128. package/dist/packages/core/src/index.js.map +1 -0
  129. package/dist/packages/core/src/infrastructure/ChangeWorkspace.js +276 -0
  130. package/dist/packages/core/src/infrastructure/ChangeWorkspace.js.map +1 -0
  131. package/dist/packages/core/src/infrastructure/ConsoleReporter.js +19 -0
  132. package/dist/packages/core/src/infrastructure/ConsoleReporter.js.map +1 -0
  133. package/dist/packages/core/src/infrastructure/DirectorySnapshot.js +106 -0
  134. package/dist/packages/core/src/infrastructure/DirectorySnapshot.js.map +1 -0
  135. package/dist/packages/core/src/infrastructure/DiskDomainPackRepository.js +57 -0
  136. package/dist/packages/core/src/infrastructure/DiskDomainPackRepository.js.map +1 -0
  137. package/dist/packages/core/src/infrastructure/DiskHarnessConfigRepository.js +58 -0
  138. package/dist/packages/core/src/infrastructure/DiskHarnessConfigRepository.js.map +1 -0
  139. package/dist/packages/core/src/infrastructure/DiskLanguageRepository.js +69 -0
  140. package/dist/packages/core/src/infrastructure/DiskLanguageRepository.js.map +1 -0
  141. package/dist/packages/core/src/infrastructure/DiskLockfileRepository.js +64 -0
  142. package/dist/packages/core/src/infrastructure/DiskLockfileRepository.js.map +1 -0
  143. package/dist/packages/core/src/infrastructure/DiskManifestRepository.js +88 -0
  144. package/dist/packages/core/src/infrastructure/DiskManifestRepository.js.map +1 -0
  145. package/dist/packages/core/src/infrastructure/DiskPackDeltaRepository.js +138 -0
  146. package/dist/packages/core/src/infrastructure/DiskPackDeltaRepository.js.map +1 -0
  147. package/dist/packages/core/src/infrastructure/DiskPackRepository.js +130 -0
  148. package/dist/packages/core/src/infrastructure/DiskPackRepository.js.map +1 -0
  149. package/dist/packages/core/src/infrastructure/DiskProjectRepository.js +127 -0
  150. package/dist/packages/core/src/infrastructure/DiskProjectRepository.js.map +1 -0
  151. package/dist/packages/core/src/infrastructure/DiskRequirementGraphRepository.js +124 -0
  152. package/dist/packages/core/src/infrastructure/DiskRequirementGraphRepository.js.map +1 -0
  153. package/dist/packages/core/src/infrastructure/DiskTraceabilityRepository.js +53 -0
  154. package/dist/packages/core/src/infrastructure/DiskTraceabilityRepository.js.map +1 -0
  155. package/dist/packages/core/src/infrastructure/GitContributionStager.js +99 -0
  156. package/dist/packages/core/src/infrastructure/GitContributionStager.js.map +1 -0
  157. package/dist/packages/core/src/infrastructure/GitMergeDriver.js +103 -0
  158. package/dist/packages/core/src/infrastructure/GitMergeDriver.js.map +1 -0
  159. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +348 -0
  160. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -0
  161. package/dist/packages/core/src/infrastructure/PackChangeDeposit.js +106 -0
  162. package/dist/packages/core/src/infrastructure/PackChangeDeposit.js.map +1 -0
  163. package/dist/packages/core/src/infrastructure/RemotePackResolver.js +181 -0
  164. package/dist/packages/core/src/infrastructure/RemotePackResolver.js.map +1 -0
  165. package/dist/packages/core/src/infrastructure/SpecopsConfigFile.js +94 -0
  166. package/dist/packages/core/src/infrastructure/SpecopsConfigFile.js.map +1 -0
  167. package/dist/packages/core/test/unit/authoring-scope.test.js +102 -0
  168. package/dist/packages/core/test/unit/authoring-scope.test.js.map +1 -0
  169. package/dist/packages/core/test/unit/change-templates.test.js +96 -0
  170. package/dist/packages/core/test/unit/change-templates.test.js.map +1 -0
  171. package/dist/packages/core/test/unit/cucumber-messages.test.js +232 -0
  172. package/dist/packages/core/test/unit/cucumber-messages.test.js.map +1 -0
  173. package/dist/packages/core/test/unit/declared-artifacts.test.js +124 -0
  174. package/dist/packages/core/test/unit/declared-artifacts.test.js.map +1 -0
  175. package/dist/packages/core/test/unit/empty-attempt.test.js +79 -0
  176. package/dist/packages/core/test/unit/empty-attempt.test.js.map +1 -0
  177. package/dist/packages/core/test/unit/gherkin-dialects.test.js +115 -0
  178. package/dist/packages/core/test/unit/gherkin-dialects.test.js.map +1 -0
  179. package/dist/packages/core/test/unit/gherkin-keyword-case.test.js +110 -0
  180. package/dist/packages/core/test/unit/gherkin-keyword-case.test.js.map +1 -0
  181. package/dist/packages/core/test/unit/gherkin-quality.test.js +151 -0
  182. package/dist/packages/core/test/unit/gherkin-quality.test.js.map +1 -0
  183. package/dist/packages/core/test/unit/gherkin-tags.test.js +127 -0
  184. package/dist/packages/core/test/unit/gherkin-tags.test.js.map +1 -0
  185. package/dist/packages/core/test/unit/git-safety.test.js +104 -0
  186. package/dist/packages/core/test/unit/git-safety.test.js.map +1 -0
  187. package/dist/packages/core/test/unit/harness-report.test.js +192 -0
  188. package/dist/packages/core/test/unit/harness-report.test.js.map +1 -0
  189. package/dist/packages/core/test/unit/harness-roles.test.js +86 -0
  190. package/dist/packages/core/test/unit/harness-roles.test.js.map +1 -0
  191. package/dist/packages/core/test/unit/inbound-change.test.js +145 -0
  192. package/dist/packages/core/test/unit/inbound-change.test.js.map +1 -0
  193. package/dist/packages/core/test/unit/matrix-dependencies.test.js +100 -0
  194. package/dist/packages/core/test/unit/matrix-dependencies.test.js.map +1 -0
  195. package/dist/packages/core/test/unit/profile-match.test.js +115 -0
  196. package/dist/packages/core/test/unit/profile-match.test.js.map +1 -0
  197. package/dist/packages/core/test/unit/reconciliation.test.js +112 -0
  198. package/dist/packages/core/test/unit/reconciliation.test.js.map +1 -0
  199. package/dist/packages/core/test/unit/requirement-readiness.test.js +161 -0
  200. package/dist/packages/core/test/unit/requirement-readiness.test.js.map +1 -0
  201. package/dist/packages/core/test/unit/resume-state.test.js +124 -0
  202. package/dist/packages/core/test/unit/resume-state.test.js.map +1 -0
  203. package/dist/packages/core/test/unit/run-budget.test.js +113 -0
  204. package/dist/packages/core/test/unit/run-budget.test.js.map +1 -0
  205. package/dist/packages/core/test/unit/traceability-merge.test.js +159 -0
  206. package/dist/packages/core/test/unit/traceability-merge.test.js.map +1 -0
  207. package/dist/packages/core/test/unit/validate-project.test.js +156 -0
  208. package/dist/packages/core/test/unit/validate-project.test.js.map +1 -0
  209. package/dist/packages/core/test/unit/value-annotations.test.js +149 -0
  210. package/dist/packages/core/test/unit/value-annotations.test.js.map +1 -0
  211. package/dist/packages/core/test/unit/write-scope.test.js +165 -0
  212. package/dist/packages/core/test/unit/write-scope.test.js.map +1 -0
  213. package/dist/packages/core/test/unit/yaml-lite.test.js +78 -0
  214. package/dist/packages/core/test/unit/yaml-lite.test.js.map +1 -0
  215. package/dist/scripts/adopt_project.js +11 -0
  216. package/dist/scripts/adopt_project.js.map +1 -0
  217. package/dist/scripts/agents/commands.js +100 -0
  218. package/dist/scripts/agents/commands.js.map +1 -0
  219. package/dist/scripts/agents/init.js +482 -0
  220. package/dist/scripts/agents/init.js.map +1 -0
  221. package/dist/scripts/alm/cli.js +154 -0
  222. package/dist/scripts/alm/cli.js.map +1 -0
  223. package/dist/scripts/alm/clients.js +30 -0
  224. package/dist/scripts/alm/clients.js.map +1 -0
  225. package/dist/scripts/alm/core.js +258 -0
  226. package/dist/scripts/alm/core.js.map +1 -0
  227. package/dist/scripts/alm/port.js +116 -0
  228. package/dist/scripts/alm/port.js.map +1 -0
  229. package/dist/scripts/alm/providers/azure.js +79 -0
  230. package/dist/scripts/alm/providers/azure.js.map +1 -0
  231. package/dist/scripts/alm/providers/github.js +124 -0
  232. package/dist/scripts/alm/providers/github.js.map +1 -0
  233. package/dist/scripts/alm/providers/http-client.js +47 -0
  234. package/dist/scripts/alm/providers/http-client.js.map +1 -0
  235. package/dist/scripts/alm/providers/index.js +107 -0
  236. package/dist/scripts/alm/providers/index.js.map +1 -0
  237. package/dist/scripts/alm/providers/jira.js +129 -0
  238. package/dist/scripts/alm/providers/jira.js.map +1 -0
  239. package/dist/scripts/bundle_pack.js +10 -0
  240. package/dist/scripts/bundle_pack.js.map +1 -0
  241. package/dist/scripts/change/archive.js +68 -0
  242. package/dist/scripts/change/archive.js.map +1 -0
  243. package/dist/scripts/change/artifacts.js +143 -0
  244. package/dist/scripts/change/artifacts.js.map +1 -0
  245. package/dist/scripts/change/cli.js +39 -0
  246. package/dist/scripts/change/cli.js.map +1 -0
  247. package/dist/scripts/change/delta.js +20 -0
  248. package/dist/scripts/change/delta.js.map +1 -0
  249. package/dist/scripts/change/instructions.js +339 -0
  250. package/dist/scripts/change/instructions.js.map +1 -0
  251. package/dist/scripts/ci_init.js +12 -0
  252. package/dist/scripts/ci_init.js.map +1 -0
  253. package/dist/scripts/cli/commands/alm/PullCommand.js +238 -0
  254. package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -0
  255. package/dist/scripts/cli/commands/change/ChangeCommand.js +867 -0
  256. package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -0
  257. package/dist/scripts/cli/commands/config/CiInitCommand.js +144 -0
  258. package/dist/scripts/cli/commands/config/CiInitCommand.js.map +1 -0
  259. package/dist/scripts/cli/commands/config/CompletionCommand.js +160 -0
  260. package/dist/scripts/cli/commands/config/CompletionCommand.js.map +1 -0
  261. package/dist/scripts/cli/commands/config/ConfigInitCommand.js +108 -0
  262. package/dist/scripts/cli/commands/config/ConfigInitCommand.js.map +1 -0
  263. package/dist/scripts/cli/commands/config/ConfigSetCommand.js +166 -0
  264. package/dist/scripts/cli/commands/config/ConfigSetCommand.js.map +1 -0
  265. package/dist/scripts/cli/commands/config/GenAgentContractCommand.js +212 -0
  266. package/dist/scripts/cli/commands/config/GenAgentContractCommand.js.map +1 -0
  267. package/dist/scripts/cli/commands/harness/RunCommand.js +1922 -0
  268. package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -0
  269. package/dist/scripts/cli/commands/mcp/McpInstallCommand.js +114 -0
  270. package/dist/scripts/cli/commands/mcp/McpInstallCommand.js.map +1 -0
  271. package/dist/scripts/cli/commands/mcp/index.js +29 -0
  272. package/dist/scripts/cli/commands/mcp/index.js.map +1 -0
  273. package/dist/scripts/cli/commands/pack/BundlePackCommand.js +59 -0
  274. package/dist/scripts/cli/commands/pack/BundlePackCommand.js.map +1 -0
  275. package/dist/scripts/cli/commands/pack/ExpandDomainPackCommand.js +559 -0
  276. package/dist/scripts/cli/commands/pack/ExpandDomainPackCommand.js.map +1 -0
  277. package/dist/scripts/cli/commands/pack/InferPackCommand.js +304 -0
  278. package/dist/scripts/cli/commands/pack/InferPackCommand.js.map +1 -0
  279. package/dist/scripts/cli/commands/pack/InitPackCommand.js +368 -0
  280. package/dist/scripts/cli/commands/pack/InitPackCommand.js.map +1 -0
  281. package/dist/scripts/cli/commands/pack/LintPackCommand.js +631 -0
  282. package/dist/scripts/cli/commands/pack/LintPackCommand.js.map +1 -0
  283. package/dist/scripts/cli/commands/pack/pack-args.js +83 -0
  284. package/dist/scripts/cli/commands/pack/pack-args.js.map +1 -0
  285. package/dist/scripts/cli/commands/project/AdoptCommand.js +414 -0
  286. package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -0
  287. package/dist/scripts/cli/commands/project/InitFromPackCommand.js +188 -0
  288. package/dist/scripts/cli/commands/project/InitFromPackCommand.js.map +1 -0
  289. package/dist/scripts/cli/commands/project/InitProjectCommand.js +791 -0
  290. package/dist/scripts/cli/commands/project/InitProjectCommand.js.map +1 -0
  291. package/dist/scripts/cli/commands/project/OnboardCommand.js +655 -0
  292. package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -0
  293. package/dist/scripts/cli/commands/project/UpdateCommand.js +206 -0
  294. package/dist/scripts/cli/commands/project/UpdateCommand.js.map +1 -0
  295. package/dist/scripts/cli/commands/project/WizardCommand.js +166 -0
  296. package/dist/scripts/cli/commands/project/WizardCommand.js.map +1 -0
  297. package/dist/scripts/cli/commands/quality/DoctorCommand.js +553 -0
  298. package/dist/scripts/cli/commands/quality/DoctorCommand.js.map +1 -0
  299. package/dist/scripts/cli/commands/quality/FixCommand.js +201 -0
  300. package/dist/scripts/cli/commands/quality/FixCommand.js.map +1 -0
  301. package/dist/scripts/cli/commands/quality/LicenseCheckCommand.js +187 -0
  302. package/dist/scripts/cli/commands/quality/LicenseCheckCommand.js.map +1 -0
  303. package/dist/scripts/cli/commands/quality/ReportCommand.js +557 -0
  304. package/dist/scripts/cli/commands/quality/ReportCommand.js.map +1 -0
  305. package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +764 -0
  306. package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -0
  307. package/dist/scripts/cli/commands/spec/DoneCommand.js +116 -0
  308. package/dist/scripts/cli/commands/spec/DoneCommand.js.map +1 -0
  309. package/dist/scripts/cli/commands/spec/PlanCommand.js +397 -0
  310. package/dist/scripts/cli/commands/spec/PlanCommand.js.map +1 -0
  311. package/dist/scripts/cli/commands/spec/ReqCommand.js +303 -0
  312. package/dist/scripts/cli/commands/spec/ReqCommand.js.map +1 -0
  313. package/dist/scripts/cli/commands/spec/StatusCommand.js +206 -0
  314. package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -0
  315. package/dist/scripts/cli/commands/spec/StudioCommand.js +241 -0
  316. package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -0
  317. package/dist/scripts/cli/commands/specops/ContributeCommand.js +313 -0
  318. package/dist/scripts/cli/commands/specops/ContributeCommand.js.map +1 -0
  319. package/dist/scripts/cli/commands/specops/DiffCommand.js +394 -0
  320. package/dist/scripts/cli/commands/specops/DiffCommand.js.map +1 -0
  321. package/dist/scripts/cli/commands/specops/SyncCommand.js +380 -0
  322. package/dist/scripts/cli/commands/specops/SyncCommand.js.map +1 -0
  323. package/dist/scripts/completion.js +24 -0
  324. package/dist/scripts/completion.js.map +1 -0
  325. package/dist/scripts/config_init.js +12 -0
  326. package/dist/scripts/config_init.js.map +1 -0
  327. package/dist/scripts/config_set.js +20 -0
  328. package/dist/scripts/config_set.js.map +1 -0
  329. package/dist/scripts/docs/blocks.js +137 -0
  330. package/dist/scripts/docs/blocks.js.map +1 -0
  331. package/dist/scripts/docs/build-site.js +425 -0
  332. package/dist/scripts/docs/build-site.js.map +1 -0
  333. package/dist/scripts/docs/nav.js +198 -0
  334. package/dist/scripts/docs/nav.js.map +1 -0
  335. package/dist/scripts/docs/record-terminal.js +477 -0
  336. package/dist/scripts/docs/record-terminal.js.map +1 -0
  337. package/dist/scripts/docs/terminal-storyboard.js +121 -0
  338. package/dist/scripts/docs/terminal-storyboard.js.map +1 -0
  339. package/dist/scripts/doctor.js +14 -0
  340. package/dist/scripts/doctor.js.map +1 -0
  341. package/dist/scripts/done.js +17 -0
  342. package/dist/scripts/done.js.map +1 -0
  343. package/dist/scripts/expand_domain_pack.js +18 -0
  344. package/dist/scripts/expand_domain_pack.js.map +1 -0
  345. package/dist/scripts/fix.js +12 -0
  346. package/dist/scripts/fix.js.map +1 -0
  347. package/dist/scripts/gen_agent_contract.js +14 -0
  348. package/dist/scripts/gen_agent_contract.js.map +1 -0
  349. package/dist/scripts/gen_mcp_tools.js +264 -0
  350. package/dist/scripts/gen_mcp_tools.js.map +1 -0
  351. package/dist/scripts/harness/init.js +358 -0
  352. package/dist/scripts/harness/init.js.map +1 -0
  353. package/dist/scripts/harness/prompt.js +18 -0
  354. package/dist/scripts/harness/prompt.js.map +1 -0
  355. package/dist/scripts/harness/report.js +323 -0
  356. package/dist/scripts/harness/report.js.map +1 -0
  357. package/dist/scripts/harness/run.js +33 -0
  358. package/dist/scripts/harness/run.js.map +1 -0
  359. package/dist/scripts/infer_pack.js +17 -0
  360. package/dist/scripts/infer_pack.js.map +1 -0
  361. package/dist/scripts/init_from_pack.js +16 -0
  362. package/dist/scripts/init_from_pack.js.map +1 -0
  363. package/dist/scripts/init_pack.js +16 -0
  364. package/dist/scripts/init_pack.js.map +1 -0
  365. package/dist/scripts/init_project.js +17 -0
  366. package/dist/scripts/init_project.js.map +1 -0
  367. package/dist/scripts/lib/agent.js +99 -0
  368. package/dist/scripts/lib/agent.js.map +1 -0
  369. package/dist/scripts/lib/capability-specs.js +80 -0
  370. package/dist/scripts/lib/capability-specs.js.map +1 -0
  371. package/dist/scripts/lib/command.js +17 -0
  372. package/dist/scripts/lib/command.js.map +1 -0
  373. package/dist/scripts/lib/diagnostics.js +62 -0
  374. package/dist/scripts/lib/diagnostics.js.map +1 -0
  375. package/dist/scripts/lib/monorepo-fanout.js +118 -0
  376. package/dist/scripts/lib/monorepo-fanout.js.map +1 -0
  377. package/dist/scripts/lib/placeholders.js +190 -0
  378. package/dist/scripts/lib/placeholders.js.map +1 -0
  379. package/dist/scripts/lib/project-root.js +124 -0
  380. package/dist/scripts/lib/project-root.js.map +1 -0
  381. package/dist/scripts/lib/requirement-graph.js +31 -0
  382. package/dist/scripts/lib/requirement-graph.js.map +1 -0
  383. package/dist/scripts/lib/surface.js +609 -0
  384. package/dist/scripts/lib/surface.js.map +1 -0
  385. package/dist/scripts/license_check.js +15 -0
  386. package/dist/scripts/license_check.js.map +1 -0
  387. package/dist/scripts/lint_pack.js +18 -0
  388. package/dist/scripts/lint_pack.js.map +1 -0
  389. package/dist/scripts/merge-traceability.js +106 -0
  390. package/dist/scripts/merge-traceability.js.map +1 -0
  391. package/dist/scripts/onboard.js +22 -0
  392. package/dist/scripts/onboard.js.map +1 -0
  393. package/dist/scripts/plan.js +17 -0
  394. package/dist/scripts/plan.js.map +1 -0
  395. package/dist/scripts/plugin/gate-hook.js +171 -0
  396. package/dist/scripts/plugin/gate-hook.js.map +1 -0
  397. package/dist/scripts/report.js +17 -0
  398. package/dist/scripts/report.js.map +1 -0
  399. package/dist/scripts/req.js +22 -0
  400. package/dist/scripts/req.js.map +1 -0
  401. package/dist/scripts/schema/cli.js +215 -0
  402. package/dist/scripts/schema/cli.js.map +1 -0
  403. package/dist/scripts/schema/registry.js +264 -0
  404. package/dist/scripts/schema/registry.js.map +1 -0
  405. package/dist/scripts/specops/add.js +180 -0
  406. package/dist/scripts/specops/add.js.map +1 -0
  407. package/dist/scripts/specops/against_lock.js +100 -0
  408. package/dist/scripts/specops/against_lock.js.map +1 -0
  409. package/dist/scripts/specops/as_change.js +49 -0
  410. package/dist/scripts/specops/as_change.js.map +1 -0
  411. package/dist/scripts/specops/contribute.js +24 -0
  412. package/dist/scripts/specops/contribute.js.map +1 -0
  413. package/dist/scripts/specops/diff.js +32 -0
  414. package/dist/scripts/specops/diff.js.map +1 -0
  415. package/dist/scripts/specops/lock.js +39 -0
  416. package/dist/scripts/specops/lock.js.map +1 -0
  417. package/dist/scripts/specops/manifest.js +90 -0
  418. package/dist/scripts/specops/manifest.js.map +1 -0
  419. package/dist/scripts/specops/remove.js +102 -0
  420. package/dist/scripts/specops/remove.js.map +1 -0
  421. package/dist/scripts/specops/sync.js +27 -0
  422. package/dist/scripts/specops/sync.js.map +1 -0
  423. package/dist/scripts/specops/verify.js +149 -0
  424. package/dist/scripts/specops/verify.js.map +1 -0
  425. package/dist/scripts/status.js +17 -0
  426. package/dist/scripts/status.js.map +1 -0
  427. package/dist/scripts/studio.js +14 -0
  428. package/dist/scripts/studio.js.map +1 -0
  429. package/dist/scripts/update.js +17 -0
  430. package/dist/scripts/update.js.map +1 -0
  431. package/dist/scripts/validate_specs.js +10 -0
  432. package/dist/scripts/validate_specs.js.map +1 -0
  433. package/examples/project.config.example +19 -0
  434. package/examples/project.yaml.example +17 -0
  435. package/package.json +105 -0
  436. package/templates/adopt/AI_RULES.md.tpl +27 -0
  437. package/templates/adopt/adr-readme.md.tpl +5 -0
  438. package/templates/adopt/baseline.feature.tpl +9 -0
  439. package/templates/adopt/spec.md.tpl +25 -0
  440. package/templates/adopt/traceability.md.tpl +11 -0
  441. package/templates/backend/AI_RULES.md.tpl +35 -0
  442. package/templates/backend/features/core/health.feature.tpl +7 -0
  443. package/templates/base/.devcontainer/devcontainer.json.tpl +18 -0
  444. package/templates/base/.dockerignore.tpl +11 -0
  445. package/templates/base/.env.dev.app.tpl +13 -0
  446. package/templates/base/.env.dev.infra.tpl +6 -0
  447. package/templates/base/.env.dev.tpl +16 -0
  448. package/templates/base/.env.example.tpl +17 -0
  449. package/templates/base/.env.feature.app.tpl +11 -0
  450. package/templates/base/.env.feature.infra.tpl +4 -0
  451. package/templates/base/.env.feature.tpl +16 -0
  452. package/templates/base/.env.prod.app.tpl +13 -0
  453. package/templates/base/.env.prod.infra.tpl +6 -0
  454. package/templates/base/.env.prod.tpl +16 -0
  455. package/templates/base/.github/workflows/specs.yml.tpl +26 -0
  456. package/templates/base/.gitignore.tpl +9 -0
  457. package/templates/base/.pre-commit-config.yaml.tpl +10 -0
  458. package/templates/base/AGENTS.md.tpl +32 -0
  459. package/templates/base/README.md.tpl +32 -0
  460. package/templates/base/docker-compose.yml.tpl +13 -0
  461. package/templates/base/docs/specs/adr/README.md.tpl +10 -0
  462. package/templates/base/docs/specs/aggregates.md.tpl +5 -0
  463. package/templates/base/docs/specs/commands.md.tpl +13 -0
  464. package/templates/base/docs/specs/domain-model.md.tpl +30 -0
  465. package/templates/base/docs/specs/events.md.tpl +5 -0
  466. package/templates/base/docs/specs/review-checklist.md.tpl +18 -0
  467. package/templates/base/docs/specs/runtime-environments.md.tpl +26 -0
  468. package/templates/base/docs/specs/status-model.md.tpl +16 -0
  469. package/templates/base/docs/specs/traceability.md.tpl +7 -0
  470. package/templates/base/docs/specs/use-cases.md.tpl +5 -0
  471. package/templates/base/spec.md.tpl +63 -0
  472. package/templates/ci/azure.yml.tpl +40 -0
  473. package/templates/ci/github.yml.tpl +40 -0
  474. package/templates/ci/gitlab.yml.tpl +21 -0
  475. package/templates/ci/jenkins.tpl +35 -0
  476. package/templates/contracts/AI_RULES.md.tpl +55 -0
  477. package/templates/contracts/asyncapi-stub.yaml.tpl +24 -0
  478. package/templates/contracts/contract-traceability.md.tpl +10 -0
  479. package/templates/contracts/openapi-stub.yaml.tpl +29 -0
  480. package/templates/contracts/pacts-gitkeep.tpl +0 -0
  481. package/templates/contracts/test-strategy.md.tpl +94 -0
  482. package/templates/frontend/AI_RULES.md.tpl +34 -0
  483. package/templates/frontend/features/core/health.feature.tpl +6 -0
  484. package/templates/harness/harness.config.yaml.tpl +74 -0
  485. package/templates/harness/prompt-prefix.md.tpl +60 -0
  486. package/templates/mobile/AI_RULES.md.tpl +56 -0
  487. package/templates/mobile/features/core/health.feature.tpl +7 -0
  488. package/templates/modules/auth/backend/registration_and_login.feature.tpl +10 -0
  489. package/templates/modules/auth/frontend/login.feature.tpl +5 -0
  490. package/templates/modules/billing/backend/billing_settlement.feature.tpl +5 -0
  491. package/templates/modules/billing/frontend/billing_summary.feature.tpl +5 -0
  492. package/templates/modules/dashboard/backend/dashboard_kpi.feature.tpl +5 -0
  493. package/templates/modules/dashboard/frontend/dashboard.feature.tpl +5 -0
  494. package/vendor/mermaid.min.js +3636 -0
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * The green diff must touch what the matrix declared (A2).
4
+ *
5
+ * A row names `test_artifact` and `technical_artifact`; the prompt hands both
6
+ * to the agent; nothing checked the diff contained them. An agent can implement
7
+ * elsewhere, pass the scenario, and leave the matrix pointing at a file where
8
+ * the logic does not live — the documentary lie `AI_RULES.md` forbids.
9
+ *
10
+ * Most of these tests are about *not* firing. A real matrix cell is markdown
11
+ * written by a person, and the scaffolded one says `` `API /health`, smoke
12
+ * test ``. A check that treats prose as a path reports every project as broken,
13
+ * and a warning that is usually wrong is a warning people learn to ignore —
14
+ * which is how `--strict`-only rules ended up useless in H14.
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ const node_test_1 = require("node:test");
51
+ const assert = __importStar(require("node:assert/strict"));
52
+ const DeclaredArtifacts_1 = require("../../src/domain/DeclaredArtifacts");
53
+ (0, node_test_1.test)("a path is a path; a sentence about a path is not", () => {
54
+ for (const yes of ["src/App.java", "App.java", "features/core/health.feature", "src/health/"]) {
55
+ assert.equal((0, DeclaredArtifacts_1.looksLikePath)(yes), true, `${yes} should read as a path`);
56
+ }
57
+ for (const no of ["API /health", "smoke test", "TBD", "TODO", "N/A", "-", "", "the health API"]) {
58
+ assert.equal((0, DeclaredArtifacts_1.looksLikePath)(no), false, `${no} should not read as a path`);
59
+ }
60
+ });
61
+ (0, node_test_1.test)("a cell can be half path and half prose, and both halves are respected", () => {
62
+ // The realistic case. Forcing the cell to be all one or all the other would
63
+ // mean either losing the check or inventing findings about the prose.
64
+ assert.deepEqual((0, DeclaredArtifacts_1.declaredPaths)("`src/Health.java`, smoke test"), ["src/Health.java"]);
65
+ assert.deepEqual((0, DeclaredArtifacts_1.declaredPaths)("`API /health`, smoke test"), []);
66
+ assert.deepEqual((0, DeclaredArtifacts_1.declaredPaths)("TBD"), []);
67
+ assert.deepEqual((0, DeclaredArtifacts_1.declaredPaths)(""), []);
68
+ assert.deepEqual((0, DeclaredArtifacts_1.declaredPaths)(null), []);
69
+ });
70
+ (0, node_test_1.test)("a declared path the diff never touched is reported, with a fix that names a real flag", () => {
71
+ const found = (0, DeclaredArtifacts_1.checkDeclaredArtifacts)({
72
+ requirement: "REQ-007",
73
+ touched: ["src/Other.java"],
74
+ technicalArtifact: "`src/Health.java`",
75
+ });
76
+ assert.equal(found.length, 1);
77
+ assert.equal(found[0].code, DeclaredArtifacts_1.ARTIFACT_CODES.UNTOUCHED);
78
+ assert.equal(found[0].severity, "warning", "a warning by default — see the module note");
79
+ assert.match(found[0].message, /src\/Health\.java/);
80
+ assert.match(found[0].fix, /specgate req link REQ-007 --code/);
81
+ });
82
+ (0, node_test_1.test)("the test artifact gets its own flag in the fix", () => {
83
+ const found = (0, DeclaredArtifacts_1.checkDeclaredArtifacts)({
84
+ requirement: "REQ-007",
85
+ touched: [],
86
+ testArtifact: "`src/test/HealthTest.java`",
87
+ });
88
+ assert.match(found[0].fix, /--test/);
89
+ });
90
+ (0, node_test_1.test)("--strict-artifacts promotes it to an error, and nothing else changes", () => {
91
+ const input = { requirement: "REQ-007", touched: [], technicalArtifact: "`src/Health.java`" };
92
+ const lenient = (0, DeclaredArtifacts_1.checkDeclaredArtifacts)(input, false);
93
+ const strict = (0, DeclaredArtifacts_1.checkDeclaredArtifacts)(input, true);
94
+ assert.equal(lenient[0].severity, "warning");
95
+ assert.equal(strict[0].severity, "error");
96
+ assert.equal(strict[0].message, lenient[0].message);
97
+ });
98
+ (0, node_test_1.test)("touching the declared file raises nothing", () => {
99
+ assert.deepEqual((0, DeclaredArtifacts_1.checkDeclaredArtifacts)({
100
+ touched: ["src/Health.java", "src/test/HealthTest.java"],
101
+ technicalArtifact: "`src/Health.java`",
102
+ testArtifact: "`src/test/HealthTest.java`",
103
+ }), []);
104
+ });
105
+ (0, node_test_1.test)("a row may name a directory and the work land on files inside it", () => {
106
+ assert.deepEqual((0, DeclaredArtifacts_1.checkDeclaredArtifacts)({
107
+ touched: ["src/health/Endpoint.java"],
108
+ technicalArtifact: "`src/health/`",
109
+ }), []);
110
+ });
111
+ (0, node_test_1.test)("a prose-only row produces no findings at all", () => {
112
+ // The scaffolded project. If this ever starts warning, every `specgate init`
113
+ // hands the user a harness that complains on its first run.
114
+ assert.deepEqual((0, DeclaredArtifacts_1.checkDeclaredArtifacts)({
115
+ requirement: "REQ-000",
116
+ touched: ["src/App.java"],
117
+ technicalArtifact: "`API /health`, smoke test",
118
+ testArtifact: "TBD",
119
+ }), []);
120
+ });
121
+ (0, node_test_1.test)("an empty diff with prose declarations is still silent", () => {
122
+ assert.deepEqual((0, DeclaredArtifacts_1.checkDeclaredArtifacts)({ touched: [], technicalArtifact: "TBD", testArtifact: "TBD" }), []);
123
+ });
124
+ //# sourceMappingURL=declared-artifacts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declared-artifacts.test.js","sourceRoot":"","sources":["../../../../../packages/core/test/unit/declared-artifacts.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * H19 — the harness gate approved an agent that wrote nothing.
38
+ *
39
+ * Reproduced end to end on 2026-08-26 (`--agent "cat {prompt_file} >
40
+ * /dev/null"` against a generated project reported `pass (1 attempt)` and
41
+ * moved the row to `Implemented`). These tests pin the decidable core of the
42
+ * fix so it cannot regress without failing here first.
43
+ */
44
+ const node_test_1 = require("node:test");
45
+ const assert = __importStar(require("node:assert/strict"));
46
+ const EmptyAttempt_1 = require("../../src/domain/EmptyAttempt");
47
+ (0, node_test_1.test)("an attempt that touched nothing is empty", () => {
48
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)([]), true);
49
+ });
50
+ (0, node_test_1.test)("an attempt carrying only the archived prompt is empty", () => {
51
+ // This is the H19 shape: the harness wrote the archive, the agent wrote
52
+ // nothing. Counting it would let the harness's bookkeeping vouch for the
53
+ // agent.
54
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)([`${EmptyAttempt_1.PROMPT_ARCHIVE_DIR}/REQ-000-attempt-1-agent.md`]), true);
55
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)([EmptyAttempt_1.PROMPT_ARCHIVE_DIR]), true);
56
+ });
57
+ (0, node_test_1.test)("one file the agent wrote is enough to not be empty", () => {
58
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)(["src/health.ts"]), false);
59
+ });
60
+ (0, node_test_1.test)("the archived prompt does not hide a real file beside it", () => {
61
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)([`${EmptyAttempt_1.PROMPT_ARCHIVE_DIR}/REQ-000-attempt-1-agent.md`, "src/health.ts"]), false);
62
+ });
63
+ (0, node_test_1.test)("a path merely starting with the archive's name is not the archive", () => {
64
+ // `.specops/harness-prompts-notes.md` is a different file; a naive
65
+ // startsWith on the bare directory name would swallow it.
66
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)([`${EmptyAttempt_1.PROMPT_ARCHIVE_DIR}-notes.md`]), false);
67
+ });
68
+ (0, node_test_1.test)("agentAuthoredPaths reports what the agent wrote, in order", () => {
69
+ assert.deepEqual((0, EmptyAttempt_1.agentAuthoredPaths)([
70
+ "src/health.ts",
71
+ `${EmptyAttempt_1.PROMPT_ARCHIVE_DIR}/REQ-000-attempt-1-agent.md`,
72
+ "tests/health.test.ts",
73
+ ]), ["src/health.ts", "tests/health.test.ts"]);
74
+ });
75
+ (0, node_test_1.test)("undefined and null touched lists do not throw", () => {
76
+ assert.equal((0, EmptyAttempt_1.isEmptyAttempt)(undefined), true);
77
+ assert.deepEqual((0, EmptyAttempt_1.agentAuthoredPaths)(null), []);
78
+ });
79
+ //# sourceMappingURL=empty-attempt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-attempt.test.js","sourceRoot":"","sources":["../../../../../packages/core/test/unit/empty-attempt.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;GAOG;AACH,yCAAiC;AACjC,2DAA6C;AAC7C,gEAIuC;AAEvC,IAAA,gBAAI,EAAC,0CAA0C,EAAE,GAAG,EAAE;IACpD,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAc,EAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,uDAAuD,EAAE,GAAG,EAAE;IACjE,wEAAwE;IACxE,yEAAyE;IACzE,SAAS;IACT,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAc,EAAC,CAAC,GAAG,iCAAkB,6BAA6B,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACzF,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAc,EAAC,CAAC,iCAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,oDAAoD,EAAE,GAAG,EAAE;IAC9D,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAc,EAAC,CAAC,eAAe,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,CAAC,KAAK,CACV,IAAA,6BAAc,EAAC,CAAC,GAAG,iCAAkB,6BAA6B,EAAE,eAAe,CAAC,CAAC,EACrF,KAAK,CACN,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,mEAAmE,EAAE,GAAG,EAAE;IAC7E,mEAAmE;IACnE,0DAA0D;IAC1D,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAc,EAAC,CAAC,GAAG,iCAAkB,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,MAAM,CAAC,SAAS,CACd,IAAA,iCAAkB,EAAC;QACjB,eAAe;QACf,GAAG,iCAAkB,6BAA6B;QAClD,sBAAsB;KACvB,CAAC,EACF,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAC1C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAc,EAAC,SAAkB,CAAC,EAAE,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,SAAS,CAAC,IAAA,iCAAkB,EAAC,IAAa,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * The vendored keyword table, checked against the official one.
4
+ *
5
+ * `GherkinDialects.ts` is data copied out of `@cucumber/gherkin` so the CLI can
6
+ * read Gherkin without a runtime dependency — `package.json` has none, and it
7
+ * runs through `npx` on other people's machines, so that is a structural
8
+ * promise rather than a preference.
9
+ *
10
+ * The price of vendoring is drift, and this is where it gets paid: every entry
11
+ * is compared with the installed official table, so bumping Cucumber either
12
+ * passes or says exactly which keyword moved. Without this file the table is a
13
+ * copy that slowly stops being one.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ const node_test_1 = require("node:test");
50
+ const assert = __importStar(require("node:assert/strict"));
51
+ const GherkinDialects_1 = require("../../src/domain/GherkinDialects");
52
+ const official = require("@cucumber/gherkin/dist/gherkin-languages.json");
53
+ const installedVersion = require("@cucumber/gherkin/package.json").version;
54
+ const KEYS = [
55
+ "feature",
56
+ "background",
57
+ "rule",
58
+ "scenario",
59
+ "scenarioOutline",
60
+ "examples",
61
+ "given",
62
+ "when",
63
+ "then",
64
+ "and",
65
+ "but",
66
+ ];
67
+ (0, node_test_1.test)("every vendored dialect matches the official table, keyword for keyword", () => {
68
+ const drift = [];
69
+ for (const [tag, dialect] of Object.entries(GherkinDialects_1.DIALECTS)) {
70
+ const source = official[tag];
71
+ if (!source) {
72
+ drift.push(`${tag}: no longer exists in the official table`);
73
+ continue;
74
+ }
75
+ if (dialect.name !== source.name || dialect.native !== source.native) {
76
+ drift.push(`${tag}: name/native changed — ${source.name} / ${source.native}`);
77
+ }
78
+ for (const key of KEYS) {
79
+ const ours = [...dialect[key]];
80
+ const theirs = [...(source[key] ?? [])];
81
+ if (JSON.stringify(ours) !== JSON.stringify(theirs)) {
82
+ drift.push(`${tag}.${key}: vendored ${JSON.stringify(ours)} vs official ${JSON.stringify(theirs)}`);
83
+ }
84
+ }
85
+ }
86
+ assert.deepEqual(drift, [], "\n The vendored table has drifted from @cucumber/gherkin. Regenerate it from\n" +
87
+ " node_modules/@cucumber/gherkin/dist/gherkin-languages.json rather than\n" +
88
+ ` editing by hand:\n ${drift.join("\n ")}`);
89
+ });
90
+ (0, node_test_1.test)("the table records which version it was taken from", () => {
91
+ // Not an equality check: the point is that the recorded version is the one
92
+ // the drift check above ran against, so a passing suite means the table
93
+ // matches *this* Cucumber, and the number in the file says which.
94
+ assert.equal(GherkinDialects_1.DIALECT_TABLE_VERSION, installedVersion, "the vendored table names a different version than the one installed — regenerate it");
95
+ });
96
+ (0, node_test_1.test)("the dialects the CLI offers are the dialects it can parse", () => {
97
+ // `specgate init` takes LANG en / es / pt. A language the scaffolder offers and
98
+ // the parser does not know would produce files the tool cannot read back.
99
+ for (const tag of ["en", "es", "pt"]) {
100
+ assert.ok(GherkinDialects_1.DIALECTS[tag], `${tag} is offered by init but missing from the table`);
101
+ }
102
+ assert.ok(GherkinDialects_1.DIALECTS[GherkinDialects_1.DEFAULT_DIALECT], "the default dialect must exist");
103
+ });
104
+ (0, node_test_1.test)("step keywords keep the trailing space the table gives them", () => {
105
+ // `"Given "` ends in a space on purpose: it is what stops `Givenchy` from
106
+ // parsing as a step. Trimming the table would silently widen every keyword.
107
+ for (const [tag, dialect] of Object.entries(GherkinDialects_1.DIALECTS)) {
108
+ for (const kind of ["given", "when", "then", "and", "but"]) {
109
+ for (const keyword of dialect[kind]) {
110
+ assert.ok(keyword.endsWith(" "), `${tag}.${kind}: ${JSON.stringify(keyword)} lost its trailing space`);
111
+ }
112
+ }
113
+ }
114
+ });
115
+ //# sourceMappingURL=gherkin-dialects.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gherkin-dialects.test.js","sourceRoot":"","sources":["../../../../../packages/core/test/unit/gherkin-dialects.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * Lines that were trying to be Gherkin keywords and are not (F3).
4
+ *
5
+ * Cucumber discards them in silence: `GIVEN a flag` is prose to it, so the
6
+ * scenario ends up with fewer steps than it appears to have — or none. That
7
+ * silence is what let H14 ship 27 scenarios which executed nothing while
8
+ * `pack lint --strict` reported the packs as fine.
9
+ *
10
+ * The risk of a check like this is the opposite failure: crying wolf on prose
11
+ * that merely resembles a keyword. Most of what is asserted here is that it
12
+ * stays quiet.
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ const node_test_1 = require("node:test");
49
+ const assert = __importStar(require("node:assert/strict"));
50
+ const Gherkin_1 = require("../../src/domain/Gherkin");
51
+ const feature = (...lines) => lines.join("\n") + "\n";
52
+ (0, node_test_1.test)("upper-case step keywords are reported with the spelling that works", () => {
53
+ // H14 exactly. The fix has to be literal: "write `Given`" is actionable,
54
+ // "no steps found" is a riddle.
55
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("Feature: Flags", " Scenario: Rollout", " GIVEN a flag", " WHEN evaluated", " THEN it works"));
56
+ assert.deepEqual(issues.map((i) => [i.line, i.found, i.expected]), [
57
+ [3, "GIVEN", "Given"],
58
+ [4, "WHEN", "When"],
59
+ [5, "THEN", "Then"],
60
+ ]);
61
+ });
62
+ (0, node_test_1.test)("a mis-cased block keyword is reported too", () => {
63
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("Feature: Flags", " SCENARIO: Rollout", " Given a flag"));
64
+ assert.equal(issues.length, 1);
65
+ assert.equal(issues[0].found, "SCENARIO");
66
+ assert.equal(issues[0].expected, "Scenario");
67
+ });
68
+ (0, node_test_1.test)("a space before the colon is caught, though the case is right", () => {
69
+ // `Feature :` reads as correct and is not: Cucumber does not recognise it,
70
+ // so the whole file silently has no feature.
71
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("Feature : Flags", " Scenario: Rollout", " Given a flag"));
72
+ assert.equal(issues.length, 1);
73
+ assert.equal(issues[0].expected, "Feature");
74
+ });
75
+ (0, node_test_1.test)("lower-case keywords are caught as well as upper-case ones", () => {
76
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("Feature: Flags", " Scenario: Rollout", " given a flag"));
77
+ assert.deepEqual(issues.map((i) => [i.found, i.expected]), [["given", "Given"]]);
78
+ });
79
+ (0, node_test_1.test)("a correct file reports nothing", () => {
80
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("@tagged", "Feature: Flags", " Background:", " Given a tenant", " Rule: Rollout", " Scenario Outline: Percentages", " Given a flag at <n>", " When users are evaluated", " Then roughly <n> receive it", " And nobody else does", " * even this one", " Examples:", " | n |", " | 50 |"));
81
+ assert.deepEqual(issues, []);
82
+ });
83
+ (0, node_test_1.test)("a word that merely starts like a keyword is not a mistake", () => {
84
+ // `Givenchy` begins with `Given`. The trailing space in the keyword table is
85
+ // what separates them, and this is the test that keeps it there.
86
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("Feature: Brands", " Scenario: Launch", " Given Givenchy launched a product"));
87
+ assert.deepEqual(issues, []);
88
+ });
89
+ (0, node_test_1.test)("keywords inside a doc string are content, not mistakes", () => {
90
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("Feature: Payloads", " Scenario: A body that looks like Gherkin", " Given a request body", ' """', " GIVEN this is documentation", " SCENARIO: and so is this", ' """', " When it is sent", " Then it is accepted"));
91
+ assert.deepEqual(issues, []);
92
+ });
93
+ (0, node_test_1.test)("data tables, comments and tags are left alone", () => {
94
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("# GIVEN this comment mentions a keyword", "@GIVEN", "Feature: Tables", " Scenario Outline: Rows", " Given a value <v>", " Examples:", " | v |", " | GIVEN |"));
95
+ assert.deepEqual(issues, []);
96
+ });
97
+ (0, node_test_1.test)("the Spanish dialect is judged by its own keywords", () => {
98
+ const wrong = (0, Gherkin_1.findKeywordCaseIssues)(feature("# language: es", "Característica: Facturación", " Escenario: Emitir", " DADO un cliente"));
99
+ assert.deepEqual(wrong.map((i) => [i.found, i.expected]), [["DADO", "Dado"]]);
100
+ const right = (0, Gherkin_1.findKeywordCaseIssues)(feature("# language: es", "Característica: Facturación", " Escenario: Emitir", " Dado un cliente"));
101
+ assert.deepEqual(right, []);
102
+ });
103
+ (0, node_test_1.test)("an English keyword in a Spanish file is not silently accepted", () => {
104
+ // `Given` is not a keyword in `es`, so Cucumber reads it as prose. Reporting
105
+ // it as an unknown keyword would be wrong — it is a dialect mismatch — but
106
+ // staying silent is what H14 was.
107
+ const issues = (0, Gherkin_1.findKeywordCaseIssues)(feature("# language: es", "Característica: X", " Escenario: Y", " Given a customer"));
108
+ assert.deepEqual(issues, [], "not a case mistake; `scenario_has_no_steps` is what reports this");
109
+ });
110
+ //# sourceMappingURL=gherkin-keyword-case.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gherkin-keyword-case.test.js","sourceRoot":"","sources":["../../../../../packages/core/test/unit/gherkin-keyword-case.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ /**
3
+ * The scenario-quality rules, tested where they now live (A3).
4
+ *
5
+ * They used to live inside `pack lint` and judge one thing: a `pack.yaml`. The
6
+ * harness does not gate packs, it gates projects, and a project's features
7
+ * arrive by routes that never touch `pack lint`. Moving the rules into the
8
+ * domain is what lets `validate --strict-scenarios`, `doctor` and `harness run`
9
+ * reach the same verdict instead of growing three drifting copies — which is
10
+ * exactly how H14 happened.
11
+ *
12
+ * Severity is the part worth pinning: two rules are errors and can never be
13
+ * demoted to style, because the scenarios they catch *pass*.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ const node_test_1 = require("node:test");
50
+ const assert = __importStar(require("node:assert/strict"));
51
+ const GherkinQuality_1 = require("../../src/domain/GherkinQuality");
52
+ const codesOf = (findings) => findings.map((f) => f.code);
53
+ const byCode = (findings, code) => findings.find((f) => f.code === code);
54
+ const GOOD = {
55
+ name: "Defining a flag emits FlagDefined",
56
+ steps: [
57
+ { keyword: "given", text: "no flag with id 'new-checkout' exists" },
58
+ { keyword: "when", text: "an operator defines the flag with default=false" },
59
+ { keyword: "then", text: "FlagDefined is emitted" },
60
+ ],
61
+ outline: false,
62
+ hasExamples: true,
63
+ };
64
+ (0, node_test_1.test)("a well-formed scenario raises nothing", () => {
65
+ assert.deepEqual((0, GherkinQuality_1.analyseScenario)(GOOD, "SCN-001"), []);
66
+ });
67
+ (0, node_test_1.test)("an empty scenario is an error, never a warning", () => {
68
+ // The whole point of A3 meeting H14: Cucumber reports this as
69
+ // `1 scenario (1 passed) · 0 steps · exit 0`. A warning would let it ship.
70
+ const found = (0, GherkinQuality_1.analyseScenario)({ ...GOOD, steps: [] }, "SCN-001");
71
+ const noSteps = byCode(found, GherkinQuality_1.QUALITY_CODES.NO_STEPS);
72
+ assert.ok(noSteps, `expected ${GherkinQuality_1.QUALITY_CODES.NO_STEPS}, got ${codesOf(found)}`);
73
+ assert.equal(noSteps.severity, "error");
74
+ assert.ok(noSteps.fix, "a rule without a fix is a rule the user cannot act on");
75
+ assert.match(noSteps.message, /case-sensitive/, "it should name the usual cause");
76
+ });
77
+ (0, node_test_1.test)("a Scenario Outline without Examples is an error — it runs zero times", () => {
78
+ const found = (0, GherkinQuality_1.analyseScenario)({ ...GOOD, outline: true, hasExamples: false }, "SCN-001");
79
+ const outline = byCode(found, GherkinQuality_1.QUALITY_CODES.OUTLINE_WITHOUT_EXAMPLES);
80
+ assert.ok(outline);
81
+ assert.equal(outline.severity, "error");
82
+ });
83
+ (0, node_test_1.test)("thin, actionless, assertionless and vague scenarios are warnings", () => {
84
+ // They weaken the signal; they do not fake it. Blocking on them would make
85
+ // the tool unusable on a repository brought in with `specgate adopt`.
86
+ const thin = (0, GherkinQuality_1.analyseScenario)({ ...GOOD, steps: [{ keyword: "given", text: "a thing" }] }, "SCN-001");
87
+ assert.equal(byCode(thin, GherkinQuality_1.QUALITY_CODES.TOO_FEW_STEPS).severity, "warning");
88
+ assert.equal(byCode(thin, GherkinQuality_1.QUALITY_CODES.NO_WHEN).severity, "warning");
89
+ assert.equal(byCode(thin, GherkinQuality_1.QUALITY_CODES.NO_THEN).severity, "warning");
90
+ const vague = (0, GherkinQuality_1.analyseScenario)({ ...GOOD, steps: [...GOOD.steps, { keyword: "then", text: "it works correctly" }] }, "SCN-001");
91
+ const v = byCode(vague, GherkinQuality_1.QUALITY_CODES.VAGUE_STEP);
92
+ assert.ok(v, `expected a vague-step finding, got ${codesOf(vague)}`);
93
+ assert.equal(v.severity, "warning");
94
+ });
95
+ (0, node_test_1.test)("every finding carries the target it was asked to report against", () => {
96
+ const found = (0, GherkinQuality_1.analyseScenario)({ ...GOOD, steps: [] }, "SCN-042", "features/x.feature");
97
+ assert.equal(found[0].target, "SCN-042");
98
+ assert.equal(found[0].file, "features/x.feature");
99
+ });
100
+ (0, node_test_1.test)("isGenericTitle knows a name from a placeholder", () => {
101
+ for (const bad of ["", "Test", "Scenario 1", "Example", "Untitled", "two words"]) {
102
+ assert.equal((0, GherkinQuality_1.isGenericTitle)(bad), true, `${JSON.stringify(bad)} should be generic`);
103
+ }
104
+ assert.equal((0, GherkinQuality_1.isGenericTitle)("Defining a flag emits FlagDefined"), false);
105
+ });
106
+ (0, node_test_1.test)("keyword case is judged on the raw text, with the line and the fix", () => {
107
+ const source = [
108
+ "Feature: Flags",
109
+ " Scenario: Defining a flag emits FlagDefined",
110
+ " GIVEN no flag exists",
111
+ " When an operator defines one",
112
+ " Then FlagDefined is emitted",
113
+ "",
114
+ ].join("\n");
115
+ const found = (0, GherkinQuality_1.analyseKeywordCase)(source, "features/flags.feature");
116
+ assert.equal(found.length, 1, `expected one, got ${JSON.stringify(found)}`);
117
+ assert.equal(found[0].code, GherkinQuality_1.QUALITY_CODES.KEYWORD_CASE);
118
+ assert.equal(found[0].severity, "error");
119
+ assert.equal(found[0].line, 3);
120
+ assert.equal(found[0].file, "features/flags.feature");
121
+ assert.match(found[0].message, /`GIVEN`/);
122
+ assert.match(found[0].message, /`Given`/);
123
+ });
124
+ (0, node_test_1.test)("a source-level analysis reports the case error and the emptiness it causes", () => {
125
+ // Both, deliberately. The case error says what to change; `no steps` says
126
+ // what it costs. One without the other is either a riddle or a nag.
127
+ const source = [
128
+ "Feature: Flags",
129
+ " Scenario: Defining a flag emits FlagDefined",
130
+ " GIVEN no flag exists",
131
+ " WHEN an operator defines one",
132
+ " THEN FlagDefined is emitted",
133
+ "",
134
+ ].join("\n");
135
+ const codes = codesOf((0, GherkinQuality_1.analyseGherkinSource)(source, "features/flags.feature"));
136
+ assert.equal(codes.filter((c) => c === GherkinQuality_1.QUALITY_CODES.KEYWORD_CASE).length, 3);
137
+ assert.ok(codes.includes(GherkinQuality_1.QUALITY_CODES.NO_STEPS));
138
+ });
139
+ (0, node_test_1.test)("a good source analyses clean, in Spanish as in English", () => {
140
+ const es = [
141
+ "# language: es",
142
+ "Característica: Facturación",
143
+ " Escenario: Emitir una factura genera InvoiceIssued",
144
+ " Dado un cliente con id 'C-1'",
145
+ " Cuando se emite la factura por 100 EUR",
146
+ " Entonces se emite InvoiceIssued",
147
+ "",
148
+ ].join("\n");
149
+ assert.deepEqual((0, GherkinQuality_1.analyseGherkinSource)(es, "features/facturacion.feature"), []);
150
+ });
151
+ //# sourceMappingURL=gherkin-quality.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gherkin-quality.test.js","sourceRoot":"","sources":["../../../../../packages/core/test/unit/gherkin-quality.test.ts"],"names":[],"mappings":"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"}