@paths.design/caws-cli 3.1.0 โ 3.2.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 +295 -150
- package/dist/budget-derivation.d.ts +35 -0
- package/dist/budget-derivation.d.ts.map +1 -0
- package/dist/budget-derivation.js +204 -0
- package/dist/cicd-optimizer.d.ts +142 -0
- package/dist/cicd-optimizer.d.ts.map +1 -0
- package/dist/cicd-optimizer.js +504 -0
- package/dist/commands/burnup.d.ts +6 -0
- package/dist/commands/burnup.d.ts.map +1 -0
- package/dist/commands/burnup.js +90 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +514 -0
- package/dist/commands/provenance.d.ts +32 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +979 -0
- package/dist/commands/tool.d.ts +13 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/tool.js +138 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +80 -0
- package/dist/config/index.d.ts +29 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +132 -0
- package/dist/error-handler.d.ts +50 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +253 -0
- package/dist/generators/working-spec.d.ts +13 -0
- package/dist/generators/working-spec.d.ts.map +1 -0
- package/dist/generators/working-spec.js +204 -0
- package/dist/index.d.ts +3 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +193 -2983
- package/dist/scaffold/cursor-hooks.d.ts +7 -0
- package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
- package/dist/scaffold/cursor-hooks.js +152 -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 +417 -0
- package/dist/scaffold/index.d.ts +20 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +486 -0
- package/dist/test-analysis.d.ts +182 -0
- package/dist/test-analysis.d.ts.map +1 -0
- package/dist/test-analysis.js +580 -0
- package/dist/tool-interface.d.ts +236 -0
- package/dist/tool-interface.d.ts.map +1 -0
- package/dist/tool-interface.js +314 -0
- package/dist/tool-loader.d.ts +77 -0
- package/dist/tool-loader.d.ts.map +1 -0
- package/dist/tool-loader.js +298 -0
- package/dist/tool-validator.d.ts +72 -0
- package/dist/tool-validator.d.ts.map +1 -0
- package/dist/tool-validator.js +387 -0
- package/dist/utils/detection.d.ts +7 -0
- package/dist/utils/detection.d.ts.map +1 -0
- package/dist/utils/detection.js +174 -0
- package/dist/utils/finalization.d.ts +17 -0
- package/dist/utils/finalization.d.ts.map +1 -0
- package/dist/utils/finalization.js +229 -0
- package/dist/utils/project-analysis.d.ts +14 -0
- package/dist/utils/project-analysis.d.ts.map +1 -0
- package/dist/utils/project-analysis.js +105 -0
- package/dist/validation/spec-validation.d.ts +29 -0
- package/dist/validation/spec-validation.d.ts.map +1 -0
- package/dist/validation/spec-validation.js +376 -0
- package/dist/waivers-manager.d.ts +167 -0
- package/dist/waivers-manager.d.ts.map +1 -0
- package/dist/waivers-manager.js +549 -0
- package/package.json +10 -12
- package/templates/.cursor/README.md +311 -0
- package/templates/.cursor/hooks/audit.sh +55 -0
- package/templates/.cursor/hooks/block-dangerous.sh +77 -0
- package/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/templates/.cursor/hooks/caws-scope-guard.sh +74 -0
- package/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/templates/.cursor/hooks/format.sh +38 -0
- package/templates/.cursor/hooks/naming-check.sh +64 -0
- package/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/templates/.cursor/hooks/validate-spec.sh +38 -0
- package/templates/.cursor/hooks.json +59 -0
- package/templates/.github/copilot/instructions.md +311 -0
- package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/templates/.vscode/launch.json +56 -0
- package/templates/.vscode/settings.json +93 -0
- package/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/templates/apps/tools/caws/README.md +1 -1
- package/templates/apps/tools/caws/schemas/working-spec.schema.json +21 -3
- package/templates/codemod/test.js +93 -1
- package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
- package/templates/apps/tools/caws/provenance.js.backup +0 -73
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffold Cursor hooks for a CAWS project
|
|
3
|
+
* @param {string} projectDir - Project directory path
|
|
4
|
+
* @param {string[]} levels - Hook levels to enable
|
|
5
|
+
*/
|
|
6
|
+
export function scaffoldCursorHooks(projectDir: string, levels?: string[]): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=cursor-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/cursor-hooks.js"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,gDAHW,MAAM,WACN,MAAM,EAAE,iBAmIlB"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Cursor Hooks Scaffolding
|
|
3
|
+
* Functions for setting up Cursor IDE hooks for CAWS
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
|
|
11
|
+
// Import detection utilities
|
|
12
|
+
const { detectCAWSSetup } = require('../utils/detection');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Scaffold Cursor hooks for a CAWS project
|
|
16
|
+
* @param {string} projectDir - Project directory path
|
|
17
|
+
* @param {string[]} levels - Hook levels to enable
|
|
18
|
+
*/
|
|
19
|
+
async function scaffoldCursorHooks(projectDir, levels = ['safety', 'quality', 'scope', 'audit']) {
|
|
20
|
+
try {
|
|
21
|
+
const cursorDir = path.join(projectDir, '.cursor');
|
|
22
|
+
const cursorHooksDir = path.join(cursorDir, 'hooks');
|
|
23
|
+
|
|
24
|
+
// Create .cursor directory structure
|
|
25
|
+
await fs.ensureDir(cursorDir);
|
|
26
|
+
await fs.ensureDir(cursorHooksDir);
|
|
27
|
+
await fs.ensureDir(path.join(cursorDir, 'logs'));
|
|
28
|
+
|
|
29
|
+
// Determine template directory
|
|
30
|
+
const setup = detectCAWSSetup(projectDir);
|
|
31
|
+
const templateDir = setup.templateDir || path.resolve(__dirname, '../templates');
|
|
32
|
+
|
|
33
|
+
const cursorTemplateDir = path.join(templateDir, '.cursor');
|
|
34
|
+
const cursorHooksTemplateDir = path.join(cursorTemplateDir, 'hooks');
|
|
35
|
+
|
|
36
|
+
if (!fs.existsSync(cursorTemplateDir)) {
|
|
37
|
+
console.warn(chalk.yellow('โ ๏ธ Cursor hooks templates not found'));
|
|
38
|
+
console.warn(chalk.blue('๐ก Skipping Cursor hooks setup'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Map levels to hook scripts
|
|
43
|
+
const hookMapping = {
|
|
44
|
+
safety: ['scan-secrets.sh', 'block-dangerous.sh'],
|
|
45
|
+
quality: ['format.sh', 'validate-spec.sh'],
|
|
46
|
+
scope: ['scope-guard.sh', 'naming-check.sh'],
|
|
47
|
+
audit: ['audit.sh'],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Determine which hooks to enable
|
|
51
|
+
const enabledHooks = new Set();
|
|
52
|
+
levels.forEach((level) => {
|
|
53
|
+
const hooks = hookMapping[level] || [];
|
|
54
|
+
hooks.forEach((hook) => enabledHooks.add(hook));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Always enable audit.sh if any hooks are enabled
|
|
58
|
+
if (enabledHooks.size > 0) {
|
|
59
|
+
enabledHooks.add('audit.sh');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Copy enabled hook scripts
|
|
63
|
+
const allHookScripts = [
|
|
64
|
+
'audit.sh',
|
|
65
|
+
'validate-spec.sh',
|
|
66
|
+
'format.sh',
|
|
67
|
+
'scan-secrets.sh',
|
|
68
|
+
'block-dangerous.sh',
|
|
69
|
+
'scope-guard.sh',
|
|
70
|
+
'naming-check.sh',
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
for (const script of allHookScripts) {
|
|
74
|
+
if (enabledHooks.has(script)) {
|
|
75
|
+
const sourcePath = path.join(cursorHooksTemplateDir, script);
|
|
76
|
+
const destPath = path.join(cursorHooksDir, script);
|
|
77
|
+
|
|
78
|
+
if (fs.existsSync(sourcePath)) {
|
|
79
|
+
await fs.copy(sourcePath, destPath);
|
|
80
|
+
// Make executable
|
|
81
|
+
await fs.chmod(destPath, 0o755);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Generate hooks.json based on enabled hooks
|
|
87
|
+
const hooksConfig = {
|
|
88
|
+
version: 1,
|
|
89
|
+
hooks: {},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Build hooks configuration based on enabled levels
|
|
93
|
+
if (levels.includes('safety')) {
|
|
94
|
+
hooksConfig.hooks.beforeShellExecution = [
|
|
95
|
+
{ command: './.cursor/hooks/block-dangerous.sh' },
|
|
96
|
+
{ command: './.cursor/hooks/audit.sh' },
|
|
97
|
+
];
|
|
98
|
+
hooksConfig.hooks.beforeMCPExecution = [{ command: './.cursor/hooks/audit.sh' }];
|
|
99
|
+
hooksConfig.hooks.beforeReadFile = [{ command: './.cursor/hooks/scan-secrets.sh' }];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (levels.includes('quality')) {
|
|
103
|
+
hooksConfig.hooks.afterFileEdit = hooksConfig.hooks.afterFileEdit || [];
|
|
104
|
+
hooksConfig.hooks.afterFileEdit.push(
|
|
105
|
+
{ command: './.cursor/hooks/format.sh' },
|
|
106
|
+
{ command: './.cursor/hooks/validate-spec.sh' }
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (levels.includes('scope')) {
|
|
111
|
+
hooksConfig.hooks.afterFileEdit = hooksConfig.hooks.afterFileEdit || [];
|
|
112
|
+
hooksConfig.hooks.afterFileEdit.push({ command: './.cursor/hooks/naming-check.sh' });
|
|
113
|
+
hooksConfig.hooks.beforeSubmitPrompt = [
|
|
114
|
+
{ command: './.cursor/hooks/scope-guard.sh' },
|
|
115
|
+
{ command: './.cursor/hooks/audit.sh' },
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (levels.includes('audit')) {
|
|
120
|
+
// Add audit to all events
|
|
121
|
+
if (!hooksConfig.hooks.afterFileEdit) {
|
|
122
|
+
hooksConfig.hooks.afterFileEdit = [];
|
|
123
|
+
}
|
|
124
|
+
hooksConfig.hooks.afterFileEdit.push({ command: './.cursor/hooks/audit.sh' });
|
|
125
|
+
|
|
126
|
+
hooksConfig.hooks.stop = [{ command: './.cursor/hooks/audit.sh' }];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Write hooks.json
|
|
130
|
+
await fs.writeFile(path.join(cursorDir, 'hooks.json'), JSON.stringify(hooksConfig, null, 2));
|
|
131
|
+
|
|
132
|
+
// Copy README
|
|
133
|
+
const readmePath = path.join(cursorTemplateDir, 'README.md');
|
|
134
|
+
if (fs.existsSync(readmePath)) {
|
|
135
|
+
await fs.copy(readmePath, path.join(cursorDir, 'README.md'));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(chalk.green('โ
Cursor hooks configured'));
|
|
139
|
+
console.log(chalk.gray(` Enabled: ${levels.join(', ')}`));
|
|
140
|
+
console.log(
|
|
141
|
+
chalk.gray(` Scripts: ${Array.from(enabledHooks).length} hook scripts installed`)
|
|
142
|
+
);
|
|
143
|
+
console.log(chalk.blue('๐ก Restart Cursor to activate hooks'));
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error(chalk.yellow('โ ๏ธ Failed to setup Cursor hooks:'), error.message);
|
|
146
|
+
console.log(chalk.blue('๐ก You can manually copy .cursor/ directory later'));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
module.exports = {
|
|
151
|
+
scaffoldCursorHooks,
|
|
152
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffold git hooks for CAWS provenance tracking
|
|
3
|
+
* @param {string} projectDir - Project directory path
|
|
4
|
+
* @param {Object} options - Hook options
|
|
5
|
+
*/
|
|
6
|
+
export function scaffoldGitHooks(projectDir: string, options?: any): Promise<{
|
|
7
|
+
added: number;
|
|
8
|
+
skipped: number;
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Remove CAWS git hooks
|
|
12
|
+
* @param {string} projectDir - Project directory path
|
|
13
|
+
*/
|
|
14
|
+
export function removeGitHooks(projectDir: string): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Check git hooks status
|
|
17
|
+
* @param {string} projectDir - Project directory path
|
|
18
|
+
*/
|
|
19
|
+
export function checkGitHooksStatus(projectDir: string): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=git-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/git-hooks.js"],"names":[],"mappings":"AASA;;;;GAIG;AACH,6CAHW,MAAM;;;GAuGhB;AAgND;;;GAGG;AACH,2CAFW,MAAM,iBAkChB;AAED;;;GAGG;AACH,gDAFW,MAAM,iBAgDhB"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Git Hooks Scaffolding for CAWS Provenance
|
|
3
|
+
* Functions for setting up git hooks that automatically update provenance
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Scaffold git hooks for CAWS provenance tracking
|
|
12
|
+
* @param {string} projectDir - Project directory path
|
|
13
|
+
* @param {Object} options - Hook options
|
|
14
|
+
*/
|
|
15
|
+
async function scaffoldGitHooks(projectDir, options = {}) {
|
|
16
|
+
const { provenance = true, validation = true, qualityGates = true, force = false } = options;
|
|
17
|
+
|
|
18
|
+
console.log('๐ Setting up Git hooks for CAWS provenance...');
|
|
19
|
+
|
|
20
|
+
const gitDir = path.join(projectDir, '.git');
|
|
21
|
+
const hooksDir = path.join(gitDir, 'hooks');
|
|
22
|
+
|
|
23
|
+
// Check if this is a git repository
|
|
24
|
+
if (!(await fs.pathExists(gitDir))) {
|
|
25
|
+
console.log('โ ๏ธ Not a git repository - skipping git hooks setup');
|
|
26
|
+
console.log('๐ก Initialize git first: git init');
|
|
27
|
+
return { added: 0, skipped: 0 };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Ensure hooks directory exists
|
|
31
|
+
await fs.ensureDir(hooksDir);
|
|
32
|
+
|
|
33
|
+
let addedCount = 0;
|
|
34
|
+
let skippedCount = 0;
|
|
35
|
+
|
|
36
|
+
// Define hook configurations
|
|
37
|
+
const hooks = [
|
|
38
|
+
{
|
|
39
|
+
name: 'pre-commit',
|
|
40
|
+
description: 'Pre-commit validation and quality checks',
|
|
41
|
+
enabled: validation || qualityGates,
|
|
42
|
+
content: generatePreCommitHook({ validation, qualityGates }),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'post-commit',
|
|
46
|
+
description: 'Post-commit provenance tracking',
|
|
47
|
+
enabled: provenance,
|
|
48
|
+
content: generatePostCommitHook(),
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'pre-push',
|
|
52
|
+
description: 'Pre-push comprehensive validation',
|
|
53
|
+
enabled: qualityGates,
|
|
54
|
+
content: generatePrePushHook(),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'commit-msg',
|
|
58
|
+
description: 'Commit message validation',
|
|
59
|
+
enabled: validation,
|
|
60
|
+
content: generateCommitMsgHook(),
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
for (const hook of hooks) {
|
|
65
|
+
if (!hook.enabled) continue;
|
|
66
|
+
|
|
67
|
+
const hookPath = path.join(hooksDir, hook.name);
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
// Check if hook already exists
|
|
71
|
+
const exists = await fs.pathExists(hookPath);
|
|
72
|
+
|
|
73
|
+
if (exists && !force) {
|
|
74
|
+
// Check if it's already a CAWS hook
|
|
75
|
+
const content = await fs.readFile(hookPath, 'utf8');
|
|
76
|
+
if (content.includes('# CAWS Hook')) {
|
|
77
|
+
console.log(`โญ๏ธ Skipped ${hook.description} (already configured)`);
|
|
78
|
+
skippedCount++;
|
|
79
|
+
continue;
|
|
80
|
+
} else {
|
|
81
|
+
console.log(`โ ๏ธ ${hook.description} exists but not CAWS-managed`);
|
|
82
|
+
if (!options.backup) {
|
|
83
|
+
console.log(`๐ก Use --force to replace, or --backup to preserve original`);
|
|
84
|
+
skippedCount++;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Backup existing hook if requested
|
|
91
|
+
if (exists && options.backup) {
|
|
92
|
+
const backupPath = `${hookPath}.backup.${Date.now()}`;
|
|
93
|
+
await fs.copy(hookPath, backupPath);
|
|
94
|
+
console.log(`๐พ Backed up existing ${hook.name} to ${path.basename(backupPath)}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Write the hook
|
|
98
|
+
await fs.writeFile(hookPath, hook.content);
|
|
99
|
+
await fs.chmod(hookPath, 0o755);
|
|
100
|
+
|
|
101
|
+
console.log(`โ
Configured ${hook.description}`);
|
|
102
|
+
addedCount++;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.log(`โ Failed to configure ${hook.description}: ${error.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (addedCount > 0) {
|
|
109
|
+
console.log(`\n๐ Git hooks configured: ${addedCount} hooks active`);
|
|
110
|
+
console.log('๐ก Hooks will run automatically on git operations');
|
|
111
|
+
console.log('๐ก Use --no-verify to skip hooks: git commit --no-verify');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return { added: addedCount, skipped: skippedCount };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Generate pre-commit hook content
|
|
119
|
+
*/
|
|
120
|
+
function generatePreCommitHook(options) {
|
|
121
|
+
const { qualityGates = true } = options;
|
|
122
|
+
|
|
123
|
+
return `#!/bin/bash
|
|
124
|
+
# CAWS Pre-commit Hook
|
|
125
|
+
# Runs validation and quality checks before commits
|
|
126
|
+
|
|
127
|
+
set -e
|
|
128
|
+
|
|
129
|
+
echo "๐ CAWS Pre-commit Validation"
|
|
130
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
131
|
+
|
|
132
|
+
# Check if CAWS is initialized
|
|
133
|
+
if [ ! -d ".caws" ]; then
|
|
134
|
+
echo "โ ๏ธ CAWS not initialized - skipping validation"
|
|
135
|
+
exit 0
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Run CAWS validation if available
|
|
139
|
+
if command -v caws >/dev/null 2>&1; then
|
|
140
|
+
echo "๐ Running CAWS validation..."
|
|
141
|
+
if caws validate --quiet; then
|
|
142
|
+
echo "โ
CAWS validation passed"
|
|
143
|
+
else
|
|
144
|
+
echo "โ CAWS validation failed"
|
|
145
|
+
echo "๐ก Fix issues or use: git commit --no-verify"
|
|
146
|
+
exit 1
|
|
147
|
+
fi
|
|
148
|
+
else
|
|
149
|
+
echo "โ ๏ธ CAWS CLI not found - install with: npm install -g @paths.design/caws-cli"
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# Run quality gates if enabled
|
|
153
|
+
${
|
|
154
|
+
qualityGates
|
|
155
|
+
? `
|
|
156
|
+
echo "๐ฏ Running quality gates..."
|
|
157
|
+
if [ -f "package.json" ]; then
|
|
158
|
+
# Run linting if available
|
|
159
|
+
if [ -f "node_modules/.bin/eslint" ] || command -v eslint >/dev/null 2>&1; then
|
|
160
|
+
echo "๐ Running ESLint..."
|
|
161
|
+
if npx eslint . --quiet; then
|
|
162
|
+
echo "โ
ESLint passed"
|
|
163
|
+
else
|
|
164
|
+
echo "โ ESLint failed - fix issues or use --no-verify"
|
|
165
|
+
exit 1
|
|
166
|
+
fi
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Run tests if available
|
|
170
|
+
if [ -f "package.json" ] && grep -q '"test"' package.json; then
|
|
171
|
+
echo "๐งช Running tests..."
|
|
172
|
+
if npm test; then
|
|
173
|
+
echo "โ
Tests passed"
|
|
174
|
+
else
|
|
175
|
+
echo "โ Tests failed - fix issues or use --no-verify"
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
fi
|
|
179
|
+
fi
|
|
180
|
+
`
|
|
181
|
+
: ''
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
echo "๐ Pre-commit checks passed!"
|
|
185
|
+
`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Generate post-commit hook content
|
|
190
|
+
*/
|
|
191
|
+
function generatePostCommitHook() {
|
|
192
|
+
return `#!/bin/bash
|
|
193
|
+
# CAWS Post-commit Hook
|
|
194
|
+
# Updates provenance tracking after successful commits
|
|
195
|
+
|
|
196
|
+
# Run in background to avoid blocking git operations
|
|
197
|
+
(
|
|
198
|
+
# Check if CAWS is initialized
|
|
199
|
+
if [ ! -d ".caws" ]; then
|
|
200
|
+
exit 0
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
# Get the current commit hash
|
|
204
|
+
COMMIT_HASH=$(git rev-parse HEAD)
|
|
205
|
+
|
|
206
|
+
# Get commit details
|
|
207
|
+
COMMIT_MESSAGE=$(git log -1 --pretty=%B | head -1)
|
|
208
|
+
AUTHOR_NAME=$(git log -1 --pretty=%an)
|
|
209
|
+
AUTHOR_EMAIL=$(git log -1 --pretty=%ae)
|
|
210
|
+
|
|
211
|
+
# Update provenance if CAWS CLI is available
|
|
212
|
+
if command -v caws >/dev/null 2>&1; then
|
|
213
|
+
echo "๐ Updating CAWS provenance for commit \${COMMIT_HASH:0:8}..."
|
|
214
|
+
|
|
215
|
+
# Run provenance update in background
|
|
216
|
+
(
|
|
217
|
+
caws provenance update \\
|
|
218
|
+
--commit "$COMMIT_HASH" \\
|
|
219
|
+
--message "$COMMIT_MESSAGE" \\
|
|
220
|
+
--author "$AUTHOR_NAME <$AUTHOR_EMAIL>" \\
|
|
221
|
+
--quiet
|
|
222
|
+
) &
|
|
223
|
+
fi
|
|
224
|
+
) >/dev/null 2>&1 &
|
|
225
|
+
`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Generate pre-push hook content
|
|
230
|
+
*/
|
|
231
|
+
function generatePrePushHook() {
|
|
232
|
+
return `#!/bin/bash
|
|
233
|
+
# CAWS Pre-push Hook
|
|
234
|
+
# Runs comprehensive checks before pushing
|
|
235
|
+
|
|
236
|
+
set -e
|
|
237
|
+
|
|
238
|
+
echo "๐ CAWS Pre-push Validation"
|
|
239
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
240
|
+
|
|
241
|
+
# Check if CAWS is initialized
|
|
242
|
+
if [ ! -d ".caws" ]; then
|
|
243
|
+
echo "โ ๏ธ CAWS not initialized - skipping validation"
|
|
244
|
+
exit 0
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
# Run full validation suite
|
|
248
|
+
if command -v caws >/dev/null 2>&1; then
|
|
249
|
+
echo "๐ Running comprehensive CAWS validation..."
|
|
250
|
+
if caws validate --quiet; then
|
|
251
|
+
echo "โ
CAWS validation passed"
|
|
252
|
+
else
|
|
253
|
+
echo "โ CAWS validation failed"
|
|
254
|
+
echo "๐ก Fix issues or use: git push --no-verify"
|
|
255
|
+
exit 1
|
|
256
|
+
fi
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
# Run security checks
|
|
260
|
+
echo "๐ Running security checks..."
|
|
261
|
+
if [ -f "package.json" ]; then
|
|
262
|
+
# Check for vulnerabilities
|
|
263
|
+
if command -v npm >/dev/null 2>&1; then
|
|
264
|
+
echo "๐ Checking for vulnerabilities..."
|
|
265
|
+
if npm audit --audit-level moderate >/dev/null 2>&1; then
|
|
266
|
+
echo "โ
Security audit passed"
|
|
267
|
+
else
|
|
268
|
+
echo "โ ๏ธ Security vulnerabilities found"
|
|
269
|
+
echo "๐ก Review with: npm audit"
|
|
270
|
+
echo "๐ก Use --no-verify to push anyway"
|
|
271
|
+
# Don't fail on warnings, just warn
|
|
272
|
+
fi
|
|
273
|
+
fi
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
echo "๐ Pre-push checks completed!"
|
|
277
|
+
`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Generate commit-msg hook content
|
|
282
|
+
*/
|
|
283
|
+
function generateCommitMsgHook() {
|
|
284
|
+
return `#!/bin/bash
|
|
285
|
+
# CAWS Commit Message Hook
|
|
286
|
+
# Validates commit message format
|
|
287
|
+
|
|
288
|
+
COMMIT_MSG_FILE=$1
|
|
289
|
+
|
|
290
|
+
# Read the commit message
|
|
291
|
+
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
292
|
+
|
|
293
|
+
# Check if CAWS is initialized
|
|
294
|
+
if [ ! -d ".caws" ]; then
|
|
295
|
+
exit 0
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
# Basic commit message validation
|
|
299
|
+
if [ \${#COMMIT_MSG} -lt 10 ]; then
|
|
300
|
+
echo "โ Commit message too short (minimum 10 characters)"
|
|
301
|
+
echo "๐ก Write descriptive commit messages"
|
|
302
|
+
exit 1
|
|
303
|
+
fi
|
|
304
|
+
|
|
305
|
+
# Check for conventional commit format (optional but encouraged)
|
|
306
|
+
if [[ $COMMIT_MSG =~ ^(feat|fix|docs|style|refactor|test|chore)(.+)? ]]; then
|
|
307
|
+
echo "โ
Conventional commit format detected"
|
|
308
|
+
else
|
|
309
|
+
echo "๐ก Consider using conventional commit format:"
|
|
310
|
+
echo " feat: add new feature"
|
|
311
|
+
echo " fix: bug fix"
|
|
312
|
+
echo " docs: documentation"
|
|
313
|
+
echo " style: formatting"
|
|
314
|
+
echo " refactor: code restructuring"
|
|
315
|
+
echo " test: testing"
|
|
316
|
+
echo " chore: maintenance"
|
|
317
|
+
fi
|
|
318
|
+
|
|
319
|
+
echo "โ
Commit message validation passed"
|
|
320
|
+
`;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Remove CAWS git hooks
|
|
325
|
+
* @param {string} projectDir - Project directory path
|
|
326
|
+
*/
|
|
327
|
+
async function removeGitHooks(projectDir) {
|
|
328
|
+
console.log('๐งน Removing CAWS Git hooks...');
|
|
329
|
+
|
|
330
|
+
const hooksDir = path.join(projectDir, '.git', 'hooks');
|
|
331
|
+
const cawsHooks = ['pre-commit', 'post-commit', 'pre-push', 'commit-msg'];
|
|
332
|
+
|
|
333
|
+
let removedCount = 0;
|
|
334
|
+
|
|
335
|
+
for (const hookName of cawsHooks) {
|
|
336
|
+
const hookPath = path.join(hooksDir, hookName);
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
if (await fs.pathExists(hookPath)) {
|
|
340
|
+
const content = await fs.readFile(hookPath, 'utf8');
|
|
341
|
+
if (content.includes('# CAWS Hook') || content.includes('# CAWS Pre-commit Hook')) {
|
|
342
|
+
await fs.remove(hookPath);
|
|
343
|
+
console.log(`โ
Removed ${hookName} hook`);
|
|
344
|
+
removedCount++;
|
|
345
|
+
} else {
|
|
346
|
+
console.log(`โญ๏ธ Skipped ${hookName} (not CAWS-managed)`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
console.log(`โ Failed to remove ${hookName}: ${error.message}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (removedCount > 0) {
|
|
355
|
+
console.log(`๐งน Removed ${removedCount} CAWS git hooks`);
|
|
356
|
+
} else {
|
|
357
|
+
console.log('โน๏ธ No CAWS git hooks found');
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Check git hooks status
|
|
363
|
+
* @param {string} projectDir - Project directory path
|
|
364
|
+
*/
|
|
365
|
+
async function checkGitHooksStatus(projectDir) {
|
|
366
|
+
const hooksDir = path.join(projectDir, '.git', 'hooks');
|
|
367
|
+
const cawsHooks = ['pre-commit', 'post-commit', 'pre-push', 'commit-msg'];
|
|
368
|
+
|
|
369
|
+
console.log('๐ Git Hooks Status:');
|
|
370
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
371
|
+
|
|
372
|
+
let activeCount = 0;
|
|
373
|
+
let totalCount = 0;
|
|
374
|
+
|
|
375
|
+
for (const hookName of cawsHooks) {
|
|
376
|
+
totalCount++;
|
|
377
|
+
const hookPath = path.join(hooksDir, hookName);
|
|
378
|
+
|
|
379
|
+
try {
|
|
380
|
+
if (await fs.pathExists(hookPath)) {
|
|
381
|
+
const content = await fs.readFile(hookPath, 'utf8');
|
|
382
|
+
const isExecutable = (await fs.stat(hookPath)).mode & 0o111;
|
|
383
|
+
|
|
384
|
+
if (content.includes('# CAWS') && isExecutable) {
|
|
385
|
+
console.log(`โ
${hookName}: Active`);
|
|
386
|
+
activeCount++;
|
|
387
|
+
} else if (content.includes('# CAWS')) {
|
|
388
|
+
console.log(`โ ๏ธ ${hookName}: Configured but not executable`);
|
|
389
|
+
} else {
|
|
390
|
+
console.log(`โ ${hookName}: Not CAWS-managed`);
|
|
391
|
+
}
|
|
392
|
+
} else {
|
|
393
|
+
console.log(`โ ${hookName}: Not installed`);
|
|
394
|
+
}
|
|
395
|
+
} catch (error) {
|
|
396
|
+
console.log(`โ ${hookName}: Error checking status`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
console.log('');
|
|
401
|
+
console.log(`๐ Status: ${activeCount}/${totalCount} CAWS hooks active`);
|
|
402
|
+
|
|
403
|
+
if (activeCount < totalCount) {
|
|
404
|
+
console.log('');
|
|
405
|
+
console.log('๐ก To install missing hooks:');
|
|
406
|
+
console.log(' caws scaffold');
|
|
407
|
+
console.log('');
|
|
408
|
+
console.log('๐ก To check detailed status:');
|
|
409
|
+
console.log(' ls -la .git/hooks/');
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
module.exports = {
|
|
414
|
+
scaffoldGitHooks,
|
|
415
|
+
removeGitHooks,
|
|
416
|
+
checkGitHooksStatus,
|
|
417
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffold existing project with CAWS components
|
|
3
|
+
* @param {Object} options - Scaffold options
|
|
4
|
+
*/
|
|
5
|
+
export function scaffoldProject(options: any): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Scaffold IDE integrations for comprehensive CAWS development experience
|
|
8
|
+
* @param {string} targetDir - Target directory for scaffolding
|
|
9
|
+
* @param {Object} options - Scaffold options
|
|
10
|
+
*/
|
|
11
|
+
export function scaffoldIDEIntegrations(targetDir: string, options: any): Promise<{
|
|
12
|
+
added: number;
|
|
13
|
+
skipped: number;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Set dependencies for scaffold module
|
|
17
|
+
* @param {Object} deps - Dependencies object
|
|
18
|
+
*/
|
|
19
|
+
export function setScaffoldDependencies(deps: any): void;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AAkKA;;;GAGG;AACH,6DAyTC;AA5cD;;;;GAIG;AACH,mDAHW,MAAM;;;GA8HhB;AAMD;;;GAGG;AACH,yDAGC"}
|