@paths.design/caws-cli 8.0.0 → 8.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 +74 -0
- package/dist/budget-derivation.d.ts.map +1 -0
- package/dist/cicd-optimizer.d.ts +142 -0
- package/dist/cicd-optimizer.d.ts.map +1 -0
- package/dist/commands/archive.d.ts +51 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +114 -6
- package/dist/commands/burnup.d.ts +6 -0
- package/dist/commands/burnup.d.ts.map +1 -0
- package/dist/commands/burnup.js +109 -10
- package/dist/commands/diagnose.d.ts +52 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +1 -1
- package/dist/commands/evaluate.d.ts +8 -0
- package/dist/commands/evaluate.d.ts.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/iterate.d.ts +8 -0
- package/dist/commands/iterate.d.ts.map +1 -0
- package/dist/commands/mode.d.ts +24 -0
- package/dist/commands/mode.d.ts.map +1 -0
- package/dist/commands/mode.js +24 -14
- package/dist/commands/plan.d.ts +49 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/provenance.d.ts +32 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +216 -93
- package/dist/commands/quality-gates.d.ts +6 -0
- package/dist/commands/quality-gates.d.ts.map +1 -0
- package/dist/commands/quality-gates.js +82 -3
- package/dist/commands/quality-monitor.d.ts +17 -0
- package/dist/commands/quality-monitor.d.ts.map +1 -0
- package/dist/commands/specs.d.ts +71 -0
- package/dist/commands/specs.d.ts.map +1 -0
- package/dist/commands/specs.js +184 -6
- package/dist/commands/status.d.ts +44 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +134 -10
- package/dist/commands/templates.d.ts +74 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +2 -2
- package/dist/commands/tool.d.ts +13 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/troubleshoot.d.ts +8 -0
- package/dist/commands/troubleshoot.d.ts.map +1 -0
- package/dist/commands/tutorial.d.ts +55 -0
- package/dist/commands/tutorial.d.ts.map +1 -0
- package/dist/commands/validate.d.ts +15 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/waivers.d.ts +8 -0
- package/dist/commands/waivers.d.ts.map +1 -0
- package/dist/commands/workflow.d.ts +85 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/config/index.d.ts +29 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/modes.d.ts +225 -0
- package/dist/config/modes.d.ts.map +1 -0
- package/dist/constants/spec-types.d.ts +41 -0
- package/dist/constants/spec-types.d.ts.map +1 -0
- package/dist/error-handler.d.ts +164 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +6 -98
- package/dist/generators/jest-config-generator.js +242 -0
- package/dist/generators/jest-config.d.ts +32 -0
- package/dist/generators/jest-config.d.ts.map +1 -0
- package/dist/generators/working-spec.d.ts +13 -0
- package/dist/generators/working-spec.d.ts.map +1 -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.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -7
- package/dist/index.js.backup +4711 -0
- package/dist/minimal-cli.d.ts +3 -0
- package/dist/minimal-cli.d.ts.map +1 -0
- package/dist/minimal-cli.js +3 -1
- package/dist/policy/PolicyManager.d.ts +104 -0
- package/dist/policy/PolicyManager.d.ts.map +1 -0
- package/dist/scaffold/claude-hooks.js +316 -0
- package/dist/scaffold/cursor-hooks.d.ts +7 -0
- package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
- package/dist/scaffold/git-hooks.d.ts +38 -0
- package/dist/scaffold/git-hooks.d.ts.map +1 -0
- package/dist/scaffold/index.d.ts +15 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +18 -0
- package/dist/spec/SpecFileManager.d.ts +146 -0
- package/dist/spec/SpecFileManager.d.ts.map +1 -0
- package/dist/templates/.claude/README.md +190 -0
- package/dist/templates/.claude/hooks/audit.sh +96 -0
- package/dist/templates/.claude/hooks/block-dangerous.sh +90 -0
- package/dist/templates/.claude/hooks/naming-check.sh +97 -0
- package/dist/templates/.claude/hooks/quality-check.sh +68 -0
- package/dist/templates/.claude/hooks/scan-secrets.sh +85 -0
- package/dist/templates/.claude/hooks/scope-guard.sh +105 -0
- package/dist/templates/.claude/hooks/validate-spec.sh +76 -0
- package/dist/templates/.claude/settings.json +95 -0
- package/dist/test-analysis.d.ts +182 -0
- package/dist/test-analysis.d.ts.map +1 -0
- package/dist/test-analysis.js +203 -10
- package/dist/tool-interface.d.ts +236 -0
- package/dist/tool-interface.d.ts.map +1 -0
- package/dist/tool-loader.d.ts +77 -0
- package/dist/tool-loader.d.ts.map +1 -0
- package/dist/tool-validator.d.ts +72 -0
- package/dist/tool-validator.d.ts.map +1 -0
- package/dist/utils/async-utils.d.ts +73 -0
- package/dist/utils/async-utils.d.ts.map +1 -0
- package/dist/utils/command-wrapper.d.ts +66 -0
- package/dist/utils/command-wrapper.d.ts.map +1 -0
- package/dist/utils/detection.d.ts +14 -0
- package/dist/utils/detection.d.ts.map +1 -0
- package/dist/utils/error-categories.js +210 -0
- package/dist/utils/finalization.d.ts +17 -0
- package/dist/utils/finalization.d.ts.map +1 -0
- package/dist/utils/git-lock.d.ts +13 -0
- package/dist/utils/git-lock.d.ts.map +1 -0
- package/dist/utils/gitignore-updater.d.ts +39 -0
- package/dist/utils/gitignore-updater.d.ts.map +1 -0
- package/dist/utils/project-analysis.d.ts +34 -0
- package/dist/utils/project-analysis.d.ts.map +1 -0
- package/dist/utils/promise-utils.d.ts +30 -0
- package/dist/utils/promise-utils.d.ts.map +1 -0
- package/dist/utils/quality-gates-utils.js +402 -0
- package/dist/utils/quality-gates.d.ts +49 -0
- package/dist/utils/quality-gates.d.ts.map +1 -0
- package/dist/utils/spec-resolver.d.ts +80 -0
- package/dist/utils/spec-resolver.d.ts.map +1 -0
- package/dist/utils/typescript-detector.d.ts +63 -0
- package/dist/utils/typescript-detector.d.ts.map +1 -0
- package/dist/utils/typescript-detector.js +36 -90
- package/dist/utils/yaml-validation.d.ts +32 -0
- package/dist/utils/yaml-validation.d.ts.map +1 -0
- package/dist/validation/spec-validation.d.ts +43 -0
- package/dist/validation/spec-validation.d.ts.map +1 -0
- package/dist/validation/spec-validation.js +59 -6
- package/dist/waivers-manager.d.ts +167 -0
- package/dist/waivers-manager.d.ts.map +1 -0
- package/package.json +5 -3
- package/templates/.claude/README.md +190 -0
- package/templates/.claude/hooks/audit.sh +96 -0
- package/templates/.claude/hooks/block-dangerous.sh +90 -0
- package/templates/.claude/hooks/naming-check.sh +97 -0
- package/templates/.claude/hooks/quality-check.sh +68 -0
- package/templates/.claude/hooks/scan-secrets.sh +85 -0
- package/templates/.claude/hooks/scope-guard.sh +105 -0
- package/templates/.claude/hooks/validate-spec.sh +76 -0
- package/templates/.claude/settings.json +95 -0
package/dist/test-analysis.js
CHANGED
|
@@ -82,12 +82,117 @@ class WaiverPatternLearner {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
|
-
* Load historical working specs
|
|
85
|
+
* Load historical working specs from git history
|
|
86
|
+
* Retrieves past versions of spec files to analyze patterns
|
|
86
87
|
*/
|
|
87
88
|
loadHistoricalSpecs() {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
const { execSync } = require('child_process');
|
|
90
|
+
const specs = [];
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
// Get list of commits that modified spec files
|
|
94
|
+
const specPaths = [
|
|
95
|
+
'.caws/working-spec.yaml',
|
|
96
|
+
'.caws/specs/*.yaml',
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
for (const specPattern of specPaths) {
|
|
100
|
+
try {
|
|
101
|
+
// Get commits that touched spec files
|
|
102
|
+
const logOutput = execSync(
|
|
103
|
+
`git log --pretty=format:"%H" --follow -- "${specPattern}" 2>/dev/null | head -20`,
|
|
104
|
+
{ cwd: this.projectRoot, encoding: 'utf8' }
|
|
105
|
+
).trim();
|
|
106
|
+
|
|
107
|
+
if (!logOutput) continue;
|
|
108
|
+
|
|
109
|
+
const commits = logOutput.split('\n').filter(Boolean);
|
|
110
|
+
|
|
111
|
+
for (const commitHash of commits) {
|
|
112
|
+
try {
|
|
113
|
+
// Get the list of files matching the pattern at that commit
|
|
114
|
+
const filesOutput = execSync(
|
|
115
|
+
`git ls-tree -r --name-only ${commitHash} -- "${specPattern}" 2>/dev/null`,
|
|
116
|
+
{ cwd: this.projectRoot, encoding: 'utf8' }
|
|
117
|
+
).trim();
|
|
118
|
+
|
|
119
|
+
if (!filesOutput) continue;
|
|
120
|
+
|
|
121
|
+
const files = filesOutput.split('\n').filter(Boolean);
|
|
122
|
+
|
|
123
|
+
for (const filePath of files) {
|
|
124
|
+
try {
|
|
125
|
+
// Get the spec content at that commit
|
|
126
|
+
const specContent = execSync(
|
|
127
|
+
`git show ${commitHash}:"${filePath}" 2>/dev/null`,
|
|
128
|
+
{ cwd: this.projectRoot, encoding: 'utf8' }
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
const spec = yaml.load(specContent);
|
|
132
|
+
if (spec && spec.id) {
|
|
133
|
+
// Get commit date for context
|
|
134
|
+
const commitDate = execSync(
|
|
135
|
+
`git show -s --format=%ci ${commitHash}`,
|
|
136
|
+
{ cwd: this.projectRoot, encoding: 'utf8' }
|
|
137
|
+
).trim();
|
|
138
|
+
|
|
139
|
+
specs.push({
|
|
140
|
+
...spec,
|
|
141
|
+
_commit: commitHash.substring(0, 7),
|
|
142
|
+
_date: commitDate,
|
|
143
|
+
_file: filePath,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
// Skip files that can't be loaded
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
} catch {
|
|
151
|
+
// Skip commits with issues
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
} catch {
|
|
155
|
+
// Pattern didn't match any files
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Also check archived specs in .caws/archive/
|
|
160
|
+
const archiveDir = path.join(this.projectRoot, '.caws', 'archive');
|
|
161
|
+
if (fs.existsSync(archiveDir)) {
|
|
162
|
+
const archiveFiles = fs.readdirSync(archiveDir)
|
|
163
|
+
.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
|
|
164
|
+
|
|
165
|
+
for (const file of archiveFiles) {
|
|
166
|
+
try {
|
|
167
|
+
const archivePath = path.join(archiveDir, file);
|
|
168
|
+
const spec = yaml.load(fs.readFileSync(archivePath, 'utf8'));
|
|
169
|
+
if (spec && spec.id) {
|
|
170
|
+
specs.push({
|
|
171
|
+
...spec,
|
|
172
|
+
_source: 'archive',
|
|
173
|
+
_file: file,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
} catch {
|
|
177
|
+
// Skip invalid archive files
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Deduplicate by spec ID, keeping the most recent version
|
|
183
|
+
const uniqueSpecs = new Map();
|
|
184
|
+
for (const spec of specs) {
|
|
185
|
+
const existing = uniqueSpecs.get(spec.id);
|
|
186
|
+
if (!existing || (spec._date && (!existing._date || spec._date > existing._date))) {
|
|
187
|
+
uniqueSpecs.set(spec.id, spec);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return Array.from(uniqueSpecs.values());
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.warn(`Failed to load historical specs: ${error.message}`);
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
91
196
|
}
|
|
92
197
|
|
|
93
198
|
/**
|
|
@@ -186,16 +291,41 @@ class WaiverPatternLearner {
|
|
|
186
291
|
class ProjectSimilarityMatcher {
|
|
187
292
|
constructor(projectRoot = process.cwd()) {
|
|
188
293
|
this.projectRoot = projectRoot;
|
|
294
|
+
this.patternLearner = new WaiverPatternLearner(projectRoot);
|
|
189
295
|
}
|
|
190
296
|
|
|
191
297
|
/**
|
|
192
298
|
* Find projects similar to the current spec
|
|
299
|
+
* Uses real historical specs from git history when available
|
|
193
300
|
*/
|
|
194
301
|
findSimilarProjects(currentSpec) {
|
|
195
|
-
//
|
|
196
|
-
|
|
302
|
+
// Load real historical specs first
|
|
303
|
+
const historicalSpecs = this.patternLearner.loadHistoricalSpecs();
|
|
304
|
+
|
|
305
|
+
// Convert historical specs to project format with budget data
|
|
306
|
+
const historicalProjects = historicalSpecs
|
|
307
|
+
.filter(spec => spec.id !== currentSpec.id) // Exclude current spec
|
|
308
|
+
.map(spec => this.specToProject(spec));
|
|
309
|
+
|
|
310
|
+
// If we have real historical data, use it
|
|
311
|
+
if (historicalProjects.length > 0) {
|
|
312
|
+
return historicalProjects
|
|
313
|
+
.map((project) => ({
|
|
314
|
+
project: project.id,
|
|
315
|
+
similarity_score: this.calculateSimilarity(currentSpec, project),
|
|
316
|
+
budget_accuracy: project.allocated_budget.files > 0
|
|
317
|
+
? project.actual_budget.files / project.allocated_budget.files
|
|
318
|
+
: 1.0,
|
|
319
|
+
waiver_count: project.waivers?.length || 0,
|
|
320
|
+
details: project,
|
|
321
|
+
}))
|
|
322
|
+
.filter((p) => p.similarity_score > 0.3)
|
|
323
|
+
.sort((a, b) => b.similarity_score - a.similarity_score)
|
|
324
|
+
.slice(0, 5);
|
|
325
|
+
}
|
|
197
326
|
|
|
198
|
-
|
|
327
|
+
// Fallback to demo data if no historical specs found
|
|
328
|
+
const demoProjects = [
|
|
199
329
|
{
|
|
200
330
|
id: 'PROJ-0123',
|
|
201
331
|
title: 'API Enhancement',
|
|
@@ -231,9 +361,9 @@ class ProjectSimilarityMatcher {
|
|
|
231
361
|
},
|
|
232
362
|
];
|
|
233
363
|
|
|
234
|
-
// Add a
|
|
364
|
+
// Add a demo project similar to ARCH-0001 for demonstration
|
|
235
365
|
if (currentSpec.id === 'ARCH-0001') {
|
|
236
|
-
|
|
366
|
+
demoProjects.push({
|
|
237
367
|
id: 'ARCH-0002',
|
|
238
368
|
title: 'Policy System Refactor',
|
|
239
369
|
risk_tier: 1,
|
|
@@ -246,7 +376,7 @@ class ProjectSimilarityMatcher {
|
|
|
246
376
|
});
|
|
247
377
|
}
|
|
248
378
|
|
|
249
|
-
return
|
|
379
|
+
return demoProjects
|
|
250
380
|
.map((project) => ({
|
|
251
381
|
project: project.id,
|
|
252
382
|
similarity_score: this.calculateSimilarity(currentSpec, project),
|
|
@@ -259,6 +389,69 @@ class ProjectSimilarityMatcher {
|
|
|
259
389
|
.slice(0, 5); // Top 5 matches
|
|
260
390
|
}
|
|
261
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Convert a spec object to project format for similarity comparison
|
|
394
|
+
*/
|
|
395
|
+
specToProject(spec) {
|
|
396
|
+
// Extract budget info from spec
|
|
397
|
+
const budget = spec.budget || spec.scope?.budget || {};
|
|
398
|
+
const allocatedFiles = budget.max_files || budget.files || 50;
|
|
399
|
+
const allocatedLoc = budget.max_loc || budget.loc || 5000;
|
|
400
|
+
|
|
401
|
+
// If spec has actual metrics, use them; otherwise estimate from allocated
|
|
402
|
+
const actualFiles = spec.metrics?.files_changed || spec.actual_files || allocatedFiles;
|
|
403
|
+
const actualLoc = spec.metrics?.lines_changed || spec.actual_loc || allocatedLoc;
|
|
404
|
+
|
|
405
|
+
// Extract tech stack from spec metadata
|
|
406
|
+
let techStack = spec.tech_stack || spec.metadata?.tech_stack || 'unknown';
|
|
407
|
+
if (!techStack || techStack === 'unknown') {
|
|
408
|
+
// Try to infer from title or description
|
|
409
|
+
const text = `${spec.title || ''} ${spec.description || ''}`.toLowerCase();
|
|
410
|
+
if (text.includes('react') || text.includes('ui') || text.includes('component')) {
|
|
411
|
+
techStack = 'react';
|
|
412
|
+
} else if (text.includes('api') || text.includes('node') || text.includes('server')) {
|
|
413
|
+
techStack = 'node';
|
|
414
|
+
} else if (text.includes('python') || text.includes('django') || text.includes('flask')) {
|
|
415
|
+
techStack = 'python';
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Extract feature type
|
|
420
|
+
let featureType = spec.feature_type || spec.type || 'general';
|
|
421
|
+
if (featureType === 'general') {
|
|
422
|
+
const text = `${spec.title || ''} ${spec.description || ''}`.toLowerCase();
|
|
423
|
+
if (text.includes('api') || text.includes('endpoint')) {
|
|
424
|
+
featureType = 'api';
|
|
425
|
+
} else if (text.includes('ui') || text.includes('component') || text.includes('view')) {
|
|
426
|
+
featureType = 'ui';
|
|
427
|
+
} else if (text.includes('data') || text.includes('migration') || text.includes('database')) {
|
|
428
|
+
featureType = 'data';
|
|
429
|
+
} else if (text.includes('refactor') || text.includes('architecture')) {
|
|
430
|
+
featureType = 'architecture';
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return {
|
|
435
|
+
id: spec.id,
|
|
436
|
+
title: spec.title || spec.name || spec.id,
|
|
437
|
+
risk_tier: spec.risk_tier || spec.tier || 2,
|
|
438
|
+
mode: spec.mode || 'feature',
|
|
439
|
+
tech_stack: techStack,
|
|
440
|
+
feature_type: featureType,
|
|
441
|
+
actual_budget: {
|
|
442
|
+
files: actualFiles,
|
|
443
|
+
loc: actualLoc,
|
|
444
|
+
},
|
|
445
|
+
allocated_budget: {
|
|
446
|
+
files: allocatedFiles,
|
|
447
|
+
loc: allocatedLoc,
|
|
448
|
+
},
|
|
449
|
+
waivers: spec.waivers || [],
|
|
450
|
+
_source: spec._source,
|
|
451
|
+
_date: spec._date,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
262
455
|
/**
|
|
263
456
|
* Calculate similarity score between two specs/projects
|
|
264
457
|
*/
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standard tool execution result
|
|
4
|
+
*/
|
|
5
|
+
export type ToolExecutionResult = {
|
|
6
|
+
/**
|
|
7
|
+
* - Whether execution succeeded
|
|
8
|
+
*/
|
|
9
|
+
success: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* - Execution duration in milliseconds
|
|
12
|
+
*/
|
|
13
|
+
duration: number;
|
|
14
|
+
/**
|
|
15
|
+
* - Tool-specific output data
|
|
16
|
+
*/
|
|
17
|
+
output: any;
|
|
18
|
+
/**
|
|
19
|
+
* - Error messages if execution failed
|
|
20
|
+
*/
|
|
21
|
+
errors: Array<string>;
|
|
22
|
+
/**
|
|
23
|
+
* - Additional execution metadata
|
|
24
|
+
*/
|
|
25
|
+
metadata: any;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Tool metadata structure
|
|
29
|
+
*/
|
|
30
|
+
export type ToolMetadata = {
|
|
31
|
+
/**
|
|
32
|
+
* - Unique tool identifier
|
|
33
|
+
*/
|
|
34
|
+
id: string;
|
|
35
|
+
/**
|
|
36
|
+
* - Human-readable tool name
|
|
37
|
+
*/
|
|
38
|
+
name: string;
|
|
39
|
+
/**
|
|
40
|
+
* - Tool version (semver)
|
|
41
|
+
*/
|
|
42
|
+
version: string;
|
|
43
|
+
/**
|
|
44
|
+
* - Tool description
|
|
45
|
+
*/
|
|
46
|
+
description: string;
|
|
47
|
+
/**
|
|
48
|
+
* - Tool capabilities (e.g., ['validation', 'security'])
|
|
49
|
+
*/
|
|
50
|
+
capabilities: Array<string>;
|
|
51
|
+
/**
|
|
52
|
+
* - Tool author
|
|
53
|
+
*/
|
|
54
|
+
author: string;
|
|
55
|
+
/**
|
|
56
|
+
* - Tool license
|
|
57
|
+
*/
|
|
58
|
+
license: string;
|
|
59
|
+
/**
|
|
60
|
+
* - Required Node.js dependencies
|
|
61
|
+
*/
|
|
62
|
+
dependencies: Array<string>;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Tool execution context
|
|
66
|
+
*/
|
|
67
|
+
export type ToolExecutionContext = {
|
|
68
|
+
/**
|
|
69
|
+
* - Current working directory
|
|
70
|
+
*/
|
|
71
|
+
workingDirectory: string;
|
|
72
|
+
/**
|
|
73
|
+
* - Environment variables
|
|
74
|
+
*/
|
|
75
|
+
environment: any;
|
|
76
|
+
/**
|
|
77
|
+
* - CAWS configuration
|
|
78
|
+
*/
|
|
79
|
+
config: any;
|
|
80
|
+
/**
|
|
81
|
+
* - Current working specification
|
|
82
|
+
*/
|
|
83
|
+
workingSpec: any;
|
|
84
|
+
/**
|
|
85
|
+
* - Execution timeout in milliseconds
|
|
86
|
+
*/
|
|
87
|
+
timeout: number;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* @fileoverview CAWS Tool Interface - Base classes and contracts for tool implementation
|
|
91
|
+
* Defines the standard interface that all CAWS tools must implement
|
|
92
|
+
* @author @darianrosebrook
|
|
93
|
+
*/
|
|
94
|
+
/**
|
|
95
|
+
* Standard tool execution result
|
|
96
|
+
* @typedef {Object} ToolExecutionResult
|
|
97
|
+
* @property {boolean} success - Whether execution succeeded
|
|
98
|
+
* @property {number} duration - Execution duration in milliseconds
|
|
99
|
+
* @property {Object} output - Tool-specific output data
|
|
100
|
+
* @property {Array<string>} errors - Error messages if execution failed
|
|
101
|
+
* @property {Object} metadata - Additional execution metadata
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
104
|
+
* Tool metadata structure
|
|
105
|
+
* @typedef {Object} ToolMetadata
|
|
106
|
+
* @property {string} id - Unique tool identifier
|
|
107
|
+
* @property {string} name - Human-readable tool name
|
|
108
|
+
* @property {string} version - Tool version (semver)
|
|
109
|
+
* @property {string} description - Tool description
|
|
110
|
+
* @property {Array<string>} capabilities - Tool capabilities (e.g., ['validation', 'security'])
|
|
111
|
+
* @property {string} author - Tool author
|
|
112
|
+
* @property {string} license - Tool license
|
|
113
|
+
* @property {Array<string>} dependencies - Required Node.js dependencies
|
|
114
|
+
*/
|
|
115
|
+
/**
|
|
116
|
+
* Tool execution context
|
|
117
|
+
* @typedef {Object} ToolExecutionContext
|
|
118
|
+
* @property {string} workingDirectory - Current working directory
|
|
119
|
+
* @property {Object} environment - Environment variables
|
|
120
|
+
* @property {Object} config - CAWS configuration
|
|
121
|
+
* @property {Object} workingSpec - Current working specification
|
|
122
|
+
* @property {number} timeout - Execution timeout in milliseconds
|
|
123
|
+
*/
|
|
124
|
+
/**
|
|
125
|
+
* Base Tool class - All CAWS tools should extend this class
|
|
126
|
+
*/
|
|
127
|
+
export class BaseTool {
|
|
128
|
+
metadata: ToolMetadata;
|
|
129
|
+
/**
|
|
130
|
+
* Execute the tool with given parameters
|
|
131
|
+
* @param {Object} parameters - Tool-specific execution parameters
|
|
132
|
+
* @param {ToolExecutionContext} context - Execution context
|
|
133
|
+
* @returns {Promise<ToolExecutionResult>} Execution result
|
|
134
|
+
*/
|
|
135
|
+
execute(parameters?: any, context?: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
136
|
+
/**
|
|
137
|
+
* Get tool metadata
|
|
138
|
+
* @returns {ToolMetadata} Tool metadata
|
|
139
|
+
*/
|
|
140
|
+
getMetadata(): ToolMetadata;
|
|
141
|
+
/**
|
|
142
|
+
* Validate tool parameters
|
|
143
|
+
* @param {Object} _parameters - Parameters to validate
|
|
144
|
+
* @throws {Error} If parameters are invalid
|
|
145
|
+
*/
|
|
146
|
+
validateParameters(_parameters: any): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Execute tool implementation (must be overridden by subclasses)
|
|
149
|
+
* @param {Object} _parameters - Tool parameters
|
|
150
|
+
* @param {ToolExecutionContext} _context - Execution context
|
|
151
|
+
* @returns {Promise<Object>} Tool-specific result
|
|
152
|
+
*/
|
|
153
|
+
executeImpl(_parameters: any, _context: ToolExecutionContext): Promise<any>;
|
|
154
|
+
/**
|
|
155
|
+
* Normalize execution result to standard format
|
|
156
|
+
* @private
|
|
157
|
+
* @param {Object} result - Raw tool result
|
|
158
|
+
* @param {number} duration - Execution duration
|
|
159
|
+
* @returns {ToolExecutionResult} Normalized result
|
|
160
|
+
*/
|
|
161
|
+
private normalizeResult;
|
|
162
|
+
/**
|
|
163
|
+
* Create error result
|
|
164
|
+
* @private
|
|
165
|
+
* @param {Error} error - Execution error
|
|
166
|
+
* @param {number} duration - Execution duration
|
|
167
|
+
* @returns {ToolExecutionResult} Error result
|
|
168
|
+
*/
|
|
169
|
+
private createErrorResult;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validation Tool base class - For tools that perform validation checks
|
|
173
|
+
*/
|
|
174
|
+
export class ValidationTool extends BaseTool {
|
|
175
|
+
capabilities: string[];
|
|
176
|
+
/**
|
|
177
|
+
* Execute validation
|
|
178
|
+
* @param {Object} parameters - Validation parameters
|
|
179
|
+
* @param {ToolExecutionContext} context - Execution context
|
|
180
|
+
* @returns {Promise<ToolExecutionResult>} Validation result
|
|
181
|
+
*/
|
|
182
|
+
executeImpl(parameters: any, context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
183
|
+
/**
|
|
184
|
+
* Perform validation (must be implemented by subclasses)
|
|
185
|
+
* @param {Object} parameters - Validation parameters
|
|
186
|
+
* @param {ToolExecutionContext} context - Execution context
|
|
187
|
+
* @returns {Promise<Object>} Validation result
|
|
188
|
+
*/
|
|
189
|
+
validate(_parameters: any, _context: any): Promise<any>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Quality Gate Tool base class - For tools that enforce quality standards
|
|
193
|
+
*/
|
|
194
|
+
export class QualityGateTool extends ValidationTool {
|
|
195
|
+
/**
|
|
196
|
+
* Get quality gate thresholds for current tier
|
|
197
|
+
* @param {number} tier - Risk tier (1-3)
|
|
198
|
+
* @returns {Object} Threshold configuration
|
|
199
|
+
*/
|
|
200
|
+
getTierThresholds(tier: number): any;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Security Tool base class - For tools that perform security checks
|
|
204
|
+
*/
|
|
205
|
+
export class SecurityTool extends ValidationTool {
|
|
206
|
+
/**
|
|
207
|
+
* Check for security violations
|
|
208
|
+
* @param {Object} target - Target to check (file, code, etc.)
|
|
209
|
+
* @returns {Promise<Array<Object>>} Array of security violations
|
|
210
|
+
*/
|
|
211
|
+
checkSecurityViolations(target: any): Promise<Array<any>>;
|
|
212
|
+
}
|
|
213
|
+
export namespace ToolUtils {
|
|
214
|
+
/**
|
|
215
|
+
* Create standardized success result
|
|
216
|
+
* @param {Object} output - Tool output
|
|
217
|
+
* @param {Object} metadata - Additional metadata
|
|
218
|
+
* @returns {ToolExecutionResult} Success result
|
|
219
|
+
*/
|
|
220
|
+
function createSuccessResult(output?: any, metadata?: any): ToolExecutionResult;
|
|
221
|
+
/**
|
|
222
|
+
* Create standardized error result
|
|
223
|
+
* @param {string} message - Error message
|
|
224
|
+
* @param {string} errorType - Error type
|
|
225
|
+
* @returns {ToolExecutionResult} Error result
|
|
226
|
+
*/
|
|
227
|
+
function createErrorResult(message: string, errorType?: string): ToolExecutionResult;
|
|
228
|
+
/**
|
|
229
|
+
* Validate required parameters
|
|
230
|
+
* @param {Object} _params - Parameters object
|
|
231
|
+
* @param {Array<string>} _required - Required parameter names
|
|
232
|
+
* @throws {Error} If required parameters are missing
|
|
233
|
+
*/
|
|
234
|
+
function validateRequired(_params: any, _required: Array<string>): void;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=tool-interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-interface.d.ts","sourceRoot":"","sources":["../src/tool-interface.js"],"names":[],"mappings":";;;;;;;;aAWc,OAAO;;;;cACP,MAAM;;;;;;;;YAEN,KAAK,CAAC,MAAM,CAAC;;;;;;;;;;;;;QAOb,MAAM;;;;UACN,MAAM;;;;aACN,MAAM;;;;iBACN,MAAM;;;;kBACN,KAAK,CAAC,MAAM,CAAC;;;;YACb,MAAM;;;;aACN,MAAM;;;;kBACN,KAAK,CAAC,MAAM,CAAC;;;;;;;;;sBAMb,MAAM;;;;;;;;;;;;;;;;aAIN,MAAM;;AApCpB;;;;GAIG;AAEH;;;;;;;;GAQG;AAEH;;;;;;;;;;;GAWG;AAEH;;;;;;;;GAQG;AAEH;;GAEG;AACH;IAEI,uBAAkC;IAGpC;;;;;OAKG;IACH,oCAHW,oBAAoB,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAmBxC;IAED;;;OAGG;IACH,eAFa,YAAY,CAIxB;IAED;;;;OAIG;IACH,8CAGC;IAED;;;;;OAKG;IACH,wCAHW,oBAAoB,GAClB,OAAO,KAAQ,CAI3B;IAED;;;;;;OAMG;IACH,wBAQC;IAED;;;;;;OAMG;IACH,0BAWC;CACF;AAED;;GAEG;AACH;IAGI,uBAAkC;IAGpC;;;;;OAKG;IACH,sCAHW,oBAAoB,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAcxC;IAED;;;;;OAKG;IACH,2CAFa,OAAO,KAAQ,CAI3B;CACF;AAED;;GAEG;AACH;IAME;;;;OAIG;IACH,wBAHW,MAAM,OA6BhB;CACF;AAED;;GAEG;AACH;IAME;;;;OAIG;IACH,sCAFa,OAAO,CAAC,KAAK,KAAQ,CAAC,CAmBlC;CACF;;IAMC;;;;;OAKG;IACH,4DAFa,mBAAmB,CAU/B;IAED;;;;;OAKG;IACH,oCAJW,MAAM,cACN,MAAM,GACJ,mBAAmB,CAU/B;IAED;;;;;OAKG;IACH,mDAHW,KAAK,CAAC,MAAM,CAAC,QAQvB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export = ToolLoader;
|
|
3
|
+
/**
|
|
4
|
+
* Tool Loader - Discovers, validates, and loads CAWS tools dynamically
|
|
5
|
+
* @extends EventEmitter
|
|
6
|
+
*/
|
|
7
|
+
declare class ToolLoader extends EventEmitter<[never]> {
|
|
8
|
+
constructor(options?: {});
|
|
9
|
+
options: {
|
|
10
|
+
toolsDir: any;
|
|
11
|
+
cacheEnabled: boolean;
|
|
12
|
+
timeout: any;
|
|
13
|
+
maxTools: any;
|
|
14
|
+
};
|
|
15
|
+
loadedTools: Map<any, any>;
|
|
16
|
+
discoveredTools: Set<any>;
|
|
17
|
+
loadingState: string;
|
|
18
|
+
/**
|
|
19
|
+
* Discover available tools in the tools directory
|
|
20
|
+
* @returns {Promise<Array<string>>} Array of tool file paths
|
|
21
|
+
*/
|
|
22
|
+
discoverTools(): Promise<Array<string>>;
|
|
23
|
+
/**
|
|
24
|
+
* Load a specific tool module
|
|
25
|
+
* @param {string} toolPath - Path to tool file
|
|
26
|
+
* @returns {Promise<Object>} Loaded tool module
|
|
27
|
+
*/
|
|
28
|
+
loadTool(toolPath: string): Promise<any>;
|
|
29
|
+
/**
|
|
30
|
+
* Load all discovered tools
|
|
31
|
+
* @returns {Promise<Map<string, Object>>} Map of loaded tools
|
|
32
|
+
*/
|
|
33
|
+
loadAllTools(): Promise<Map<string, any>>;
|
|
34
|
+
/**
|
|
35
|
+
* Get a loaded tool by ID
|
|
36
|
+
* @param {string} toolId - Tool identifier
|
|
37
|
+
* @returns {Object|null} Tool object or null if not found
|
|
38
|
+
*/
|
|
39
|
+
getTool(toolId: string): any | null;
|
|
40
|
+
/**
|
|
41
|
+
* Get all loaded tools
|
|
42
|
+
* @returns {Map<string, Object>} Map of loaded tools
|
|
43
|
+
*/
|
|
44
|
+
getAllTools(): Map<string, any>;
|
|
45
|
+
/**
|
|
46
|
+
* Unload a tool (remove from cache)
|
|
47
|
+
* @param {string} toolId - Tool identifier
|
|
48
|
+
* @returns {boolean} True if tool was unloaded
|
|
49
|
+
*/
|
|
50
|
+
unloadTool(toolId: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Validate tool file before loading
|
|
53
|
+
* @private
|
|
54
|
+
* @param {string} toolPath - Path to tool file
|
|
55
|
+
*/
|
|
56
|
+
private validateToolFile;
|
|
57
|
+
/**
|
|
58
|
+
* Load module with timeout protection
|
|
59
|
+
* @private
|
|
60
|
+
* @param {string} toolPath - Path to tool file
|
|
61
|
+
*/
|
|
62
|
+
private loadModuleWithTimeout;
|
|
63
|
+
/**
|
|
64
|
+
* Validate tool interface compliance
|
|
65
|
+
* @private
|
|
66
|
+
* @param {Object} toolModule - Loaded tool module
|
|
67
|
+
* @param {string} toolId - Tool identifier
|
|
68
|
+
*/
|
|
69
|
+
private validateToolInterface;
|
|
70
|
+
/**
|
|
71
|
+
* Get loader statistics
|
|
72
|
+
* @returns {Object} Statistics object
|
|
73
|
+
*/
|
|
74
|
+
getStats(): any;
|
|
75
|
+
}
|
|
76
|
+
import { EventEmitter } from "events";
|
|
77
|
+
//# sourceMappingURL=tool-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-loader.d.ts","sourceRoot":"","sources":["../src/tool-loader.js"],"names":[],"mappings":";;AAcA;;;GAGG;AACH;IACE,0BAkBC;IAXC;;;;;MAMC;IAED,2BAA4B;IAC5B,0BAAgC;IAChC,qBAA0B;IAG5B;;;OAGG;IACH,iBAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAkDlC;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,KAAQ,CAmC3B;IAED;;;OAGG;IACH,gBAFa,OAAO,CAAC,GAAG,CAAC,MAAM,MAAS,CAAC,CAuBxC;IAED;;;;OAIG;IACH,gBAHW,MAAM,GACJ,MAAO,IAAI,CAIvB;IAED;;;OAGG;IACH,eAFa,GAAG,CAAC,MAAM,MAAS,CAI/B;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,CAQnB;IAED;;;;OAIG;IACH,yBAgCC;IAED;;;;OAIG;IACH,8BAkBC;IAED;;;;;OAKG;IACH,8BAyBC;IAED;;;OAGG;IACH,gBAQC;CACF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export = ToolValidator;
|
|
3
|
+
/**
|
|
4
|
+
* Tool Validator - Security validation and allowlist enforcement
|
|
5
|
+
*/
|
|
6
|
+
declare class ToolValidator {
|
|
7
|
+
constructor(options?: {});
|
|
8
|
+
options: {
|
|
9
|
+
allowlistPath: any;
|
|
10
|
+
strictMode: boolean;
|
|
11
|
+
maxFileSize: any;
|
|
12
|
+
};
|
|
13
|
+
allowlist: any;
|
|
14
|
+
validationCache: Map<any, any>;
|
|
15
|
+
/**
|
|
16
|
+
* Load and parse the tools allowlist
|
|
17
|
+
* @returns {Promise<Array<string>>} Array of allowed commands/patterns
|
|
18
|
+
*/
|
|
19
|
+
loadAllowlist(): Promise<Array<string>>;
|
|
20
|
+
/**
|
|
21
|
+
* Validate a tool against security requirements
|
|
22
|
+
* @param {Object} tool - Tool object with module and metadata
|
|
23
|
+
* @returns {Promise<Object>} Validation result
|
|
24
|
+
*/
|
|
25
|
+
validateTool(tool: any): Promise<any>;
|
|
26
|
+
/**
|
|
27
|
+
* Check file-level security
|
|
28
|
+
* @private
|
|
29
|
+
* @param {Object} tool - Tool object
|
|
30
|
+
*/
|
|
31
|
+
private checkFileSecurity;
|
|
32
|
+
/**
|
|
33
|
+
* Check code-level security
|
|
34
|
+
* @private
|
|
35
|
+
* @param {Object} tool - Tool object
|
|
36
|
+
*/
|
|
37
|
+
private checkCodeSecurity;
|
|
38
|
+
/**
|
|
39
|
+
* Check interface compliance
|
|
40
|
+
* @private
|
|
41
|
+
* @param {Object} tool - Tool object
|
|
42
|
+
*/
|
|
43
|
+
private checkInterfaceCompliance;
|
|
44
|
+
/**
|
|
45
|
+
* Check metadata validity
|
|
46
|
+
* @private
|
|
47
|
+
* @param {Object} tool - Tool object
|
|
48
|
+
*/
|
|
49
|
+
private checkMetadataValidity;
|
|
50
|
+
/**
|
|
51
|
+
* Check dependency safety
|
|
52
|
+
* @private
|
|
53
|
+
* @param {Object} tool - Tool object
|
|
54
|
+
*/
|
|
55
|
+
private checkDependencySafety;
|
|
56
|
+
/**
|
|
57
|
+
* Validate a command against the allowlist
|
|
58
|
+
* @param {string} command - Command to validate
|
|
59
|
+
* @returns {boolean} True if command is allowed
|
|
60
|
+
*/
|
|
61
|
+
validateCommand(command: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Clear validation cache
|
|
64
|
+
*/
|
|
65
|
+
clearCache(): void;
|
|
66
|
+
/**
|
|
67
|
+
* Get validator statistics
|
|
68
|
+
* @returns {Object} Statistics object
|
|
69
|
+
*/
|
|
70
|
+
getStats(): any;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=tool-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-validator.d.ts","sourceRoot":"","sources":["../src/tool-validator.js"],"names":[],"mappings":";;AAYA;;GAEG;AACH;IACE,0BAiBC;IATC;;;;MAKC;IAED,eAAqB;IACrB,+BAAgC;IAGlC;;;OAGG;IACH,iBAFa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAqBlC;IAED;;;;OAIG;IACH,yBAFa,OAAO,KAAQ,CAsF3B;IAED;;;;OAIG;IACH,0BAgCC;IAED;;;;OAIG;IACH,0BA8CC;IAED;;;;OAIG;IACH,iCAkBC;IAED;;;;OAIG;IACH,8BAqCC;IAED;;;;OAIG;IACH,8BA4BC;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAmBnB;IAED;;OAEG;IACH,mBAEC;IAED;;;OAGG;IACH,gBAOC;CACF"}
|