@paths.design/caws-cli 3.5.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/budget-derivation.d.ts +41 -2
- package/dist/budget-derivation.d.ts.map +1 -1
- package/dist/budget-derivation.js +417 -30
- package/dist/commands/archive.d.ts +50 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +353 -0
- package/dist/commands/iterate.d.ts.map +1 -1
- package/dist/commands/iterate.js +12 -13
- package/dist/commands/mode.d.ts +24 -0
- package/dist/commands/mode.d.ts.map +1 -0
- package/dist/commands/mode.js +259 -0
- package/dist/commands/plan.d.ts +49 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +448 -0
- package/dist/commands/quality-gates.d.ts +52 -0
- package/dist/commands/quality-gates.d.ts.map +1 -0
- package/dist/commands/quality-gates.js +490 -0
- package/dist/commands/specs.d.ts +71 -0
- package/dist/commands/specs.d.ts.map +1 -0
- package/dist/commands/specs.js +735 -0
- package/dist/commands/status.d.ts +4 -3
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +552 -22
- package/dist/commands/tutorial.d.ts +55 -0
- package/dist/commands/tutorial.d.ts.map +1 -0
- package/dist/commands/tutorial.js +481 -0
- package/dist/commands/validate.d.ts +10 -2
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +199 -39
- package/dist/config/modes.d.ts +225 -0
- package/dist/config/modes.d.ts.map +1 -0
- package/dist/config/modes.js +321 -0
- package/dist/constants/spec-types.d.ts +41 -0
- package/dist/constants/spec-types.d.ts.map +1 -0
- package/dist/constants/spec-types.js +42 -0
- package/dist/index-new.d.ts +5 -0
- package/dist/index-new.d.ts.map +1 -0
- package/dist/index-new.js +317 -0
- package/dist/index.js +227 -10
- package/dist/index.js.backup +4711 -0
- package/dist/policy/PolicyManager.d.ts +104 -0
- package/dist/policy/PolicyManager.d.ts.map +1 -0
- package/dist/policy/PolicyManager.js +399 -0
- package/dist/scaffold/cursor-hooks.d.ts.map +1 -1
- package/dist/scaffold/cursor-hooks.js +15 -0
- package/dist/scaffold/git-hooks.d.ts.map +1 -1
- package/dist/scaffold/git-hooks.js +32 -44
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +19 -0
- package/dist/spec/SpecFileManager.d.ts +146 -0
- package/dist/spec/SpecFileManager.d.ts.map +1 -0
- package/dist/spec/SpecFileManager.js +419 -0
- package/dist/utils/quality-gates-errors.js +520 -0
- package/dist/utils/quality-gates.d.ts +49 -0
- package/dist/utils/quality-gates.d.ts.map +1 -0
- package/dist/utils/quality-gates.js +361 -0
- package/dist/utils/spec-resolver.d.ts +88 -0
- package/dist/utils/spec-resolver.d.ts.map +1 -0
- package/dist/utils/spec-resolver.js +602 -0
- package/dist/validation/spec-validation.d.ts +14 -0
- package/dist/validation/spec-validation.d.ts.map +1 -1
- package/dist/validation/spec-validation.js +225 -13
- package/package.json +6 -5
- package/templates/.cursor/hooks/caws-scope-guard.sh +64 -8
- package/templates/.cursor/hooks/validate-spec.sh +22 -12
- package/templates/.cursor/rules/00-claims-verification.mdc +144 -0
- package/templates/.cursor/rules/01-working-style.mdc +50 -0
- package/templates/.cursor/rules/02-quality-gates.mdc +370 -0
- package/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
- package/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
- package/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
- package/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
- package/templates/.cursor/rules/07-process-ops.mdc +20 -0
- package/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
- package/templates/.cursor/rules/09-docstrings.mdc +89 -0
- package/templates/.cursor/rules/10-authorship-and-attribution.mdc +15 -0
- package/templates/.cursor/rules/11-documentation-quality-standards.mdc +390 -0
- package/templates/.cursor/rules/12-scope-management-waivers.mdc +385 -0
- package/templates/.cursor/rules/13-implementation-completeness.mdc +516 -0
- package/templates/.cursor/rules/14-language-agnostic-standards.mdc +588 -0
- package/templates/.cursor/rules/15-sophisticated-todo-detection.mdc +425 -0
- package/templates/.cursor/rules/README.md +150 -0
- package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
- package/templates/apps/tools/caws/provenance.js.backup +73 -0
- package/templates/scripts/quality-gates/check-god-objects.js +146 -0
- package/templates/scripts/quality-gates/run-quality-gates.js +50 -0
- package/templates/scripts/v3/analysis/todo_analyzer.py +1950 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CAWS Plan Command
|
|
3
|
+
* Automated plan generation from specifications (multi-spec aware)
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const { safeAsync, outputResult } = require('../error-handler');
|
|
11
|
+
|
|
12
|
+
// Import spec resolution system
|
|
13
|
+
const { resolveSpec } = require('../utils/spec-resolver');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Plan templates for different spec types
|
|
17
|
+
*/
|
|
18
|
+
const PLAN_TEMPLATES = {
|
|
19
|
+
feature: {
|
|
20
|
+
sections: [
|
|
21
|
+
'Overview',
|
|
22
|
+
'Acceptance Criteria Analysis',
|
|
23
|
+
'Implementation Strategy',
|
|
24
|
+
'Testing Strategy',
|
|
25
|
+
'Risk Assessment',
|
|
26
|
+
'Dependencies',
|
|
27
|
+
'Timeline',
|
|
28
|
+
'Success Metrics',
|
|
29
|
+
],
|
|
30
|
+
defaultTasks: [
|
|
31
|
+
'Set up development environment',
|
|
32
|
+
'Implement core functionality',
|
|
33
|
+
'Add error handling',
|
|
34
|
+
'Write comprehensive tests',
|
|
35
|
+
'Update documentation',
|
|
36
|
+
'Performance optimization',
|
|
37
|
+
'Security review',
|
|
38
|
+
'Final validation',
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
fix: {
|
|
42
|
+
sections: [
|
|
43
|
+
'Problem Analysis',
|
|
44
|
+
'Root Cause Investigation',
|
|
45
|
+
'Solution Design',
|
|
46
|
+
'Implementation Plan',
|
|
47
|
+
'Testing Strategy',
|
|
48
|
+
'Rollback Plan',
|
|
49
|
+
'Verification',
|
|
50
|
+
],
|
|
51
|
+
defaultTasks: [
|
|
52
|
+
'Reproduce the issue',
|
|
53
|
+
'Identify root cause',
|
|
54
|
+
'Design fix approach',
|
|
55
|
+
'Implement solution',
|
|
56
|
+
'Write regression tests',
|
|
57
|
+
'Update documentation',
|
|
58
|
+
'Deploy and verify',
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
refactor: {
|
|
62
|
+
sections: [
|
|
63
|
+
'Current State Analysis',
|
|
64
|
+
'Refactoring Goals',
|
|
65
|
+
'Approach Strategy',
|
|
66
|
+
'Implementation Plan',
|
|
67
|
+
'Testing Strategy',
|
|
68
|
+
'Performance Impact',
|
|
69
|
+
'Migration Plan',
|
|
70
|
+
],
|
|
71
|
+
defaultTasks: [
|
|
72
|
+
'Analyze current code',
|
|
73
|
+
'Design new architecture',
|
|
74
|
+
'Plan incremental changes',
|
|
75
|
+
'Implement refactoring',
|
|
76
|
+
'Update tests',
|
|
77
|
+
'Performance validation',
|
|
78
|
+
'Documentation update',
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Load spec for plan generation
|
|
85
|
+
* @param {string} specId - Spec identifier
|
|
86
|
+
* @returns {Promise<Object|null>} Spec data or null
|
|
87
|
+
*/
|
|
88
|
+
async function loadSpecForPlanning(specId) {
|
|
89
|
+
try {
|
|
90
|
+
const resolved = await resolveSpec({
|
|
91
|
+
specId,
|
|
92
|
+
warnLegacy: false,
|
|
93
|
+
});
|
|
94
|
+
return resolved.spec;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Generate and display implementation plan
|
|
102
|
+
* @param {Object} spec - Spec data
|
|
103
|
+
* @param {string} specId - Spec identifier
|
|
104
|
+
* @param {Object} options - Command options
|
|
105
|
+
*/
|
|
106
|
+
async function generateAndDisplayPlan(spec, specId, options) {
|
|
107
|
+
// Generate plan
|
|
108
|
+
const plan = generateImplementationPlan(spec);
|
|
109
|
+
|
|
110
|
+
// Determine output path
|
|
111
|
+
const outputPath = options.output || `.caws/plans/${specId}-plan.md`;
|
|
112
|
+
|
|
113
|
+
// Write plan to file
|
|
114
|
+
await writePlanToFile(plan, outputPath);
|
|
115
|
+
|
|
116
|
+
// Display plan summary
|
|
117
|
+
displayGeneratedPlan(plan);
|
|
118
|
+
|
|
119
|
+
console.log(chalk.green(`✅ Plan generated: ${outputPath}`));
|
|
120
|
+
|
|
121
|
+
return outputResult({
|
|
122
|
+
command: 'plan generate',
|
|
123
|
+
specId,
|
|
124
|
+
outputPath,
|
|
125
|
+
planSections: plan.sections.length,
|
|
126
|
+
tasks: plan.tasks.length,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Generate implementation tasks from acceptance criteria
|
|
132
|
+
* @param {Array} criteria - Acceptance criteria
|
|
133
|
+
* @returns {Array} Generated tasks
|
|
134
|
+
*/
|
|
135
|
+
function generateTasksFromCriteria(criteria) {
|
|
136
|
+
const tasks = [];
|
|
137
|
+
|
|
138
|
+
criteria.forEach((criterion, index) => {
|
|
139
|
+
const criterionId = criterion.id || `A${index + 1}`;
|
|
140
|
+
const description = criterion.description || criterion.title || `Implement ${criterionId}`;
|
|
141
|
+
|
|
142
|
+
// Break down complex criteria into multiple tasks
|
|
143
|
+
if (description.includes('and') || description.includes('then') || description.length > 100) {
|
|
144
|
+
// Split into multiple tasks
|
|
145
|
+
const parts = description.split(/[.;]/).filter((part) => part.trim().length > 0);
|
|
146
|
+
parts.forEach((part, partIndex) => {
|
|
147
|
+
tasks.push({
|
|
148
|
+
id: `${criterionId}.${partIndex + 1}`,
|
|
149
|
+
title: part.trim(),
|
|
150
|
+
criterion: criterionId,
|
|
151
|
+
type: 'implementation',
|
|
152
|
+
estimatedHours: 2,
|
|
153
|
+
dependencies: partIndex > 0 ? [`${criterionId}.${partIndex}`] : [],
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
// Single task for simple criteria
|
|
158
|
+
tasks.push({
|
|
159
|
+
id: criterionId,
|
|
160
|
+
title: description,
|
|
161
|
+
criterion: criterionId,
|
|
162
|
+
type: 'implementation',
|
|
163
|
+
estimatedHours: 3,
|
|
164
|
+
dependencies: [],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return tasks;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Generate testing tasks for acceptance criteria
|
|
174
|
+
* @param {Array} criteria - Acceptance criteria
|
|
175
|
+
* @returns {Array} Generated test tasks
|
|
176
|
+
*/
|
|
177
|
+
function generateTestTasks(criteria) {
|
|
178
|
+
const tasks = [];
|
|
179
|
+
|
|
180
|
+
criteria.forEach((criterion, index) => {
|
|
181
|
+
const criterionId = criterion.id || `A${index + 1}`;
|
|
182
|
+
|
|
183
|
+
tasks.push({
|
|
184
|
+
id: `test-${criterionId}`,
|
|
185
|
+
title: `Write tests for ${criterionId}`,
|
|
186
|
+
criterion: criterionId,
|
|
187
|
+
type: 'testing',
|
|
188
|
+
estimatedHours: 2,
|
|
189
|
+
dependencies: [criterionId],
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
tasks.push({
|
|
193
|
+
id: `integration-${criterionId}`,
|
|
194
|
+
title: `Integration tests for ${criterionId}`,
|
|
195
|
+
criterion: criterionId,
|
|
196
|
+
type: 'testing',
|
|
197
|
+
estimatedHours: 1,
|
|
198
|
+
dependencies: [`test-${criterionId}`],
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return tasks;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Generate implementation plan from spec
|
|
207
|
+
* @param {Object} spec - Spec data
|
|
208
|
+
* @returns {Object} Generated plan
|
|
209
|
+
*/
|
|
210
|
+
function generateImplementationPlan(spec) {
|
|
211
|
+
const template = PLAN_TEMPLATES[spec.type] || PLAN_TEMPLATES.feature;
|
|
212
|
+
|
|
213
|
+
// Generate tasks from acceptance criteria
|
|
214
|
+
const implementationTasks = generateTasksFromCriteria(spec.acceptance_criteria || []);
|
|
215
|
+
const testTasks = generateTestTasks(spec.acceptance_criteria || []);
|
|
216
|
+
|
|
217
|
+
// Combine all tasks
|
|
218
|
+
const allTasks = [
|
|
219
|
+
...template.defaultTasks.map((task, index) => ({
|
|
220
|
+
id: `setup-${index + 1}`,
|
|
221
|
+
title: task,
|
|
222
|
+
type: 'setup',
|
|
223
|
+
estimatedHours: 1,
|
|
224
|
+
dependencies: [],
|
|
225
|
+
})),
|
|
226
|
+
...implementationTasks,
|
|
227
|
+
...testTasks,
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
// Calculate timeline
|
|
231
|
+
const totalHours = allTasks.reduce((sum, task) => sum + task.estimatedHours, 0);
|
|
232
|
+
const estimatedDays = Math.ceil(totalHours / 8); // Assuming 8-hour work days
|
|
233
|
+
|
|
234
|
+
// Generate plan content
|
|
235
|
+
const planContent = {
|
|
236
|
+
spec_id: spec.id,
|
|
237
|
+
title: `Implementation Plan: ${spec.title}`,
|
|
238
|
+
generated_at: new Date().toISOString(),
|
|
239
|
+
sections: template.sections,
|
|
240
|
+
tasks: allTasks,
|
|
241
|
+
timeline: {
|
|
242
|
+
total_hours: totalHours,
|
|
243
|
+
estimated_days: estimatedDays,
|
|
244
|
+
parallel_execution: true,
|
|
245
|
+
},
|
|
246
|
+
risks: [
|
|
247
|
+
{
|
|
248
|
+
level: 'low',
|
|
249
|
+
description: 'Standard implementation risks',
|
|
250
|
+
mitigation: 'Follow established patterns and conduct thorough testing',
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
return planContent;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Write plan to file
|
|
260
|
+
* @param {Object} plan - Plan data
|
|
261
|
+
* @param {string} outputPath - Output file path
|
|
262
|
+
* @returns {Promise<void>}
|
|
263
|
+
*/
|
|
264
|
+
async function writePlanToFile(plan, outputPath) {
|
|
265
|
+
const planDir = path.dirname(outputPath);
|
|
266
|
+
await fs.ensureDir(planDir);
|
|
267
|
+
|
|
268
|
+
const markdownContent = generatePlanMarkdown(plan);
|
|
269
|
+
await fs.writeFile(outputPath, markdownContent);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Generate markdown content from plan
|
|
274
|
+
* @param {Object} plan - Plan data
|
|
275
|
+
* @returns {string} Markdown content
|
|
276
|
+
*/
|
|
277
|
+
function generatePlanMarkdown(plan) {
|
|
278
|
+
let content = `# ${plan.title}\n\n`;
|
|
279
|
+
content += `**Generated:** ${new Date(plan.generated_at).toLocaleString()}\n`;
|
|
280
|
+
content += `**Spec ID:** ${plan.spec_id}\n\n`;
|
|
281
|
+
|
|
282
|
+
// Overview section
|
|
283
|
+
content += `## Overview\n\n`;
|
|
284
|
+
content += `This plan outlines the implementation strategy for the specified requirements.\n`;
|
|
285
|
+
content += `**Timeline:** ${plan.timeline.estimated_days} days (${plan.timeline.total_hours} hours)\n\n`;
|
|
286
|
+
|
|
287
|
+
// Tasks section
|
|
288
|
+
content += `## Implementation Tasks\n\n`;
|
|
289
|
+
|
|
290
|
+
// Group tasks by type
|
|
291
|
+
const setupTasks = plan.tasks.filter((task) => task.type === 'setup');
|
|
292
|
+
const implementationTasks = plan.tasks.filter((task) => task.type === 'implementation');
|
|
293
|
+
const testTasks = plan.tasks.filter((task) => task.type === 'testing');
|
|
294
|
+
|
|
295
|
+
if (setupTasks.length > 0) {
|
|
296
|
+
content += `### Setup (${setupTasks.length} tasks)\n\n`;
|
|
297
|
+
setupTasks.forEach((task) => {
|
|
298
|
+
content += `- [ ] **${task.id}** - ${task.title} (${task.estimatedHours}h)\n`;
|
|
299
|
+
});
|
|
300
|
+
content += '\n';
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (implementationTasks.length > 0) {
|
|
304
|
+
content += `### Implementation (${implementationTasks.length} tasks)\n\n`;
|
|
305
|
+
implementationTasks.forEach((task) => {
|
|
306
|
+
const deps =
|
|
307
|
+
task.dependencies.length > 0 ? ` (depends on: ${task.dependencies.join(', ')})` : '';
|
|
308
|
+
content += `- [ ] **${task.id}** - ${task.title} (${task.estimatedHours}h)${deps}\n`;
|
|
309
|
+
});
|
|
310
|
+
content += '\n';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (testTasks.length > 0) {
|
|
314
|
+
content += `### Testing (${testTasks.length} tasks)\n\n`;
|
|
315
|
+
testTasks.forEach((task) => {
|
|
316
|
+
const deps =
|
|
317
|
+
task.dependencies.length > 0 ? ` (depends on: ${task.dependencies.join(', ')})` : '';
|
|
318
|
+
content += `- [ ] **${task.id}** - ${task.title} (${task.estimatedHours}h)${deps}\n`;
|
|
319
|
+
});
|
|
320
|
+
content += '\n';
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Risk assessment
|
|
324
|
+
content += `## Risk Assessment\n\n`;
|
|
325
|
+
plan.risks.forEach((risk, index) => {
|
|
326
|
+
content += `### ${risk.level.toUpperCase()} Risk ${index + 1}\n`;
|
|
327
|
+
content += `${risk.description}\n\n`;
|
|
328
|
+
content += `**Mitigation:** ${risk.mitigation}\n\n`;
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Success metrics
|
|
332
|
+
content += `## Success Metrics\n\n`;
|
|
333
|
+
content += `- All acceptance criteria implemented and tested\n`;
|
|
334
|
+
content += `- Code coverage meets project standards\n`;
|
|
335
|
+
content += `- Performance requirements satisfied\n`;
|
|
336
|
+
content += `- No breaking changes to existing functionality\n`;
|
|
337
|
+
content += `- Documentation updated\n\n`;
|
|
338
|
+
|
|
339
|
+
return content;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Display generated plan
|
|
344
|
+
* @param {Object} plan - Plan data
|
|
345
|
+
*/
|
|
346
|
+
function displayGeneratedPlan(plan) {
|
|
347
|
+
console.log(chalk.bold.cyan(`\n📋 Generated Implementation Plan`));
|
|
348
|
+
console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
349
|
+
|
|
350
|
+
console.log(chalk.bold(`Title: ${plan.title}`));
|
|
351
|
+
console.log(chalk.gray(`Spec: ${plan.spec_id}`));
|
|
352
|
+
console.log(chalk.gray(`Generated: ${new Date(plan.generated_at).toLocaleString()}`));
|
|
353
|
+
console.log('');
|
|
354
|
+
|
|
355
|
+
// Task summary
|
|
356
|
+
const setupTasks = plan.tasks.filter((task) => task.type === 'setup').length;
|
|
357
|
+
const implementationTasks = plan.tasks.filter((task) => task.type === 'implementation').length;
|
|
358
|
+
const testTasks = plan.tasks.filter((task) => task.type === 'testing').length;
|
|
359
|
+
|
|
360
|
+
console.log(chalk.bold('Task Breakdown:'));
|
|
361
|
+
if (setupTasks > 0) console.log(chalk.gray(` Setup: ${setupTasks} tasks`));
|
|
362
|
+
if (implementationTasks > 0)
|
|
363
|
+
console.log(chalk.gray(` Implementation: ${implementationTasks} tasks`));
|
|
364
|
+
if (testTasks > 0) console.log(chalk.gray(` Testing: ${testTasks} tasks`));
|
|
365
|
+
|
|
366
|
+
console.log(
|
|
367
|
+
chalk.gray(
|
|
368
|
+
` Total: ${plan.tasks.length} tasks, ${plan.timeline.total_hours} hours, ${plan.timeline.estimated_days} days`
|
|
369
|
+
)
|
|
370
|
+
);
|
|
371
|
+
console.log('');
|
|
372
|
+
|
|
373
|
+
// Next steps
|
|
374
|
+
console.log(chalk.bold.yellow('💡 Next Steps:'));
|
|
375
|
+
console.log(chalk.yellow(' 1. Review and customize the generated plan'));
|
|
376
|
+
console.log(chalk.yellow(' 2. Update task priorities and dependencies'));
|
|
377
|
+
console.log(chalk.yellow(' 3. Start implementation following the task order'));
|
|
378
|
+
console.log(chalk.yellow(' 4. Update progress: caws progress update --criterion-id A1'));
|
|
379
|
+
console.log('');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Plan command handler
|
|
384
|
+
* @param {string} action - Action to perform (generate)
|
|
385
|
+
* @param {Object} options - Command options
|
|
386
|
+
*/
|
|
387
|
+
async function planCommand(action, options = {}) {
|
|
388
|
+
return safeAsync(
|
|
389
|
+
async () => {
|
|
390
|
+
switch (action) {
|
|
391
|
+
case 'generate': {
|
|
392
|
+
const specId = options.specId || options.spec;
|
|
393
|
+
|
|
394
|
+
if (!specId) {
|
|
395
|
+
// Try to auto-detect single spec
|
|
396
|
+
const { checkMultiSpecStatus } = require('../utils/spec-resolver');
|
|
397
|
+
const status = await checkMultiSpecStatus();
|
|
398
|
+
|
|
399
|
+
if (status.specCount === 1) {
|
|
400
|
+
// Use the single spec automatically
|
|
401
|
+
const registry = await require('../utils/spec-resolver').loadSpecsRegistry();
|
|
402
|
+
const singleSpecId = Object.keys(registry.specs)[0];
|
|
403
|
+
console.log(chalk.blue(`📋 Auto-detected single spec: ${singleSpecId}`));
|
|
404
|
+
|
|
405
|
+
const spec = await loadSpecForPlanning(singleSpecId);
|
|
406
|
+
if (!spec) {
|
|
407
|
+
throw new Error(`Auto-detected spec '${singleSpecId}' could not be loaded`);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
await generateAndDisplayPlan(spec, singleSpecId, options);
|
|
411
|
+
} else if (status.specCount > 1) {
|
|
412
|
+
throw new Error(
|
|
413
|
+
'Multiple specs detected. Please specify which one: caws plan generate --spec-id <id>\n' +
|
|
414
|
+
'Available specs: ' +
|
|
415
|
+
Object.keys(status.registry?.specs || {}).join(', ')
|
|
416
|
+
);
|
|
417
|
+
} else {
|
|
418
|
+
throw new Error('No specs found. Create a spec first: caws specs create <id>');
|
|
419
|
+
}
|
|
420
|
+
} else {
|
|
421
|
+
// Load spec for planning
|
|
422
|
+
const spec = await loadSpecForPlanning(specId);
|
|
423
|
+
if (!spec) {
|
|
424
|
+
throw new Error(`Spec '${specId}' not found`);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return await generateAndDisplayPlan(spec, specId, options);
|
|
428
|
+
}
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
default:
|
|
433
|
+
throw new Error(`Unknown plan action: ${action}. Use: generate`);
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
`plan ${action}`,
|
|
437
|
+
true
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
module.exports = {
|
|
442
|
+
planCommand,
|
|
443
|
+
generateImplementationPlan,
|
|
444
|
+
writePlanToFile,
|
|
445
|
+
generatePlanMarkdown,
|
|
446
|
+
displayGeneratedPlan,
|
|
447
|
+
PLAN_TEMPLATES,
|
|
448
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality Gates Configuration
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Update provenance with quality gates results
|
|
6
|
+
* @param {Object} results - Quality gates results
|
|
7
|
+
* @param {boolean} crisisMode - Whether in crisis mode
|
|
8
|
+
* @param {string[]} stagedFiles - Array of staged files
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Detect agent type for provenance tracking
|
|
12
|
+
* @returns {string} Agent type identifier
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Check if a waiver applies to the given gate
|
|
16
|
+
* @param {string} gate - Gate name to check
|
|
17
|
+
* @returns {Object} Waiver check result
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Detect if project is in crisis response mode
|
|
21
|
+
* @returns {boolean} True if in crisis mode
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Get staged files from git
|
|
25
|
+
* @returns {string[]} Array of staged file paths
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Check for god objects in staged Rust files with waiver and crisis mode support
|
|
29
|
+
* @param {string[]} stagedFiles - Array of staged file paths
|
|
30
|
+
* @param {boolean} crisisMode - Whether in crisis response mode
|
|
31
|
+
* @returns {Object} God object analysis results
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Check for hidden TODOs in staged files with waiver and crisis mode support
|
|
35
|
+
* @param {string[]} stagedFiles - Array of staged file paths
|
|
36
|
+
* @param {boolean} crisisMode - Whether in crisis response mode
|
|
37
|
+
* @returns {Object} TODO analysis results
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Check for human override in working spec
|
|
41
|
+
* @returns {Object} Human override check result
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* Get CAWS tier from working spec
|
|
45
|
+
* @returns {number|null} CAWS tier (1, 2, or 3) or null if not found
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* Run comprehensive quality gates on staged files
|
|
49
|
+
* @param {Object} options - Command options
|
|
50
|
+
*/
|
|
51
|
+
export function qualityGatesCommand(options?: any): Promise<any>;
|
|
52
|
+
//# sourceMappingURL=quality-gates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-gates.d.ts","sourceRoot":"","sources":["../../src/commands/quality-gates.js"],"names":[],"mappings":"AAqBA;;GAEG;AAkBH;;;;;GAKG;AAGH;;;GAGG;AA6BH;;;;GAIG;AAiCH;;;GAGG;AAoCH;;;GAGG;AAeH;;;;;GAKG;AAmFH;;;;;GAKG;AAqEH;;;GAGG;AA0BH;;;GAGG;AAaH;;;GAGG;AACH,iEAmGC"}
|