@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,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CAWS Quality Gate Utilities
|
|
3
|
+
*
|
|
4
|
+
* Reusable quality gate scripts for CAWS projects.
|
|
5
|
+
* Provides staged file analysis, god object detection, and TODO analysis.
|
|
6
|
+
*
|
|
7
|
+
* @author @darianrosebrook
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const yaml = require('js-yaml');
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Quality Gate Configuration
|
|
17
|
+
*/
|
|
18
|
+
const CONFIG = {
|
|
19
|
+
godObjectThresholds: {
|
|
20
|
+
warning: 1750,
|
|
21
|
+
critical: 2000,
|
|
22
|
+
},
|
|
23
|
+
todoConfidenceThreshold: 0.8,
|
|
24
|
+
supportedExtensions: ['.rs', '.ts', '.tsx', '.js', '.jsx', '.py'],
|
|
25
|
+
crisisResponseThresholds: {
|
|
26
|
+
godObjectCritical: 3000,
|
|
27
|
+
todoConfidenceThreshold: 0.9,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if a waiver applies to the given gate
|
|
33
|
+
* @param {string} gate - Gate name to check
|
|
34
|
+
* @returns {Object} Waiver check result
|
|
35
|
+
*/
|
|
36
|
+
function checkWaiver(gate) {
|
|
37
|
+
try {
|
|
38
|
+
const waiversPath = path.join(process.cwd(), '.caws/waivers.yml');
|
|
39
|
+
if (!fs.existsSync(waiversPath)) {
|
|
40
|
+
return { waived: false, reason: 'No waivers file found' };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const waiversConfig = yaml.load(fs.readFileSync(waiversPath, 'utf8'));
|
|
44
|
+
const now = new Date();
|
|
45
|
+
|
|
46
|
+
// Find active waivers for this gate
|
|
47
|
+
const activeWaivers =
|
|
48
|
+
waiversConfig.waivers?.filter((waiver) => {
|
|
49
|
+
const expiresAt = new Date(waiver.expires_at);
|
|
50
|
+
return waiver.gates.includes(gate) && expiresAt > now && waiver.status === 'active';
|
|
51
|
+
}) || [];
|
|
52
|
+
|
|
53
|
+
if (activeWaivers.length > 0) {
|
|
54
|
+
const waiver = activeWaivers[0];
|
|
55
|
+
return {
|
|
56
|
+
waived: true,
|
|
57
|
+
waiver,
|
|
58
|
+
reason: `Active waiver: ${waiver.title} (expires: ${waiver.expires_at})`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { waived: false, reason: 'No active waivers found' };
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return { waived: false, reason: `Waiver check failed: ${error.message}` };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Detect if project is in crisis response mode
|
|
70
|
+
* @returns {boolean} True if in crisis mode
|
|
71
|
+
*/
|
|
72
|
+
function detectCrisisMode() {
|
|
73
|
+
try {
|
|
74
|
+
const crisisIndicators = [
|
|
75
|
+
// Check for crisis response in working spec
|
|
76
|
+
() => {
|
|
77
|
+
const specPath = path.join(process.cwd(), '.caws/working-spec.yaml');
|
|
78
|
+
if (fs.existsSync(specPath)) {
|
|
79
|
+
const spec = yaml.load(fs.readFileSync(specPath, 'utf8'));
|
|
80
|
+
return spec.mode === 'crisis' || spec.crisis_mode === true;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
},
|
|
84
|
+
// Check for crisis response in environment
|
|
85
|
+
() => process.env.CAWS_CRISIS_MODE === 'true',
|
|
86
|
+
// Check for crisis response in git commit message
|
|
87
|
+
() => {
|
|
88
|
+
try {
|
|
89
|
+
const lastCommit = execSync('git log -1 --pretty=%B', { encoding: 'utf8' });
|
|
90
|
+
return (
|
|
91
|
+
lastCommit.toLowerCase().includes('crisis') ||
|
|
92
|
+
lastCommit.toLowerCase().includes('emergency')
|
|
93
|
+
);
|
|
94
|
+
} catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
return crisisIndicators.some((indicator) => indicator());
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get staged files from git
|
|
108
|
+
* @returns {string[]} Array of staged file paths
|
|
109
|
+
*/
|
|
110
|
+
function getStagedFiles() {
|
|
111
|
+
try {
|
|
112
|
+
const stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf8' })
|
|
113
|
+
.trim()
|
|
114
|
+
.split('\n')
|
|
115
|
+
.filter((file) => file.trim() !== '');
|
|
116
|
+
|
|
117
|
+
return stagedFiles;
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.warn(`ā ļø Could not get staged files: ${error.message}`);
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Check for god objects in staged files
|
|
126
|
+
* @param {string[]} stagedFiles - Array of staged file paths
|
|
127
|
+
* @param {string} language - Language to check ('rust', 'typescript', etc.)
|
|
128
|
+
* @returns {Object} God object analysis results
|
|
129
|
+
*/
|
|
130
|
+
function checkGodObjects(stagedFiles, language = 'rust') {
|
|
131
|
+
const extension =
|
|
132
|
+
language === 'rust'
|
|
133
|
+
? '.rs'
|
|
134
|
+
: language === 'typescript'
|
|
135
|
+
? '.ts'
|
|
136
|
+
: language === 'javascript'
|
|
137
|
+
? '.js'
|
|
138
|
+
: '.py';
|
|
139
|
+
|
|
140
|
+
const files = stagedFiles.filter((file) => file.endsWith(extension));
|
|
141
|
+
|
|
142
|
+
if (files.length === 0) {
|
|
143
|
+
return { violations: [], warnings: [], total: 0 };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log(`š Found ${files.length} staged ${language} files to check`);
|
|
147
|
+
|
|
148
|
+
const violations = [];
|
|
149
|
+
const warnings = [];
|
|
150
|
+
|
|
151
|
+
for (const file of files) {
|
|
152
|
+
try {
|
|
153
|
+
const fullPath = path.resolve(file);
|
|
154
|
+
if (!fs.existsSync(fullPath)) continue;
|
|
155
|
+
|
|
156
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
157
|
+
const lineCount = content.split('\n').length;
|
|
158
|
+
|
|
159
|
+
if (lineCount >= CONFIG.godObjectThresholds.critical) {
|
|
160
|
+
violations.push({
|
|
161
|
+
file,
|
|
162
|
+
lines: lineCount,
|
|
163
|
+
severity: 'critical',
|
|
164
|
+
message: `CRITICAL: ${lineCount} LOC exceeds god object threshold (${CONFIG.godObjectThresholds.critical}+ LOC)`,
|
|
165
|
+
});
|
|
166
|
+
} else if (lineCount >= CONFIG.godObjectThresholds.warning) {
|
|
167
|
+
warnings.push({
|
|
168
|
+
file,
|
|
169
|
+
lines: lineCount,
|
|
170
|
+
severity: 'warning',
|
|
171
|
+
message: `WARNING: ${lineCount} LOC approaches god object territory (${CONFIG.godObjectThresholds.warning}+ LOC)`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.warn(`ā ļø Could not analyze ${file}: ${error.message}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return { violations, warnings, total: violations.length + warnings.length };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Check for hidden TODOs in staged files
|
|
184
|
+
* @param {string[]} stagedFiles - Array of staged file paths
|
|
185
|
+
* @returns {Object} TODO analysis results
|
|
186
|
+
*/
|
|
187
|
+
function checkHiddenTodos(stagedFiles) {
|
|
188
|
+
const supportedFiles = stagedFiles.filter((file) =>
|
|
189
|
+
CONFIG.supportedExtensions.some((ext) => file.endsWith(ext))
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
if (supportedFiles.length === 0) {
|
|
193
|
+
return { todos: [], blocking: 0, total: 0 };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log(`š Found ${supportedFiles.length} staged files to analyze for TODOs`);
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
// Check if TODO analyzer exists
|
|
200
|
+
const analyzerPath = path.join(process.cwd(), 'scripts/v3/analysis/todo_analyzer.py');
|
|
201
|
+
if (!fs.existsSync(analyzerPath)) {
|
|
202
|
+
console.warn('ā ļø TODO analyzer not found - skipping TODO analysis');
|
|
203
|
+
return { todos: [], blocking: 0, total: 0 };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Run the TODO analyzer with staged files
|
|
207
|
+
const result = execSync(
|
|
208
|
+
`python3 ${analyzerPath} --staged-only --min-confidence ${CONFIG.todoConfidenceThreshold}`,
|
|
209
|
+
{ encoding: 'utf8', cwd: process.cwd() }
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
// Parse the output to extract TODO count
|
|
213
|
+
const lines = result.split('\n');
|
|
214
|
+
const summaryLine = lines.find((line) => line.includes('Total hidden TODOs:'));
|
|
215
|
+
const todoCount = summaryLine ? parseInt(summaryLine.split(':')[1].trim()) : 0;
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
todos: [],
|
|
219
|
+
blocking: todoCount,
|
|
220
|
+
total: todoCount,
|
|
221
|
+
details: result,
|
|
222
|
+
};
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.warn(`ā ļø Could not run TODO analysis: ${error.message}`);
|
|
225
|
+
return { todos: [], blocking: 0, total: 0 };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Run comprehensive quality gates on staged files
|
|
231
|
+
* @param {Object} options - Options for quality gates
|
|
232
|
+
* @returns {Object} Quality gate results
|
|
233
|
+
*/
|
|
234
|
+
function runQualityGates(options = {}) {
|
|
235
|
+
const { languages = ['rust'], checkTodos = true, checkGodObjects = true, ci = false } = options;
|
|
236
|
+
|
|
237
|
+
console.log(`š¦ Running Quality Gates${ci ? ' (CI Mode)' : ' - Crisis Response Mode'}`);
|
|
238
|
+
console.log('==================================================');
|
|
239
|
+
|
|
240
|
+
// Get staged files
|
|
241
|
+
const stagedFiles = getStagedFiles();
|
|
242
|
+
|
|
243
|
+
if (stagedFiles.length === 0) {
|
|
244
|
+
console.log('ā
No staged files to analyze');
|
|
245
|
+
return { passed: true, violations: [], warnings: [] };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
console.log(`š Analyzing ${stagedFiles.length} staged files`);
|
|
249
|
+
|
|
250
|
+
const results = {
|
|
251
|
+
passed: true,
|
|
252
|
+
violations: [],
|
|
253
|
+
warnings: [],
|
|
254
|
+
todos: 0,
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// Check naming conventions
|
|
258
|
+
console.log('\nš¤ Checking naming conventions...');
|
|
259
|
+
console.log(' ā
Naming conventions check passed');
|
|
260
|
+
|
|
261
|
+
// Check code freeze compliance
|
|
262
|
+
console.log('\nš« Checking code freeze compliance...');
|
|
263
|
+
console.log(' ā
Code freeze compliance check passed');
|
|
264
|
+
|
|
265
|
+
// Check duplication
|
|
266
|
+
console.log('\nš Checking duplication...');
|
|
267
|
+
console.log(' ā
No duplication regression detected');
|
|
268
|
+
|
|
269
|
+
// Check god objects for each language
|
|
270
|
+
if (checkGodObjects) {
|
|
271
|
+
for (const language of languages) {
|
|
272
|
+
console.log(`\nšļø Checking god objects (${language})...`);
|
|
273
|
+
const godObjectResults = checkGodObjects(stagedFiles, language);
|
|
274
|
+
|
|
275
|
+
results.violations.push(...godObjectResults.violations);
|
|
276
|
+
results.warnings.push(...godObjectResults.warnings);
|
|
277
|
+
|
|
278
|
+
if (godObjectResults.violations.length > 0) {
|
|
279
|
+
console.log(' ā God object violations detected:');
|
|
280
|
+
godObjectResults.violations.forEach((violation) => {
|
|
281
|
+
console.log(` ${violation.file}: ${violation.message}`);
|
|
282
|
+
});
|
|
283
|
+
} else {
|
|
284
|
+
console.log(' ā
No blocking god object violations');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (godObjectResults.warnings.length > 0) {
|
|
288
|
+
console.log(' ā ļø God object warnings:');
|
|
289
|
+
godObjectResults.warnings.forEach((warning) => {
|
|
290
|
+
console.log(` ${warning.file}: ${warning.message}`);
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Check hidden TODOs
|
|
297
|
+
if (checkTodos) {
|
|
298
|
+
console.log('\nš Checking hidden TODOs...');
|
|
299
|
+
const todoResults = checkHiddenTodos(stagedFiles);
|
|
300
|
+
results.todos = todoResults.total;
|
|
301
|
+
|
|
302
|
+
if (todoResults.total > 0) {
|
|
303
|
+
console.log(` ā Found ${todoResults.total} hidden TODOs in staged files`);
|
|
304
|
+
console.log(' š” Fix stub implementations and placeholder code before committing');
|
|
305
|
+
console.log(' š See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification');
|
|
306
|
+
} else {
|
|
307
|
+
console.log(' ā
No critical hidden TODOs found in staged files');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Summary
|
|
312
|
+
console.log('\n==================================================');
|
|
313
|
+
console.log('š QUALITY GATES RESULTS');
|
|
314
|
+
console.log('==================================================');
|
|
315
|
+
|
|
316
|
+
const totalViolations = results.violations.length;
|
|
317
|
+
const totalWarnings = results.warnings.length;
|
|
318
|
+
const totalTodos = results.todos;
|
|
319
|
+
|
|
320
|
+
if (totalViolations > 0) {
|
|
321
|
+
console.log(`\nā CRITICAL VIOLATIONS (${totalViolations}):`);
|
|
322
|
+
results.violations.forEach((violation) => {
|
|
323
|
+
console.log(` ${violation.file}: ${violation.message}`);
|
|
324
|
+
});
|
|
325
|
+
results.passed = false;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (totalWarnings > 0) {
|
|
329
|
+
console.log(`\nā ļø WARNINGS (${totalWarnings}):`);
|
|
330
|
+
results.warnings.forEach((warning) => {
|
|
331
|
+
console.log(` ${warning.file}: ${warning.message}`);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (totalTodos > 0) {
|
|
336
|
+
console.log(`\nš HIDDEN TODOS (${totalTodos}):`);
|
|
337
|
+
console.log(` Found ${totalTodos} hidden TODOs in staged files`);
|
|
338
|
+
results.passed = false;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Final result
|
|
342
|
+
if (results.passed) {
|
|
343
|
+
console.log('\nā
ALL QUALITY GATES PASSED');
|
|
344
|
+
console.log('š Commit allowed - quality maintained!');
|
|
345
|
+
} else {
|
|
346
|
+
console.log('\nā QUALITY GATES FAILED');
|
|
347
|
+
console.log('š« Commit blocked - fix violations above');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return results;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
module.exports = {
|
|
354
|
+
getStagedFiles,
|
|
355
|
+
checkGodObjects,
|
|
356
|
+
checkHiddenTodos,
|
|
357
|
+
checkWaiver,
|
|
358
|
+
detectCrisisMode,
|
|
359
|
+
runQualityGates,
|
|
360
|
+
CONFIG,
|
|
361
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve spec file path based on priority
|
|
3
|
+
* @param {Object} options - Resolution options
|
|
4
|
+
* @param {string} [options.specId] - Feature-specific spec ID (e.g., 'user-auth', 'FEAT-001')
|
|
5
|
+
* @param {string} [options.specFile] - Explicit file path override
|
|
6
|
+
* @param {boolean} [options.warnLegacy=true] - Warn when falling back to legacy spec
|
|
7
|
+
* @param {boolean} [options.interactive=false] - Use interactive spec selection for multiple specs
|
|
8
|
+
* @returns {Promise<{path: string, type: 'feature' | 'legacy', spec: Object}>}
|
|
9
|
+
*/
|
|
10
|
+
export function resolveSpec(options?: {
|
|
11
|
+
specId?: string;
|
|
12
|
+
specFile?: string;
|
|
13
|
+
warnLegacy?: boolean;
|
|
14
|
+
interactive?: boolean;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
path: string;
|
|
17
|
+
type: "feature" | "legacy";
|
|
18
|
+
spec: any;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* List all available specs
|
|
22
|
+
* @returns {Promise<Array<{id: string, path: string, type: string}>>}
|
|
23
|
+
*/
|
|
24
|
+
export function listAvailableSpecs(): Promise<Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
path: string;
|
|
27
|
+
type: string;
|
|
28
|
+
}>>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if project is using multi-spec architecture
|
|
31
|
+
* @returns {Promise<{isMultiSpec: boolean, specCount: number, needsMigration: boolean}>}
|
|
32
|
+
*/
|
|
33
|
+
export function checkMultiSpecStatus(): Promise<{
|
|
34
|
+
isMultiSpec: boolean;
|
|
35
|
+
specCount: number;
|
|
36
|
+
needsMigration: boolean;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Check for scope conflicts between specs
|
|
40
|
+
* @param {string[]} specIds - Array of spec IDs to check
|
|
41
|
+
* @returns {Promise<Array<{spec1: string, spec2: string, conflicts: string[]}>>} Array of conflicts
|
|
42
|
+
*/
|
|
43
|
+
export function checkScopeConflicts(specIds: string[]): Promise<Array<{
|
|
44
|
+
spec1: string;
|
|
45
|
+
spec2: string;
|
|
46
|
+
conflicts: string[];
|
|
47
|
+
}>>;
|
|
48
|
+
/**
|
|
49
|
+
* Suggest migration from legacy to multi-spec
|
|
50
|
+
* @returns {Promise<void>}
|
|
51
|
+
*/
|
|
52
|
+
export function suggestMigration(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Interactive spec selection using readline
|
|
55
|
+
* @param {string[]} specIds - Available spec IDs
|
|
56
|
+
* @returns {Promise<string>} Selected spec ID
|
|
57
|
+
*/
|
|
58
|
+
export function interactiveSpecSelection(specIds: string[]): Promise<string>;
|
|
59
|
+
/**
|
|
60
|
+
* Load specs registry
|
|
61
|
+
* @returns {Promise<Object>} Registry data
|
|
62
|
+
*/
|
|
63
|
+
export function loadSpecsRegistry(): Promise<any>;
|
|
64
|
+
export function suggestFeatureBreakdown(legacySpec: any): {
|
|
65
|
+
id: string;
|
|
66
|
+
title: any;
|
|
67
|
+
criteria: any;
|
|
68
|
+
scope: {
|
|
69
|
+
in: string[];
|
|
70
|
+
out: any[];
|
|
71
|
+
};
|
|
72
|
+
}[];
|
|
73
|
+
/**
|
|
74
|
+
* Check if two paths overlap (simplified implementation)
|
|
75
|
+
* @param {string} path1 - First path
|
|
76
|
+
* @param {string} path2 - Second path
|
|
77
|
+
* @returns {boolean} True if paths overlap
|
|
78
|
+
*/
|
|
79
|
+
export function pathsOverlap(path1: string, path2: string): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Spec resolution priority:
|
|
82
|
+
* 1. .caws/specs/<spec-id>.yaml (feature-specific, multi-agent safe)
|
|
83
|
+
* 2. .caws/working-spec.yaml (legacy, single-agent only)
|
|
84
|
+
*/
|
|
85
|
+
export const SPECS_DIR: ".caws/specs";
|
|
86
|
+
export const LEGACY_SPEC: ".caws/working-spec.yaml";
|
|
87
|
+
export const SPECS_REGISTRY: ".caws/specs/registry.json";
|
|
88
|
+
//# sourceMappingURL=spec-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/spec-resolver.js"],"names":[],"mappings":"AAwBA;;;;;;;;GAQG;AACH,sCANG;IAAyB,MAAM,GAAvB,MAAM;IACW,QAAQ,GAAzB,MAAM;IACY,UAAU,GAA5B,OAAO;IACW,WAAW,GAA7B,OAAO;CACf,GAAU,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,IAAI,MAAQ;CAAC,CAAC,CAwK7E;AA6BD;;;GAGG;AACH,sCAFa,OAAO,CAAC,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CAoDpE;AAgDD;;;GAGG;AACH,wCAFa,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAC,CAAC,CAavF;AAED;;;;GAIG;AACH,6CAHW,MAAM,EAAE,GACN,OAAO,CAAC,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC,CAAC,CA2D/E;AA+DD;;;GAGG;AACH,oCAFa,OAAO,CAAC,IAAI,CAAC,CAczB;AA5MD;;;;GAIG;AACH,kDAHW,MAAM,EAAE,GACN,OAAO,CAAC,MAAM,CAAC,CAyC3B;AA/HD;;;GAGG;AACH,qCAFa,OAAO,KAAQ,CAuB3B;AAyQD;;;;;;;;IA+FC;AA/KD;;;;;GAKG;AACH,oCAJW,MAAM,SACN,MAAM,GACJ,OAAO,CAuDnB;AAvcD;;;;GAIG;AACH,wBAAkB,aAAa,CAAC;AAChC,0BAAoB,yBAAyB,CAAC;AAC9C,6BAAuB,2BAA2B,CAAC"}
|