create-qa-architect 5.0.7 → 5.4.3
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/.github/workflows/auto-release.yml +49 -0
- package/.github/workflows/quality.yml +11 -11
- package/.github/workflows/shell-ci.yml.example +82 -0
- package/.github/workflows/shell-quality.yml.example +148 -0
- package/README.md +165 -12
- package/config/shell-ci.yml +82 -0
- package/config/shell-quality.yml +148 -0
- package/docs/ADOPTION-SUMMARY.md +41 -0
- package/docs/ARCHITECTURE-REVIEW.md +67 -0
- package/docs/ARCHITECTURE.md +29 -45
- package/docs/CI-COST-ANALYSIS.md +323 -0
- package/docs/CODE-REVIEW.md +100 -0
- package/docs/REQUIREMENTS.md +148 -0
- package/docs/SECURITY-AUDIT.md +68 -0
- package/docs/test-trace-matrix.md +28 -0
- package/eslint.config.cjs +2 -0
- package/lib/commands/analyze-ci.js +616 -0
- package/lib/commands/deps.js +293 -0
- package/lib/commands/index.js +29 -0
- package/lib/commands/validate.js +85 -0
- package/lib/config-validator.js +28 -45
- package/lib/error-reporter.js +14 -2
- package/lib/github-api.js +138 -13
- package/lib/license-signing.js +125 -0
- package/lib/license-validator.js +359 -71
- package/lib/licensing.js +434 -106
- package/lib/package-utils.js +9 -9
- package/lib/prelaunch-validator.js +828 -0
- package/lib/project-maturity.js +58 -6
- package/lib/quality-tools-generator.js +495 -0
- package/lib/result-types.js +112 -0
- package/lib/security-enhancements.js +1 -1
- package/lib/smart-strategy-generator.js +46 -10
- package/lib/telemetry.js +1 -1
- package/lib/template-loader.js +52 -19
- package/lib/ui-helpers.js +1 -1
- package/lib/validation/cache-manager.js +36 -6
- package/lib/validation/config-security.js +100 -33
- package/lib/validation/index.js +68 -97
- package/lib/validation/workflow-validation.js +28 -7
- package/package.json +4 -6
- package/scripts/check-test-coverage.sh +46 -0
- package/scripts/validate-claude-md.js +80 -0
- package/setup.js +923 -301
- package/create-saas-monetization.js +0 -1513
package/lib/validation/index.js
CHANGED
|
@@ -4,6 +4,27 @@ const { ConfigSecurityScanner } = require('./config-security')
|
|
|
4
4
|
const { DocumentationValidator } = require('./documentation')
|
|
5
5
|
const { WorkflowValidator } = require('./workflow-validation')
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Validation check configuration
|
|
9
|
+
*/
|
|
10
|
+
const VALIDATION_CHECKS = [
|
|
11
|
+
{
|
|
12
|
+
name: 'configSecurity',
|
|
13
|
+
label: 'Configuration security',
|
|
14
|
+
method: 'runConfigSecurity',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'documentation',
|
|
18
|
+
label: 'Documentation validation',
|
|
19
|
+
method: 'runDocumentationValidation',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'workflows',
|
|
23
|
+
label: 'Workflow validation',
|
|
24
|
+
method: 'runWorkflowValidation',
|
|
25
|
+
},
|
|
26
|
+
]
|
|
27
|
+
|
|
7
28
|
/**
|
|
8
29
|
* Enhanced Validation Runner
|
|
9
30
|
* Coordinates all validation checks
|
|
@@ -43,63 +64,31 @@ class ValidationRunner {
|
|
|
43
64
|
async runComprehensiveCheck() {
|
|
44
65
|
console.log('🔍 Running comprehensive validation...\n')
|
|
45
66
|
|
|
46
|
-
const results =
|
|
47
|
-
|
|
48
|
-
documentation: null,
|
|
49
|
-
workflows: null,
|
|
50
|
-
overall: { passed: true, issues: [] },
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
console.log('⏳ [1/3] Running configuration security scan...')
|
|
55
|
-
results.configSecurity = await this.runConfigSecurity()
|
|
56
|
-
console.log('✅ [1/3] Configuration security complete')
|
|
57
|
-
} catch (error) {
|
|
58
|
-
console.log('❌ [1/3] Configuration security failed')
|
|
59
|
-
results.configSecurity = { passed: false, error: error.message }
|
|
60
|
-
results.overall.passed = false
|
|
61
|
-
results.overall.issues.push(`Configuration Security: ${error.message}`)
|
|
62
|
-
}
|
|
67
|
+
const results = this._initResults()
|
|
68
|
+
const total = VALIDATION_CHECKS.length
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
console.log('⏳ [2/3] Running documentation validation...')
|
|
68
|
-
results.documentation = await this.runDocumentationValidation()
|
|
69
|
-
console.log('✅ [2/3] Documentation validation complete')
|
|
70
|
-
} catch (error) {
|
|
71
|
-
console.log('❌ [2/3] Documentation validation failed')
|
|
72
|
-
results.documentation = { passed: false, error: error.message }
|
|
73
|
-
results.overall.passed = false
|
|
74
|
-
results.overall.issues.push(`Documentation: ${error.message}`)
|
|
75
|
-
}
|
|
70
|
+
for (let i = 0; i < VALIDATION_CHECKS.length; i++) {
|
|
71
|
+
const check = VALIDATION_CHECKS[i]
|
|
72
|
+
const stepNum = i + 1
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
console.log('⏳ [3/3] Running workflow validation...')
|
|
81
|
-
results.workflows = await this.runWorkflowValidation()
|
|
82
|
-
console.log('✅ [3/3] Workflow validation complete')
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.log('❌ [3/3] Workflow validation failed')
|
|
85
|
-
results.workflows = { passed: false, error: error.message }
|
|
86
|
-
results.overall.passed = false
|
|
87
|
-
results.overall.issues.push(`Workflows: ${error.message}`)
|
|
88
|
-
}
|
|
74
|
+
console.log(
|
|
75
|
+
`⏳ [${stepNum}/${total}] Running ${check.label.toLowerCase()}...`
|
|
76
|
+
)
|
|
89
77
|
|
|
90
|
-
|
|
78
|
+
try {
|
|
79
|
+
results[check.name] = await this[check.method]()
|
|
80
|
+
console.log(`✅ [${stepNum}/${total}] ${check.label} complete`)
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.log(`❌ [${stepNum}/${total}] ${check.label} failed`)
|
|
83
|
+
results[check.name] = { passed: false, error: error.message }
|
|
84
|
+
results.overall.passed = false
|
|
85
|
+
results.overall.issues.push(`${check.label}: ${error.message}`)
|
|
86
|
+
}
|
|
91
87
|
|
|
92
|
-
|
|
93
|
-
console.log('✅ All validation checks passed!')
|
|
94
|
-
} else {
|
|
95
|
-
// Detect test scenario and use appropriate prefix
|
|
96
|
-
const isTest = process.argv.join(' ').includes('test')
|
|
97
|
-
const prefix = isTest ? '📋 TEST SCENARIO:' : '❌'
|
|
98
|
-
console.error(`${prefix} Validation failed with issues:`)
|
|
99
|
-
results.overall.issues.forEach(issue => console.error(` - ${issue}`))
|
|
100
|
-
throw new Error('Comprehensive validation failed')
|
|
88
|
+
console.log('')
|
|
101
89
|
}
|
|
102
90
|
|
|
91
|
+
this._reportResults(results)
|
|
103
92
|
return results
|
|
104
93
|
}
|
|
105
94
|
|
|
@@ -110,71 +99,53 @@ class ValidationRunner {
|
|
|
110
99
|
async runComprehensiveCheckParallel() {
|
|
111
100
|
console.log('🔍 Running comprehensive validation (parallel)...\n')
|
|
112
101
|
|
|
113
|
-
const results =
|
|
114
|
-
configSecurity: null,
|
|
115
|
-
documentation: null,
|
|
116
|
-
workflows: null,
|
|
117
|
-
overall: { passed: true, issues: [] },
|
|
118
|
-
}
|
|
102
|
+
const results = this._initResults()
|
|
119
103
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this.runConfigSecurity()
|
|
104
|
+
const validationPromises = VALIDATION_CHECKS.map(check =>
|
|
105
|
+
this[check.method]()
|
|
123
106
|
.then(result => {
|
|
124
|
-
results.
|
|
125
|
-
console.log(
|
|
107
|
+
results[check.name] = result
|
|
108
|
+
console.log(`✅ ${check.label} complete`)
|
|
126
109
|
})
|
|
127
110
|
.catch(error => {
|
|
128
|
-
console.log(
|
|
129
|
-
results.
|
|
111
|
+
console.log(`❌ ${check.label} failed`)
|
|
112
|
+
results[check.name] = { passed: false, error: error.message }
|
|
130
113
|
results.overall.passed = false
|
|
131
|
-
results.overall.issues.push(
|
|
132
|
-
`Configuration Security: ${error.message}`
|
|
133
|
-
)
|
|
134
|
-
}),
|
|
135
|
-
|
|
136
|
-
this.runDocumentationValidation()
|
|
137
|
-
.then(result => {
|
|
138
|
-
results.documentation = result
|
|
139
|
-
console.log('✅ Documentation validation complete')
|
|
114
|
+
results.overall.issues.push(`${check.label}: ${error.message}`)
|
|
140
115
|
})
|
|
141
|
-
|
|
142
|
-
console.log('❌ Documentation validation failed')
|
|
143
|
-
results.documentation = { passed: false, error: error.message }
|
|
144
|
-
results.overall.passed = false
|
|
145
|
-
results.overall.issues.push(`Documentation: ${error.message}`)
|
|
146
|
-
}),
|
|
116
|
+
)
|
|
147
117
|
|
|
148
|
-
this.runWorkflowValidation()
|
|
149
|
-
.then(result => {
|
|
150
|
-
results.workflows = result
|
|
151
|
-
console.log('✅ Workflow validation complete')
|
|
152
|
-
})
|
|
153
|
-
.catch(error => {
|
|
154
|
-
console.log('❌ Workflow validation failed')
|
|
155
|
-
results.workflows = { passed: false, error: error.message }
|
|
156
|
-
results.overall.passed = false
|
|
157
|
-
results.overall.issues.push(`Workflows: ${error.message}`)
|
|
158
|
-
}),
|
|
159
|
-
]
|
|
160
|
-
|
|
161
|
-
// Wait for all validations to complete
|
|
162
118
|
await Promise.all(validationPromises)
|
|
119
|
+
console.log('')
|
|
120
|
+
|
|
121
|
+
this._reportResults(results)
|
|
122
|
+
return results
|
|
123
|
+
}
|
|
163
124
|
|
|
164
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Initialize results object
|
|
127
|
+
*/
|
|
128
|
+
_initResults() {
|
|
129
|
+
const results = { overall: { passed: true, issues: [] } }
|
|
130
|
+
VALIDATION_CHECKS.forEach(check => {
|
|
131
|
+
results[check.name] = null
|
|
132
|
+
})
|
|
133
|
+
return results
|
|
134
|
+
}
|
|
165
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Report validation results
|
|
138
|
+
*/
|
|
139
|
+
_reportResults(results) {
|
|
166
140
|
if (results.overall.passed) {
|
|
167
141
|
console.log('✅ All validation checks passed!')
|
|
168
142
|
} else {
|
|
169
|
-
// Detect test scenario and use appropriate prefix
|
|
170
143
|
const isTest = process.argv.join(' ').includes('test')
|
|
171
144
|
const prefix = isTest ? '📋 TEST SCENARIO:' : '❌'
|
|
172
145
|
console.error(`${prefix} Validation failed with issues:`)
|
|
173
146
|
results.overall.issues.forEach(issue => console.error(` - ${issue}`))
|
|
174
147
|
throw new Error('Comprehensive validation failed')
|
|
175
148
|
}
|
|
176
|
-
|
|
177
|
-
return results
|
|
178
149
|
}
|
|
179
150
|
}
|
|
180
151
|
|
|
@@ -95,15 +95,36 @@ class WorkflowValidator {
|
|
|
95
95
|
for (const file of workflowFiles) {
|
|
96
96
|
const filePath = path.join(workflowDir, file)
|
|
97
97
|
const content = fs.readFileSync(filePath, 'utf8')
|
|
98
|
-
const results = linter(content, filePath) || []
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
try {
|
|
100
|
+
const results = linter(content, filePath) || []
|
|
101
|
+
|
|
102
|
+
if (Array.isArray(results) && results.length > 0) {
|
|
103
|
+
// Filter out false positives for 'vars' context (valid GitHub feature, not recognized by actionlint WASM)
|
|
104
|
+
const filteredResults = results.filter(
|
|
105
|
+
result =>
|
|
106
|
+
!(
|
|
107
|
+
result.kind === 'expression' &&
|
|
108
|
+
result.message?.includes('undefined variable "vars"')
|
|
109
|
+
)
|
|
105
110
|
)
|
|
106
|
-
|
|
111
|
+
issueCount += filteredResults.length
|
|
112
|
+
filteredResults.forEach(result => {
|
|
113
|
+
this.issues.push(
|
|
114
|
+
`actionlint: ${result.file}:${result.line}:${result.column} ${result.kind} - ${result.message}`
|
|
115
|
+
)
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
} catch (lintError) {
|
|
119
|
+
// WASM actionlint has limits on file complexity - skip silently for large files
|
|
120
|
+
if (
|
|
121
|
+
lintError.message?.includes('unreachable') &&
|
|
122
|
+
content.length > 10000
|
|
123
|
+
) {
|
|
124
|
+
// Large file exceeded WASM limits - not a validation failure
|
|
125
|
+
continue
|
|
126
|
+
}
|
|
127
|
+
throw lintError
|
|
107
128
|
}
|
|
108
129
|
}
|
|
109
130
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-qa-architect",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.3",
|
|
4
4
|
"description": "QA Architect - Bootstrap quality automation for JavaScript/TypeScript and Python projects with GitHub Actions, pre-commit hooks, linting, formatting, and smart test strategy",
|
|
5
5
|
"main": "setup.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"create-qa-architect": "./setup.js"
|
|
8
|
-
"create-saas-monetization": "./create-saas-monetization.js"
|
|
7
|
+
"create-qa-architect": "./setup.js"
|
|
9
8
|
},
|
|
10
9
|
"scripts": {
|
|
11
10
|
"prepare": "husky",
|
|
@@ -21,8 +20,8 @@
|
|
|
21
20
|
"validate:comprehensive": "node setup.js --comprehensive --no-markdownlint",
|
|
22
21
|
"validate:all": "npm run validate:comprehensive && npm run security:audit",
|
|
23
22
|
"validate:pre-push": "npm run test:patterns --if-present && npm run lint && npm run format:check && npm run test:commands --if-present && npm test --if-present",
|
|
24
|
-
"test": "export QAA_DEVELOPER=true && node tests/setup.test.js && node tests/integration.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/parallel-validation.test.js && node tests/python-integration.test.js && node tests/interactive.test.js && node tests/monorepo.test.js && node tests/template-loader.test.js && node tests/critical-fixes.test.js && node tests/interactive-routing-fix.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/premium-dependency-monitoring.test.js && node tests/multi-language-dependency-monitoring.test.js && node tests/cli-deps-integration.test.js && node tests/real-world-packages.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/python-detection-sensitivity.test.js && node tests/python-parser-fixes.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/real-purchase-flow.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/project-maturity-cli.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js && node tests/gitleaks-real-binary-test.js && node tests/tier-enforcement.test.js",
|
|
25
|
-
"test:unit": "export QAA_DEVELOPER=true && node tests/setup.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/template-loader.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js",
|
|
23
|
+
"test": "export QAA_DEVELOPER=true && node tests/result-types.test.js && node tests/setup.test.js && node tests/integration.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/parallel-validation.test.js && node tests/python-integration.test.js && node tests/interactive.test.js && node tests/monorepo.test.js && node tests/template-loader.test.js && node tests/critical-fixes.test.js && node tests/interactive-routing-fix.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/premium-dependency-monitoring.test.js && node tests/multi-language-dependency-monitoring.test.js && node tests/cli-deps-integration.test.js && node tests/deps-edge-cases.test.js && node tests/real-world-packages.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/python-detection-sensitivity.test.js && node tests/python-parser-fixes.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/real-purchase-flow.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/workflow-tiers.test.js && node tests/analyze-ci.test.js && node tests/analyze-ci-integration.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/project-maturity-cli.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js && node tests/gitleaks-real-binary-test.js && node tests/tier-enforcement.test.js",
|
|
24
|
+
"test:unit": "export QAA_DEVELOPER=true && node tests/result-types.test.js && node tests/setup.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/template-loader.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/workflow-tiers.test.js && node tests/analyze-ci.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js",
|
|
26
25
|
"test:fast": "npm run test:unit",
|
|
27
26
|
"test:medium": "npm run test:fast && npm run test:patterns && npm run test:commands",
|
|
28
27
|
"test:slow": "export QAA_DEVELOPER=true && node tests/python-integration.test.js && node tests/interactive.test.js && node tests/monorepo.test.js && node tests/critical-fixes.test.js && node tests/interactive-routing-fix.test.js && node tests/premium-dependency-monitoring.test.js && node tests/multi-language-dependency-monitoring.test.js && node tests/cli-deps-integration.test.js && node tests/real-world-packages.test.js && node tests/python-detection-sensitivity.test.js && node tests/python-parser-fixes.test.js && node tests/real-purchase-flow.test.js && node tests/project-maturity-cli.test.js && node tests/gitleaks-real-binary-test.js && npm run test:e2e",
|
|
@@ -66,7 +65,6 @@
|
|
|
66
65
|
"license": "SEE LICENSE IN LICENSE",
|
|
67
66
|
"files": [
|
|
68
67
|
"setup.js",
|
|
69
|
-
"create-saas-monetization.js",
|
|
70
68
|
"config/",
|
|
71
69
|
"docs/",
|
|
72
70
|
"lib/",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Check test coverage for new features
|
|
3
|
+
# Run manually or via pre-commit hook (warning only)
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
YELLOW='\033[1;33m'
|
|
8
|
+
NC='\033[0m'
|
|
9
|
+
|
|
10
|
+
warnings=0
|
|
11
|
+
|
|
12
|
+
echo "🔍 Checking test coverage..."
|
|
13
|
+
|
|
14
|
+
# Find source files without corresponding test files
|
|
15
|
+
for file in $(find src -name "*.ts" -o -name "*.tsx" 2>/dev/null | grep -v "\.test\." | grep -v "\.d\.ts" || true); do
|
|
16
|
+
# Skip layout, page, and config files (Next.js conventions)
|
|
17
|
+
if [[ "$file" == *"/layout."* ]] || [[ "$file" == *"/page."* ]] || [[ "$file" == *".config."* ]]; then
|
|
18
|
+
continue
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Skip API routes (tested via integration tests)
|
|
22
|
+
if [[ "$file" == *"/api/"* ]]; then
|
|
23
|
+
continue
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Check for corresponding test file
|
|
27
|
+
test_file="${file%.*}.test.${file##*.}"
|
|
28
|
+
|
|
29
|
+
if [ ! -f "$test_file" ] && [ ! -f "tests/unit/$(basename ${file%.*}).test.ts" ]; then
|
|
30
|
+
# Only warn for lib/ and components/ (core business logic)
|
|
31
|
+
if [[ "$file" == *"/lib/"* ]] || [[ "$file" == *"/components/"* ]]; then
|
|
32
|
+
echo -e "${YELLOW}⚠️ May need test: $file${NC}"
|
|
33
|
+
((warnings++)) || true
|
|
34
|
+
fi
|
|
35
|
+
fi
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
if [ $warnings -gt 0 ]; then
|
|
39
|
+
echo ""
|
|
40
|
+
echo -e "${YELLOW}⚠️ $warnings file(s) in lib/ or components/ may need tests${NC}"
|
|
41
|
+
echo " Run: pnpm test:coverage to check actual coverage"
|
|
42
|
+
else
|
|
43
|
+
echo "✅ All core files appear to have tests"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
exit 0
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Validates CLAUDE.md consistency with package.json
|
|
6
|
+
* Checks that package name and version are correctly referenced
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require('fs')
|
|
10
|
+
const path = require('path')
|
|
11
|
+
|
|
12
|
+
function validateClaudeMd() {
|
|
13
|
+
console.log('🔍 Validating CLAUDE.md...\n')
|
|
14
|
+
|
|
15
|
+
// Read package.json
|
|
16
|
+
const packagePath = path.join(__dirname, '..', 'package.json')
|
|
17
|
+
if (!fs.existsSync(packagePath)) {
|
|
18
|
+
console.error('❌ package.json not found')
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'))
|
|
23
|
+
const packageName = pkg.name
|
|
24
|
+
const packageVersion = pkg.version
|
|
25
|
+
|
|
26
|
+
// Read CLAUDE.md
|
|
27
|
+
const claudeMdPath = path.join(__dirname, '..', 'CLAUDE.md')
|
|
28
|
+
if (!fs.existsSync(claudeMdPath)) {
|
|
29
|
+
console.error('❌ CLAUDE.md not found')
|
|
30
|
+
process.exit(1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const claudeMd = fs.readFileSync(claudeMdPath, 'utf8')
|
|
34
|
+
|
|
35
|
+
let errors = 0
|
|
36
|
+
|
|
37
|
+
// Check for package name reference
|
|
38
|
+
if (!claudeMd.includes(packageName)) {
|
|
39
|
+
console.error(
|
|
40
|
+
`❌ CLAUDE.md does not reference package name: ${packageName}`
|
|
41
|
+
)
|
|
42
|
+
errors++
|
|
43
|
+
} else {
|
|
44
|
+
console.log(`✅ Package name referenced: ${packageName}`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Check for version reference (optional - just warn)
|
|
48
|
+
if (!claudeMd.includes(packageVersion)) {
|
|
49
|
+
console.warn(
|
|
50
|
+
`⚠️ CLAUDE.md does not reference current version: ${packageVersion}`
|
|
51
|
+
)
|
|
52
|
+
console.warn(' This is not a critical error, but consider updating.')
|
|
53
|
+
} else {
|
|
54
|
+
console.log(`✅ Version referenced: ${packageVersion}`)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Basic content checks
|
|
58
|
+
const requiredSections = ['Project Overview', 'Commands', 'Architecture']
|
|
59
|
+
|
|
60
|
+
requiredSections.forEach(section => {
|
|
61
|
+
if (!claudeMd.includes(section)) {
|
|
62
|
+
console.error(`❌ Missing required section: ${section}`)
|
|
63
|
+
errors++
|
|
64
|
+
} else {
|
|
65
|
+
console.log(`✅ Section found: ${section}`)
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
console.log()
|
|
70
|
+
|
|
71
|
+
if (errors > 0) {
|
|
72
|
+
console.error(`❌ CLAUDE.md validation failed with ${errors} error(s)`)
|
|
73
|
+
process.exit(1)
|
|
74
|
+
} else {
|
|
75
|
+
console.log('✅ CLAUDE.md validation passed!')
|
|
76
|
+
process.exit(0)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
validateClaudeMd()
|