create-qa-architect 5.0.6 → 5.3.1

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 (37) hide show
  1. package/.github/workflows/auto-release.yml +49 -0
  2. package/.github/workflows/dependabot-auto-merge.yml +32 -0
  3. package/LICENSE +3 -3
  4. package/README.md +54 -15
  5. package/docs/ADOPTION-SUMMARY.md +41 -0
  6. package/docs/ARCHITECTURE-REVIEW.md +67 -0
  7. package/docs/ARCHITECTURE.md +29 -41
  8. package/docs/CODE-REVIEW.md +100 -0
  9. package/docs/PREFLIGHT_REPORT.md +32 -40
  10. package/docs/REQUIREMENTS.md +148 -0
  11. package/docs/SECURITY-AUDIT.md +68 -0
  12. package/docs/TESTING.md +3 -4
  13. package/docs/test-trace-matrix.md +28 -0
  14. package/lib/billing-dashboard.html +6 -12
  15. package/lib/commands/deps.js +245 -0
  16. package/lib/commands/index.js +25 -0
  17. package/lib/commands/validate.js +85 -0
  18. package/lib/error-reporter.js +13 -1
  19. package/lib/github-api.js +108 -13
  20. package/lib/license-signing.js +110 -0
  21. package/lib/license-validator.js +359 -71
  22. package/lib/licensing.js +343 -111
  23. package/lib/prelaunch-validator.js +828 -0
  24. package/lib/quality-tools-generator.js +495 -0
  25. package/lib/result-types.js +112 -0
  26. package/lib/security-enhancements.js +1 -1
  27. package/lib/smart-strategy-generator.js +28 -9
  28. package/lib/template-loader.js +52 -19
  29. package/lib/validation/cache-manager.js +36 -6
  30. package/lib/validation/config-security.js +82 -15
  31. package/lib/validation/workflow-validation.js +49 -23
  32. package/package.json +8 -10
  33. package/scripts/check-test-coverage.sh +46 -0
  34. package/setup.js +356 -285
  35. package/templates/QUALITY_TROUBLESHOOTING.md +32 -33
  36. package/templates/scripts/smart-test-strategy.sh +1 -1
  37. package/create-saas-monetization.js +0 -1513
package/setup.js CHANGED
@@ -1,5 +1,68 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ /**
4
+ * DR26 fix: Architectural Refactoring Plan for setup.js (2201 lines)
5
+ *
6
+ * PRIORITY: This file should be split into focused modules to improve
7
+ * maintainability, testability, and reduce cognitive load.
8
+ *
9
+ * PROPOSED MODULE STRUCTURE (target: < 500 lines per module):
10
+ *
11
+ * 1. lib/commands/validate.js (~300 lines)
12
+ * - Validation command logic
13
+ * - Config validation workflows
14
+ * - Prelaunch validation integration
15
+ *
16
+ * 2. lib/commands/deps.js (~200 lines)
17
+ * - Dependency monitoring setup
18
+ * - Dependabot configuration
19
+ * - GitHub API integration calls
20
+ *
21
+ * 3. lib/commands/activate.js (~150 lines)
22
+ * - License activation flow
23
+ * - Interactive license prompts
24
+ * - License validation integration
25
+ *
26
+ * 4. lib/commands/setup-main.js (~800 lines)
27
+ * - Main setup orchestration
28
+ * - Template generation
29
+ * - File writing operations
30
+ * - Husky/lint-staged configuration
31
+ *
32
+ * 5. lib/setup-config.js (~200 lines)
33
+ * - Configuration merging logic
34
+ * - Package.json updates
35
+ * - Workflow injection helpers
36
+ *
37
+ * 6. setup.js (core CLI, ~200 lines)
38
+ * - Argument parsing
39
+ * - Command routing
40
+ * - Help/version display
41
+ * - Exit code handling
42
+ *
43
+ * MIGRATION CHECKLIST:
44
+ * - [ ] Extract validation command to lib/commands/validate.js
45
+ * - [ ] Extract deps command to lib/commands/deps.js
46
+ * - [ ] Extract license activation to lib/commands/activate.js
47
+ * - [ ] Extract main setup flow to lib/commands/setup-main.js
48
+ * - [ ] Extract config helpers to lib/setup-config.js
49
+ * - [ ] Update all tests to use new module structure
50
+ * - [ ] Verify all CLI commands still work (--help, --deps, --validate, etc.)
51
+ * - [ ] Update integration tests
52
+ * - [ ] Run full test suite and ensure 100% pass rate
53
+ *
54
+ * BENEFITS:
55
+ * - Easier to test individual commands
56
+ * - Reduced cognitive load when modifying specific features
57
+ * - Better code organization and discoverability
58
+ * - Easier to add new commands in the future
59
+ * - Faster development cycles (smaller files to navigate)
60
+ *
61
+ * BLOCKED BY: None (can be done incrementally)
62
+ * ESTIMATED EFFORT: 2-3 days with full test coverage
63
+ * RISK: Medium (need to ensure no regressions in CLI behavior)
64
+ */
65
+
3
66
  const fs = require('fs')
4
67
  const path = require('path')
5
68
  const { execSync } = require('child_process')
@@ -49,29 +112,23 @@ const {
49
112
  } = require('./config/defaults')
50
113
 
51
114
  // Enhanced validation capabilities
52
- const { ValidationRunner } = require('./lib/validation')
53
115
  const { validateQualityConfig } = require('./lib/config-validator')
54
116
 
55
117
  // Interactive mode capabilities
56
118
  const { InteractivePrompt } = require('./lib/interactive/prompt')
57
119
  const { runInteractiveFlow } = require('./lib/interactive/questions')
58
120
 
59
- // Basic dependency monitoring (Free Tier)
60
- const {
61
- hasNpmProject,
62
- generateBasicDependabotConfig,
63
- writeBasicDependabotConfig,
64
- } = require('./lib/dependency-monitoring-basic')
65
-
66
- // Premium dependency monitoring (Pro/Team/Enterprise Tiers)
67
- const {
68
- generatePremiumDependabotConfig,
69
- writePremiumDependabotConfig,
70
- } = require('./lib/dependency-monitoring-premium')
121
+ // Note: Dependency monitoring imports moved to ./lib/commands/deps.js
71
122
 
72
123
  // Custom template loading
73
124
  const { TemplateLoader } = require('./lib/template-loader')
74
125
 
126
+ // Command handlers (extracted for maintainability)
127
+ const {
128
+ handleValidationCommands,
129
+ handleDependencyMonitoring,
130
+ } = require('./lib/commands')
131
+
75
132
  // Licensing system
76
133
  const {
77
134
  getLicenseInfo,
@@ -91,6 +148,26 @@ const {
91
148
  getTestTierScripts,
92
149
  } = require('./lib/smart-strategy-generator')
93
150
 
151
+ // Quality Tools Generator (Lighthouse, size-limit, axe-core, commitlint, coverage)
152
+ const {
153
+ writeLighthouseConfig,
154
+ writeSizeLimitConfig,
155
+ writeCommitlintConfig,
156
+ writeCommitMsgHook,
157
+ writeAxeTestSetup,
158
+ getQualityToolsDependencies,
159
+ getQualityToolsScripts,
160
+ } = require('./lib/quality-tools-generator')
161
+
162
+ // Pre-Launch Validation (SEO, links, a11y, docs, env)
163
+ const {
164
+ writeValidationScripts,
165
+ writeEnvValidator,
166
+ writePa11yConfig,
167
+ getPrelaunchScripts,
168
+ getPrelaunchDependencies,
169
+ } = require('./lib/prelaunch-validator')
170
+
94
171
  // Telemetry (opt-in usage tracking)
95
172
  const { TelemetrySession, showTelemetryStatus } = require('./lib/telemetry')
96
173
 
@@ -103,7 +180,6 @@ const {
103
180
  // Critical setup enhancements (fixes production quality gaps)
104
181
  const {
105
182
  applyProductionQualityFixes,
106
- // generateEnhancedPreCommitHook,
107
183
  validateProjectSetup,
108
184
  } = require('./lib/setup-enhancements')
109
185
 
@@ -151,7 +227,12 @@ function injectCollaborationSteps(workflowContent, options = {}) {
151
227
  const safeReadDir = dir => {
152
228
  try {
153
229
  return fs.readdirSync(dir, { withFileTypes: true })
154
- } catch {
230
+ } catch (error) {
231
+ // Silent failure fix: Log non-ENOENT errors in DEBUG mode
232
+ // ENOENT is expected (dir doesn't exist), other errors may indicate issues
233
+ if (process.env.DEBUG && error?.code !== 'ENOENT') {
234
+ console.warn(`āš ļø Could not read directory ${dir}: ${error.message}`)
235
+ }
155
236
  return []
156
237
  }
157
238
  }
@@ -332,6 +413,7 @@ function parseArguments(rawArgs) {
332
413
  const isCheckMaturityMode = sanitizedArgs.includes('--check-maturity')
333
414
  const isValidateConfigMode = sanitizedArgs.includes('--validate-config')
334
415
  const isActivateLicenseMode = sanitizedArgs.includes('--activate-license')
416
+ const isPrelaunchMode = sanitizedArgs.includes('--prelaunch')
335
417
  const isDryRun = sanitizedArgs.includes('--dry-run')
336
418
  const ciProviderIndex = sanitizedArgs.findIndex(arg => arg === '--ci')
337
419
  const ciProvider =
@@ -355,6 +437,7 @@ function parseArguments(rawArgs) {
355
437
  const disableActionlint = sanitizedArgs.includes('--no-actionlint')
356
438
  const disableMarkdownlint = sanitizedArgs.includes('--no-markdownlint')
357
439
  const disableEslintSecurity = sanitizedArgs.includes('--no-eslint-security')
440
+ const allowLatestGitleaks = sanitizedArgs.includes('--allow-latest-gitleaks')
358
441
 
359
442
  return {
360
443
  sanitizedArgs,
@@ -371,6 +454,7 @@ function parseArguments(rawArgs) {
371
454
  isCheckMaturityMode,
372
455
  isValidateConfigMode,
373
456
  isActivateLicenseMode,
457
+ isPrelaunchMode,
374
458
  isDryRun,
375
459
  ciProvider,
376
460
  enableSlackAlerts,
@@ -381,6 +465,7 @@ function parseArguments(rawArgs) {
381
465
  disableActionlint,
382
466
  disableMarkdownlint,
383
467
  disableEslintSecurity,
468
+ allowLatestGitleaks,
384
469
  }
385
470
  }
386
471
 
@@ -408,6 +493,7 @@ function parseArguments(rawArgs) {
408
493
  isCheckMaturityMode,
409
494
  isValidateConfigMode,
410
495
  isActivateLicenseMode,
496
+ isPrelaunchMode,
411
497
  isDryRun,
412
498
  ciProvider,
413
499
  enableSlackAlerts,
@@ -418,6 +504,7 @@ function parseArguments(rawArgs) {
418
504
  disableActionlint,
419
505
  disableMarkdownlint,
420
506
  disableEslintSecurity,
507
+ allowLatestGitleaks,
421
508
  } = parsedConfig
422
509
 
423
510
  // Initialize telemetry session (opt-in only, fails silently)
@@ -490,6 +577,7 @@ function parseArguments(rawArgs) {
490
577
  disableActionlint,
491
578
  disableMarkdownlint,
492
579
  disableEslintSecurity,
580
+ allowLatestGitleaks,
493
581
  } = parsedConfig)
494
582
 
495
583
  console.log('šŸ“‹ Configuration after interactive selections applied\n')
@@ -531,6 +619,7 @@ VALIDATION OPTIONS:
531
619
  --validate-docs Run documentation validation only
532
620
  --validate-config Validate .qualityrc.json configuration file
533
621
  --check-maturity Detect and display project maturity level
622
+ --prelaunch Add pre-launch validation suite (SEO, links, a11y, docs)
534
623
 
535
624
  LICENSE, TELEMETRY & ERROR REPORTING:
536
625
  --license-status Show current license tier and available features
@@ -572,6 +661,9 @@ EXAMPLES:
572
661
  npx create-qa-architect@latest --check-maturity
573
662
  → Detect project maturity level (minimal, bootstrap, development, production-ready)
574
663
 
664
+ npx create-qa-architect@latest --prelaunch
665
+ → Add pre-launch validation: SEO (sitemap, robots, meta), links, a11y, docs
666
+
575
667
  npx create-qa-architect@latest --validate-config
576
668
  → Validate .qualityrc.json configuration file against JSON Schema
577
669
 
@@ -644,257 +736,8 @@ HELP:
644
736
  process.exit(0)
645
737
  }
646
738
 
647
- // Handle validation-only commands
648
- async function handleValidationCommands() {
649
- const validationOptions = {
650
- disableNpmAudit,
651
- disableGitleaks,
652
- disableActionlint,
653
- disableMarkdownlint,
654
- disableEslintSecurity,
655
- }
656
- const validator = new ValidationRunner(validationOptions)
657
-
658
- if (isConfigSecurityMode) {
659
- try {
660
- await validator.runConfigSecurity()
661
- process.exit(0)
662
- } catch (error) {
663
- console.error(
664
- `\nāŒ Configuration security validation failed:\n${error.message}`
665
- )
666
- process.exit(1)
667
- }
668
- }
669
-
670
- if (isDocsValidationMode) {
671
- try {
672
- await validator.runDocumentationValidation()
673
- process.exit(0)
674
- } catch (error) {
675
- console.error(`\nāŒ Documentation validation failed:\n${error.message}`)
676
- process.exit(1)
677
- }
678
- }
679
-
680
- if (isComprehensiveMode || isValidationMode) {
681
- try {
682
- // Use parallel validation for 3-5x speedup (runs checks concurrently)
683
- await validator.runComprehensiveCheckParallel()
684
- process.exit(0)
685
- } catch (error) {
686
- console.error(`\nāŒ Comprehensive validation failed:\n${error.message}`)
687
- process.exit(1)
688
- }
689
- }
690
- }
691
-
692
- // Detect Python project
693
- function detectPythonProject(projectPath) {
694
- const pythonFiles = [
695
- 'pyproject.toml',
696
- 'requirements.txt',
697
- 'setup.py',
698
- 'Pipfile',
699
- ]
700
- return pythonFiles.some(file => fs.existsSync(path.join(projectPath, file)))
701
- }
702
-
703
- // Detect Rust project
704
- function detectRustProject(projectPath) {
705
- return fs.existsSync(path.join(projectPath, 'Cargo.toml'))
706
- }
707
-
708
- // Detect Ruby project
709
- function detectRubyProject(projectPath) {
710
- return fs.existsSync(path.join(projectPath, 'Gemfile'))
711
- }
712
-
713
- // Handle dependency monitoring (Free/Pro/Team/Enterprise)
714
- async function handleDependencyMonitoring() {
715
- const projectPath = process.cwd()
716
- const license = getLicenseInfo()
717
-
718
- // Detect all supported ecosystems (npm, Python, Ruby, Rust, etc.)
719
- const hasNpm = hasNpmProject(projectPath)
720
- const hasPython = detectPythonProject(projectPath)
721
- const hasRust = detectRustProject(projectPath)
722
- const hasRuby = detectRubyProject(projectPath)
723
-
724
- if (!hasNpm && !hasPython && !hasRust && !hasRuby) {
725
- console.error(
726
- 'āŒ No supported dependency file found (package.json, pyproject.toml, requirements.txt, Gemfile, Cargo.toml).'
727
- )
728
- console.log("šŸ’” Make sure you're in a directory with dependency files.")
729
- process.exit(1)
730
- }
731
-
732
- if (hasNpm) console.log('šŸ“¦ Detected: npm project')
733
- if (hasPython) console.log('šŸ Detected: Python project')
734
- if (hasRust) console.log('šŸ¦€ Detected: Rust project')
735
- if (hasRuby) console.log('šŸ’Ž Detected: Ruby project')
736
- console.log(`šŸ“‹ License tier: ${license.tier.toUpperCase()}`)
737
-
738
- // Enforce Free tier caps for dependency monitoring (counted as dependency PRs)
739
- if (license.tier === 'FREE') {
740
- const capCheck = checkUsageCaps('dependency-pr')
741
- if (!capCheck.allowed) {
742
- console.error(`āŒ ${capCheck.reason}`)
743
- console.error(
744
- ' Upgrade to Pro, Team, or Enterprise for unlimited runs: https://vibebuildlab.com/tools/qa-architect'
745
- )
746
- process.exit(1)
747
- }
748
-
749
- const increment = incrementUsage('dependency-pr')
750
- const usage = increment.usage || capCheck.usage
751
- const caps = capCheck.caps
752
- if (usage && caps && caps.maxDependencyPRsPerMonth !== undefined) {
753
- console.log(
754
- `🧮 Usage: ${usage.dependencyPRs}/${caps.maxDependencyPRsPerMonth} dependency monitoring runs used this month`
755
- )
756
- }
757
- }
758
-
759
- const dependabotPath = path.join(projectPath, '.github', 'dependabot.yml')
760
-
761
- // Use premium or basic config based on license tier
762
- // Free beta ended with v4.1.1 - Premium features now require Pro/Team/Enterprise tier
763
- // Pro/Team/Enterprise: Framework-aware dependency monitoring with grouping
764
- // Free: Basic npm-only dependency monitoring
765
- const shouldUsePremium =
766
- license.tier === 'PRO' ||
767
- license.tier === 'TEAM' ||
768
- license.tier === 'ENTERPRISE'
769
-
770
- // Free tier only supports npm projects. Fail fast with a clear message.
771
- if (!shouldUsePremium && !hasNpm && (hasPython || hasRust || hasRuby)) {
772
- console.error(
773
- 'āŒ Dependency monitoring for this project requires a Pro, Team, or Enterprise license.'
774
- )
775
- console.error(
776
- ' Free tier supports npm projects only. Detected non-npm ecosystems.'
777
- )
778
- console.error(
779
- ' Options: add npm/package.json, or upgrade and re-run: npx create-qa-architect@latest --deps after activation.'
780
- )
781
- process.exit(1)
782
- }
783
-
784
- if (shouldUsePremium) {
785
- console.log(
786
- '\nšŸš€ Setting up framework-aware dependency monitoring (Premium)...\n'
787
- )
788
-
789
- const configData = generatePremiumDependabotConfig({
790
- projectPath,
791
- schedule: 'weekly',
792
- })
793
-
794
- if (configData) {
795
- const { ecosystems } = configData
796
- const ecosystemNames = Object.keys(ecosystems)
797
-
798
- if (ecosystemNames.length > 0) {
799
- console.log('šŸ” Detected ecosystems:')
800
-
801
- // Find primary ecosystem and total package count
802
- let primaryEcosystem = null
803
- ecosystemNames.forEach(ecoName => {
804
- const eco = ecosystems[ecoName]
805
- const frameworks = Object.keys(eco.detected || {})
806
- const totalPackages = frameworks.reduce((sum, fw) => {
807
- return sum + (eco.detected[fw]?.count || 0)
808
- }, 0)
809
-
810
- console.log(` • ${ecoName}: ${totalPackages} packages`)
811
-
812
- if (eco.primary) {
813
- primaryEcosystem = ecoName
814
- }
815
- })
816
-
817
- if (primaryEcosystem) {
818
- console.log(`\nšŸŽÆ Primary ecosystem: ${primaryEcosystem}`)
819
- }
820
- }
821
-
822
- writePremiumDependabotConfig(configData, dependabotPath)
823
- console.log(
824
- '\nāœ… Created .github/dependabot.yml with framework grouping'
825
- )
826
-
827
- console.log('\nšŸŽ‰ Premium dependency monitoring setup complete!')
828
- console.log('\nšŸ“‹ What was added (Pro Tier):')
829
- console.log(' • Framework-aware dependency grouping')
830
- console.log(
831
- ` • ${Object.keys(configData.config.updates[0].groups || {}).length} dependency groups created`
832
- )
833
- console.log(' • Intelligent update batching (reduces PRs by 60%+)')
834
- console.log(' • GitHub Actions dependency monitoring')
835
- }
836
- } else {
837
- console.log(
838
- '\nšŸ” Setting up basic dependency monitoring (Free Tier)...\n'
839
- )
840
-
841
- const dependabotConfig = generateBasicDependabotConfig({
842
- projectPath,
843
- schedule: 'weekly',
844
- })
845
-
846
- if (dependabotConfig) {
847
- writeBasicDependabotConfig(dependabotConfig, dependabotPath)
848
- console.log('āœ… Created .github/dependabot.yml')
849
- }
850
-
851
- console.log('\nšŸŽ‰ Basic dependency monitoring setup complete!')
852
- console.log('\nšŸ“‹ What was added (Free Tier):')
853
- console.log(' • Basic Dependabot configuration for npm packages')
854
- console.log(' • Weekly dependency updates on Monday 9am')
855
- console.log(' • GitHub Actions dependency monitoring')
856
-
857
- // Show upgrade message for premium features
858
- console.log('\nšŸ”’ Premium features now available:')
859
- console.log(
860
- ' āœ… Framework-aware package grouping (React, Vue, Angular)'
861
- )
862
- console.log(' • Coming soon: Multi-language support (Python, Rust, Go)')
863
- console.log(' • Planned: Advanced security audit workflows')
864
- console.log(' • Planned: Custom update schedules and notifications')
865
-
866
- showUpgradeMessage('Framework-Aware Dependency Grouping')
867
- }
868
-
869
- // Auto-enable Dependabot on GitHub if token available
870
- console.log('\nšŸ”§ Attempting to enable Dependabot on GitHub...')
871
- try {
872
- const { setupDependabot } = require('./lib/github-api')
873
- const result = await setupDependabot(projectPath, { verbose: true })
874
-
875
- if (result.success) {
876
- console.log('āœ… Dependabot alerts and security updates enabled!')
877
- } else if (result.errors.length > 0) {
878
- console.log('āš ļø Could not auto-enable Dependabot:')
879
- result.errors.forEach(err => console.log(` • ${err}`))
880
- console.log('\nšŸ’” Manual steps needed:')
881
- console.log(' • Go to GitHub repo → Settings → Code security')
882
- console.log(
883
- ' • Enable "Dependabot alerts" and "Dependabot security updates"'
884
- )
885
- }
886
- } catch (error) {
887
- console.log('āš ļø Could not auto-enable Dependabot:', error.message)
888
- console.log('\nšŸ’” Manual steps:')
889
- console.log(' • Enable Dependabot in GitHub repo settings')
890
- }
891
-
892
- console.log('\nšŸ’” Next steps:')
893
- console.log(' • Review and commit .github/dependabot.yml')
894
- console.log(
895
- ' • Dependabot will start monitoring weekly for dependency updates'
896
- )
897
- }
739
+ // Note: handleValidationCommands, handleDependencyMonitoring, detectPythonProject,
740
+ // detectRustProject, detectRubyProject are now imported from ./lib/commands
898
741
 
899
742
  // Handle license status command
900
743
  if (isLicenseStatusMode) {
@@ -964,6 +807,83 @@ HELP:
964
807
  })()
965
808
  }
966
809
 
810
+ // Handle pre-launch validation setup command
811
+ if (isPrelaunchMode) {
812
+ return (async () => {
813
+ try {
814
+ const projectPath = process.cwd()
815
+ const PackageJson = checkNodeVersionAndLoadPackageJson()
816
+ const pkgJson = await PackageJson.load(projectPath)
817
+ const license = getLicenseInfo()
818
+ const isPro =
819
+ license.tier === 'PRO' ||
820
+ license.tier === 'TEAM' ||
821
+ license.tier === 'ENTERPRISE'
822
+
823
+ console.log('\nšŸ“‹ Setting up pre-launch validation suite...\n')
824
+ console.log(` License tier: ${license.tier.toUpperCase()}`)
825
+
826
+ // Check feature availability
827
+ if (!hasFeature('prelaunchValidation')) {
828
+ console.error('āŒ Pre-launch validation requires a valid license.')
829
+ showUpgradeMessage('Pre-launch validation')
830
+ process.exit(1)
831
+ }
832
+
833
+ // Write validation scripts
834
+ const scriptsWritten = writeValidationScripts(projectPath)
835
+ console.log(` āœ… Created ${scriptsWritten.length} validation scripts`)
836
+
837
+ // Write pa11y config
838
+ writePa11yConfig(projectPath)
839
+ console.log(' āœ… Created .pa11yci config')
840
+
841
+ // Write env validator for Pro+
842
+ if (isPro && hasFeature('envValidation')) {
843
+ writeEnvValidator(projectPath)
844
+ console.log(' āœ… Created env vars validator (Pro)')
845
+ }
846
+
847
+ // Add scripts to package.json
848
+ const prelaunchScripts = getPrelaunchScripts(isPro)
849
+ const prelaunchDeps = getPrelaunchDependencies(isPro)
850
+
851
+ // Merge scripts
852
+ const existingScripts = pkgJson.content.scripts || {}
853
+ pkgJson.update({
854
+ scripts: { ...existingScripts, ...prelaunchScripts },
855
+ })
856
+
857
+ // Merge devDependencies
858
+ const existingDevDeps = pkgJson.content.devDependencies || {}
859
+ pkgJson.update({
860
+ devDependencies: { ...existingDevDeps, ...prelaunchDeps },
861
+ })
862
+
863
+ await pkgJson.save()
864
+
865
+ console.log('\nāœ… Pre-launch validation setup complete!\n')
866
+ console.log('Available scripts:')
867
+ console.log(' npm run validate:sitemap - Check sitemap.xml')
868
+ console.log(' npm run validate:robots - Check robots.txt')
869
+ console.log(' npm run validate:meta - Check meta tags')
870
+ console.log(' npm run validate:links - Check for broken links')
871
+ console.log(' npm run validate:a11y - Run accessibility audit')
872
+ console.log(' npm run validate:docs - Check documentation')
873
+ if (isPro) {
874
+ console.log(' npm run validate:env - Audit env vars (Pro)')
875
+ }
876
+ console.log(' npm run validate:prelaunch - Run all checks')
877
+ console.log('\nšŸ’” Run: npm install && npm run validate:prelaunch')
878
+
879
+ process.exit(0)
880
+ } catch (error) {
881
+ console.error('Pre-launch validation setup error:', error.message)
882
+ process.exit(1)
883
+ }
884
+ })()
885
+ }
886
+
967
887
  // Run validation commands if requested
968
888
  if (
969
889
  isValidationMode ||
@@ -974,13 +894,152 @@ HELP:
974
894
  // Handle validation commands and exit
975
895
  return (async () => {
976
896
  try {
977
- await handleValidationCommands()
897
+ await handleValidationCommands({
898
+ isConfigSecurityMode,
899
+ isDocsValidationMode,
900
+ isComprehensiveMode,
901
+ isValidationMode,
902
+ disableNpmAudit,
903
+ disableGitleaks,
904
+ disableActionlint,
905
+ disableMarkdownlint,
906
+ disableEslintSecurity,
907
+ allowLatestGitleaks,
908
+ })
978
909
  } catch (error) {
979
910
  console.error('Validation error:', error.message)
980
911
  process.exit(1)
981
912
  }
982
913
  })()
983
914
  } else {
915
+ /**
916
+ * Setup quality tools based on license tier
917
+ * - Lighthouse CI (Free: basic, Pro: with thresholds)
918
+ * - Bundle size limits (Pro only)
919
+ * - axe-core accessibility (Free)
920
+ * - Conventional commits (Free)
921
+ * - Coverage thresholds (Pro only)
922
+ */
923
+ async function setupQualityTools(_usesTypeScript, _packageJson) {
924
+ const qualitySpinner = showProgress('Setting up quality tools...')
925
+
926
+ try {
927
+ const projectPath = process.cwd()
928
+ const PackageJson = checkNodeVersionAndLoadPackageJson()
929
+ const pkgJson = await PackageJson.load(projectPath)
930
+ const addedTools = []
931
+
932
+ // Determine which features are available
933
+ const hasLighthouse = hasFeature('lighthouseCI')
934
+ const hasLighthouseThresholds = hasFeature('lighthouseThresholds')
935
+ const hasBundleSizeLimits = hasFeature('bundleSizeLimits')
936
+ const hasAxeAccessibility = hasFeature('axeAccessibility')
937
+ const hasConventionalCommits = hasFeature('conventionalCommits')
938
+ const hasCoverageThresholds = hasFeature('coverageThresholds')
939
+
940
+ // 1. Lighthouse CI - available to all, thresholds for Pro+
941
+ if (hasLighthouse) {
942
+ const lighthousePath = path.join(projectPath, 'lighthouserc.js')
943
+ if (!fs.existsSync(lighthousePath)) {
944
+ writeLighthouseConfig(projectPath, {
945
+ hasThresholds: hasLighthouseThresholds,
946
+ })
947
+ addedTools.push(
948
+ hasLighthouseThresholds
949
+ ? 'Lighthouse CI (with thresholds)'
950
+ : 'Lighthouse CI (basic)'
951
+ )
952
+ }
953
+ }
954
+
955
+ // 2. Bundle size limits - Pro only
956
+ if (hasBundleSizeLimits) {
957
+ if (!pkgJson.content['size-limit']) {
958
+ writeSizeLimitConfig(projectPath)
959
+ addedTools.push('Bundle size limits (size-limit)')
960
+ }
961
+ }
962
+
963
+ // 3. axe-core accessibility testing - available to all
964
+ if (hasAxeAccessibility) {
965
+ const axeTestPath = path.join(
966
+ projectPath,
967
+ 'tests',
968
+ 'accessibility.test.js'
969
+ )
970
+ if (!fs.existsSync(axeTestPath)) {
971
+ writeAxeTestSetup(projectPath)
972
+ addedTools.push('axe-core accessibility tests')
973
+ }
974
+ }
975
+
976
+ // 4. Conventional commits (commitlint) - available to all
977
+ if (hasConventionalCommits) {
978
+ const commitlintPath = path.join(projectPath, 'commitlint.config.js')
979
+ if (!fs.existsSync(commitlintPath)) {
980
+ writeCommitlintConfig(projectPath)
981
+ writeCommitMsgHook(projectPath)
982
+ addedTools.push('Conventional commits (commitlint)')
983
+ }
984
+ }
985
+
986
+ // 5. Coverage thresholds - Pro only (info message handled elsewhere)
987
+ if (hasCoverageThresholds) {
988
+ addedTools.push('Coverage thresholds (70% lines, 70% functions)')
989
+ }
990
+
991
+ // Add dependencies for enabled features
992
+ const deps = getQualityToolsDependencies({
993
+ lighthouse: hasLighthouse,
994
+ sizeLimit: hasBundleSizeLimits,
995
+ commitlint: hasConventionalCommits,
996
+ axeCore: hasAxeAccessibility,
997
+ })
998
+
999
+ // Add scripts for enabled features
1000
+ const scripts = getQualityToolsScripts({
1001
+ lighthouse: hasLighthouse,
1002
+ sizeLimit: hasBundleSizeLimits,
1003
+ axeCore: hasAxeAccessibility,
1004
+ coverage: hasCoverageThresholds,
1005
+ })
1006
+
1007
+ // Merge dependencies and scripts
1008
+ pkgJson.content.devDependencies = mergeDevDependencies(
1009
+ pkgJson.content.devDependencies || {},
1010
+ deps
1011
+ )
1012
+ pkgJson.content.scripts = mergeScripts(
1013
+ pkgJson.content.scripts || {},
1014
+ scripts
1015
+ )
1016
+ await pkgJson.save()
1017
+
1018
+ if (addedTools.length > 0) {
1019
+ qualitySpinner.succeed(
1020
+ `Quality tools configured: ${addedTools.length} tools`
1021
+ )
1022
+ addedTools.forEach(tool => console.log(` āœ… ${tool}`))
1023
+
1024
+ // Show Pro upsell for missing features
1025
+ if (!hasBundleSizeLimits || !hasCoverageThresholds) {
1026
+ console.log('\nšŸ’Ž Upgrade to Pro for additional quality tools:')
1027
+ if (!hasBundleSizeLimits) {
1028
+ console.log(' • Bundle size limits (size-limit)')
1029
+ }
1030
+ if (!hasCoverageThresholds) {
1031
+ console.log(' • Coverage threshold enforcement')
1032
+ }
1033
+ }
1034
+ } else {
1035
+ qualitySpinner.succeed('Quality tools already configured')
1036
+ }
1037
+ } catch (error) {
1038
+ qualitySpinner.warn('Could not set up some quality tools')
1039
+ console.warn('āš ļø Quality tools setup error:', error.message)
1040
+ }
1041
+ }
1042
+
984
1043
  // Normal setup flow
985
1044
  async function runMainSetup() {
986
1045
  // Record telemetry start event (opt-in only, fails silently)
@@ -1027,7 +1086,7 @@ HELP:
1027
1086
  if (!repoCheck.allowed) {
1028
1087
  console.error(`\nāŒ ${repoCheck.reason}`)
1029
1088
  console.error(
1030
- ' Upgrade to Pro for unlimited repos: https://vibebuildlab.com/tools/qa-architect'
1089
+ ' Upgrade to Pro for unlimited repos: https://vibebuildlab.com/qa-architect'
1031
1090
  )
1032
1091
  process.exit(1)
1033
1092
  }
@@ -1128,7 +1187,7 @@ HELP:
1128
1187
  const hasTypeScriptDependency = Boolean(
1129
1188
  (packageJson.devDependencies &&
1130
1189
  packageJson.devDependencies.typescript) ||
1131
- (packageJson.dependencies && packageJson.dependencies.typescript)
1190
+ (packageJson.dependencies && packageJson.dependencies.typescript)
1132
1191
  )
1133
1192
 
1134
1193
  const tsconfigCandidates = ['tsconfig.json', 'tsconfig.base.json']
@@ -1199,7 +1258,17 @@ HELP:
1199
1258
  }
1200
1259
 
1201
1260
  return false
1202
- } catch {
1261
+ } catch (error) {
1262
+ // Silent failure fix: Log unexpected errors in debug mode
1263
+ if (
1264
+ process.env.DEBUG &&
1265
+ error.code !== 'ENOENT' &&
1266
+ error.code !== 'EACCES'
1267
+ ) {
1268
+ console.warn(
1269
+ `āš ļø Could not scan ${dir} for Python files: ${error.message}`
1270
+ )
1271
+ }
1203
1272
  return false
1204
1273
  }
1205
1274
  }
@@ -1374,20 +1443,19 @@ HELP:
1374
1443
  })
1375
1444
  }
1376
1445
  } else {
1377
- // Config exists, validate it
1378
- // Temporarily disabled - debugging
1379
- // const validationResult = validateQualityConfig(qualityrcPath)
1380
- // if (!validationResult.valid) {
1381
- // console.warn(
1382
- // 'āš ļø Warning: Existing .qualityrc.json has validation issues:'
1383
- // )
1384
- // validationResult.errors.forEach(error => {
1385
- // console.warn(` - ${error}`)
1386
- // })
1387
- // console.warn(
1388
- // ' Setup will continue, but you may want to fix these issues.\n'
1389
- // )
1390
- // }
1446
+ // TD8 fix: Re-enabled validation (was disabled for debugging)
1447
+ const validationResult = validateQualityConfig(qualityrcPath)
1448
+ if (!validationResult.valid) {
1449
+ console.warn(
1450
+ 'āš ļø Warning: Existing .qualityrc.json has validation issues:'
1451
+ )
1452
+ validationResult.errors.forEach(error => {
1453
+ console.warn(` - ${error}`)
1454
+ })
1455
+ console.warn(
1456
+ ' Setup will continue, but you may want to fix these issues.\n'
1457
+ )
1458
+ }
1391
1459
  }
1392
1460
 
1393
1461
  // Load and merge templates (custom + defaults)
@@ -1714,7 +1782,7 @@ try {
1714
1782
  const CAP = 50
1715
1783
  if (usage.prePushRuns >= CAP) {
1716
1784
  console.error('āŒ Free tier limit reached: ' + usage.prePushRuns + '/' + CAP + ' pre-push runs this month')
1717
- console.error(' Upgrade to Pro, Team, or Enterprise: https://vibebuildlab.com/tools/qa-architect')
1785
+ console.error(' Upgrade to Pro, Team, or Enterprise: https://vibebuildlab.com/qa-architect')
1718
1786
  process.exit(1)
1719
1787
  }
1720
1788
 
@@ -2002,6 +2070,9 @@ echo "āœ… Pre-push validation passed!"
2002
2070
  showUpgradeMessage('Smart Test Strategy')
2003
2071
  }
2004
2072
 
2073
+ // Quality Tools Integration
2074
+ await setupQualityTools(usesTypeScript, packageJson)
2075
+
2005
2076
  // Generate placeholder test file with helpful documentation
2006
2077
  const testsDir = path.join(process.cwd(), 'tests')
2007
2078
  const testExtension = usesTypeScript ? 'ts' : 'js'