create-qa-architect 5.3.1 → 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.
@@ -157,6 +157,9 @@ class ProjectMaturityDetector {
157
157
  hasTests: this.hasTests(),
158
158
  hasDependencies: this.hasDependencies(),
159
159
  hasCssFiles: this.hasCssFiles(),
160
+ hasShellScripts: this.hasShellScripts(),
161
+ shellScriptCount: this.countShellScripts(),
162
+ isShellProject: this.isShellProject(),
160
163
  packageJsonExists: this.packageJsonExists(),
161
164
  }
162
165
  }
@@ -266,7 +269,7 @@ class ProjectMaturityDetector {
266
269
  const deps = packageJson.dependencies || {}
267
270
  const devDeps = packageJson.devDependencies || {}
268
271
  return Object.keys(deps).length > 0 || Object.keys(devDeps).length > 0
269
- } catch {
272
+ } catch (_error) {
270
273
  return false
271
274
  }
272
275
  }
@@ -287,6 +290,36 @@ class ProjectMaturityDetector {
287
290
  )
288
291
  }
289
292
 
293
+ /**
294
+ * Check if project has shell scripts
295
+ * @returns {boolean} True if shell scripts exist
296
+ */
297
+ hasShellScripts() {
298
+ return this.countShellScripts() > 0
299
+ }
300
+
301
+ /**
302
+ * Count shell script files
303
+ * @returns {number} Number of shell script files
304
+ */
305
+ countShellScripts() {
306
+ const extensions = ['.sh', '.bash']
307
+
308
+ return this.countFilesRecursive(this.projectPath, {
309
+ extensions,
310
+ excludeDirs: EXCLUDE_DIRECTORIES.PROJECT_MATURITY,
311
+ maxDepth: 4,
312
+ })
313
+ }
314
+
315
+ /**
316
+ * Check if this is primarily a shell script project
317
+ * @returns {boolean} True if shell project (has .sh files, no package.json)
318
+ */
319
+ isShellProject() {
320
+ return this.hasShellScripts() && !this.packageJsonExists()
321
+ }
322
+
290
323
  /**
291
324
  * Check if package.json exists
292
325
  * @returns {boolean} True if package.json exists
@@ -405,9 +438,17 @@ class ProjectMaturityDetector {
405
438
  }
406
439
  }
407
440
  } catch (error) {
408
- // Silently ignore permission errors
409
- if (this.verbose) {
410
- console.warn(`Warning: Could not read directory ${dir}:`, error.message)
441
+ // Always log permission errors (affects maturity detection accuracy)
442
+ if (error.code === 'EACCES') {
443
+ console.warn(`⚠️ Permission denied: ${dir} (excluded from analysis)`)
444
+ } else if (error.code !== 'ENOENT') {
445
+ console.warn(
446
+ `⚠️ Could not read ${dir}: ${error.message} (${error.code})`
447
+ )
448
+ }
449
+
450
+ if (this.verbose && error.stack) {
451
+ console.warn(` Stack: ${error.stack}`)
411
452
  }
412
453
  }
413
454
 
@@ -435,7 +476,7 @@ class ProjectMaturityDetector {
435
476
 
436
477
  /**
437
478
  * Generate GitHub Actions outputs for maturity detection
438
- * @returns {{maturity: string, sourceCount: number, testCount: number, hasDeps: boolean, hasDocs: boolean, hasCss: boolean, requiredChecks: string, optionalChecks: string, disabledChecks: string}} GitHub Actions output format
479
+ * @returns {{maturity: string, sourceCount: number, testCount: number, hasDeps: boolean, hasDocs: boolean, hasCss: boolean, hasShell: boolean, shellCount: number, isShellProject: boolean, requiredChecks: string, optionalChecks: string, disabledChecks: string}} GitHub Actions output format
439
480
  */
440
481
  generateGitHubActionsOutput() {
441
482
  const maturity = this.detect()
@@ -449,6 +490,9 @@ class ProjectMaturityDetector {
449
490
  hasDeps: stats.hasDependencies,
450
491
  hasDocs: stats.hasDocumentation,
451
492
  hasCss: stats.hasCssFiles,
493
+ hasShell: stats.hasShellScripts,
494
+ shellCount: stats.shellScriptCount,
495
+ isShellProject: stats.isShellProject,
452
496
  requiredChecks: checks.required.join(','),
453
497
  optionalChecks: checks.optional.join(','),
454
498
  disabledChecks: checks.disabled.join(','),
@@ -472,7 +516,12 @@ class ProjectMaturityDetector {
472
516
  console.log(` • Test files: ${stats.testFiles}`)
473
517
  console.log(` • Documentation: ${stats.hasDocumentation ? 'Yes' : 'No'}`)
474
518
  console.log(` • Dependencies: ${stats.hasDependencies ? 'Yes' : 'No'}`)
475
- console.log(` • CSS files: ${stats.hasCssFiles ? 'Yes' : 'No'}\n`)
519
+ console.log(` • CSS files: ${stats.hasCssFiles ? 'Yes' : 'No'}`)
520
+ console.log(` • Shell scripts: ${stats.shellScriptCount}`)
521
+ if (stats.isShellProject) {
522
+ console.log(` • Project type: Shell script project`)
523
+ }
524
+ console.log()
476
525
 
477
526
  console.log('Quality Checks:')
478
527
  console.log(` ✅ Required: ${level.checks.required.join(', ')}`)
@@ -504,6 +553,9 @@ if (require.main === module) {
504
553
  console.log(`has-deps=${output.hasDeps}`)
505
554
  console.log(`has-docs=${output.hasDocs}`)
506
555
  console.log(`has-css=${output.hasCss}`)
556
+ console.log(`has-shell=${output.hasShell}`)
557
+ console.log(`shell-count=${output.shellCount}`)
558
+ console.log(`is-shell-project=${output.isShellProject}`)
507
559
  console.log(`required-checks=${output.requiredChecks}`)
508
560
  console.log(`optional-checks=${output.optionalChecks}`)
509
561
  console.log(`disabled-checks=${output.disabledChecks}`)
@@ -170,9 +170,19 @@ function readPackageJson(projectPath) {
170
170
  } catch (error) {
171
171
  // DR22 fix: Provide specific error messages for different failure types
172
172
  if (error instanceof SyntaxError) {
173
- console.error(`❌ package.json has invalid JSON syntax: ${error.message}`)
173
+ const errorId = 'PKG_JSON_INVALID_SYNTAX'
174
+ console.error(`❌ [${errorId}] package.json has invalid JSON syntax:`)
174
175
  console.error(` File: ${pkgPath}`)
175
- console.error(' Please fix JSON syntax errors before continuing')
176
+ console.error(` Error: ${error.message}`)
177
+ console.error(`\n Recovery steps:`)
178
+ console.error(` 1. Validate JSON: cat ${pkgPath} | jq .`)
179
+ console.error(
180
+ ` 2. Common issues: trailing commas, missing quotes, unclosed brackets`
181
+ )
182
+ console.error(` 3. Use a JSON validator: https://jsonlint.com`)
183
+ console.error(
184
+ `\n ⚠️ Smart Test Strategy will use generic fallback until this is fixed\n`
185
+ )
176
186
  } else if (error.code === 'EACCES') {
177
187
  console.error(`❌ Permission denied reading package.json: ${pkgPath}`)
178
188
  console.error(' Check file permissions and try again')
@@ -235,7 +245,14 @@ function generateSmartStrategy(options = {}) {
235
245
  )
236
246
 
237
247
  if (!fs.existsSync(templatePath)) {
238
- throw new Error(`Smart strategy template not found at ${templatePath}`)
248
+ throw new Error(
249
+ `Smart strategy template not found at ${templatePath}\n` +
250
+ `This indicates a package installation issue.\n\n` +
251
+ `Troubleshooting steps:\n` +
252
+ `1. Reinstall the package: npm install -g create-qa-architect@latest\n` +
253
+ `2. Check file permissions: ls -la ${path.dirname(templatePath)}\n` +
254
+ `3. Report issue if problem persists: https://github.com/vibebuildlab/qa-architect/issues/new`
255
+ )
239
256
  }
240
257
 
241
258
  let template = fs.readFileSync(templatePath, 'utf8')
package/lib/telemetry.js CHANGED
@@ -75,7 +75,7 @@ function loadTelemetryData() {
75
75
  const data = fs.readFileSync(file, 'utf8')
76
76
  return JSON.parse(data)
77
77
  }
78
- } catch {
78
+ } catch (_error) {
79
79
  // If corrupted, start fresh
80
80
  console.warn('⚠️ Telemetry data corrupted, starting fresh')
81
81
  }
package/lib/ui-helpers.js CHANGED
@@ -58,7 +58,7 @@ function showProgress(message) {
58
58
  const oraImport = require('ora')
59
59
  const ora = /** @type {any} */ (oraImport.default || oraImport)
60
60
  return ora(message).start()
61
- } catch {
61
+ } catch (_error) {
62
62
  // Fallback if ora not installed (graceful degradation)
63
63
  console.log(formatMessage('working', message))
64
64
  return {
@@ -37,11 +37,19 @@ class ConfigSecurityScanner {
37
37
  // checksumMap dependency injection - FOR TESTING ONLY
38
38
  // WARNING: Do not use in production CLI - this bypasses security verification!
39
39
  if (options.checksumMap) {
40
- if (process.env.NODE_ENV === 'production') {
40
+ // Security fix: Block checksumMap override in production
41
+ // Only allow in explicit test/development mode
42
+ const isTestMode = process.env.NODE_ENV === 'test'
43
+ const isDeveloperMode = process.env.QAA_DEVELOPER === 'true'
44
+ const isProduction = process.env.NODE_ENV === 'production'
45
+
46
+ if (isProduction || (!isTestMode && !isDeveloperMode)) {
41
47
  throw new Error(
42
- 'checksumMap override not allowed in production environment'
48
+ 'checksumMap override not allowed in production. ' +
49
+ 'Only permitted when NODE_ENV=test or QAA_DEVELOPER=true'
43
50
  )
44
51
  }
52
+
45
53
  if (!options.quiet) {
46
54
  console.warn(
47
55
  '⚠️ WARNING: Using custom checksum map - FOR TESTING ONLY!'
@@ -118,23 +126,14 @@ class ConfigSecurityScanner {
118
126
  )
119
127
  }
120
128
 
121
- // Check if fallback to unpinned gitleaks is explicitly allowed
122
- if (this.options.allowLatestGitleaks) {
123
- console.warn(
124
- '🚨 WARNING: Using npx gitleaks (supply chain risk - downloads latest version)'
125
- )
126
- console.warn(
127
- '📌 Consider: brew install gitleaks (macOS) or choco install gitleaks (Windows)'
128
- )
129
- return 'npx gitleaks'
130
- }
131
-
132
- // Security-first: fail hard instead of silent fallback
129
+ // Security-first: fail hard instead of any fallback
130
+ // SECURITY: Removed npx gitleaks fallback to prevent command injection
133
131
  throw new Error(
134
132
  `Cannot resolve secure gitleaks binary. Options:\n` +
135
133
  `1. Install globally: brew install gitleaks (macOS) or choco install gitleaks (Windows)\n` +
136
134
  `2. Set GITLEAKS_PATH to your preferred binary\n` +
137
- `3. Use --allow-latest-gitleaks flag (NOT RECOMMENDED - supply chain risk)`
135
+ `Note: --allow-latest-gitleaks flag is deprecated and no longer supported.\n` +
136
+ `npx gitleaks has been intentionally removed due to supply chain security risk.`
138
137
  )
139
138
  }
140
139
  }
@@ -404,11 +403,16 @@ class ConfigSecurityScanner {
404
403
  spinner.succeed('npm audit completed')
405
404
  }
406
405
  } catch {
407
- spinner.warn(`Could not parse ${packageManager} audit output`)
408
- console.warn(`Could not parse ${packageManager} audit output`)
406
+ spinner.fail(`Could not parse ${packageManager} audit output`)
407
+ this.issues.push(
408
+ `${packageManager} audit: Unable to parse audit output. Run '${packageManager} audit --json' manually to inspect vulnerabilities.`
409
+ )
409
410
  }
410
411
  } else {
411
- spinner.succeed('npm audit completed')
412
+ spinner.fail('npm audit returned an error with no output')
413
+ this.issues.push(
414
+ `${packageManager} audit: Failed with no output. Run '${packageManager} audit --json' manually to inspect vulnerabilities.`
415
+ )
412
416
  }
413
417
  }
414
418
  }
@@ -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
- configSecurity: null,
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
- console.log('') // Add spacing between checks
65
-
66
- try {
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
- console.log('') // Add spacing between checks
78
-
79
- try {
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
- console.log('') // Add spacing
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
- if (results.overall.passed) {
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
- // Run all validations in parallel
121
- const validationPromises = [
122
- this.runConfigSecurity()
104
+ const validationPromises = VALIDATION_CHECKS.map(check =>
105
+ this[check.method]()
123
106
  .then(result => {
124
- results.configSecurity = result
125
- console.log('✅ Configuration security complete')
107
+ results[check.name] = result
108
+ console.log(`✅ ${check.label} complete`)
126
109
  })
127
110
  .catch(error => {
128
- console.log('❌ Configuration security failed')
129
- results.configSecurity = { passed: false, error: error.message }
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
- .catch(error => {
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
- console.log('') // Add spacing
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-qa-architect",
3
- "version": "5.3.1",
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": {
@@ -20,8 +20,8 @@
20
20
  "validate:comprehensive": "node setup.js --comprehensive --no-markdownlint",
21
21
  "validate:all": "npm run validate:comprehensive && npm run security:audit",
22
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",
23
- "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",
24
- "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",
25
25
  "test:fast": "npm run test:unit",
26
26
  "test:medium": "npm run test:fast && npm run test:patterns && npm run test:commands",
27
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",
@@ -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()