@paths.design/caws-cli 5.0.1 → 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.
Files changed (115) hide show
  1. package/README.md +15 -12
  2. package/dist/budget-derivation.d.ts +74 -0
  3. package/dist/budget-derivation.d.ts.map +1 -0
  4. package/dist/cicd-optimizer.d.ts +142 -0
  5. package/dist/cicd-optimizer.d.ts.map +1 -0
  6. package/dist/commands/archive.d.ts +50 -0
  7. package/dist/commands/archive.d.ts.map +1 -0
  8. package/dist/commands/burnup.d.ts +6 -0
  9. package/dist/commands/burnup.d.ts.map +1 -0
  10. package/dist/commands/diagnose.d.ts +52 -0
  11. package/dist/commands/diagnose.d.ts.map +1 -0
  12. package/dist/commands/evaluate.d.ts +8 -0
  13. package/dist/commands/evaluate.d.ts.map +1 -0
  14. package/dist/commands/init.d.ts +5 -0
  15. package/dist/commands/init.d.ts.map +1 -0
  16. package/dist/commands/iterate.d.ts +8 -0
  17. package/dist/commands/iterate.d.ts.map +1 -0
  18. package/dist/commands/mode.d.ts +24 -0
  19. package/dist/commands/mode.d.ts.map +1 -0
  20. package/dist/commands/plan.d.ts +49 -0
  21. package/dist/commands/plan.d.ts.map +1 -0
  22. package/dist/commands/provenance.d.ts +32 -0
  23. package/dist/commands/provenance.d.ts.map +1 -0
  24. package/dist/commands/provenance.js +27 -22
  25. package/dist/commands/quality-gates.d.ts +52 -0
  26. package/dist/commands/quality-gates.d.ts.map +1 -0
  27. package/dist/commands/quality-gates.js +190 -455
  28. package/dist/commands/quality-monitor.d.ts +17 -0
  29. package/dist/commands/quality-monitor.d.ts.map +1 -0
  30. package/dist/commands/specs.d.ts +71 -0
  31. package/dist/commands/specs.d.ts.map +1 -0
  32. package/dist/commands/specs.js +34 -35
  33. package/dist/commands/status.d.ts +44 -0
  34. package/dist/commands/status.d.ts.map +1 -0
  35. package/dist/commands/status.js +10 -7
  36. package/dist/commands/templates.d.ts +74 -0
  37. package/dist/commands/templates.d.ts.map +1 -0
  38. package/dist/commands/tool.d.ts +13 -0
  39. package/dist/commands/tool.d.ts.map +1 -0
  40. package/dist/commands/tool.js +63 -63
  41. package/dist/commands/troubleshoot.d.ts +8 -0
  42. package/dist/commands/troubleshoot.d.ts.map +1 -0
  43. package/dist/commands/tutorial.d.ts +55 -0
  44. package/dist/commands/tutorial.d.ts.map +1 -0
  45. package/dist/commands/validate.d.ts +15 -0
  46. package/dist/commands/validate.d.ts.map +1 -0
  47. package/dist/commands/waivers.d.ts +8 -0
  48. package/dist/commands/waivers.d.ts.map +1 -0
  49. package/dist/commands/waivers.js +38 -39
  50. package/dist/commands/workflow.d.ts +85 -0
  51. package/dist/commands/workflow.d.ts.map +1 -0
  52. package/dist/config/index.d.ts +29 -0
  53. package/dist/config/index.d.ts.map +1 -0
  54. package/dist/config/modes.d.ts +225 -0
  55. package/dist/config/modes.d.ts.map +1 -0
  56. package/dist/constants/spec-types.d.ts +41 -0
  57. package/dist/constants/spec-types.d.ts.map +1 -0
  58. package/dist/error-handler.d.ts +164 -0
  59. package/dist/error-handler.d.ts.map +1 -0
  60. package/dist/generators/jest-config.d.ts +32 -0
  61. package/dist/generators/jest-config.d.ts.map +1 -0
  62. package/dist/generators/working-spec.d.ts +13 -0
  63. package/dist/generators/working-spec.d.ts.map +1 -0
  64. package/dist/index-new.d.ts +5 -0
  65. package/dist/index-new.d.ts.map +1 -0
  66. package/dist/index-new.js +317 -0
  67. package/dist/index.d.ts +5 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +1 -0
  70. package/dist/index.js.backup +4711 -0
  71. package/dist/minimal-cli.d.ts +3 -0
  72. package/dist/minimal-cli.d.ts.map +1 -0
  73. package/dist/policy/PolicyManager.d.ts +104 -0
  74. package/dist/policy/PolicyManager.d.ts.map +1 -0
  75. package/dist/policy/PolicyManager.js +60 -28
  76. package/dist/scaffold/cursor-hooks.d.ts +7 -0
  77. package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
  78. package/dist/scaffold/git-hooks.d.ts +20 -0
  79. package/dist/scaffold/git-hooks.d.ts.map +1 -0
  80. package/dist/scaffold/git-hooks.js +89 -27
  81. package/dist/scaffold/index.d.ts +20 -0
  82. package/dist/scaffold/index.d.ts.map +1 -0
  83. package/dist/scaffold/index.js +25 -0
  84. package/dist/spec/SpecFileManager.d.ts +146 -0
  85. package/dist/spec/SpecFileManager.d.ts.map +1 -0
  86. package/dist/test-analysis.d.ts +182 -0
  87. package/dist/test-analysis.d.ts.map +1 -0
  88. package/dist/tool-interface.d.ts +236 -0
  89. package/dist/tool-interface.d.ts.map +1 -0
  90. package/dist/tool-loader.d.ts +77 -0
  91. package/dist/tool-loader.d.ts.map +1 -0
  92. package/dist/tool-validator.d.ts +72 -0
  93. package/dist/tool-validator.d.ts.map +1 -0
  94. package/dist/utils/async-utils.js +188 -0
  95. package/dist/utils/command-wrapper.js +200 -0
  96. package/dist/utils/detection.d.ts +7 -0
  97. package/dist/utils/detection.d.ts.map +1 -0
  98. package/dist/utils/finalization.d.ts +17 -0
  99. package/dist/utils/finalization.d.ts.map +1 -0
  100. package/dist/utils/project-analysis.d.ts +14 -0
  101. package/dist/utils/project-analysis.d.ts.map +1 -0
  102. package/dist/utils/promise-utils.js +72 -0
  103. package/dist/utils/quality-gates.d.ts +49 -0
  104. package/dist/utils/quality-gates.d.ts.map +1 -0
  105. package/dist/utils/spec-resolver.d.ts +88 -0
  106. package/dist/utils/spec-resolver.d.ts.map +1 -0
  107. package/dist/utils/typescript-detector.d.ts +63 -0
  108. package/dist/utils/typescript-detector.d.ts.map +1 -0
  109. package/dist/validation/spec-validation.d.ts +43 -0
  110. package/dist/validation/spec-validation.d.ts.map +1 -0
  111. package/dist/waivers-manager.d.ts +167 -0
  112. package/dist/waivers-manager.d.ts.map +1 -0
  113. package/package.json +1 -1
  114. package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
  115. 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paths.design/caws-cli",
3
- "version": "5.0.1",
3
+ "version": "5.1.0",
4
4
  "description": "CAWS CLI - Coding Agent Workflow System command line tools",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -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
+ };