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.
- package/.github/workflows/auto-release.yml +49 -0
- package/.github/workflows/dependabot-auto-merge.yml +32 -0
- package/LICENSE +3 -3
- package/README.md +54 -15
- package/docs/ADOPTION-SUMMARY.md +41 -0
- package/docs/ARCHITECTURE-REVIEW.md +67 -0
- package/docs/ARCHITECTURE.md +29 -41
- package/docs/CODE-REVIEW.md +100 -0
- package/docs/PREFLIGHT_REPORT.md +32 -40
- package/docs/REQUIREMENTS.md +148 -0
- package/docs/SECURITY-AUDIT.md +68 -0
- package/docs/TESTING.md +3 -4
- package/docs/test-trace-matrix.md +28 -0
- package/lib/billing-dashboard.html +6 -12
- package/lib/commands/deps.js +245 -0
- package/lib/commands/index.js +25 -0
- package/lib/commands/validate.js +85 -0
- package/lib/error-reporter.js +13 -1
- package/lib/github-api.js +108 -13
- package/lib/license-signing.js +110 -0
- package/lib/license-validator.js +359 -71
- package/lib/licensing.js +343 -111
- package/lib/prelaunch-validator.js +828 -0
- 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 +28 -9
- package/lib/template-loader.js +52 -19
- package/lib/validation/cache-manager.js +36 -6
- package/lib/validation/config-security.js +82 -15
- package/lib/validation/workflow-validation.js +49 -23
- package/package.json +8 -10
- package/scripts/check-test-coverage.sh +46 -0
- package/setup.js +356 -285
- package/templates/QUALITY_TROUBLESHOOTING.md +32 -33
- package/templates/scripts/smart-test-strategy.sh +1 -1
- 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
|
-
//
|
|
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
|
-
//
|
|
648
|
-
|
|
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/
|
|
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
|
-
|
|
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
|
-
//
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
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/
|
|
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'
|