@paths.design/caws-cli 5.0.0 ā 5.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/README.md +15 -12
- 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 +50 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/burnup.d.ts +6 -0
- package/dist/commands/burnup.d.ts.map +1 -0
- package/dist/commands/diagnose.d.ts +52 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- 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/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 +27 -22
- 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 +190 -455
- 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 +34 -35
- package/dist/commands/status.d.ts +44 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +10 -7
- package/dist/commands/templates.d.ts +74 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/tool.d.ts +13 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/tool.js +63 -63
- 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/waivers.js +38 -39
- 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/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 +1 -0
- 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/policy/PolicyManager.d.ts +104 -0
- package/dist/policy/PolicyManager.d.ts.map +1 -0
- package/dist/policy/PolicyManager.js +60 -28
- 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 +20 -0
- package/dist/scaffold/git-hooks.d.ts.map +1 -0
- package/dist/scaffold/git-hooks.js +89 -27
- package/dist/scaffold/index.d.ts +20 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +25 -0
- package/dist/spec/SpecFileManager.d.ts +146 -0
- package/dist/spec/SpecFileManager.d.ts.map +1 -0
- package/dist/test-analysis.d.ts +182 -0
- package/dist/test-analysis.d.ts.map +1 -0
- 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.js +188 -0
- package/dist/utils/command-wrapper.js +200 -0
- package/dist/utils/detection.d.ts +7 -0
- package/dist/utils/detection.d.ts.map +1 -0
- package/dist/utils/finalization.d.ts +17 -0
- package/dist/utils/finalization.d.ts.map +1 -0
- package/dist/utils/project-analysis.d.ts +14 -0
- package/dist/utils/project-analysis.d.ts.map +1 -0
- package/dist/utils/promise-utils.js +72 -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 +88 -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/validation/spec-validation.d.ts +43 -0
- package/dist/validation/spec-validation.d.ts.map +1 -0
- package/dist/waivers-manager.d.ts +167 -0
- package/dist/waivers-manager.d.ts.map +1 -0
- package/package.json +1 -1
- package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
- package/templates/apps/tools/caws/provenance.js.backup +73 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect if project is using TypeScript
|
|
3
|
+
* @param {string} projectDir - Project directory path
|
|
4
|
+
* @returns {Object} TypeScript detection result
|
|
5
|
+
*/
|
|
6
|
+
export function detectTypeScript(projectDir?: string): any;
|
|
7
|
+
/**
|
|
8
|
+
* Detect testing framework in use
|
|
9
|
+
* @param {string} projectDir - Project directory path
|
|
10
|
+
* @param {Object} packageJson - Parsed package.json (optional)
|
|
11
|
+
* @returns {Object} Testing framework detection result
|
|
12
|
+
*/
|
|
13
|
+
export function detectTestFramework(projectDir?: string, packageJson?: any): any;
|
|
14
|
+
export function getWorkspaceDirectories(projectDir?: string): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Get workspace directories from package.json
|
|
17
|
+
* @param {string} projectDir - Project directory path
|
|
18
|
+
* @returns {string[]} Array of workspace directories
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Get workspace directories from npm/yarn package.json workspaces
|
|
22
|
+
* @param {string} projectDir - Project directory path
|
|
23
|
+
* @returns {string[]} Array of workspace directories
|
|
24
|
+
*/
|
|
25
|
+
export function getNpmWorkspaces(projectDir: string): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Get workspace directories from pnpm-workspace.yaml
|
|
28
|
+
* @param {string} projectDir - Project directory path
|
|
29
|
+
* @returns {string[]} Array of workspace directories
|
|
30
|
+
*/
|
|
31
|
+
export function getPnpmWorkspaces(projectDir: string): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Get workspace directories from lerna.json
|
|
34
|
+
* @param {string} projectDir - Project directory path
|
|
35
|
+
* @returns {string[]} Array of workspace directories
|
|
36
|
+
*/
|
|
37
|
+
export function getLernaWorkspaces(projectDir: string): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Check if a dependency exists in hoisted node_modules
|
|
40
|
+
* @param {string} depName - Dependency name to check
|
|
41
|
+
* @param {string} projectDir - Project directory path
|
|
42
|
+
* @returns {boolean} True if dependency found in hoisted node_modules
|
|
43
|
+
*/
|
|
44
|
+
export function checkHoistedDependency(depName: string, projectDir: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if TypeScript project needs test configuration
|
|
47
|
+
* @param {string} projectDir - Project directory path
|
|
48
|
+
* @returns {Object} Configuration status
|
|
49
|
+
*/
|
|
50
|
+
export function checkTypeScriptTestConfig(projectDir?: string): any;
|
|
51
|
+
/**
|
|
52
|
+
* Generate configuration recommendations
|
|
53
|
+
* @param {Object} tsDetection - TypeScript detection result
|
|
54
|
+
* @param {Object} testDetection - Test framework detection result
|
|
55
|
+
* @returns {string[]} Array of recommendations
|
|
56
|
+
*/
|
|
57
|
+
export function generateRecommendations(tsDetection: any, testDetection: any): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Display TypeScript detection results
|
|
60
|
+
* @param {Object} detection - Detection result from checkTypeScriptTestConfig
|
|
61
|
+
*/
|
|
62
|
+
export function displayTypeScriptDetection(detection: any): void;
|
|
63
|
+
//# sourceMappingURL=typescript-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript-detector.d.ts","sourceRoot":"","sources":["../../src/utils/typescript-detector.js"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,8CAHW,MAAM,OAkChB;AAED;;;;;GAKG;AACH,iDAJW,MAAM,0BAkDhB;AAuKD,uEASC;AA9KD;;;;GAIG;AACH;;;;GAIG;AACH,6CAHW,MAAM,GACJ,MAAM,EAAE,CA6CpB;AAED;;;;GAIG;AACH,8CAHW,MAAM,GACJ,MAAM,EAAE,CA6CpB;AAED;;;;GAIG;AACH,+CAHW,MAAM,GACJ,MAAM,EAAE,CA4CpB;AAED;;;;;GAKG;AACH,gDAJW,MAAM,cACN,MAAM,GACJ,OAAO,CAKnB;AAaD;;;;GAIG;AACH,uDAHW,MAAM,OA0EhB;AAED;;;;;GAKG;AACH,+EAFa,MAAM,EAAE,CAuBpB;AAED;;;GAGG;AACH,iEAoBC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic validation of working spec
|
|
3
|
+
* @param {Object} spec - Working spec object
|
|
4
|
+
* @param {Object} options - Validation options
|
|
5
|
+
* @returns {Object} Validation result
|
|
6
|
+
*/
|
|
7
|
+
export function validateWorkingSpec(spec: any, _options?: {}): any;
|
|
8
|
+
/**
|
|
9
|
+
* Enhanced validation with suggestions and auto-fix
|
|
10
|
+
* @param {Object} spec - Working spec object
|
|
11
|
+
* @param {Object} options - Validation options
|
|
12
|
+
* @returns {Object} Enhanced validation result
|
|
13
|
+
*/
|
|
14
|
+
export function validateWorkingSpecWithSuggestions(spec: any, options?: any): any;
|
|
15
|
+
/**
|
|
16
|
+
* Get suggestion for a missing field
|
|
17
|
+
* @param {string} field - Field name
|
|
18
|
+
* @param {Object} _spec - Spec object (for context)
|
|
19
|
+
* @returns {string} Suggestion text
|
|
20
|
+
*/
|
|
21
|
+
export function getFieldSuggestion(field: string, _spec: any): string;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a field can be auto-fixed
|
|
24
|
+
* @param {string} field - Field name
|
|
25
|
+
* @param {Object} _spec - Spec object (for context)
|
|
26
|
+
* @returns {boolean} Whether field can be auto-fixed
|
|
27
|
+
*/
|
|
28
|
+
export function canAutoFixField(field: string, _spec: any): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Calculate compliance score based on errors and warnings
|
|
31
|
+
* Score ranges from 0 (many issues) to 1 (perfect)
|
|
32
|
+
* @param {Array} errors - Validation errors
|
|
33
|
+
* @param {Array} warnings - Validation warnings
|
|
34
|
+
* @returns {number} Compliance score (0-1)
|
|
35
|
+
*/
|
|
36
|
+
export function calculateComplianceScore(errors: any[], warnings: any[]): number;
|
|
37
|
+
/**
|
|
38
|
+
* Get compliance grade from score
|
|
39
|
+
* @param {number} score - Compliance score (0-1)
|
|
40
|
+
* @returns {string} Grade (A, B, C, D, F)
|
|
41
|
+
*/
|
|
42
|
+
export function getComplianceGrade(score: number): string;
|
|
43
|
+
//# sourceMappingURL=spec-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-validation.d.ts","sourceRoot":"","sources":["../../src/validation/spec-validation.js"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,mEA8HC;AAED;;;;;GAKG;AACH,kFAyWC;AAoCD;;;;;GAKG;AACH,0CAJW,MAAM,eAEJ,MAAM,CAkBlB;AAED;;;;;GAKG;AACH,uCAJW,MAAM,eAEJ,OAAO,CAKnB;AAnED;;;;;;GAMG;AACH,0EAFa,MAAM,CAclB;AAED;;;;GAIG;AACH,0CAHW,MAAM,GACJ,MAAM,CAQlB"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export = WaiversManager;
|
|
2
|
+
/**
|
|
3
|
+
* Waiver Manager Class
|
|
4
|
+
* Handles waiver creation, validation, expiration, and audit logging
|
|
5
|
+
*/
|
|
6
|
+
declare class WaiversManager {
|
|
7
|
+
constructor(options?: {});
|
|
8
|
+
projectRoot: any;
|
|
9
|
+
waiversDir: string;
|
|
10
|
+
waiversFile: string;
|
|
11
|
+
auditLogFile: string;
|
|
12
|
+
/**
|
|
13
|
+
* Waiver Schema Definition
|
|
14
|
+
*/
|
|
15
|
+
getWaiverSchema(): {
|
|
16
|
+
type: string;
|
|
17
|
+
required: string[];
|
|
18
|
+
properties: {
|
|
19
|
+
id: {
|
|
20
|
+
type: string;
|
|
21
|
+
pattern: string;
|
|
22
|
+
description: string;
|
|
23
|
+
};
|
|
24
|
+
title: {
|
|
25
|
+
type: string;
|
|
26
|
+
minLength: number;
|
|
27
|
+
maxLength: number;
|
|
28
|
+
description: string;
|
|
29
|
+
};
|
|
30
|
+
reason: {
|
|
31
|
+
type: string;
|
|
32
|
+
enum: string[];
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
description: {
|
|
36
|
+
type: string;
|
|
37
|
+
minLength: number;
|
|
38
|
+
maxLength: number;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
gates: {
|
|
42
|
+
type: string;
|
|
43
|
+
items: {
|
|
44
|
+
type: string;
|
|
45
|
+
enum: string[];
|
|
46
|
+
};
|
|
47
|
+
minItems: number;
|
|
48
|
+
description: string;
|
|
49
|
+
};
|
|
50
|
+
risk_assessment: {
|
|
51
|
+
type: string;
|
|
52
|
+
properties: {
|
|
53
|
+
impact_level: {
|
|
54
|
+
type: string;
|
|
55
|
+
enum: string[];
|
|
56
|
+
};
|
|
57
|
+
mitigation_plan: {
|
|
58
|
+
type: string;
|
|
59
|
+
minLength: number;
|
|
60
|
+
};
|
|
61
|
+
review_required: {
|
|
62
|
+
type: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
required: string[];
|
|
66
|
+
};
|
|
67
|
+
expires_at: {
|
|
68
|
+
type: string;
|
|
69
|
+
format: string;
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
72
|
+
approved_by: {
|
|
73
|
+
type: string;
|
|
74
|
+
description: string;
|
|
75
|
+
};
|
|
76
|
+
created_at: {
|
|
77
|
+
type: string;
|
|
78
|
+
format: string;
|
|
79
|
+
description: string;
|
|
80
|
+
};
|
|
81
|
+
metadata: {
|
|
82
|
+
type: string;
|
|
83
|
+
properties: {
|
|
84
|
+
related_pr: {
|
|
85
|
+
type: string;
|
|
86
|
+
};
|
|
87
|
+
related_issue: {
|
|
88
|
+
type: string;
|
|
89
|
+
};
|
|
90
|
+
environment: {
|
|
91
|
+
type: string;
|
|
92
|
+
enum: string[];
|
|
93
|
+
};
|
|
94
|
+
urgency: {
|
|
95
|
+
type: string;
|
|
96
|
+
enum: string[];
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Create a new waiver
|
|
104
|
+
*/
|
|
105
|
+
createWaiver(waiverData: any): Promise<{
|
|
106
|
+
id: string;
|
|
107
|
+
title: any;
|
|
108
|
+
reason: any;
|
|
109
|
+
description: any;
|
|
110
|
+
gates: any;
|
|
111
|
+
risk_assessment: any;
|
|
112
|
+
expires_at: any;
|
|
113
|
+
approved_by: any;
|
|
114
|
+
created_at: string;
|
|
115
|
+
metadata: any;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Check if waiver applies to specific gates
|
|
119
|
+
*/
|
|
120
|
+
checkWaiverCoverage(gatesToCheck: any, context?: {}): Promise<{
|
|
121
|
+
coveredGates: any[];
|
|
122
|
+
waiverDetails: {
|
|
123
|
+
gate: any;
|
|
124
|
+
waiver_id: any;
|
|
125
|
+
reason: any;
|
|
126
|
+
expires_at: any;
|
|
127
|
+
approved_by: any;
|
|
128
|
+
}[];
|
|
129
|
+
allCovered: boolean;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Get all active waivers
|
|
133
|
+
*/
|
|
134
|
+
getActiveWaivers(): Promise<any[]>;
|
|
135
|
+
/**
|
|
136
|
+
* Revoke a waiver
|
|
137
|
+
*/
|
|
138
|
+
revokeWaiver(waiverId: any, reason?: string): Promise<any>;
|
|
139
|
+
/**
|
|
140
|
+
* Extend waiver expiration
|
|
141
|
+
*/
|
|
142
|
+
extendWaiver(waiverId: any, newExpiryDate: any, approvedBy: any): Promise<any>;
|
|
143
|
+
/**
|
|
144
|
+
* Get waiver statistics and health metrics
|
|
145
|
+
*/
|
|
146
|
+
getWaiverStats(): Promise<{
|
|
147
|
+
total_active: number;
|
|
148
|
+
by_reason: {};
|
|
149
|
+
by_risk_level: {};
|
|
150
|
+
expiring_soon: any[];
|
|
151
|
+
high_risk: any[];
|
|
152
|
+
total_gates_waived: number;
|
|
153
|
+
average_lifespan_days: number;
|
|
154
|
+
}>;
|
|
155
|
+
generateWaiverId(): Promise<string>;
|
|
156
|
+
validateWaiver(waiver: any): {
|
|
157
|
+
valid: boolean;
|
|
158
|
+
errors: string[];
|
|
159
|
+
};
|
|
160
|
+
checkWaiverConflicts(newWaiver: any): Promise<string[]>;
|
|
161
|
+
waiverAppliesToContext(waiver: any, context: any): boolean;
|
|
162
|
+
loadActiveWaivers(): Promise<any[]>;
|
|
163
|
+
saveActiveWaivers(waivers: any): Promise<void>;
|
|
164
|
+
auditLog(action: any, waiverId: any, details: any): Promise<void>;
|
|
165
|
+
flagForReview(waiver: any): Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=waivers-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers-manager.d.ts","sourceRoot":"","sources":["../src/waivers-manager.js"],"names":[],"mappings":";AAaA;;;GAGG;AACH;IACE,0BAUC;IATC,iBAAuD;IACvD,mBAAiE;IACjE,oBAAoE;IACpE,qBAAkE;IAQpE;;OAEG;IACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiGC;IAED;;OAEG;IACH;;;;;;;;;;;OA4DC;IAED;;OAEG;IACH;;;;;;;;;;OA+BC;IAED;;OAEG;IACH,mCAgBC;IAED;;OAEG;IACH,2DAeC;IAED;;OAEG;IACH,+EAuBC;IAED;;OAEG;IACH;;;;;;;;OA2DC;IAID,oCAUC;IAED;;;MAkDC;IAED,wDAkBC;IAED,2DAUC;IAED,oCAyCC;IAED,+CAuBC;IAED,kEAaC;IAED,0CA2CC;CACF"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview CAWS Prompt Linter
|
|
5
|
+
* Validates prompts for secrets and ensures tool allowlist compliance
|
|
6
|
+
* @author @darianrosebrook
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require("fs");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Common secret patterns to detect
|
|
13
|
+
*/
|
|
14
|
+
const SECRET_PATTERNS = [
|
|
15
|
+
// API Keys
|
|
16
|
+
/api[_-]?key[_-]?token\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
17
|
+
/x-api-key\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
18
|
+
/authorization\s*[=:]\s*['"]?(Bearer\s+)?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
19
|
+
|
|
20
|
+
// Tokens
|
|
21
|
+
/token\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
22
|
+
/access[_-]?token\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
23
|
+
/refresh[_-]?token\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
24
|
+
/auth[_-]?token\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
25
|
+
|
|
26
|
+
// Passwords
|
|
27
|
+
/password\s*[=:]\s*['"]?([a-zA-Z0-9_-]{8,})['"]?/gi,
|
|
28
|
+
/passwd\s*[=:]\s*['"]?([a-zA-Z0-9_-]{8,})['"]?/gi,
|
|
29
|
+
/pwd\s*[=:]\s*['"]?([a-zA-Z0-9_-]{8,})['"]?/gi,
|
|
30
|
+
|
|
31
|
+
// Secrets
|
|
32
|
+
/secret\s*[=:]\s*['"]?([a-zA-Z0-9_-]{16,})['"]?/gi,
|
|
33
|
+
/private[_-]?key\s*[=:]\s*['"]?([a-zA-Z0-9_-]{20,})['"]?/gi,
|
|
34
|
+
|
|
35
|
+
// Environment variables that might contain secrets
|
|
36
|
+
/process\.env\.[A-Z_]+_KEY/gi,
|
|
37
|
+
/process\.env\.[A-Z_]+_TOKEN/gi,
|
|
38
|
+
/process\.env\.[A-Z_]+_SECRET/gi,
|
|
39
|
+
/process\.env\.[A-Z_]+_PASSWORD/gi,
|
|
40
|
+
|
|
41
|
+
// URLs with potential secrets
|
|
42
|
+
/https?:\/\/[^/]*@[^/]+/gi,
|
|
43
|
+
|
|
44
|
+
// Base64 encoded strings that might be secrets
|
|
45
|
+
/[A-Za-z0-9+/=]{40,}/g,
|
|
46
|
+
|
|
47
|
+
// AWS keys
|
|
48
|
+
/AKIA[A-Z0-9]{16}/gi,
|
|
49
|
+
|
|
50
|
+
// GitHub tokens
|
|
51
|
+
/ghp_[A-Za-z0-9]{36}/gi,
|
|
52
|
+
/github_pat_[A-Za-z0-9]{22}/gi,
|
|
53
|
+
|
|
54
|
+
// Slack tokens
|
|
55
|
+
/xoxb-[0-9]+-[0-9]+-[0-9]+-[a-zA-Z0-9]+/gi,
|
|
56
|
+
|
|
57
|
+
// Database connection strings
|
|
58
|
+
/mongodb(\+srv)?:\/\/[^:]+:[^@]+@[^/]+/gi,
|
|
59
|
+
/postgres:\/\/[^:]+:[^@]+@[^/]+/gi,
|
|
60
|
+
/mysql:\/\/[^:]+:[^@]+@[^/]+/gi,
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Scan file for potential secrets
|
|
65
|
+
* @param {string} filePath - Path to file to scan
|
|
66
|
+
* @returns {Array} Array of potential secret matches
|
|
67
|
+
*/
|
|
68
|
+
function scanForSecrets(filePath) {
|
|
69
|
+
try {
|
|
70
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
71
|
+
const matches = [];
|
|
72
|
+
|
|
73
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
74
|
+
const patternMatches = [...content.matchAll(pattern)];
|
|
75
|
+
for (const match of patternMatches) {
|
|
76
|
+
matches.push({
|
|
77
|
+
file: filePath,
|
|
78
|
+
line: content.substring(0, match.index).split("\n").length,
|
|
79
|
+
pattern: pattern.toString(),
|
|
80
|
+
match: match[0],
|
|
81
|
+
severity: "high",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return matches;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(`ā Error scanning ${filePath}:`, error.message);
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Validate tools against allowlist
|
|
95
|
+
* @param {Array} tools - Tools used in prompts
|
|
96
|
+
* @param {Array} allowlist - Allowed tools
|
|
97
|
+
* @returns {Array} Array of violations
|
|
98
|
+
*/
|
|
99
|
+
function validateToolAllowlist(tools, allowlist) {
|
|
100
|
+
const violations = [];
|
|
101
|
+
|
|
102
|
+
for (const tool of tools) {
|
|
103
|
+
if (!allowlist.includes(tool)) {
|
|
104
|
+
violations.push({
|
|
105
|
+
tool,
|
|
106
|
+
severity: "high",
|
|
107
|
+
message: `Tool "${tool}" not in allowlist`,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return violations;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Extract tools from prompt content
|
|
117
|
+
* @param {string} content - Prompt content
|
|
118
|
+
* @returns {Array} Array of tools mentioned
|
|
119
|
+
*/
|
|
120
|
+
function extractTools(content) {
|
|
121
|
+
const tools = [];
|
|
122
|
+
|
|
123
|
+
// Common tool patterns
|
|
124
|
+
const toolPatterns = [
|
|
125
|
+
/using\s+(node|npm|yarn|pnpm|git|docker|kubectl|aws|azure|gcloud)/gi,
|
|
126
|
+
/(node|npm|yarn|pnpm|git|docker|kubectl|aws|azure|gcloud)\s+command/gi,
|
|
127
|
+
/execute\s+(node|npm|yarn|pnpm|git|docker|kubectl|aws|azure|gcloud)/gi,
|
|
128
|
+
/run\s+(node|npm|yarn|pnpm|git|docker|kubectl|aws|azure|gcloud)/gi,
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
for (const pattern of toolPatterns) {
|
|
132
|
+
const matches = [...content.matchAll(pattern)];
|
|
133
|
+
for (const match of matches) {
|
|
134
|
+
const tool = match[1] || match[0];
|
|
135
|
+
if (!tools.includes(tool)) {
|
|
136
|
+
tools.push(tool);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return tools;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Lint prompts for security and compliance
|
|
146
|
+
* @param {Array} promptFiles - Array of prompt file paths
|
|
147
|
+
* @param {Array} allowlist - Allowed tools
|
|
148
|
+
* @returns {Object} Lint results
|
|
149
|
+
*/
|
|
150
|
+
function lintPrompts(promptFiles, allowlist) {
|
|
151
|
+
const results = {
|
|
152
|
+
secrets: [],
|
|
153
|
+
violations: [],
|
|
154
|
+
cleanFiles: 0,
|
|
155
|
+
totalFiles: promptFiles.length,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
for (const file of promptFiles) {
|
|
159
|
+
if (!fs.existsSync(file)) {
|
|
160
|
+
console.warn(`ā ļø Prompt file not found: ${file}`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Scan for secrets
|
|
165
|
+
const secretMatches = scanForSecrets(file);
|
|
166
|
+
results.secrets.push(...secretMatches);
|
|
167
|
+
|
|
168
|
+
// Extract and validate tools
|
|
169
|
+
const content = fs.readFileSync(file, "utf8");
|
|
170
|
+
const tools = extractTools(content);
|
|
171
|
+
const toolViolations = validateToolAllowlist(tools, allowlist);
|
|
172
|
+
results.violations.push(...toolViolations.map((v) => ({ ...v, file })));
|
|
173
|
+
|
|
174
|
+
// Check if file is clean
|
|
175
|
+
if (secretMatches.length === 0 && toolViolations.length === 0) {
|
|
176
|
+
results.cleanFiles++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return results;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Load tool allowlist from file
|
|
185
|
+
* @param {string} allowlistPath - Path to allowlist file
|
|
186
|
+
* @returns {Array} Array of allowed tools
|
|
187
|
+
*/
|
|
188
|
+
function loadAllowlist(allowlistPath) {
|
|
189
|
+
try {
|
|
190
|
+
if (!fs.existsSync(allowlistPath)) {
|
|
191
|
+
console.warn(`ā ļø Allowlist file not found: ${allowlistPath}`);
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const content = fs.readFileSync(allowlistPath, "utf8");
|
|
196
|
+
return JSON.parse(content);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error(`ā Error loading allowlist:`, error.message);
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// CLI interface
|
|
204
|
+
if (require.main === module) {
|
|
205
|
+
const promptFiles = process.argv.slice(2);
|
|
206
|
+
const allowlistArg = process.argv
|
|
207
|
+
.find((arg) => arg.startsWith("--allowlist="))
|
|
208
|
+
?.split("=")[1];
|
|
209
|
+
const allowlistPath = allowlistArg || ".agent/tools-allow.json";
|
|
210
|
+
|
|
211
|
+
if (promptFiles.length === 0) {
|
|
212
|
+
console.log("CAWS Prompt Linter");
|
|
213
|
+
console.log(
|
|
214
|
+
"Usage: node prompt-lint.js <prompt-file1> [prompt-file2] ... [options]"
|
|
215
|
+
);
|
|
216
|
+
console.log("Options:");
|
|
217
|
+
console.log(
|
|
218
|
+
" --allowlist=<path> Path to tools allowlist file (default: .agent/tools-allow.json)"
|
|
219
|
+
);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Load allowlist
|
|
224
|
+
const allowlist = loadAllowlist(allowlistPath);
|
|
225
|
+
|
|
226
|
+
console.log("š Linting prompts for security and compliance...");
|
|
227
|
+
console.log(`š Allowlist loaded: ${allowlist.length} tools`);
|
|
228
|
+
console.log(`š Scanning ${promptFiles.length} files...`);
|
|
229
|
+
|
|
230
|
+
// Lint prompts
|
|
231
|
+
const results = lintPrompts(promptFiles, allowlist);
|
|
232
|
+
|
|
233
|
+
// Report results
|
|
234
|
+
if (results.secrets.length > 0) {
|
|
235
|
+
console.log("\nšØ POTENTIAL SECRETS DETECTED:");
|
|
236
|
+
results.secrets.forEach((secret, index) => {
|
|
237
|
+
console.log(
|
|
238
|
+
` ${index + 1}. ${secret.file}:${
|
|
239
|
+
secret.line
|
|
240
|
+
} - ${secret.match.substring(0, 50)}...`
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (results.violations.length > 0) {
|
|
246
|
+
console.log("\nā ļø TOOL VIOLATIONS:");
|
|
247
|
+
results.violations.forEach((violation, index) => {
|
|
248
|
+
console.log(` ${index + 1}. ${violation.file} - ${violation.message}`);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
console.log("\nš SUMMARY:");
|
|
253
|
+
console.log(` - Files scanned: ${results.totalFiles}`);
|
|
254
|
+
console.log(` - Clean files: ${results.cleanFiles}`);
|
|
255
|
+
console.log(` - Secrets found: ${results.secrets.length}`);
|
|
256
|
+
console.log(` - Violations: ${results.violations.length}`);
|
|
257
|
+
|
|
258
|
+
// Exit with error if issues found
|
|
259
|
+
if (results.secrets.length > 0 || results.violations.length > 0) {
|
|
260
|
+
console.log("\nā Linting failed - security issues detected");
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log("ā
All prompts passed security checks");
|
|
265
|
+
process.exit(0);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = {
|
|
269
|
+
scanForSecrets,
|
|
270
|
+
validateToolAllowlist,
|
|
271
|
+
extractTools,
|
|
272
|
+
lintPrompts,
|
|
273
|
+
loadAllowlist,
|
|
274
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview CAWS Provenance Tracker - Real Implementation
|
|
5
|
+
* @author @darianrosebrook
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const crypto = require('crypto');
|
|
11
|
+
const { execSync } = require('child_process');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate comprehensive provenance data for CAWS operations
|
|
15
|
+
* @param {Object} options - Configuration options
|
|
16
|
+
* @returns {Object} Complete provenance record
|
|
17
|
+
*/
|
|
18
|
+
function generateProvenance(options = {}) {
|
|
19
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
// Agent and model information
|
|
23
|
+
agent: options.agent || 'caws-cli',
|
|
24
|
+
model: options.model || 'cli-interactive',
|
|
25
|
+
model_hash: options.modelHash || generateModelHash(),
|
|
26
|
+
|
|
27
|
+
// Tool and security information
|
|
28
|
+
tool_allowlist: options.toolAllowlist || generateToolAllowlist(projectRoot),
|
|
29
|
+
prompts: options.prompts || [],
|
|
30
|
+
|
|
31
|
+
// Git and version control information
|
|
32
|
+
commit: getCurrentCommit(projectRoot),
|
|
33
|
+
branch: getCurrentBranch(projectRoot),
|
|
34
|
+
repository: getRepositoryInfo(projectRoot),
|
|
35
|
+
|
|
36
|
+
// File and artifact information
|
|
37
|
+
artifacts: generateArtifactList(projectRoot),
|
|
38
|
+
dependencies: generateDependencyInfo(projectRoot),
|
|
39
|
+
|
|
40
|
+
// Execution results and metadata
|
|
41
|
+
results: options.results || {},
|
|
42
|
+
approvals: options.approvals || [],
|
|
43
|
+
execution_context: generateExecutionContext(),
|
|
44
|
+
|
|
45
|
+
// Security and integrity
|
|
46
|
+
integrity: generateIntegrityInfo(),
|
|
47
|
+
|
|
48
|
+
// Timestamps and versioning
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
version: require(path.join(projectRoot, 'package.json')).version || '1.0.0',
|
|
51
|
+
provenance_hash: generateProvenanceHash(),
|
|
52
|
+
|
|
53
|
+
// Build and deployment information
|
|
54
|
+
build_info: generateBuildInfo(projectRoot),
|
|
55
|
+
|
|
56
|
+
// Change tracking
|
|
57
|
+
change_summary: generateChangeSummary(projectRoot),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Mock provenance saving
|
|
62
|
+
function saveProvenance(provenance, filepath) {
|
|
63
|
+
const dir = path.dirname(filepath);
|
|
64
|
+
if (!fs.existsSync(dir)) {
|
|
65
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
66
|
+
}
|
|
67
|
+
fs.writeFileSync(filepath, JSON.stringify(provenance, null, 2));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = {
|
|
71
|
+
generateProvenance,
|
|
72
|
+
saveProvenance,
|
|
73
|
+
};
|