create-qa-architect 5.0.1 → 5.0.7

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 (40) hide show
  1. package/.github/RELEASE_CHECKLIST.md +2 -4
  2. package/.github/workflows/daily-deploy-check.yml +136 -0
  3. package/.github/workflows/dependabot-auto-merge.yml +32 -0
  4. package/.github/workflows/nightly-gitleaks-verification.yml +1 -1
  5. package/.github/workflows/release.yml +12 -10
  6. package/.github/workflows/weekly-audit.yml +173 -0
  7. package/LICENSE +3 -3
  8. package/README.md +11 -17
  9. package/config/defaults.js +22 -1
  10. package/config/quality-config.schema.json +1 -1
  11. package/create-saas-monetization.js +65 -27
  12. package/docs/ARCHITECTURE.md +16 -13
  13. package/docs/DEPLOYMENT.md +1 -2
  14. package/docs/PREFLIGHT_REPORT.md +100 -0
  15. package/docs/TESTING.md +4 -6
  16. package/lib/billing-dashboard.html +6 -12
  17. package/lib/config-validator.js +8 -2
  18. package/lib/dependency-monitoring-premium.js +21 -19
  19. package/lib/github-api.js +249 -0
  20. package/lib/interactive/questions.js +4 -0
  21. package/lib/license-validator.js +1 -1
  22. package/lib/licensing.js +16 -18
  23. package/lib/package-utils.js +9 -8
  24. package/lib/project-maturity.js +1 -1
  25. package/lib/template-loader.js +2 -0
  26. package/lib/ui-helpers.js +2 -1
  27. package/lib/validation/base-validator.js +5 -1
  28. package/lib/validation/cache-manager.js +1 -0
  29. package/lib/validation/config-security.js +9 -4
  30. package/lib/validation/validation-factory.js +1 -1
  31. package/lib/validation/workflow-validation.js +27 -22
  32. package/lib/yaml-utils.js +15 -10
  33. package/package.json +17 -14
  34. package/scripts/check-docs.sh +63 -0
  35. package/scripts/smart-test-strategy.sh +98 -0
  36. package/scripts/test-e2e-package.sh +283 -0
  37. package/scripts/validate-command-patterns.js +112 -0
  38. package/setup.js +38 -9
  39. package/templates/QUALITY_TROUBLESHOOTING.md +32 -33
  40. package/templates/scripts/smart-test-strategy.sh +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-qa-architect",
3
- "version": "5.0.1",
3
+ "version": "5.0.7",
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": {
@@ -12,17 +12,17 @@
12
12
  "format": "prettier --write .",
13
13
  "format:check": "prettier --check .",
14
14
  "lint": "eslint . && stylelint \"**/*.{css,scss,sass,less,pcss}\" --allow-empty-input",
15
+ "type-check": "tsc --noEmit",
15
16
  "lint:fix": "eslint . --fix && stylelint \"**/*.{css,scss,sass,less,pcss}\" --fix --allow-empty-input",
16
17
  "security:audit": "npm audit --audit-level high",
17
18
  "security:secrets": "node -e \"const fs=require('fs');const content=fs.readFileSync('package.json','utf8');if(/[\\\"\\'][a-zA-Z0-9+/]{20,}[\\\"\\']/.test(content)){console.error('❌ Potential hardcoded secrets in package.json');process.exit(1)}else{console.log('✅ No secrets detected in package.json')}\"",
18
19
  "security:config": "node setup.js --security-config",
19
20
  "validate:docs": "node setup.js --validate-docs",
20
- "validate:claude": "node scripts/validate-claude-md.js",
21
21
  "validate:comprehensive": "node setup.js --comprehensive --no-markdownlint",
22
- "validate:all": "npm run validate:comprehensive && npm run security:audit && npm run validate:claude",
22
+ "validate:all": "npm run validate:comprehensive && npm run security:audit",
23
23
  "validate:pre-push": "npm run test:patterns --if-present && npm run lint && npm run format:check && npm run test:commands --if-present && npm test --if-present",
24
- "test": "export QAA_DEVELOPER=true && node tests/setup.test.js && node tests/integration.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/parallel-validation.test.js && node tests/python-integration.test.js && node tests/interactive.test.js && node tests/monorepo.test.js && node tests/template-loader.test.js && node tests/critical-fixes.test.js && node tests/interactive-routing-fix.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/premium-dependency-monitoring.test.js && node tests/multi-language-dependency-monitoring.test.js && node tests/cli-deps-integration.test.js && node tests/real-world-packages.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/python-detection-sensitivity.test.js && node tests/python-parser-fixes.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/real-purchase-flow.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/project-maturity-cli.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-claude-md.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js && node tests/gitleaks-real-binary-test.js && node tests/tier-enforcement.test.js",
25
- "test:unit": "export QAA_DEVELOPER=true && node tests/setup.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/template-loader.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-claude-md.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",
24
+ "test": "export QAA_DEVELOPER=true && node tests/setup.test.js && node tests/integration.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/parallel-validation.test.js && node tests/python-integration.test.js && node tests/interactive.test.js && node tests/monorepo.test.js && node tests/template-loader.test.js && node tests/critical-fixes.test.js && node tests/interactive-routing-fix.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/premium-dependency-monitoring.test.js && node tests/multi-language-dependency-monitoring.test.js && node tests/cli-deps-integration.test.js && node tests/real-world-packages.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/python-detection-sensitivity.test.js && node tests/python-parser-fixes.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/real-purchase-flow.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/project-maturity-cli.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js && node tests/gitleaks-real-binary-test.js && node tests/tier-enforcement.test.js",
25
+ "test:unit": "export QAA_DEVELOPER=true && node tests/setup.test.js && node tests/error-paths.test.js && node tests/error-messages.test.js && node tests/cache-manager.test.js && node tests/template-loader.test.js && node tests/telemetry.test.js && node tests/error-reporter.test.js && node tests/validation-factory.test.js && node tests/setup-error-coverage.test.js && node tests/licensing.test.js && node tests/security-licensing.test.js && node tests/base-validator.test.js && node tests/dependency-monitoring-basic.test.js && node tests/workflow-validation.test.js && node tests/setup-critical-paths.test.js && node tests/project-maturity.test.js && node tests/package-manager-detection.test.js && node tests/check-docs.test.js && node tests/validate-command-patterns.test.js && node tests/gitleaks-binary-resolution.test.js && node tests/gitleaks-production-checksums.test.js && node tests/gitleaks-checksum-verification.test.js",
26
26
  "test:fast": "npm run test:unit",
27
27
  "test:medium": "npm run test:fast && npm run test:patterns && npm run test:commands",
28
28
  "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",
@@ -73,6 +73,8 @@
73
73
  "legal/",
74
74
  "marketing/",
75
75
  "templates/",
76
+ "scripts/",
77
+ "LICENSE",
76
78
  ".github/",
77
79
  ".prettierrc",
78
80
  ".prettierignore",
@@ -84,12 +86,12 @@
84
86
  ],
85
87
  "repository": {
86
88
  "type": "git",
87
- "url": "git+https://github.com/brettstark73/qa-architect.git"
89
+ "url": "git+https://github.com/vibebuildlab/qa-architect.git"
88
90
  },
89
91
  "bugs": {
90
- "url": "https://github.com/brettstark73/qa-architect/issues"
92
+ "url": "https://github.com/vibebuildlab/qa-architect/issues"
91
93
  },
92
- "homepage": "https://github.com/brettstark73/qa-architect#readme",
94
+ "homepage": "https://vibebuildlab.com/qa-architect",
93
95
  "engines": {
94
96
  "node": ">=20"
95
97
  },
@@ -104,15 +106,17 @@
104
106
  }
105
107
  },
106
108
  "devDependencies": {
109
+ "@types/node": "^20",
107
110
  "actionlint": "^2.0.6",
111
+ "typescript": "^5",
108
112
  "c8": "^10.1.2",
109
- "eslint": "^9.12.0",
113
+ "eslint": "^9.39.2",
110
114
  "eslint-plugin-security": "^3.0.1",
111
115
  "globals": "^15.9.0",
112
116
  "husky": "^9.1.4",
113
117
  "lint-staged": "^15.2.10",
114
- "prettier": "^3.3.3",
115
- "stylelint": "^16.8.0",
118
+ "prettier": "^3.7.4",
119
+ "stylelint": "^16.26.1",
116
120
  "stylelint-config-standard": "^37.0.0"
117
121
  },
118
122
  "volta": {
@@ -121,7 +125,6 @@
121
125
  },
122
126
  "lint-staged": {
123
127
  "CLAUDE.md": [
124
- "node scripts/validate-claude-md.js",
125
128
  "prettier --write"
126
129
  ],
127
130
  "config/defaults.js": [
@@ -156,11 +159,11 @@
156
159
  ]
157
160
  },
158
161
  "dependencies": {
159
- "@npmcli/package-json": "^7.0.1",
162
+ "@npmcli/package-json": "^7.0.4",
160
163
  "ajv": "^8.17.1",
161
164
  "ajv-formats": "^3.0.1",
162
165
  "js-yaml": "^4.1.0",
163
- "markdownlint-cli2": "^0.19.0",
166
+ "markdownlint-cli2": "^0.20.0",
164
167
  "ora": "^8.1.1",
165
168
  "tar": "^7.4.3"
166
169
  }
@@ -0,0 +1,63 @@
1
+ #!/bin/bash
2
+ # Documentation consistency checker
3
+ # Run before any release to catch documentation gaps
4
+
5
+ set -e
6
+
7
+ echo "🔍 Checking documentation consistency..."
8
+
9
+ # Check version consistency
10
+ PACKAGE_VERSION=$(node -p "require('./package.json').version")
11
+ if ! grep -q "## \[$PACKAGE_VERSION\]" CHANGELOG.md; then
12
+ echo "❌ CHANGELOG.md missing entry for version $PACKAGE_VERSION"
13
+ exit 1
14
+ fi
15
+
16
+ # Check that setup.js file creation matches README documentation
17
+ echo "📁 Verifying file inventory..."
18
+
19
+ # Extract files created by setup.js
20
+ SETUP_FILES=$(grep -E "writeFileSync.*Path" setup.js | sed -E 's/.*writeFileSync\([^,]+, [^)]+\)//' | wc -l)
21
+ echo "Setup script creates approximately $SETUP_FILES files"
22
+
23
+ # Check for common missing files in README
24
+ MISSING_FILES=()
25
+
26
+ if grep -q "\.nvmrc" setup.js && ! grep -q "\.nvmrc" README.md; then
27
+ MISSING_FILES+=(".nvmrc")
28
+ fi
29
+
30
+ if grep -q "\.npmrc" setup.js && ! grep -q "\.npmrc" README.md; then
31
+ MISSING_FILES+=(".npmrc")
32
+ fi
33
+
34
+ if grep -q "stylelintrc" setup.js && ! grep -q "stylelintrc" README.md; then
35
+ MISSING_FILES+=(".stylelintrc.json")
36
+ fi
37
+
38
+ if grep -q "lighthouserc" setup.js && ! grep -q "lighthouserc" README.md; then
39
+ MISSING_FILES+=(".lighthouserc.js")
40
+ fi
41
+
42
+ if [ ${#MISSING_FILES[@]} -gt 0 ]; then
43
+ echo "❌ README.md missing documentation for files:"
44
+ printf ' - %s\n' "${MISSING_FILES[@]}"
45
+ exit 1
46
+ fi
47
+
48
+ # Check for Python features if implemented
49
+ if grep -q "Python" setup.js; then
50
+ if ! grep -q "Python" README.md; then
51
+ echo "❌ Python features implemented but not documented in README.md"
52
+ exit 1
53
+ fi
54
+ fi
55
+
56
+ # Security validation is now handled by:
57
+ # - /bs:audit --security command
58
+ # - security-auditor agent
59
+ # - npm audit in CI workflows
60
+ # - gitleaks in pre-push hooks
61
+ echo "🔐 Security validation handled by automated tooling (npm audit, gitleaks, CI workflows)"
62
+
63
+ echo "✅ Documentation consistency checks passed!"
@@ -0,0 +1,98 @@
1
+ #!/bin/bash
2
+ # Smart Test Strategy - QA Architect
3
+ set -e
4
+
5
+ echo "🧠 Analyzing changes for optimal test strategy..."
6
+
7
+ # =============================================================================
8
+ # SECURITY: Always run npm audit for critical vulnerabilities (fast, ~2 seconds)
9
+ # =============================================================================
10
+ echo ""
11
+ echo "🔒 Running security audit (critical vulnerabilities only)..."
12
+ if npm audit --audit-level=critical --omit=dev 2>/dev/null; then
13
+ echo "✅ No critical vulnerabilities found"
14
+ else
15
+ echo "❌ CRITICAL vulnerabilities detected! Fix before pushing."
16
+ echo " Run: npm audit fix"
17
+ exit 1
18
+ fi
19
+ echo ""
20
+
21
+ # Collect metrics
22
+ CHANGED_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null | wc -l | tr -d ' ')
23
+ CHANGED_LINES=$(git diff --stat HEAD~1..HEAD 2>/dev/null | tail -1 | grep -o '[0-9]* insertions' | grep -o '[0-9]*' || echo "0")
24
+ CURRENT_BRANCH=$(git branch --show-current)
25
+ HOUR=$(date +%H)
26
+ DAY_OF_WEEK=$(date +%u)
27
+
28
+ # Project-specific high-risk patterns
29
+ HIGH_RISK_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null | grep -E "(setup\.js|lib/.*|templates/.*|config/.*)" || true)
30
+ API_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null | grep -E "api/" || true)
31
+ CONFIG_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null | grep -E "(package\.json|\.env|config)" || true)
32
+ TEST_FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null | grep -E "test|spec" || true)
33
+
34
+ # Calculate risk score (0-10)
35
+ RISK_SCORE=0
36
+
37
+ # File-based risk
38
+ [[ -n "$HIGH_RISK_FILES" ]] && RISK_SCORE=$((RISK_SCORE + 4))
39
+ [[ -n "$API_FILES" ]] && RISK_SCORE=$((RISK_SCORE + 2))
40
+ [[ -n "$CONFIG_FILES" ]] && RISK_SCORE=$((RISK_SCORE + 2))
41
+
42
+ # Size-based risk
43
+ [[ $CHANGED_FILES -gt 10 ]] && RISK_SCORE=$((RISK_SCORE + 2))
44
+ [[ $CHANGED_FILES -gt 20 ]] && RISK_SCORE=$((RISK_SCORE + 3))
45
+ [[ $CHANGED_LINES -gt 200 ]] && RISK_SCORE=$((RISK_SCORE + 2))
46
+
47
+ # Branch-based risk
48
+ case $CURRENT_BRANCH in
49
+ main|master|production) RISK_SCORE=$((RISK_SCORE + 3)) ;;
50
+ hotfix/*) RISK_SCORE=$((RISK_SCORE + 4)) ;;
51
+ release/*) RISK_SCORE=$((RISK_SCORE + 2)) ;;
52
+ develop) RISK_SCORE=$((RISK_SCORE + 1)) ;;
53
+ esac
54
+
55
+ # Time pressure adjustment (strip leading zeros)
56
+ HOUR_NUM=$((10#$HOUR))
57
+ if [[ $HOUR_NUM -ge 9 && $HOUR_NUM -le 17 && $DAY_OF_WEEK -le 5 ]]; then
58
+ SPEED_BONUS=true
59
+ else
60
+ SPEED_BONUS=false
61
+ fi
62
+
63
+ # Display analysis
64
+ echo "📊 Analysis Results:"
65
+ echo " 📁 Files: $CHANGED_FILES"
66
+ echo " 📏 Lines: $CHANGED_LINES"
67
+ echo " 🌿 Branch: $CURRENT_BRANCH"
68
+ echo " 🎯 Risk Score: $RISK_SCORE/10"
69
+ echo " ⚡ Speed Bonus: $SPEED_BONUS"
70
+ echo ""
71
+
72
+ # Decision logic
73
+ # NOTE: test:commands and test:e2e are ALWAYS excluded from pre-push (run in CI only)
74
+ # - test:commands: Takes 60+ seconds, verifies npm scripts work in isolated env
75
+ # - test:e2e: Requires browser/package build, CI has better infrastructure
76
+ # These run in GitHub Actions on every PR and push to main
77
+
78
+ if [[ $RISK_SCORE -ge 7 ]]; then
79
+ echo "🔴 HIGH RISK - Comprehensive validation (pre-push)"
80
+ echo " • Patterns + unit tests + security audit"
81
+ echo " • (command + e2e tests run in CI only)"
82
+ npm run test:patterns && npm test && npm run security:audit
83
+ elif [[ $RISK_SCORE -ge 4 ]]; then
84
+ echo "🟡 MEDIUM RISK - Standard validation"
85
+ echo " • Fast tests + patterns"
86
+ npm run test:patterns && npm run test:fast
87
+ elif [[ $RISK_SCORE -ge 2 || "$SPEED_BONUS" == "false" ]]; then
88
+ echo "🟢 LOW RISK - Fast validation"
89
+ echo " • Unit tests only"
90
+ npm run test:fast
91
+ else
92
+ echo "⚪ MINIMAL RISK - Quality checks only"
93
+ echo " • Lint + format check"
94
+ npm run lint && npm run format:check
95
+ fi
96
+
97
+ echo ""
98
+ echo "💡 Tip: Run 'npm run test:comprehensive' locally for full validation"
@@ -0,0 +1,283 @@
1
+ #!/bin/bash
2
+ # E2E Package Test - Validates the package works for consumers
3
+ # Catches issues like Codex findings before release
4
+
5
+ set -e
6
+
7
+ # Use isolated npm cache to avoid permission issues on shared caches
8
+ export npm_config_cache="${npm_config_cache:-$(mktemp -d)}"
9
+ export NPM_CONFIG_CACHE="$npm_config_cache"
10
+ # Disable husky during packaging so pack works in CI/sandboxed environments
11
+ export HUSKY=0
12
+
13
+ echo "🧪 E2E Package Validation Test"
14
+ echo "================================"
15
+ echo ""
16
+
17
+ # Colors
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ NC='\033[0m' # No Color
22
+
23
+ # Track failures
24
+ FAILURES=0
25
+
26
+ fail() {
27
+ echo -e "${RED}❌ $1${NC}"
28
+ FAILURES=$((FAILURES + 1))
29
+ }
30
+
31
+ pass() {
32
+ echo -e "${GREEN}✅ $1${NC}"
33
+ }
34
+
35
+ warn() {
36
+ echo -e "${YELLOW}⚠️ $1${NC}"
37
+ }
38
+
39
+ # 1. Package Contents Validation
40
+ echo "📦 Step 1: Validating package contents..."
41
+ echo "Running: npm pack (scripts disabled)"
42
+ TARBALL=$(npm pack --ignore-scripts 2>&1 | tail -1)
43
+
44
+ if [ ! -f "$TARBALL" ]; then
45
+ fail "npm pack failed to create tarball"
46
+ exit 1
47
+ fi
48
+
49
+ pass "Created tarball: $TARBALL"
50
+
51
+ # Extract tarball and check files
52
+ EXTRACT_DIR=$(mktemp -d)
53
+ tar -xzf "$TARBALL" -C "$EXTRACT_DIR"
54
+ PKG_DIR="$EXTRACT_DIR/package"
55
+
56
+ echo " Checking required files in package..."
57
+ REQUIRED_FILES=(
58
+ "setup.js"
59
+ ".prettierrc"
60
+ ".prettierignore"
61
+ "eslint.config.cjs"
62
+ "eslint.config.ts.cjs"
63
+ ".stylelintrc.json"
64
+ ".editorconfig"
65
+ ".nvmrc"
66
+ "config/defaults.js"
67
+ "lib/validation/index.js"
68
+ ".github/workflows/quality.yml"
69
+ )
70
+ # Note: .npmrc is intentionally excluded - npm won't package it anyway (local config only)
71
+
72
+ for file in "${REQUIRED_FILES[@]}"; do
73
+ if [ -f "$PKG_DIR/$file" ] || [ -d "$PKG_DIR/$file" ]; then
74
+ pass " $file"
75
+ else
76
+ fail " Missing required file: $file"
77
+ fi
78
+ done
79
+
80
+ # 2. Consumer Installation Simulation
81
+ echo ""
82
+ echo "🏗️ Step 2: Simulating consumer installation..."
83
+ TEST_DIR=$(mktemp -d)
84
+ cd "$TEST_DIR"
85
+
86
+ echo " Creating test project..."
87
+ git init -q
88
+ git config user.email "test@example.com"
89
+ git config user.name "Test User"
90
+
91
+ cat > package.json <<'EOF'
92
+ {
93
+ "name": "e2e-test-consumer",
94
+ "version": "1.0.0",
95
+ "description": "E2E test consumer",
96
+ "keywords": ["test"],
97
+ "license": "MIT"
98
+ }
99
+ EOF
100
+
101
+ pass "Test project created"
102
+
103
+ echo " Installing from tarball..."
104
+ npm install "$OLDPWD/$TARBALL" --silent 2>&1 > /dev/null || {
105
+ fail "npm install from tarball failed"
106
+ cd "$OLDPWD"
107
+ rm -rf "$TEST_DIR" "$EXTRACT_DIR"
108
+ rm -f "$TARBALL"
109
+ exit 1
110
+ }
111
+
112
+ pass "Package installed"
113
+
114
+ # 3. Run setup
115
+ echo ""
116
+ echo "🚀 Step 3: Running setup..."
117
+ SETUP_OUTPUT=$(QAA_DEVELOPER=true node ./node_modules/create-qa-architect/setup.js 2>&1)
118
+ echo "$SETUP_OUTPUT" | grep -q "Setting up Quality Automation" && pass "Setup executed" || fail "Setup failed"
119
+ echo " Setup output:"
120
+ echo "$SETUP_OUTPUT" | head -20
121
+
122
+ # 4. Verify generated files
123
+ echo ""
124
+ echo "📋 Step 4: Verifying generated files..."
125
+ EXPECTED_FILES=(
126
+ ".prettierrc"
127
+ ".prettierignore"
128
+ "eslint.config.cjs"
129
+ ".stylelintrc.json"
130
+ ".editorconfig"
131
+ ".nvmrc"
132
+ ".npmrc"
133
+ ".github/workflows/quality.yml"
134
+ )
135
+
136
+ for file in "${EXPECTED_FILES[@]}"; do
137
+ if [ -f "$file" ]; then
138
+ pass " Generated: $file"
139
+ else
140
+ fail " Missing generated file: $file"
141
+ fi
142
+ done
143
+
144
+ # 5. Validate package.json modifications
145
+ echo ""
146
+ echo "📝 Step 5: Validating package.json modifications..."
147
+
148
+ if grep -q "\"format\":" package.json; then
149
+ pass " npm scripts added"
150
+ else
151
+ fail " npm scripts not added"
152
+ fi
153
+
154
+ if grep -q "husky" package.json; then
155
+ pass " devDependencies added"
156
+ else
157
+ fail " devDependencies not added"
158
+ fi
159
+
160
+ if grep -q "lint-staged" package.json; then
161
+ pass " lint-staged config added"
162
+ else
163
+ fail " lint-staged config not added"
164
+ fi
165
+
166
+ # 6. Test npm scripts use npx (not node setup.js)
167
+ echo ""
168
+ echo "🔍 Step 6: Validating npm scripts use npx..."
169
+
170
+ if grep -q "\"security:config.*npx create-qa-architect" package.json; then
171
+ pass " security:config uses npx"
172
+ else
173
+ fail " security:config doesn't use npx (Codex finding regression!)"
174
+ fi
175
+
176
+ if grep -q "\"validate:docs.*npx create-qa-architect" package.json; then
177
+ pass " validate:docs uses npx"
178
+ else
179
+ fail " validate:docs doesn't use npx (Codex finding regression!)"
180
+ fi
181
+
182
+ # 7. Validate workflow doesn't have UNCONDITIONAL setup.js references
183
+ echo ""
184
+ echo "🔧 Step 7: Validating generated workflow..."
185
+
186
+ # The workflow can have conditional references like:
187
+ # if [ -f "setup.js" ]; then
188
+ # node setup.js --something
189
+ # fi
190
+ # But should NOT have unconditional references like the old:
191
+ # node "$GITHUB_WORKSPACE/setup.js"
192
+ #
193
+ # Check for the specific bad pattern we fixed (Codex finding)
194
+ if grep -q 'node "$GITHUB_WORKSPACE/setup.js"' .github/workflows/quality.yml; then
195
+ fail " Workflow has unconditional GITHUB_WORKSPACE setup.js reference (Codex finding regression!)"
196
+ else
197
+ pass " Workflow doesn't have unconditional setup.js references"
198
+ fi
199
+
200
+ # Conditional references with guards are OK (will fallback in consumer repos)
201
+
202
+ # 8. NEW: Actually run the generated commands (catches broken CLI flags!)
203
+ echo ""
204
+ echo "🚀 Step 8: Testing generated commands actually work..."
205
+ echo " This step would have caught the ESLint --ext bug!"
206
+
207
+ # Install devDependencies first
208
+ echo " Installing devDependencies..."
209
+ npm install --silent > /dev/null 2>&1 || {
210
+ fail " npm install failed"
211
+ }
212
+
213
+ # Create test files for commands to process
214
+ # Use valid code that won't trigger linting errors
215
+ echo "module.exports = { name: 'test' };" > test.js
216
+ echo "body { color: red; }" > test.css
217
+
218
+ # Test format:check - should work (even if files need formatting)
219
+ echo " Testing: npm run format:check"
220
+ # Format the files first so format:check passes
221
+ npm run format >/dev/null 2>&1
222
+ if npm run format:check 2>&1 >/dev/null; then
223
+ pass " format:check works"
224
+ else
225
+ fail " format:check failed (check Prettier flags!)"
226
+ fi
227
+
228
+ # Test lint (CRITICAL: this would have caught --ext bug!)
229
+ echo " Testing: npm run lint"
230
+ LINT_OUTPUT=$(npm run lint 2>&1)
231
+ if echo "$LINT_OUTPUT" | grep -q "error"; then
232
+ fail " lint failed (check for deprecated flags like --ext!)"
233
+ echo " ESLint error output:"
234
+ echo "$LINT_OUTPUT" | grep -A 5 "error" | head -10
235
+ else
236
+ pass " lint works"
237
+ fi
238
+
239
+ # Test direct ESLint
240
+ echo " Testing: npx eslint test.js"
241
+ if npx eslint test.js 2>&1 >/dev/null; then
242
+ pass " Direct ESLint works"
243
+ else
244
+ fail " Direct ESLint failed"
245
+ fi
246
+
247
+ # Test stylelint
248
+ echo " Testing: npx stylelint test.css"
249
+ if npx stylelint test.css 2>&1 >/dev/null; then
250
+ pass " Stylelint works"
251
+ else
252
+ fail " Stylelint failed"
253
+ fi
254
+
255
+ # 9. Test --dry-run mode
256
+ echo ""
257
+ echo "🧪 Step 9: Testing --dry-run mode..."
258
+ cd "$OLDPWD"
259
+ if node ./setup.js --dry-run 2>&1 | grep -q "DRY RUN MODE"; then
260
+ pass "--dry-run mode works"
261
+ else
262
+ fail "--dry-run mode doesn't work"
263
+ fi
264
+
265
+ # Cleanup
266
+ cd "$OLDPWD"
267
+ rm -rf "$TEST_DIR" "$EXTRACT_DIR"
268
+ rm -f "$TARBALL"
269
+
270
+ # Report
271
+ echo ""
272
+ echo "================================"
273
+ if [ $FAILURES -eq 0 ]; then
274
+ echo -e "${GREEN}✅ All E2E tests passed!${NC}"
275
+ echo ""
276
+ echo "Package is ready for release."
277
+ exit 0
278
+ else
279
+ echo -e "${RED}❌ $FAILURES test(s) failed${NC}"
280
+ echo ""
281
+ echo "Fix these issues before releasing."
282
+ exit 1
283
+ fi
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ /**
5
+ * Validates that command patterns in config/defaults.js
6
+ * don't contain known deprecated patterns
7
+ *
8
+ * This prevents issues like the ESLint --ext bug from being committed
9
+ */
10
+
11
+ const fs = require('fs')
12
+ const path = require('path')
13
+
14
+ const DEPRECATED_PATTERNS = [
15
+ {
16
+ pattern: /eslint.*--ext\s+\S+/,
17
+ message: 'ESLint --ext flag is deprecated in ESLint 9 flat config',
18
+ file: 'config/defaults.js',
19
+ suggestion: 'Use "eslint ." - file selection is in eslint.config.js',
20
+ },
21
+ {
22
+ pattern: /husky install/,
23
+ message: 'husky install is deprecated in Husky 9+',
24
+ file: 'config/defaults.js',
25
+ suggestion: 'Use just "husky" as the prepare script',
26
+ },
27
+ {
28
+ pattern: /prettier.*--no-semi/,
29
+ message: '--no-semi is deprecated in Prettier 3+',
30
+ file: 'config/defaults.js',
31
+ suggestion: 'Use .prettierrc configuration file',
32
+ },
33
+ {
34
+ pattern: /stylelint.*--config\s+\S+/,
35
+ message: 'Stylelint --config flag should use config file',
36
+ file: 'config/defaults.js',
37
+ suggestion: 'Use .stylelintrc.json instead',
38
+ },
39
+ ]
40
+
41
+ const FILES_TO_CHECK = [
42
+ 'config/defaults.js',
43
+ 'setup.js',
44
+ 'lib/package-utils.js',
45
+ ]
46
+
47
+ function validateFile(filePath, patterns) {
48
+ const fullPath = path.join(__dirname, '..', filePath)
49
+
50
+ if (!fs.existsSync(fullPath)) {
51
+ console.warn(`⚠️ File not found: ${filePath} (skipping)`)
52
+ return []
53
+ }
54
+
55
+ const content = fs.readFileSync(fullPath, 'utf8')
56
+ const errors = []
57
+
58
+ patterns.forEach(({ pattern, message, file, suggestion }) => {
59
+ // Only check patterns for this file
60
+ if (file && file !== filePath) {
61
+ return
62
+ }
63
+
64
+ if (pattern.test(content)) {
65
+ errors.push({
66
+ file: filePath,
67
+ message,
68
+ suggestion,
69
+ pattern: pattern.toString(),
70
+ })
71
+ }
72
+ })
73
+
74
+ return errors
75
+ }
76
+
77
+ function main() {
78
+ console.log('🔍 Validating command patterns...\n')
79
+
80
+ let totalErrors = 0
81
+ const allErrors = []
82
+
83
+ FILES_TO_CHECK.forEach(filePath => {
84
+ const errors = validateFile(filePath, DEPRECATED_PATTERNS)
85
+ totalErrors += errors.length
86
+ allErrors.push(...errors)
87
+ })
88
+
89
+ if (totalErrors > 0) {
90
+ console.error(`❌ Found ${totalErrors} deprecated pattern(s):\n`)
91
+
92
+ allErrors.forEach(({ file, message, suggestion, pattern }) => {
93
+ console.error(` ${file}:`)
94
+ console.error(` ❌ ${message}`)
95
+ console.error(` 💡 ${suggestion}`)
96
+ console.error(` 🔎 Pattern: ${pattern}`)
97
+ console.error('')
98
+ })
99
+
100
+ console.error('Fix these before committing!\n')
101
+ process.exit(1)
102
+ }
103
+
104
+ console.log('✅ No deprecated command patterns found')
105
+ process.exit(0)
106
+ }
107
+
108
+ if (require.main === module) {
109
+ main()
110
+ }
111
+
112
+ module.exports = { validateFile, DEPRECATED_PATTERNS }