@specsafe/cli 0.7.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +100 -279
  2. package/canonical/personas/bolt-zane.md +29 -0
  3. package/canonical/personas/forge-reva.md +29 -0
  4. package/canonical/personas/herald-cass.md +30 -0
  5. package/canonical/personas/mason-kai.md +30 -0
  6. package/canonical/personas/scout-elena.md +27 -0
  7. package/canonical/personas/warden-lyra.md +30 -0
  8. package/canonical/rules/.cursorrules.mdc +53 -0
  9. package/canonical/rules/.rules +48 -0
  10. package/canonical/rules/AGENTS.md +48 -0
  11. package/canonical/rules/CLAUDE.md +48 -0
  12. package/canonical/rules/CONVENTIONS.md +41 -0
  13. package/canonical/rules/GEMINI.md +50 -0
  14. package/canonical/rules/continue-config.yaml +5 -0
  15. package/canonical/skills/specsafe-archive/SKILL.md +63 -0
  16. package/canonical/skills/specsafe-code/SKILL.md +7 -0
  17. package/canonical/skills/specsafe-code/workflow.md +212 -0
  18. package/canonical/skills/specsafe-complete/SKILL.md +7 -0
  19. package/canonical/skills/specsafe-complete/workflow.md +130 -0
  20. package/canonical/skills/specsafe-doctor/SKILL.md +103 -0
  21. package/canonical/skills/specsafe-explore/SKILL.md +7 -0
  22. package/canonical/skills/specsafe-explore/workflow.md +100 -0
  23. package/canonical/skills/specsafe-init/SKILL.md +119 -0
  24. package/canonical/skills/specsafe-new/SKILL.md +7 -0
  25. package/canonical/skills/specsafe-new/workflow.md +156 -0
  26. package/canonical/skills/specsafe-qa/SKILL.md +7 -0
  27. package/canonical/skills/specsafe-qa/workflow.md +223 -0
  28. package/canonical/skills/specsafe-spec/SKILL.md +7 -0
  29. package/canonical/skills/specsafe-spec/workflow.md +158 -0
  30. package/canonical/skills/specsafe-status/SKILL.md +77 -0
  31. package/canonical/skills/specsafe-test/SKILL.md +7 -0
  32. package/canonical/skills/specsafe-test/workflow.md +210 -0
  33. package/canonical/skills/specsafe-verify/SKILL.md +7 -0
  34. package/canonical/skills/specsafe-verify/workflow.md +143 -0
  35. package/canonical/templates/project-state-template.md +33 -0
  36. package/canonical/templates/qa-report-template.md +55 -0
  37. package/canonical/templates/spec-template.md +52 -0
  38. package/canonical/templates/specsafe-config-template.json +10 -0
  39. package/generators/dist/adapters/aider.d.ts +2 -0
  40. package/generators/dist/adapters/aider.js +23 -0
  41. package/generators/dist/adapters/aider.js.map +1 -0
  42. package/generators/dist/adapters/antigravity.d.ts +2 -0
  43. package/generators/dist/adapters/antigravity.js +33 -0
  44. package/generators/dist/adapters/antigravity.js.map +1 -0
  45. package/generators/dist/adapters/claude-code.d.ts +2 -0
  46. package/generators/dist/adapters/claude-code.js +31 -0
  47. package/generators/dist/adapters/claude-code.js.map +1 -0
  48. package/generators/dist/adapters/continue.d.ts +2 -0
  49. package/generators/dist/adapters/continue.js +33 -0
  50. package/generators/dist/adapters/continue.js.map +1 -0
  51. package/generators/dist/adapters/cursor.d.ts +2 -0
  52. package/generators/dist/adapters/cursor.js +32 -0
  53. package/generators/dist/adapters/cursor.js.map +1 -0
  54. package/generators/dist/adapters/gemini.d.ts +2 -0
  55. package/generators/dist/adapters/gemini.js +36 -0
  56. package/generators/dist/adapters/gemini.js.map +1 -0
  57. package/generators/dist/adapters/index.d.ts +13 -0
  58. package/generators/dist/adapters/index.js +29 -0
  59. package/generators/dist/adapters/index.js.map +1 -0
  60. package/generators/dist/adapters/opencode.d.ts +2 -0
  61. package/generators/dist/adapters/opencode.js +32 -0
  62. package/generators/dist/adapters/opencode.js.map +1 -0
  63. package/generators/dist/adapters/types.d.ts +49 -0
  64. package/generators/dist/adapters/types.js +14 -0
  65. package/generators/dist/adapters/types.js.map +1 -0
  66. package/generators/dist/adapters/utils.d.ts +12 -0
  67. package/generators/dist/adapters/utils.js +68 -0
  68. package/generators/dist/adapters/utils.js.map +1 -0
  69. package/generators/dist/adapters/zed.d.ts +2 -0
  70. package/generators/dist/adapters/zed.js +31 -0
  71. package/generators/dist/adapters/zed.js.map +1 -0
  72. package/generators/dist/doctor.d.ts +10 -0
  73. package/generators/dist/doctor.js +123 -0
  74. package/generators/dist/doctor.js.map +1 -0
  75. package/generators/dist/index.d.ts +2 -0
  76. package/generators/dist/index.js +45 -0
  77. package/generators/dist/index.js.map +1 -0
  78. package/generators/dist/init.d.ts +9 -0
  79. package/generators/dist/init.js +167 -0
  80. package/generators/dist/init.js.map +1 -0
  81. package/generators/dist/install.d.ts +5 -0
  82. package/generators/dist/install.js +66 -0
  83. package/generators/dist/install.js.map +1 -0
  84. package/generators/dist/registry.d.ts +3 -0
  85. package/generators/dist/registry.js +8 -0
  86. package/generators/dist/registry.js.map +1 -0
  87. package/generators/dist/update.d.ts +5 -0
  88. package/generators/dist/update.js +40 -0
  89. package/generators/dist/update.js.map +1 -0
  90. package/package.json +32 -27
  91. package/dist/commands/apply.d.ts +0 -3
  92. package/dist/commands/apply.d.ts.map +0 -1
  93. package/dist/commands/apply.js +0 -182
  94. package/dist/commands/apply.js.map +0 -1
  95. package/dist/commands/archive.d.ts +0 -3
  96. package/dist/commands/archive.d.ts.map +0 -1
  97. package/dist/commands/archive.js +0 -99
  98. package/dist/commands/archive.js.map +0 -1
  99. package/dist/commands/capsule.d.ts +0 -8
  100. package/dist/commands/capsule.d.ts.map +0 -1
  101. package/dist/commands/capsule.js +0 -466
  102. package/dist/commands/capsule.js.map +0 -1
  103. package/dist/commands/complete.d.ts +0 -3
  104. package/dist/commands/complete.d.ts.map +0 -1
  105. package/dist/commands/complete.js +0 -140
  106. package/dist/commands/complete.js.map +0 -1
  107. package/dist/commands/constitution.d.ts +0 -3
  108. package/dist/commands/constitution.d.ts.map +0 -1
  109. package/dist/commands/constitution.js +0 -192
  110. package/dist/commands/constitution.js.map +0 -1
  111. package/dist/commands/create.d.ts +0 -10
  112. package/dist/commands/create.d.ts.map +0 -1
  113. package/dist/commands/create.js +0 -120
  114. package/dist/commands/create.js.map +0 -1
  115. package/dist/commands/delta.d.ts +0 -3
  116. package/dist/commands/delta.d.ts.map +0 -1
  117. package/dist/commands/delta.js +0 -82
  118. package/dist/commands/delta.js.map +0 -1
  119. package/dist/commands/diff.d.ts +0 -3
  120. package/dist/commands/diff.d.ts.map +0 -1
  121. package/dist/commands/diff.js +0 -102
  122. package/dist/commands/diff.js.map +0 -1
  123. package/dist/commands/doctor.d.ts +0 -3
  124. package/dist/commands/doctor.d.ts.map +0 -1
  125. package/dist/commands/doctor.js +0 -204
  126. package/dist/commands/doctor.js.map +0 -1
  127. package/dist/commands/done.d.ts +0 -3
  128. package/dist/commands/done.d.ts.map +0 -1
  129. package/dist/commands/done.js +0 -237
  130. package/dist/commands/done.js.map +0 -1
  131. package/dist/commands/explore.d.ts +0 -3
  132. package/dist/commands/explore.d.ts.map +0 -1
  133. package/dist/commands/explore.js +0 -236
  134. package/dist/commands/explore.js.map +0 -1
  135. package/dist/commands/export.d.ts +0 -7
  136. package/dist/commands/export.d.ts.map +0 -1
  137. package/dist/commands/export.js +0 -179
  138. package/dist/commands/export.js.map +0 -1
  139. package/dist/commands/extend.d.ts +0 -6
  140. package/dist/commands/extend.d.ts.map +0 -1
  141. package/dist/commands/extend.js +0 -167
  142. package/dist/commands/extend.js.map +0 -1
  143. package/dist/commands/init-old.d.ts +0 -3
  144. package/dist/commands/init-old.d.ts.map +0 -1
  145. package/dist/commands/init-old.js +0 -146
  146. package/dist/commands/init-old.js.map +0 -1
  147. package/dist/commands/init.d.ts +0 -3
  148. package/dist/commands/init.d.ts.map +0 -1
  149. package/dist/commands/init.js +0 -298
  150. package/dist/commands/init.js.map +0 -1
  151. package/dist/commands/list.d.ts +0 -3
  152. package/dist/commands/list.d.ts.map +0 -1
  153. package/dist/commands/list.js +0 -122
  154. package/dist/commands/list.js.map +0 -1
  155. package/dist/commands/memory.d.ts +0 -3
  156. package/dist/commands/memory.d.ts.map +0 -1
  157. package/dist/commands/memory.js +0 -166
  158. package/dist/commands/memory.js.map +0 -1
  159. package/dist/commands/new.d.ts +0 -3
  160. package/dist/commands/new.d.ts.map +0 -1
  161. package/dist/commands/new.js +0 -508
  162. package/dist/commands/new.js.map +0 -1
  163. package/dist/commands/qa.d.ts +0 -3
  164. package/dist/commands/qa.d.ts.map +0 -1
  165. package/dist/commands/qa.js +0 -179
  166. package/dist/commands/qa.js.map +0 -1
  167. package/dist/commands/rules.d.ts +0 -6
  168. package/dist/commands/rules.d.ts.map +0 -1
  169. package/dist/commands/rules.js +0 -232
  170. package/dist/commands/rules.js.map +0 -1
  171. package/dist/commands/shard.d.ts +0 -6
  172. package/dist/commands/shard.d.ts.map +0 -1
  173. package/dist/commands/shard.js +0 -199
  174. package/dist/commands/shard.js.map +0 -1
  175. package/dist/commands/spec.d.ts +0 -3
  176. package/dist/commands/spec.d.ts.map +0 -1
  177. package/dist/commands/spec.js +0 -302
  178. package/dist/commands/spec.js.map +0 -1
  179. package/dist/commands/status.d.ts +0 -3
  180. package/dist/commands/status.d.ts.map +0 -1
  181. package/dist/commands/status.js +0 -47
  182. package/dist/commands/status.js.map +0 -1
  183. package/dist/commands/test-apply.d.ts +0 -3
  184. package/dist/commands/test-apply.d.ts.map +0 -1
  185. package/dist/commands/test-apply.js +0 -228
  186. package/dist/commands/test-apply.js.map +0 -1
  187. package/dist/commands/test-create.d.ts +0 -3
  188. package/dist/commands/test-create.d.ts.map +0 -1
  189. package/dist/commands/test-create.js +0 -183
  190. package/dist/commands/test-create.js.map +0 -1
  191. package/dist/commands/test-guide.d.ts +0 -3
  192. package/dist/commands/test-guide.d.ts.map +0 -1
  193. package/dist/commands/test-guide.js +0 -190
  194. package/dist/commands/test-guide.js.map +0 -1
  195. package/dist/commands/test-report.d.ts +0 -3
  196. package/dist/commands/test-report.d.ts.map +0 -1
  197. package/dist/commands/test-report.js +0 -196
  198. package/dist/commands/test-report.js.map +0 -1
  199. package/dist/commands/test-submit.d.ts +0 -6
  200. package/dist/commands/test-submit.d.ts.map +0 -1
  201. package/dist/commands/test-submit.js +0 -236
  202. package/dist/commands/test-submit.js.map +0 -1
  203. package/dist/commands/verify.d.ts +0 -3
  204. package/dist/commands/verify.d.ts.map +0 -1
  205. package/dist/commands/verify.js +0 -288
  206. package/dist/commands/verify.js.map +0 -1
  207. package/dist/config.d.ts +0 -23
  208. package/dist/config.d.ts.map +0 -1
  209. package/dist/config.js +0 -44
  210. package/dist/config.js.map +0 -1
  211. package/dist/index.d.ts +0 -8
  212. package/dist/index.d.ts.map +0 -1
  213. package/dist/index.js +0 -129
  214. package/dist/index.js.map +0 -1
  215. package/dist/rules/downloader.d.ts +0 -40
  216. package/dist/rules/downloader.d.ts.map +0 -1
  217. package/dist/rules/downloader.js +0 -253
  218. package/dist/rules/downloader.js.map +0 -1
  219. package/dist/rules/index.d.ts +0 -8
  220. package/dist/rules/index.d.ts.map +0 -1
  221. package/dist/rules/index.js +0 -8
  222. package/dist/rules/index.js.map +0 -1
  223. package/dist/rules/registry.d.ts +0 -45
  224. package/dist/rules/registry.d.ts.map +0 -1
  225. package/dist/rules/registry.js +0 -158
  226. package/dist/rules/registry.js.map +0 -1
  227. package/dist/rules/types.d.ts +0 -86
  228. package/dist/rules/types.d.ts.map +0 -1
  229. package/dist/rules/types.js +0 -6
  230. package/dist/rules/types.js.map +0 -1
  231. package/dist/utils/detectTools.d.ts +0 -15
  232. package/dist/utils/detectTools.d.ts.map +0 -1
  233. package/dist/utils/detectTools.js +0 -54
  234. package/dist/utils/detectTools.js.map +0 -1
  235. package/dist/utils/generateToolConfig.d.ts +0 -12
  236. package/dist/utils/generateToolConfig.d.ts.map +0 -1
  237. package/dist/utils/generateToolConfig.js +0 -1179
  238. package/dist/utils/generateToolConfig.js.map +0 -1
  239. package/dist/utils/testRunner.d.ts +0 -39
  240. package/dist/utils/testRunner.d.ts.map +0 -1
  241. package/dist/utils/testRunner.js +0 -325
  242. package/dist/utils/testRunner.js.map +0 -1
@@ -1,199 +0,0 @@
1
- /**
2
- * Shard Command - Analyze and split specs into AI-consumable chunks
3
- */
4
- import { Command } from 'commander';
5
- import chalk from 'chalk';
6
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
7
- import { resolve, basename } from 'path';
8
- import { ShardEngine } from '@specsafe/core';
9
- const VALID_STRATEGIES = new Set([
10
- 'by-section',
11
- 'by-requirement',
12
- 'by-scenario',
13
- 'auto',
14
- ]);
15
- const DEFAULT_MAX_TOKENS = 2000;
16
- function parseStrategy(input) {
17
- if (!input) {
18
- return 'auto';
19
- }
20
- if (!VALID_STRATEGIES.has(input)) {
21
- throw new Error(`Invalid strategy "${input}". Expected one of: ${Array.from(VALID_STRATEGIES).join(', ')}`);
22
- }
23
- return input;
24
- }
25
- function parseMaxTokens(input) {
26
- const value = Number.parseInt(input, 10);
27
- if (!Number.isFinite(value) || value <= 0) {
28
- throw new Error(`Invalid --max-tokens value "${input}". It must be a positive integer.`);
29
- }
30
- return value;
31
- }
32
- function sanitizeFileSegment(value) {
33
- return value.replace(/[^a-zA-Z0-9._-]+/g, '-');
34
- }
35
- export const shardCommand = new Command('shard')
36
- .description('Analyze and split specs into AI-consumable chunks')
37
- .argument('<spec>', 'Path to the spec file')
38
- .option('-s, --strategy <strategy>', 'Sharding strategy (by-section|by-requirement|by-scenario|auto)')
39
- .option('-m, --max-tokens <number>', 'Maximum tokens per shard for auto strategy', String(DEFAULT_MAX_TOKENS))
40
- .option('-o, --output <dir>', 'Output directory for shard files')
41
- .option('--no-preserve-context', 'Do not preserve context across shards')
42
- .option('--no-include-metadata', 'Do not include metadata in shards')
43
- .option('--json', 'Output as JSON')
44
- .action(async (specPath, options) => {
45
- try {
46
- const resolvedPath = resolve(process.cwd(), specPath);
47
- if (!existsSync(resolvedPath)) {
48
- console.error(chalk.red(`Error: Spec file not found: ${specPath}`));
49
- process.exit(1);
50
- }
51
- const specContent = readFileSync(resolvedPath, 'utf-8');
52
- const strategy = parseStrategy(options.strategy);
53
- const maxTokensPerShard = parseMaxTokens(options.maxTokens);
54
- const preserveContext = options.preserveContext !== false;
55
- const includeMetadata = options.includeMetadata !== false;
56
- const shardOptions = {
57
- strategy,
58
- maxTokensPerShard,
59
- preserveContext,
60
- includeMetadata,
61
- };
62
- const engine = new ShardEngine(shardOptions);
63
- const result = engine.shard(specContent, shardOptions);
64
- if (!result.success) {
65
- console.error(chalk.red('Error sharding spec:'), result.error);
66
- process.exit(1);
67
- }
68
- const { plan, durationMs } = result;
69
- if (options.json) {
70
- console.log(JSON.stringify({
71
- success: true,
72
- durationMs,
73
- plan: {
74
- ...plan,
75
- shards: plan.shards.map(s => ({
76
- id: s.id,
77
- type: s.type,
78
- tokenCount: s.tokenCount,
79
- priority: s.priority,
80
- sectionName: s.sectionName,
81
- })),
82
- },
83
- }, null, 2));
84
- return;
85
- }
86
- displayAnalysis(plan);
87
- displayShardPlan(plan);
88
- if (options.output) {
89
- await writeShards(plan, options.output, specPath);
90
- }
91
- console.log(chalk.gray(`\nCompleted in ${durationMs}ms`));
92
- }
93
- catch (error) {
94
- const message = error instanceof Error ? error.message : String(error);
95
- console.error(chalk.red('Error:'), message);
96
- process.exit(1);
97
- }
98
- });
99
- /**
100
- * Display analysis results
101
- */
102
- function displayAnalysis(plan) {
103
- const { analysis } = plan;
104
- console.log(chalk.bold.blue(`\nšŸ“Š Spec Analysis\n`));
105
- console.log(chalk.gray('Complexity:'), chalk.cyan(`${analysis.complexity}/100`));
106
- console.log(chalk.gray('Total Tokens:'), chalk.cyan(analysis.totalTokens.toLocaleString()));
107
- console.log(chalk.gray('Sections:'), chalk.cyan(analysis.sectionCount));
108
- console.log(chalk.gray('Requirements:'), chalk.cyan(analysis.requirementCount));
109
- console.log(chalk.gray('Scenarios:'), chalk.cyan(analysis.scenarioCount));
110
- console.log(chalk.gray('\nRecommended Strategy:'), chalk.green(analysis.recommendedStrategy));
111
- console.log(chalk.gray(analysis.recommendationReason));
112
- }
113
- /**
114
- * Display shard plan
115
- */
116
- function displayShardPlan(plan) {
117
- console.log(chalk.bold.blue(`\nšŸ“ Shard Plan\n`));
118
- console.log(chalk.gray('Total Shards:'), chalk.cyan(plan.shards.length));
119
- console.log(chalk.gray('Estimated Tokens:'), chalk.cyan(plan.estimatedTokens.toLocaleString()));
120
- if (plan.crossReferences.length > 0) {
121
- console.log(chalk.gray('Cross-References:'), chalk.cyan(plan.crossReferences.length));
122
- }
123
- console.log(chalk.bold('\nShards:'));
124
- for (const shard of plan.shards) {
125
- const tokens = shard.tokenCount || 0;
126
- const typeColor = shard.type === 'metadata'
127
- ? chalk.gray
128
- : shard.type === 'requirement'
129
- ? chalk.yellow
130
- : shard.type === 'scenario'
131
- ? chalk.blue
132
- : chalk.white;
133
- console.log(` ${chalk.cyan(shard.id.padEnd(20))} ${typeColor(shard.type.padEnd(12))} ${tokens
134
- .toString()
135
- .padStart(6)} tokens${shard.sectionName ? ` - ${chalk.gray(shard.sectionName)}` : ''}`);
136
- if (shard.dependencies.length > 0) {
137
- console.log(` ${chalk.gray('└─ Dependencies:')} ${shard.dependencies.map(d => chalk.gray(d)).join(', ')}`);
138
- }
139
- }
140
- if (plan.recommendedOrder.length > 0 && plan.recommendedOrder.length !== plan.shards.length) {
141
- console.log(chalk.bold('\nRecommended Processing Order:'));
142
- console.log(` ${plan.recommendedOrder.map(id => chalk.cyan(id)).join(' → ')}`);
143
- }
144
- if (plan.crossReferences.length > 0) {
145
- console.log(chalk.bold('\nCross-References:'));
146
- for (const ref of plan.crossReferences.slice(0, 10)) {
147
- console.log(` ${chalk.cyan(ref.from)} ${chalk.gray('→')} ${chalk.cyan(ref.to)} (${chalk.yellow(ref.type)})`);
148
- }
149
- if (plan.crossReferences.length > 10) {
150
- console.log(` ${chalk.gray(`... and ${plan.crossReferences.length - 10} more`)}`);
151
- }
152
- }
153
- }
154
- /**
155
- * Write shards to files
156
- */
157
- async function writeShards(plan, outputDir, specPath) {
158
- const resolvedDir = resolve(process.cwd(), outputDir);
159
- if (!existsSync(resolvedDir)) {
160
- mkdirSync(resolvedDir, { recursive: true });
161
- }
162
- const baseName = sanitizeFileSegment(basename(specPath).replace(/\.(md|txt|spec)$/i, '')) || 'spec';
163
- console.log(chalk.bold.blue(`\nšŸ’¾ Writing Shards\n`));
164
- console.log(chalk.gray(`Output directory: ${resolvedDir}\n`));
165
- for (const shard of plan.shards) {
166
- const safeShardId = sanitizeFileSegment(shard.id);
167
- const fileName = `${baseName}-${safeShardId}.md`;
168
- const filePath = resolve(resolvedDir, fileName);
169
- let content = shard.content;
170
- if (shard.tokenCount && shard.type !== 'metadata') {
171
- content =
172
- `<!--\nShard: ${shard.id}\nType: ${shard.type}\nTokens: ${shard.tokenCount}\nPriority: ${shard.priority}\n` +
173
- (shard.sectionName ? `Section: ${shard.sectionName}\n` : '') +
174
- (shard.dependencies.length > 0 ? `Dependencies: ${shard.dependencies.join(', ')}\n` : '') +
175
- '-->\n\n' +
176
- content;
177
- }
178
- writeFileSync(filePath, content, 'utf-8');
179
- console.log(chalk.green('āœ“') + ` ${fileName}`);
180
- }
181
- const summaryPath = resolve(resolvedDir, `${baseName}-plan.json`);
182
- const summary = {
183
- specPath,
184
- generatedAt: new Date().toISOString(),
185
- plan: {
186
- ...plan,
187
- shards: plan.shards.map((s) => ({
188
- id: s.id,
189
- type: s.type,
190
- tokenCount: s.tokenCount,
191
- priority: s.priority,
192
- sectionName: s.sectionName,
193
- })),
194
- },
195
- };
196
- writeFileSync(summaryPath, JSON.stringify(summary, null, 2), 'utf-8');
197
- console.log(chalk.green('āœ“') + ` ${baseName}-plan.json`);
198
- }
199
- //# sourceMappingURL=shard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shard.js","sourceRoot":"","sources":["../../src/commands/shard.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare const specCommand: Command;
3
- //# sourceMappingURL=spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,WAAW,SA2NpB,CAAC"}
@@ -1,302 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import ora from 'ora';
4
- import { Workflow, ProjectTracker, validateSpecId } from '@specsafe/core';
5
- import { readFile, writeFile } from 'fs/promises';
6
- import { join, basename } from 'path';
7
- import { input, editor, confirm } from '@inquirer/prompts';
8
- export const specCommand = new Command('spec')
9
- .description('Validate spec and enhance with AI-assisted generation from PRD')
10
- .argument('<id>', 'Spec ID (or use --from-prd to generate from PRD)')
11
- .option('--from-prd', 'Generate detailed spec from PRD section')
12
- .option('--interactive', 'Use interactive mode to refine requirements', true)
13
- .option('--auto-generate', 'Auto-generate scenarios from PRD')
14
- .action(async (id, options) => {
15
- const spinner = ora(`Processing ${id}...`).start();
16
- try {
17
- // Validate spec ID format
18
- validateSpecId(id);
19
- const workflow = new Workflow();
20
- const tracker = new ProjectTracker(process.cwd());
21
- // Load existing specs from disk
22
- await tracker.loadSpecsIntoWorkflow(workflow);
23
- // Check if spec exists
24
- let spec = workflow.getSpec(id);
25
- let specContent;
26
- let specPath;
27
- if (!spec) {
28
- // Try to load from file
29
- try {
30
- specPath = join('specs/active', `${id}.md`);
31
- specContent = await readFile(specPath, 'utf-8');
32
- // Extract name from content (first heading)
33
- const nameMatch = specContent.match(/^#\s+(.+?)\s+Specification/m);
34
- const name = nameMatch ? nameMatch[1] : id;
35
- // Create spec in workflow
36
- spec = workflow.createSpec(id, name, `Spec loaded from ${specPath}`, 'developer', basename(process.cwd()));
37
- await tracker.addSpec(spec);
38
- spinner.text = `Loaded spec from file...`;
39
- }
40
- catch (fileError) {
41
- throw new Error(`Spec ${id} not found. Run 'specsafe new <name>' to create it first.`);
42
- }
43
- }
44
- else {
45
- specPath = join('specs/active', `${id}.md`);
46
- try {
47
- specContent = await readFile(specPath, 'utf-8');
48
- }
49
- catch {
50
- throw new Error(`Spec file not found: ${specPath}`);
51
- }
52
- }
53
- spinner.stop();
54
- // Check if PRD section exists
55
- const hasPrd = specContent.includes('## 1. Product Requirements Document') ||
56
- specContent.includes('## Problem Statement');
57
- if (!hasPrd) {
58
- console.log(chalk.yellow('\nāš ļø No PRD section found in spec.'));
59
- const shouldAdd = await confirm({
60
- message: 'Would you like to add a PRD section?',
61
- default: true
62
- });
63
- if (shouldAdd) {
64
- const problemStatement = await editor({
65
- message: 'Problem Statement:',
66
- default: 'Describe the problem this feature solves...'
67
- });
68
- const userStories = await editor({
69
- message: 'User Stories:',
70
- default: 'As a [user], I want [goal], so that [reason]'
71
- });
72
- // Insert PRD section after metadata
73
- const prdSection = `\n## 1. Product Requirements Document (PRD)\n\n### 1.1 Problem Statement\n${problemStatement}\n\n### 1.2 User Stories\n${userStories}\n\n### 1.3 Acceptance Criteria\n- [ ] Criterion 1\n- [ ] Criterion 2\n\n### 1.4 Technical Considerations\n\n`;
74
- const insertPoint = specContent.indexOf('## 2.');
75
- if (insertPoint > 0) {
76
- specContent = specContent.slice(0, insertPoint) + prdSection + specContent.slice(insertPoint);
77
- }
78
- else {
79
- specContent += '\n' + prdSection;
80
- }
81
- await writeFile(specPath, specContent);
82
- console.log(chalk.green('\nāœ… Added PRD section to spec'));
83
- }
84
- }
85
- // Parse PRD and generate requirements
86
- if (options.fromPrd || options.autoGenerate) {
87
- spinner.start('Generating requirements from PRD...');
88
- const generatedRequirements = parsePrdForRequirements(specContent);
89
- const generatedScenarios = parsePrdForScenarios(specContent);
90
- spinner.stop();
91
- if (generatedRequirements.length > 0) {
92
- console.log(chalk.blue('\nšŸ“‹ Generated Requirements from PRD:\n'));
93
- for (const req of generatedRequirements) {
94
- console.log(chalk.white(` ${req.id}: ${req.text}`));
95
- }
96
- if (options.interactive) {
97
- const shouldAdd = await confirm({
98
- message: 'Add these requirements to the spec?',
99
- default: true
100
- });
101
- if (shouldAdd) {
102
- // Update spec with requirements
103
- spec.requirements = [
104
- ...spec.requirements,
105
- ...generatedRequirements.filter(r => !spec.requirements.some((er) => er.id === r.id))
106
- ];
107
- // Update spec content
108
- specContent = updateRequirementsSection(specContent, generatedRequirements);
109
- await writeFile(specPath, specContent);
110
- console.log(chalk.green(`\nāœ… Added ${generatedRequirements.length} requirements`));
111
- }
112
- }
113
- }
114
- if (generatedScenarios.length > 0) {
115
- console.log(chalk.blue('\nšŸŽ¬ Generated Scenarios:\n'));
116
- for (const scenario of generatedScenarios) {
117
- console.log(chalk.white(` Scenario: ${scenario.name}`));
118
- }
119
- if (options.interactive) {
120
- const shouldAddScenarios = await confirm({
121
- message: 'Add these scenarios to the spec?',
122
- default: true
123
- });
124
- if (shouldAddScenarios) {
125
- specContent = updateScenariosSection(specContent, generatedScenarios);
126
- await writeFile(specPath, specContent);
127
- console.log(chalk.green(`\nāœ… Added ${generatedScenarios.length} scenarios`));
128
- }
129
- }
130
- }
131
- }
132
- // Interactive refinement
133
- if (options.interactive) {
134
- const addMore = await confirm({
135
- message: 'Add additional requirements interactively?',
136
- default: spec.requirements.length === 0
137
- });
138
- if (addMore) {
139
- let adding = true;
140
- while (adding) {
141
- const reqText = await input({
142
- message: 'Requirement description (or press Enter to finish):'
143
- });
144
- if (!reqText) {
145
- adding = false;
146
- break;
147
- }
148
- const priority = await input({
149
- message: 'Priority (P0/P1/P2):',
150
- default: 'P1'
151
- });
152
- const newReq = {
153
- id: `FR-${spec.requirements.length + 1}`,
154
- text: reqText,
155
- priority,
156
- scenarios: []
157
- };
158
- spec.requirements.push(newReq);
159
- // Update file
160
- specContent = updateRequirementsSection(specContent, [newReq]);
161
- await writeFile(specPath, specContent);
162
- console.log(chalk.green(` Added: ${newReq.id}`));
163
- }
164
- }
165
- }
166
- // Validate requirements
167
- if (spec.requirements.length === 0) {
168
- console.log(chalk.yellow('\nāš ļø No requirements defined yet'));
169
- console.log(chalk.blue('Add requirements to the spec file before moving to TEST stage'));
170
- }
171
- else {
172
- spinner.succeed(chalk.green(`${id} validated: ${spec.requirements.length} requirements defined`));
173
- }
174
- // Persist state
175
- await tracker.addSpec(spec);
176
- console.log(chalk.blue('\nNext steps:'));
177
- console.log(chalk.gray(` • Run: specsafe test ${id} → Generate tests from requirements`));
178
- console.log(chalk.gray(` • Run: specsafe verify ${id} → Verify implementation`));
179
- }
180
- catch (error) {
181
- spinner.fail(chalk.red(error.message));
182
- if (error.message.includes('not found')) {
183
- console.log(chalk.gray(`šŸ’” Tip: Run 'specsafe new <name>' to create a spec first.`));
184
- console.log(chalk.gray(` Expected file: specs/active/SPEC-YYYYMMDD-NNN.md`));
185
- }
186
- process.exit(1);
187
- }
188
- });
189
- function parsePrdForRequirements(content) {
190
- const requirements = [];
191
- // Extract user stories
192
- const userStoryMatch = content.match(/### 1\.2 User Stories\n([\s\S]*?)(?=###|$)/);
193
- if (userStoryMatch) {
194
- const stories = userStoryMatch[1]
195
- .split('\n')
196
- .filter(line => line.trim().match(/^As\s+a/i))
197
- .map(line => line.trim());
198
- stories.forEach((story, index) => {
199
- requirements.push({
200
- id: `FR-${index + 1}`,
201
- text: story,
202
- priority: 'P1',
203
- scenarios: []
204
- });
205
- });
206
- }
207
- // Extract acceptance criteria
208
- const criteriaMatch = content.match(/### 1\.3 Acceptance Criteria\n([\s\S]*?)(?=###|$)/);
209
- if (criteriaMatch) {
210
- const criteria = criteriaMatch[1]
211
- .split('\n')
212
- .filter(line => line.trim().startsWith('- [ ]') || line.trim().startsWith('- '))
213
- .map(line => line.replace(/^- \[ \]\s*/, '').replace(/^- \[x\]\s*/i, '').replace(/^- /, '').trim());
214
- criteria.forEach((criterion, index) => {
215
- if (!requirements.some(r => r.text.includes(criterion))) {
216
- requirements.push({
217
- id: `FR-${requirements.length + 1}`,
218
- text: `Acceptance: ${criterion}`,
219
- priority: 'P0',
220
- scenarios: []
221
- });
222
- }
223
- });
224
- }
225
- return requirements;
226
- }
227
- function parsePrdForScenarios(content) {
228
- const scenarios = [];
229
- // Try to extract from user stories
230
- const userStoryMatch = content.match(/### 1\.2 User Stories\n([\s\S]*?)(?=###|$)/);
231
- if (userStoryMatch) {
232
- const stories = userStoryMatch[1]
233
- .split('\n')
234
- .filter(line => line.trim().match(/^As\s+a/i));
235
- stories.forEach((story, index) => {
236
- // Parse "As a X, I want Y, so that Z"
237
- const match = story.match(/As\s+a[n]?\s+(\w+),?\s*I\s+want\s+(.+?),?\s*so\s+that\s+(.+)/i);
238
- if (match) {
239
- scenarios.push({
240
- name: `User ${match[1]} completes goal`,
241
- given: `I am a ${match[1]}`,
242
- when: `I want to ${match[2]}`,
243
- thenOutcome: `I can ${match[3]}`
244
- });
245
- }
246
- });
247
- }
248
- return scenarios;
249
- }
250
- function updateRequirementsSection(content, newRequirements) {
251
- // Find or create the requirements table
252
- const tableHeader = '| ID | Requirement | Priority | Acceptance Criteria |';
253
- const tableSeparator = '|----|-------------|----------|---------------------|';
254
- const requirementsRows = newRequirements.map(r => `| ${r.id} | ${r.text} | ${r.priority} | |`);
255
- if (content.includes(tableHeader)) {
256
- // Append to existing table
257
- const tableEndMatch = content.match(/\| FR-\d+ \|[^|]+\|[^|]+\|[^|]+\|/g);
258
- if (tableEndMatch) {
259
- const lastRow = tableEndMatch[tableEndMatch.length - 1];
260
- const insertIndex = content.indexOf(lastRow) + lastRow.length;
261
- content = content.slice(0, insertIndex) + '\n' + requirementsRows.join('\n') + content.slice(insertIndex);
262
- return content;
263
- }
264
- // Table header exists but no data rows yet - add after separator
265
- const separatorIndex = content.indexOf(tableSeparator);
266
- if (separatorIndex !== -1) {
267
- const insertIndex = separatorIndex + tableSeparator.length;
268
- content = content.slice(0, insertIndex) + '\n' + requirementsRows.join('\n') + content.slice(insertIndex);
269
- return content;
270
- }
271
- }
272
- // Fallback: If no table header found, try to find Functional Requirements section
273
- const funcReqMatch = content.match(/(### Functional Requirements\n[\s\S]*?)(?=###|##\s+\d+|$)/);
274
- if (funcReqMatch) {
275
- // Insert table after the section header
276
- const sectionEnd = funcReqMatch.index + funcReqMatch[1].length;
277
- content = content.slice(0, sectionEnd) +
278
- '\n\n' + tableHeader + '\n' + tableSeparator + '\n' + requirementsRows.join('\n') +
279
- content.slice(sectionEnd);
280
- return content;
281
- }
282
- // Last resort: append a new Functional Requirements section at the end
283
- content = content.trimEnd() + '\n\n### Functional Requirements\n\n' +
284
- tableHeader + '\n' + tableSeparator + '\n' + requirementsRows.join('\n') + '\n';
285
- return content;
286
- }
287
- function updateScenariosSection(content, scenarios) {
288
- const scenariosText = scenarios.map((s, i) => `### Scenario ${i + 1}: ${s.name}
289
- - **Given** ${s.given}
290
- - **When** ${s.when}
291
- - **Then** ${s.thenOutcome}
292
- `).join('\n');
293
- // Find "## 4. Scenarios" section
294
- const scenariosMatch = content.match(/## 4\. Scenarios[\s\S]*?(?=## 5\.|## 6\.|$)/);
295
- if (scenariosMatch) {
296
- // Append to existing scenarios
297
- const insertPoint = content.indexOf(scenariosMatch[0]) + scenariosMatch[0].length;
298
- content = content.slice(0, insertPoint) + '\n' + scenariosText + content.slice(insertPoint);
299
- }
300
- return content;
301
- }
302
- //# sourceMappingURL=spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare const statusCommand: Command;
3
- //# sourceMappingURL=status.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAgDtB,CAAC"}
@@ -1,47 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import { ProjectTracker } from '@specsafe/core';
4
- export const statusCommand = new Command('status')
5
- .description('Show project status')
6
- .action(async () => {
7
- try {
8
- const tracker = new ProjectTracker(process.cwd());
9
- const state = await tracker.readState();
10
- if (!state) {
11
- console.log(chalk.yellow('No SpecSafe project found. Run: specsafe init'));
12
- return;
13
- }
14
- console.log(chalk.bold.blue(`\nšŸ“Š ${state.projectName} - Project Status\n`));
15
- // Metrics
16
- console.log(chalk.bold('Metrics:'));
17
- console.log(` Total Specs: ${state.metrics.totalSpecs}`);
18
- console.log(` Completion Rate: ${(state.metrics.completionRate * 100).toFixed(1)}%`);
19
- console.log(` Last Updated: ${state.lastUpdated.toISOString().split('T')[0]}`);
20
- // By stage
21
- console.log(chalk.bold('\nBy Stage:'));
22
- const stages = ['spec', 'test', 'code', 'qa', 'complete', 'archived'];
23
- stages.forEach(stage => {
24
- const count = state.metrics.byStage[stage];
25
- const color = count > 0 ? chalk.green : chalk.gray;
26
- console.log(` ${stage.toUpperCase().padEnd(10)} ${color(count.toString().padStart(3))}`);
27
- });
28
- // Recent specs
29
- if (state.specs.length > 0) {
30
- console.log(chalk.bold('\nRecent Specs:'));
31
- const recentSpecs = state.specs
32
- .sort((a, b) => b.lastUpdated.getTime() - a.lastUpdated.getTime())
33
- .slice(0, 5);
34
- recentSpecs.forEach(spec => {
35
- const stageColor = spec.stage === 'complete' ? chalk.green :
36
- spec.stage === 'archived' ? chalk.gray : chalk.blue;
37
- console.log(` ${spec.id} - ${spec.name} [${stageColor(spec.stage.toUpperCase())}]`);
38
- });
39
- }
40
- console.log(); // Empty line
41
- }
42
- catch (error) {
43
- console.error(chalk.red('Error reading status:'), error.message);
44
- process.exit(1);
45
- }
46
- });
47
- //# sourceMappingURL=status.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;QAExC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC,CAAC;YAC3E,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,WAAW,qBAAqB,CAAC,CAAC,CAAC;QAE7E,UAAU;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAEhF,WAAW;QACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAU,CAAC;QAC/E,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACrB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5F,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAC3C,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK;iBAC5B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;iBACjE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAEf,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACzB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC1C,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBACtE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;YACvF,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,aAAa;IAC9B,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare const testApplyCommand: Command;
3
- //# sourceMappingURL=test-apply.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-apply.d.ts","sourceRoot":"","sources":["../../src/commands/test-apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,gBAAgB,SAmNzB,CAAC"}