@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
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ <div align="center">
2
+
3
+ # ⬡ Specgate
4
+
5
+ **Specs as executable contracts — requirements, scenarios and traceability that CI enforces.**
6
+
7
+ [![CI](https://github.com/rsaglobaltech/specgate/actions/workflows/ci.yml/badge.svg)](https://github.com/rsaglobaltech/specgate/actions/workflows/ci.yml)
8
+ [![npm latest](https://img.shields.io/npm/v/specgate?logo=npm&label=npm)](https://www.npmjs.com/package/specgate)
9
+ [![npm beta](https://img.shields.io/npm/v/specgate/beta?logo=npm&label=beta)](https://www.npmjs.com/package/specgate)
10
+ [![Docs](https://img.shields.io/badge/docs-github_pages-0e8078)](https://rsaglobaltech.github.io/specgate/)
11
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](#-license)
12
+
13
+ </div>
14
+
15
+ > Stop coding before requirements are operationally clear. Every requirement
16
+ > maps to a scenario, a domain artefact, an implementation and a test — and the
17
+ > gate fails when one is missing.
18
+
19
+ ---
20
+
21
+ ## ⚡ Start
22
+
23
+ > **Just renamed** ([ADR-0024](docs/specs/adr/0024-the-tool-is-renamed-the-format-is-not.md)): until the
24
+ > first release under the new name the registries still hold `create-spec-driven-app` and the `csda` image — both kept as aliases.
25
+
26
+ **Existing codebase** — the common enterprise case:
27
+
28
+ ```bash
29
+ cd your-repo
30
+ npx @rsaglobaltech/specgate@latest onboard # reads the repo, proposes its capabilities
31
+ npx @rsaglobaltech/specgate@latest adopt # writes the spec skeleton, touches no code
32
+ npx @rsaglobaltech/specgate@latest validate .
33
+ ```
34
+
35
+ **New project:**
36
+
37
+ ```bash
38
+ npx @rsaglobaltech/specgate@latest init # interactive wizard
39
+ ```
40
+
41
+ Requires **Node.js ≥ 22** — or none at all with the Docker image:
42
+
43
+ ```bash
44
+ docker run --rm -v "$PWD:/workspace" ghcr.io/rsaglobaltech/specgate validate . --strict-tdd
45
+ ```
46
+
47
+ → [Getting started](docs/getting-started.md) · [Quickstart for joiners](docs/quickstart.md)
48
+
49
+ ## 🪜 Adopt one level at a time
50
+
51
+ Each level is useful on its own and never requires the ones above it.
52
+
53
+ | Level | You get | Commands | Cost |
54
+ | --- | --- | --- | --- |
55
+ | **L1** | Traceable specs in your repo | `onboard`, `adopt` | ~1 hour |
56
+ | **L2** | A PR gate enforcing spec and test coverage | `validate --strict-tdd` | ~1 hour |
57
+ | **L3** | Versioned, reusable domain requirements | `specops add / sync / diff` | ~1 day |
58
+ | **L4** | Agent-driven delivery, one requirement at a time | `agents init`, `harness run` | ~1 week |
59
+
60
+ ## 🛠️ What it does
61
+
62
+ **A daily loop, not a one-shot scaffolder.** `specgate status` says where the
63
+ project stands and what to run next; `specgate plan` is the queue; `specgate req` adds
64
+ and links requirements so nobody hand-edits the ten-column matrix; `specgate done`
65
+ closes them.
66
+ → [Quickstart](docs/quickstart.md) · [Command reference](docs/commands.md)
67
+
68
+ **Specs that are checked.** `specgate validate` fails the build when a requirement
69
+ has no scenario, no test, or no row in the traceability matrix. `--strict-tdd`
70
+ fails it when a requirement moves past Draft without a test.
71
+ → [Writing specs](docs/writing-specs.md) · [Validating](docs/validating.md)
72
+
73
+ **Changes you review as intent.** Modify a spec that already shipped through a
74
+ reviewable delta — only what moves, never a copy. Archiving merges it into the
75
+ spec tree, writes the matrix rows and materialises the feature files, so a
76
+ merged proposal cannot quietly become undone work.
77
+ → [Reviewing changes](docs/reviewing-changes.md)
78
+
79
+ **Domain knowledge as a dependency.** A pack is a versioned, schema-validated
80
+ domain model. Install it, pin it, upgrade it deliberately — and review the
81
+ upgrade as intent with `specops diff --as-change`, not as a file diff.
82
+ → [Domain packs](docs/domain-packs.md)
83
+
84
+ **An agent surface that is a contract.** Twelve commands speak JSON with stable
85
+ diagnostic codes and a `fix` on each — every command of the daily loop, and a
86
+ test asserts it. `specgate agents init` wires the loop into eight agent tools from
87
+ one definition.
88
+ → [Agents](docs/agents.md) · [The agent contract](docs/specs/agent-contract.md)
89
+
90
+ **Unattended delivery.** `specgate harness run` drives plan → agent → verify → done
91
+ for every pending requirement, each in its own git worktree. It never merges.
92
+ `specgate ci init` generates the gate for GitHub, GitLab, Azure or Jenkins, and
93
+ `specgate alm sync` keeps Jira or Azure Boards in step.
94
+
95
+ **Any agent CLI.** No agent runtime, no SDK dependency: the agent is any shell
96
+ command containing `{prompt_file}` — `claude -p < {prompt_file}`, `aider --yes
97
+ --message-file {prompt_file}`, or `my-wrapper.sh {prompt_file}` for anything
98
+ else. Commit your team's commands in `.harness/profiles.yaml` and pick one by
99
+ name.
100
+ → [Automation](docs/automation.md) · [The harness](docs/harness.md) · [Jira and Azure Boards](docs/alm.md)
101
+
102
+ **It stays current.** `specgate update` refreshes the generated agent files after an
103
+ upgrade, three-way merging your edits rather than clobbering them. `specgate doctor`
104
+ reports what has drifted, with a fix per finding.
105
+ → [Command reference](docs/commands.md)
106
+
107
+ ## 🆚 How it compares
108
+
109
+ | Capability | **this** | [OpenSpec](https://github.com/Fission-AI/OpenSpec) | [spec-kit](https://github.com/github/spec-kit) | [Cursor rules](https://docs.cursor.com/context/rules-for-ai) | README only |
110
+ | --- | :-: | :-: | :-: | :-: | :-: |
111
+ | Change lifecycle | ✅ | ✅ | ❌ | ❌ | ❌ |
112
+ | Versioned domain packs | ✅ | ❌ | ⚠️ | ❌ | ❌ |
113
+ | Traceability matrix + CI gate | ✅ | ❌ | ⚠️ | ❌ | ❌ |
114
+ | Agent JSON contract | ✅ | ✅ | ❌ | ❌ | ❌ |
115
+ | Vendor-neutral | ✅ | ✅ | ✅ | ❌ | ✅ |
116
+ | Smaller surface to learn | ❌ | ✅ | ✅ | ✅ | ✅ |
117
+
118
+ OpenSpec is the closest tool and the honest comparison: if you want the change
119
+ loop without versioned packs or an enforced matrix, theirs is the better fit.
120
+ → [Full matrix, trade-offs and migration paths](docs/comparisons.md)
121
+
122
+ ## 📚 Documentation
123
+
124
+ - [Command reference](docs/commands.md) — every command, grouped by when you reach for it
125
+ - [How-to guides](docs/how-to.md) — by task and by adoption level
126
+ - [Tutorial](docs/tutorial.md) — long-form, on a real public pack
127
+ - [Supply chain](docs/supply-chain.md) — pack pinning, digests, signing, air-gapped installs, SBOM
128
+ - [Architecture](docs/specs/architecture.md) — three repos, three lifecycles
129
+ - [Bootstrap prompt](docs/bootstrap-prompt.md) — the one freeform-AI step
130
+ - [Case study](docs/case-studies/case-1.md) · [ADRs](docs/specs/adr/README.md) · [Docs site](https://rsaglobaltech.github.io/specgate/) · [Spec coverage report](https://rsaglobaltech.github.io/specgate/report.html)
131
+
132
+ ## 🧰 Companion tools
133
+
134
+ **MCP server** ([`mcp-spec-driven`](packages/mcp-spec-driven)) · **Language
135
+ server** ([`lsp-spec-driven`](packages/lsp-spec-driven)) · **VS Code extension**
136
+ ([`vscode-spec-driven`](packages/vscode-spec-driven)) · **Maven and Gradle
137
+ plugins** for teams that do not want Node on the build agent.
138
+
139
+ ## 🤝 Contributing
140
+
141
+ PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Good first contributions:
142
+ new module templates, validator rules, additional domain packs.
143
+ [MAINTAINERS.md](MAINTAINERS.md) says who owns what;
144
+ [SECURITY.md](SECURITY.md) is how to report a vulnerability privately.
145
+
146
+ ## 📄 License
147
+
148
+ MIT © RSA Global Tech
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require("../dist/bin/specgate.js");
@@ -0,0 +1,383 @@
1
+ #!/usr/bin/env node
2
+
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ import { spawnSync } from "child_process";
6
+
7
+ const rootDir = path.resolve(__dirname, "..", "..");
8
+ const distScripts = path.join(__dirname, "..", "scripts");
9
+ const packageJson = require(path.join(rootDir, "package.json"));
10
+ const VERSION: string = packageJson.version || "0.0.0";
11
+ import { ICommand } from "../scripts/lib/command";
12
+ import { SURFACE, helpRows, coreHelpRows, hiddenCommandCount } from "../scripts/lib/surface";
13
+
14
+ /** Resolve a registry row's `script` segments to a path under dist/scripts. */
15
+ function resolveScript(segments: string[]): string {
16
+ return path.join(distScripts, ...segments);
17
+ }
18
+
19
+ // ── Pretty output helpers ─────────────────────────────────────────────────────────
20
+
21
+ const COLOR_ENABLED =
22
+ process.stdout.isTTY && process.env.NO_COLOR === undefined && process.env.TERM !== "dumb";
23
+
24
+ const c = {
25
+ reset: COLOR_ENABLED ? "\x1b[0m" : "",
26
+ bold: COLOR_ENABLED ? "\x1b[1m" : "",
27
+ dim: COLOR_ENABLED ? "\x1b[2m" : "",
28
+ red: COLOR_ENABLED ? "\x1b[31m" : "",
29
+ green: COLOR_ENABLED ? "\x1b[32m" : "",
30
+ yellow: COLOR_ENABLED ? "\x1b[33m" : "",
31
+ blue: COLOR_ENABLED ? "\x1b[34m" : "",
32
+ magenta: COLOR_ENABLED ? "\x1b[35m" : "",
33
+ cyan: COLOR_ENABLED ? "\x1b[36m" : "",
34
+ };
35
+
36
+ function info(msg: string): void {
37
+ process.stdout.write(`${c.cyan}ℹ${c.reset} ${msg}\n`);
38
+ }
39
+
40
+ function error(msg: string): void {
41
+ process.stderr.write(`${c.red}✖${c.reset} ${msg}\n`);
42
+ }
43
+
44
+ function banner(): string {
45
+ return (
46
+ `\n` +
47
+ ` ${c.bold}${c.cyan}🧭 specgate${c.reset} ${c.dim}v${VERSION}${c.reset}\n` +
48
+ ` ${c.dim}Specs as executable contracts — requirements, scenarios and traceability that CI enforces.${c.reset}\n`
49
+ );
50
+ }
51
+
52
+ function section(title: string): string {
53
+ return `\n ${c.bold}${title}${c.reset}\n`;
54
+ }
55
+
56
+ function cmd(emoji: string, name: string, summary: string, pad = 16): string {
57
+ // Use Array.from to count code points (emojis with surrogate pairs count as 1)
58
+ const visible = Array.from(name).length;
59
+ const padding = " ".repeat(Math.max(1, pad - visible));
60
+ return ` ${c.green}${emoji}${c.reset} ${c.green}${name}${c.reset}${padding}${c.dim}${summary}${c.reset}\n`;
61
+ }
62
+
63
+ function flag(name: string, summary: string, pad = 18): string {
64
+ const visible = Array.from(name).length;
65
+ const padding = " ".repeat(Math.max(1, pad - visible));
66
+ return ` ${c.green}${name}${c.reset}${padding}${c.dim}${summary}${c.reset}\n`;
67
+ }
68
+
69
+ function example(line: string, comment?: string): string {
70
+ const prefix = comment ? ` ${c.dim}# ${comment}${c.reset}\n` : "";
71
+ return `${prefix} ${c.yellow}$${c.reset} ${line}\n`;
72
+ }
73
+
74
+ /**
75
+ * The worked examples of `--help --all`. Prose, not surface: they are chosen
76
+ * for what they teach, so they are declared here rather than derived.
77
+ */
78
+ const EXAMPLES =
79
+ example(`npx @rsaglobaltech/specgate@latest init`, "Generate a new project (wizard)") +
80
+ example(
81
+ `npx @rsaglobaltech/specgate@latest adopt --project-dir ./my-existing-repo`,
82
+ "Adopt SDD on an existing codebase"
83
+ ) +
84
+ example(
85
+ `npx @rsaglobaltech/specgate@latest init --config ./project.config --out ./projects`,
86
+ "Generate a new project from a config file"
87
+ ) +
88
+ example(
89
+ `npx @rsaglobaltech/specgate@latest validate ./projects/my-app --strict-tdd`,
90
+ "Validate with the TDD gate"
91
+ ) +
92
+ example(
93
+ `npx @rsaglobaltech/specgate@latest expand --pack-root ./domain-packs \\\n --pack parking-management/backend --project-dir ./projects/my-app \\\n --var PROJECT_NAME="My App" --var PROJECT_SLUG=my-app --var DOMAIN="parking ops"`,
94
+ "Apply a local pack"
95
+ ) +
96
+ example(
97
+ `npx @rsaglobaltech/specgate@latest expand --pack-repo https://github.com/acme/parking-specops.git \\\n --pack-version v0.1.0 --pack backend --project-dir ./projects/smart-parking \\\n --var PROJECT_NAME="Smart Parking"`,
98
+ "Apply a remote pack pinned to a git tag"
99
+ ) +
100
+ example(
101
+ `npx @rsaglobaltech/specgate@latest specops sync --project-dir ./projects/smart-parking`,
102
+ "Re-expand everything in .specops.lock / specops.config.yaml"
103
+ ) +
104
+ example(
105
+ `npx @rsaglobaltech/specgate@latest specops diff --project-dir ./projects/smart-parking --pack-version v0.2.0`,
106
+ "Preview a version bump"
107
+ ) +
108
+ example(
109
+ `npx @rsaglobaltech/specgate@latest plan --project-dir ./projects/smart-parking`,
110
+ "Show what requirements still need work"
111
+ ) +
112
+ example(
113
+ `npx @rsaglobaltech/specgate@latest plan --project-dir ./projects/smart-parking --format json`,
114
+ "Same, machine-readable for AI agents"
115
+ ) +
116
+ example(
117
+ `npx @rsaglobaltech/specgate@latest done REQ-007 --check`,
118
+ "Mark REQ-007 Implemented (after validate passes)"
119
+ ) +
120
+ example(
121
+ `npx @rsaglobaltech/specgate@latest pack init --out ./domain-packs --name "Billing Backend" --type contracts`,
122
+ "Scaffold a contracts-flavoured pack"
123
+ );
124
+
125
+ /**
126
+ * The daily loop, narrowed.
127
+ *
128
+ * The surface grew past twenty, which is more than anyone reads. A new user
129
+ * needs `init` or `adopt` once, then lives in status → plan → req → change →
130
+ * validate → done. Everything else is real but not first — `--help --all`
131
+ * shows it, and `specgate config set profile full` makes that the default.
132
+ *
133
+ * Both help profiles are rendered from the surface registry, so a command
134
+ * cannot exist without appearing in one of them or being deliberately absent
135
+ * from both.
136
+ */
137
+ function renderGroups(groups: any[]): string {
138
+ return groups
139
+ .map((g) => section(g.title) + g.rows.map((r: any) => cmd(r.icon, r.label, r.summary)).join(""))
140
+ .join("");
141
+ }
142
+
143
+ function usageCore() {
144
+ process.stdout.write(
145
+ banner() +
146
+ section("USAGE") +
147
+ ` ${c.cyan}specgate${c.reset} ${c.bold}<command>${c.reset} [options]\n` +
148
+ ` ${c.dim}Run ‘<command> --help’ for per-command details.${c.reset}\n` +
149
+ renderGroups(coreHelpRows()) +
150
+ section("MORE") +
151
+ ` ${c.dim}${hiddenCommandCount()} more commands cover packs, automation, agents and reporting.${c.reset}\n` +
152
+ ` ${c.green}specgate --help --all${c.reset}${c.dim} show every command${c.reset}\n` +
153
+ ` ${c.green}specgate config set profile full${c.reset}${c.dim} make that the default${c.reset}\n` +
154
+ section("EXAMPLES") +
155
+ example(`npx @rsaglobaltech/specgate@latest adopt`, "Existing codebase") +
156
+ example(`npx @rsaglobaltech/specgate@latest init`, "New project (wizard)") +
157
+ example(`specgate status`, "Start of day") +
158
+ "\n"
159
+ );
160
+ }
161
+
162
+ /**
163
+ * `core` unless the project says otherwise. Read from .csda/config.json so a
164
+ * team that lives in the full surface is not re-narrowed on every invocation.
165
+ */
166
+ function helpProfile(): string {
167
+ if (process.env.CSDA_PROFILE) return process.env.CSDA_PROFILE;
168
+ try {
169
+ const raw = fs.readFileSync(path.join(process.cwd(), ".csda", "config.json"), "utf8");
170
+ const parsed = JSON.parse(raw);
171
+ if (parsed && typeof parsed.profile === "string") return parsed.profile;
172
+ } catch {
173
+ // No config, unreadable, or malformed — core is the safe default.
174
+ }
175
+ return "core";
176
+ }
177
+
178
+ function usage(opts?: { all?: boolean }) {
179
+ if (opts && opts.all) return usageFull();
180
+ if (helpProfile() === "full") return usageFull();
181
+ return usageCore();
182
+ }
183
+
184
+ function usageFull() {
185
+ process.stdout.write(
186
+ banner() +
187
+ section("USAGE") +
188
+ ` ${c.cyan}specgate${c.reset} ${c.bold}<command>${c.reset} [options]\n` +
189
+ ` ${c.dim}Run ‘<command> --help’ for per-command details.${c.reset}\n` +
190
+ renderGroups(helpRows()) +
191
+ section("GLOBAL FLAGS") +
192
+ flag("-h, --help", "Show this help.") +
193
+ flag("-v, --version", "Show CLI version.") +
194
+ section("EXAMPLES") +
195
+ EXAMPLES +
196
+ section("LEARN MORE") +
197
+ ` ${c.dim}📖 How-to guide ${c.reset}${c.blue}https://github.com/rsaglobaltech/specgate/blob/main/docs/how-to.md${c.reset}\n` +
198
+ ` ${c.dim}🌐 Documentation ${c.reset}${c.blue}https://rsaglobaltech.github.io/specgate/${c.reset}\n` +
199
+ ` ${c.dim}🪲 Report a bug ${c.reset}${c.blue}https://github.com/rsaglobaltech/specgate/issues${c.reset}\n` +
200
+ `\n`
201
+ );
202
+ }
203
+
204
+ function ensureExecutable(scriptPath: string): void {
205
+ if (!fs.existsSync(scriptPath)) {
206
+ error(`Required script not found: ${scriptPath}`);
207
+ process.exit(3);
208
+ }
209
+ }
210
+
211
+ function runNodeScript(scriptPath: string, args: string[]): void {
212
+ const result = spawnSync(process.execPath, [scriptPath, ...args], {
213
+ stdio: "inherit",
214
+ env: process.env,
215
+ });
216
+
217
+ if (result.error) {
218
+ error(`Failed to execute script: ${result.error.message}`);
219
+ process.exit(1);
220
+ }
221
+
222
+ if (result.signal) {
223
+ error(`Process terminated by signal: ${result.signal}`);
224
+ process.exit(1);
225
+ }
226
+
227
+ process.exit(typeof result.status === "number" ? result.status : 1);
228
+ }
229
+
230
+ export class CreateSpecDrivenAppCommand implements ICommand {
231
+ public execute(args: string[] = []): void {
232
+ args = args.length ? args : process.argv.slice(2);
233
+
234
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
235
+ usage({ all: args.includes("--all") });
236
+ process.exit(0);
237
+ }
238
+
239
+ if (args[0] === "--version" || args[0] === "-v") {
240
+ process.stdout.write(`${VERSION}\n`);
241
+ process.exit(0);
242
+ }
243
+
244
+ const command = args[0];
245
+
246
+ const row = SURFACE.find((c: any) => c.name === command);
247
+ if (!row) {
248
+ info(`Unknown command: ${command}`);
249
+ usage();
250
+ process.exit(2);
251
+ }
252
+
253
+ // Three commands need more than a table row. Each is a genuine parsing
254
+ // decision, not a route, which is why it lives here and not in the registry.
255
+ if (command === "init") return dispatchInit(args.slice(1));
256
+ if (command === "validate") return dispatchValidate(args.slice(1));
257
+ if (command === "harness" && args[1] === "prompt") return dispatchHarnessPrompt(args);
258
+
259
+ // A command with its own script owns its sub-commands: the dispatcher hands
260
+ // the whole tail over and the script reports an unknown one in its own words.
261
+ if (row.script) {
262
+ const target = resolveScript(row.script);
263
+ ensureExecutable(target);
264
+ runNodeScript(target, args.slice(1));
265
+ return;
266
+ }
267
+
268
+ // Otherwise the sub-command is the route, and an unknown one stops here.
269
+ const subName = args[1];
270
+ const sub = (row.subcommands || []).find((s: any) => s.name === subName);
271
+ if (!sub) {
272
+ const expected = (row.subcommands || []).map((s: any) => s.name).join(", ");
273
+ error(`Unknown ${command} sub-command: ${subName || "(none)"}. Expected: ${expected}`);
274
+ usage();
275
+ process.exit(2);
276
+ }
277
+
278
+ const target = resolveScript(sub.script);
279
+ ensureExecutable(target);
280
+ runNodeScript(target, args.slice(sub.argsFrom === undefined ? 2 : sub.argsFrom));
281
+ }
282
+ }
283
+
284
+ /**
285
+ * `init` is two commands wearing one name: `--from-pack` composes it with
286
+ * `specops add`, which needs its own orchestrator rather than another flag
287
+ * inside init.
288
+ */
289
+ function dispatchInit(passThrough: string[]): void {
290
+ // Reject --engine=shell — the Bash engine was removed in this release.
291
+ const engineIdx = passThrough.indexOf("--engine");
292
+ if (
293
+ passThrough.includes("--engine=shell") ||
294
+ (engineIdx !== -1 && passThrough[engineIdx + 1] === "shell")
295
+ ) {
296
+ error(
297
+ "--engine=shell was removed. The CLI is now Node-only. Drop the flag to use the (sole) Node engine."
298
+ );
299
+ process.exit(2);
300
+ }
301
+ const script = passThrough.includes("--from-pack")
302
+ ? resolveScript(["init_from_pack.js"])
303
+ : resolveScript(["init_project.js"]);
304
+ ensureExecutable(script);
305
+ runNodeScript(script, passThrough);
306
+ }
307
+
308
+ /**
309
+ * `validate` is the gate, so a typo in a flag must not read as "nothing to
310
+ * report". It is the one command whose arguments the dispatcher checks.
311
+ */
312
+ function dispatchValidate(validateArgs: string[]): void {
313
+ const script = resolveScript(["validate_specs.js"]);
314
+ ensureExecutable(script);
315
+
316
+ const positional = validateArgs.filter((a) => !a.startsWith("-"));
317
+ if (positional.length !== 1) {
318
+ error(`'validate' expects exactly one positional argument: <project_dir>`);
319
+ usage();
320
+ process.exit(2);
321
+ }
322
+ const VALIDATE_FLAGS = new Set([
323
+ "--strict-tdd",
324
+ "--strict-scenarios",
325
+ "--strict-requirements",
326
+ "--strict-links",
327
+ "--against-lock",
328
+ "--json",
329
+ ]);
330
+ const unknownFlags = validateArgs.filter((a) => a.startsWith("-") && !VALIDATE_FLAGS.has(a));
331
+ if (unknownFlags.length > 0) {
332
+ error(`Unknown flag(s) for validate: ${unknownFlags.join(", ")}`);
333
+ usage();
334
+ process.exit(2);
335
+ }
336
+
337
+ runNodeScript(script, validateArgs);
338
+ }
339
+
340
+ /**
341
+ * `harness prompt <REQ-id>` is a friendly alias for `harness run --dry-run
342
+ * --req <REQ>`: it prints the prompt the agent would receive, with no git, no
343
+ * agent and no gate.
344
+ */
345
+ function dispatchHarnessPrompt(args: string[]): void {
346
+ const reqId = args[2];
347
+ if (!reqId || !/^REQ-\d+$/.test(reqId)) {
348
+ error("`harness prompt` expects a REQ-id, e.g. `specgate harness prompt REQ-001`.");
349
+ usage();
350
+ process.exit(2);
351
+ }
352
+ const script = resolveScript(["harness", "run.js"]);
353
+ ensureExecutable(script);
354
+ runNodeScript(script, ["--dry-run", "--req", reqId, ...args.slice(3)]);
355
+ }
356
+
357
+ /**
358
+ * Run when this module *is* the entry point, or when the published `bin/` shim
359
+ * required it.
360
+ *
361
+ * The shim is two lines — `require("../dist/bin/specgate.js")` — so
362
+ * `require.main` is the shim and not this module, and the check has to
363
+ * recognise it by name.
364
+ *
365
+ * Compare on the basename. An earlier form asked
366
+ * `filename.endsWith("bin/specgate.js")`, and on Windows
367
+ * `filename` is `bin\specgate.js`, so it never matched: the CLI
368
+ * loaded, dispatched nothing, and exited 0 with no output on either stream.
369
+ * Every test that spawns the CLI failed — 437 of them — and none of the
370
+ * messages said why, because there was no message.
371
+ *
372
+ * It survived because this branch had never been through CI, and the two
373
+ * platforms it was developed on both use `/`.
374
+ */
375
+ const isEntryPoint =
376
+ require.main === module ||
377
+ (require.main
378
+ ? ["specgate.js", "specgate.js"].includes(path.basename(require.main.filename))
379
+ : false);
380
+
381
+ if (isEntryPoint) {
382
+ new CreateSpecDrivenAppCommand().execute();
383
+ }