create-qa-architect 5.0.0 → 5.0.6

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 (56) hide show
  1. package/.github/RELEASE_CHECKLIST.md +2 -4
  2. package/.github/workflows/daily-deploy-check.yml +136 -0
  3. package/.github/workflows/nightly-gitleaks-verification.yml +1 -1
  4. package/.github/workflows/quality.yml +3 -0
  5. package/.github/workflows/release.yml +12 -10
  6. package/.github/workflows/weekly-audit.yml +173 -0
  7. package/LICENSE +66 -0
  8. package/README.md +44 -30
  9. package/config/defaults.js +22 -1
  10. package/config/quality-config.schema.json +1 -1
  11. package/create-saas-monetization.js +75 -27
  12. package/docs/ARCHITECTURE.md +53 -0
  13. package/docs/DEPLOYMENT.md +62 -0
  14. package/docs/PREFLIGHT_REPORT.md +108 -0
  15. package/docs/SLA_GATES.md +28 -0
  16. package/docs/TESTING.md +61 -0
  17. package/docs/security/SOC2_STARTER.md +29 -0
  18. package/lib/config-validator.js +8 -2
  19. package/lib/dependency-monitoring-basic.js +73 -26
  20. package/lib/dependency-monitoring-premium.js +21 -19
  21. package/lib/github-api.js +249 -0
  22. package/lib/interactive/questions.js +4 -0
  23. package/lib/license-validator.js +1 -1
  24. package/lib/licensing.js +11 -10
  25. package/lib/package-utils.js +224 -8
  26. package/lib/project-maturity.js +1 -1
  27. package/lib/setup-enhancements.js +33 -0
  28. package/lib/template-loader.js +2 -0
  29. package/lib/ui-helpers.js +2 -1
  30. package/lib/validation/base-validator.js +5 -1
  31. package/lib/validation/cache-manager.js +1 -0
  32. package/lib/validation/config-security.js +5 -4
  33. package/lib/validation/validation-factory.js +1 -1
  34. package/lib/yaml-utils.js +15 -10
  35. package/package.json +18 -13
  36. package/scripts/check-docs.sh +63 -0
  37. package/scripts/smart-test-strategy.sh +98 -0
  38. package/scripts/test-e2e-package.sh +283 -0
  39. package/scripts/validate-command-patterns.js +112 -0
  40. package/setup.js +161 -44
  41. package/templates/QUALITY_TROUBLESHOOTING.md +403 -0
  42. package/templates/ci/circleci-config.yml +35 -0
  43. package/templates/ci/gitlab-ci.yml +47 -0
  44. package/templates/integration-tests/api-service.test.js +244 -0
  45. package/templates/integration-tests/frontend-app.test.js +267 -0
  46. package/templates/scripts/smart-test-strategy.sh +109 -0
  47. package/templates/test-stubs/e2e.smoke.test.js +12 -0
  48. package/templates/test-stubs/unit.test.js +7 -0
  49. package/legal/README.md +0 -106
  50. package/legal/copyright.md +0 -76
  51. package/legal/disclaimer.md +0 -146
  52. package/legal/privacy-policy.html +0 -324
  53. package/legal/privacy-policy.md +0 -196
  54. package/legal/terms-of-service.md +0 -224
  55. package/marketing/beta-user-email-campaign.md +0 -372
  56. package/marketing/landing-page.html +0 -721
@@ -13,6 +13,16 @@
13
13
  * - Conversion landing page
14
14
  * - Beta user email campaigns
15
15
  * - Upgrade prompts and messaging
16
+ *
17
+ * Roadmap / Future Ideas:
18
+ * - Extract licensing to shared npm package (@vibebuildlab/licensing)
19
+ * - Single source of truth across all Vibe Lab products
20
+ * - Central license server with one API for all products
21
+ * - Device/activation limits (optional enforcement)
22
+ * - License revocation for chargebacks
23
+ * - Team/seat-based licensing with org management
24
+ * - SSO/SAML integration for Enterprise tier
25
+ * - Usage-based billing option (metered pricing)
16
26
  */
17
27
 
18
28
  'use strict'
@@ -29,7 +39,7 @@ const FOUNDER_ENTERPRISE_PRICE = '74.50'
29
39
 
30
40
  class SaaSMonetizationBootstrap {
31
41
  constructor() {
32
- this.projectRoot = process.cwd()
42
+ this.projectRoot = path.resolve(process.cwd())
33
43
  this.config = {}
34
44
  this.templates = {
35
45
  stripe: this.getStripeTemplate(),
@@ -40,6 +50,56 @@ class SaaSMonetizationBootstrap {
40
50
  }
41
51
  }
42
52
 
53
+ resolveProjectPath(relativePath) {
54
+ const normalizedRoot = this.projectRoot.endsWith(path.sep)
55
+ ? this.projectRoot
56
+ : `${this.projectRoot}${path.sep}`
57
+ const resolvedPath = path.resolve(this.projectRoot, relativePath)
58
+
59
+ if (
60
+ resolvedPath !== this.projectRoot &&
61
+ !resolvedPath.startsWith(normalizedRoot)
62
+ ) {
63
+ throw new Error(
64
+ `Refusing to access path outside project root: ${relativePath}`
65
+ )
66
+ }
67
+
68
+ return resolvedPath
69
+ }
70
+
71
+ ensureDir(relativePath) {
72
+ const target = this.resolveProjectPath(relativePath)
73
+ // Path is constrained to the project root before touching the filesystem
74
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
75
+ if (!fs.existsSync(target)) {
76
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
77
+ fs.mkdirSync(target, { recursive: true })
78
+ }
79
+ return target
80
+ }
81
+
82
+ writeProjectFile(relativePath, content) {
83
+ const target = this.resolveProjectPath(relativePath)
84
+ // Path is constrained to the project root before touching the filesystem
85
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
86
+ fs.writeFileSync(target, content)
87
+ }
88
+
89
+ readProjectFile(relativePath) {
90
+ const target = this.resolveProjectPath(relativePath)
91
+ // Path is constrained to the project root before touching the filesystem
92
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
93
+ return fs.readFileSync(target, 'utf8')
94
+ }
95
+
96
+ projectFileExists(relativePath) {
97
+ const target = this.resolveProjectPath(relativePath)
98
+ // Path is constrained to the project root before touching the filesystem
99
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
100
+ return fs.existsSync(target)
101
+ }
102
+
43
103
  async run() {
44
104
  console.log('🚀 Create SaaS Monetization')
45
105
  console.log('═══════════════════════════════════')
@@ -149,10 +209,7 @@ class SaaSMonetizationBootstrap {
149
209
  const dirs = ['lib/monetization', 'legal', 'marketing', 'billing']
150
210
 
151
211
  dirs.forEach(dir => {
152
- const fullPath = path.join(this.projectRoot, dir)
153
- if (!fs.existsSync(fullPath)) {
154
- fs.mkdirSync(fullPath, { recursive: true })
155
- }
212
+ this.ensureDir(dir)
156
213
  })
157
214
  }
158
215
 
@@ -162,8 +219,8 @@ class SaaSMonetizationBootstrap {
162
219
  .replace(/{{PRO_PRICE}}/g, this.config.proPrice)
163
220
  .replace(/{{ENTERPRISE_PRICE}}/g, this.config.enterprisePrice)
164
221
 
165
- fs.writeFileSync(
166
- path.join(this.projectRoot, 'lib/monetization/stripe-integration.js'),
222
+ this.writeProjectFile(
223
+ path.join('lib/monetization', 'stripe-integration.js'),
167
224
  stripeCode
168
225
  )
169
226
  }
@@ -178,8 +235,8 @@ class SaaSMonetizationBootstrap {
178
235
  .replace(/{{FOUNDER_PRO_PRICE}}/g, this.config.founderProPrice)
179
236
  .replace(/{{DOMAIN}}/g, this.config.domain)
180
237
 
181
- fs.writeFileSync(
182
- path.join(this.projectRoot, 'lib/monetization/licensing.js'),
238
+ this.writeProjectFile(
239
+ path.join('lib/monetization', 'licensing.js'),
183
240
  licensingCode
184
241
  )
185
242
  }
@@ -194,7 +251,7 @@ class SaaSMonetizationBootstrap {
194
251
  .replace(/{{DESCRIPTION}}/g, this.config.description)
195
252
  .replace(/{{DATE}}/g, new Date().toISOString().split('T')[0])
196
253
 
197
- fs.writeFileSync(path.join(this.projectRoot, 'legal', filename), content)
254
+ this.writeProjectFile(path.join('legal', filename), content)
198
255
  }
199
256
  }
200
257
 
@@ -223,10 +280,7 @@ class SaaSMonetizationBootstrap {
223
280
  )
224
281
  .replace(/{{SUPPORT_EMAIL}}/g, this.config.supportEmail)
225
282
 
226
- fs.writeFileSync(
227
- path.join(this.projectRoot, 'marketing', filename),
228
- content
229
- )
283
+ this.writeProjectFile(path.join('marketing', filename), content)
230
284
  }
231
285
  }
232
286
 
@@ -242,17 +296,14 @@ class SaaSMonetizationBootstrap {
242
296
  )
243
297
  .replace(/{{PREMIUM_FEATURES}}/g, this.config.premiumFeatures)
244
298
 
245
- fs.writeFileSync(
246
- path.join(this.projectRoot, 'billing/dashboard.html'),
247
- billingCode
248
- )
299
+ this.writeProjectFile(path.join('billing', 'dashboard.html'), billingCode)
249
300
  }
250
301
 
251
302
  async updatePackageJson() {
252
- const packagePath = path.join(this.projectRoot, 'package.json')
303
+ const packagePath = 'package.json'
253
304
 
254
- if (fs.existsSync(packagePath)) {
255
- const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'))
305
+ if (this.projectFileExists(packagePath)) {
306
+ const pkg = JSON.parse(this.readProjectFile(packagePath))
256
307
 
257
308
  // Add monetization scripts
258
309
  pkg.scripts = pkg.scripts || {}
@@ -266,7 +317,7 @@ class SaaSMonetizationBootstrap {
266
317
  pkg.dependencies.stripe = '^14.15.0'
267
318
  pkg.dependencies.crypto = '^1.0.1'
268
319
 
269
- fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2))
320
+ this.writeProjectFile(packagePath, JSON.stringify(pkg, null, 2))
270
321
  }
271
322
  }
272
323
 
@@ -297,7 +348,7 @@ COMPANY_NAME=${this.config.companyName}
297
348
  # STRIPE_PUBLISHABLE_KEY=pk_live_your_live_key_here
298
349
  `
299
350
 
300
- fs.writeFileSync(path.join(this.projectRoot, '.env.template'), envTemplate)
351
+ this.writeProjectFile('.env.template', envTemplate)
301
352
  }
302
353
 
303
354
  async generateDeploymentGuide() {
@@ -473,10 +524,7 @@ For implementation questions:
473
524
  **Revenue Potential**: $1,500-5,000/month recurring
474
525
  `
475
526
 
476
- fs.writeFileSync(
477
- path.join(this.projectRoot, 'MONETIZATION_GUIDE.md'),
478
- guide
479
- )
527
+ this.writeProjectFile('MONETIZATION_GUIDE.md', guide)
480
528
  }
481
529
 
482
530
  // Template methods (condensed versions of our implementations)
@@ -0,0 +1,53 @@
1
+ # Architecture
2
+
3
+ ## Overview
4
+
5
+ QA Architect is a CLI tool that bootstraps quality automation in JavaScript/TypeScript and Python projects.
6
+
7
+ ## Core Components
8
+
9
+ ```
10
+ create-qa-architect/
11
+ ├── setup.js # Main CLI entry point
12
+ ├── lib/
13
+ │ ├── smart-strategy-generator.js # Smart test strategy (Pro)
14
+ │ ├── dependency-monitoring-*.js # Dependency monitoring
15
+ │ └── validation/ # Validation utilities
16
+ ├── templates/ # Project templates
17
+ │ ├── eslint.config.cjs
18
+ │ ├── .prettierrc
19
+ │ ├── .husky/
20
+ │ └── scripts/
21
+ └── config/ # Language-specific configs
22
+ ├── pyproject.toml
23
+ └── quality-python.yml
24
+ ```
25
+
26
+ ## Data Flow
27
+
28
+ 1. **Detection Phase**: Detect project type (JS/TS/Python/mixed)
29
+ 2. **Configuration Phase**: Generate appropriate configs
30
+ 3. **Installation Phase**: Copy templates, update package.json
31
+ 4. **Validation Phase**: Verify setup is complete
32
+
33
+ ## Extension Points
34
+
35
+ - Custom templates via `--template` flag
36
+ - Language detection can be extended in `setup.js`
37
+ - New quality checks via template files
38
+
39
+ ## Smart Test Strategy (Pro)
40
+
41
+ Risk-based pre-push validation that adapts to change context:
42
+
43
+ 1. Calculate risk score (0-10) based on files changed
44
+ 2. Select appropriate test tier (minimal → comprehensive)
45
+ 3. Run tests with appropriate depth
46
+
47
+ ## CLI Flags
48
+
49
+ - `--update` - Update existing setup
50
+ - `--deps` - Dependency monitoring only
51
+ - `--security-config` - Security validation
52
+ - `--check-maturity` - Project maturity report
53
+ - `--comprehensive` - Full validation suite
@@ -0,0 +1,62 @@
1
+ # Deployment Guide
2
+
3
+ ## Overview
4
+
5
+ QA Architect is published to npm as `create-qa-architect`.
6
+
7
+ ## Prerequisites
8
+
9
+ - Node.js 20+
10
+ - npm account with publish access
11
+ - Git repository access
12
+
13
+ ## Release Process
14
+
15
+ ### 1. Pre-Release Validation
16
+
17
+ ```bash
18
+ npm run prerelease # Run all tests and validations
19
+ npm run test:coverage # Verify coverage thresholds
20
+ ```
21
+
22
+ ### 2. Version Bump
23
+
24
+ ```bash
25
+ npm run release:patch # Bug fixes (1.0.x)
26
+ npm run release:minor # New features (1.x.0)
27
+ npm run release:major # Breaking changes (x.0.0)
28
+ ```
29
+
30
+ ### 3. Publish
31
+
32
+ GitHub Actions automatically publishes on tagged releases.
33
+
34
+ For manual publish:
35
+
36
+ ```bash
37
+ npm publish
38
+ ```
39
+
40
+ ## Verification
41
+
42
+ After release, verify:
43
+
44
+ ```bash
45
+ npx create-qa-architect@latest --version
46
+ npx create-qa-architect@latest --help
47
+ ```
48
+
49
+ ## Rollback
50
+
51
+ If issues are discovered:
52
+
53
+ ```bash
54
+ npm unpublish create-qa-architect@VERSION
55
+ # or
56
+ npm deprecate create-qa-architect@VERSION "Critical bug, use VERSION instead"
57
+ ```
58
+
59
+ ## npm Registry
60
+
61
+ - Package: https://www.npmjs.com/package/create-qa-architect
62
+ - Documentation: https://github.com/vibebuildlab/qa-architect
@@ -0,0 +1,108 @@
1
+ # Preflight Review: QA Architect (create-qa-architect)
2
+
3
+ **Depth**: standard
4
+ **Date**: 2025-12-09
5
+ **Version**: 5.0.2
6
+
7
+ ---
8
+
9
+ ## Overall Status: ✅ PASS
10
+
11
+ All critical launch blockers pass. Minor issues documented below are acceptable for npm package release.
12
+
13
+ ---
14
+
15
+ ## Critical Issues (P0) - Must Fix
16
+
17
+ | Issue | Category | Location | Fix |
18
+ | ----- | -------- | -------- | --- |
19
+ | None | - | - | - |
20
+
21
+ ---
22
+
23
+ ## Important Issues (P1) - Should Fix
24
+
25
+ | Issue | Category | Location | Recommendation |
26
+ | ------------------------ | -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------ |
27
+ | Gitleaks false positives | Security | tests/\*.test.js | Test fixtures use fake API key patterns (QAA-XXXX format); not real secrets. Consider adding `.gitleaksignore` for test files. |
28
+ | npm version mismatch | Release | package.json | Local 5.0.2, npm shows 5.0.1. Publish pending or recently published. |
29
+
30
+ ---
31
+
32
+ ## P0 Functional Checks
33
+
34
+ | Check | Status | Notes |
35
+ | ----------------- | ------ | ---------------------- |
36
+ | All tests passing | ✅ | Full test suite passes |
37
+ | npm audit | ✅ | 0 vulnerabilities |
38
+ | ESLint | ✅ | No errors |
39
+ | Build/validation | ✅ | Core validation passes |
40
+
41
+ ---
42
+
43
+ ## P0 Security Checks
44
+
45
+ | Check | Status | Notes |
46
+ | ------------------------- | ------ | -------------------------------------------------------------------- |
47
+ | npm audit (high/critical) | ✅ | 0 vulnerabilities found |
48
+ | Hardcoded secrets scan | ⚠️ | 4 findings - all in test files with fake keys (QAA-1234-XXXX format) |
49
+ | No production secrets | ✅ | No `.env` files, no real API keys |
50
+
51
+ ---
52
+
53
+ ## Product Packaging
54
+
55
+ | Item | Status | Notes |
56
+ | ------------ | ------ | ----------------------- |
57
+ | CHANGELOG.md | ✅ | Present |
58
+ | LICENSE | ✅ | Present |
59
+ | README.md | ✅ | Present |
60
+ | .env.example | N/A | Not needed for CLI tool |
61
+ | Version tags | ✅ | v4.3.0 - v5.0.2 |
62
+ | Git status | ✅ | Clean working tree |
63
+
64
+ ---
65
+
66
+ ## Quality Violations
67
+
68
+ | Type | Count | Assessment |
69
+ | ----------------------- | ----- | ------------------------------------------------------------ |
70
+ | eslint-disable comments | 24 | All have security justification comments explaining why safe |
71
+ | any types | 0 | JavaScript project, N/A |
72
+
73
+ **Note**: The `eslint-disable` comments are all for security-related ESLint rules (detect-unsafe-regex, detect-non-literal-fs-filename, detect-object-injection) and each includes a detailed safety justification explaining why the pattern is safe in context.
74
+
75
+ ---
76
+
77
+ ## Silent Killer Check (N/A for npm package)
78
+
79
+ | Integration | Status | Notes |
80
+ | --------------- | ------ | --------------------- |
81
+ | Stripe webhooks | N/A | CLI tool, no webhooks |
82
+ | OAuth redirects | N/A | CLI tool |
83
+ | API keys | N/A | CLI tool |
84
+ | CORS config | N/A | CLI tool |
85
+
86
+ ---
87
+
88
+ ## Next Steps
89
+
90
+ 1. **Optional**: Add `.gitleaksignore` to exclude test files with fake license keys
91
+ 2. **Verify**: Confirm npm publish completed for 5.0.2 (may be propagating)
92
+ 3. **Ready**: Proceed with launch/release announcement
93
+
94
+ ---
95
+
96
+ ## Recommendation
97
+
98
+ **✅ CLEARED FOR LAUNCH**
99
+
100
+ This is an npm CLI package, not a web application. All critical checks pass:
101
+
102
+ - Tests passing
103
+ - No security vulnerabilities
104
+ - No real secrets
105
+ - Clean git state
106
+ - Proper versioning and packaging
107
+
108
+ The gitleaks findings are false positives on intentional test fixtures using fake license key formats.
@@ -0,0 +1,28 @@
1
+ # Quality Gates & Merge Readiness (Default Recommendations)
2
+
3
+ These defaults are meant to give teams a simple, enforceable bar. They are intentionally conservative so most repos can adopt them on day one without re-architecting.
4
+
5
+ ## Targets
6
+
7
+ - Coverage: **80%** (line) for critical paths; **70%** repo-wide minimum.
8
+ - Lint: **0** blocking ESLint/Stylelint errors; warnings allowed but surface in PR comment/summary.
9
+ - Secrets: **0** leaked secrets (gitleaks hard fail).
10
+ - Dependency vulns: No **high/critical** advisories (npm/yarn/pnpm audit). Medium allowed with justification.
11
+ - Performance budgets (CI): installs < 2m; test suite < 5m (already enforced in workflow).
12
+
13
+ ## How to enforce
14
+
15
+ - GitHub Actions: quality.yml is wired to fail on lint/scan/test failures. Set env `MIN_COVERAGE=80` to gate on coverage (add a coverage reporter such as `c8` or `vitest --coverage`).
16
+ - Branch protection: require the “Quality Checks” workflow to pass; enable dismiss stale approvals on push.
17
+ - PR comments: run setup with `--pr-comments` to surface gate status in the PR thread.
18
+ - Alerts: run setup with `--alerts-slack` to post failures to Slack.
19
+
20
+ ## Exceptions
21
+
22
+ - Allow temporary waivers via labels (e.g., `risk-accepted`) and document in the PR body.
23
+ - Lower coverage floors for greenfield proofs-of-concept (set `MIN_COVERAGE=60`) but time-box the exemption.
24
+
25
+ ## Next steps
26
+
27
+ - Add repo-specific risk areas to `.qualityrc.json` under `riskAreas`.
28
+ - Track SLA drift in reports (future: audit log + team dashboard hooks).
@@ -0,0 +1,61 @@
1
+ # Testing Strategy
2
+
3
+ ## Overview
4
+
5
+ QA Architect uses Jest for testing with a focus on integration tests that validate real CLI workflows.
6
+
7
+ ## Running Tests
8
+
9
+ ```bash
10
+ npm test # Run all tests
11
+ npm run test:coverage # Run with coverage report
12
+ npm run test:watch # Watch mode for development
13
+ ```
14
+
15
+ ## Test Structure
16
+
17
+ ```
18
+ tests/
19
+ ├── setup.test.js # Main CLI integration tests
20
+ ├── cli-deps-integration.test.js # Dependency CLI tests
21
+ ├── real-world-packages.test.js # Real package validation
22
+ └── premium-dependency-monitoring.test.js # Pro feature tests
23
+ ```
24
+
25
+ ## Coverage Requirements
26
+
27
+ - **Overall**: 75%+ lines, statements, functions, branches
28
+ - **New files**: 75%+ coverage before merging
29
+ - **Critical files**: `setup.js` requires 80%+
30
+
31
+ ## Testing Patterns
32
+
33
+ ### Integration Tests
34
+
35
+ Test real CLI workflows with temp directories:
36
+
37
+ ```javascript
38
+ const testDir = createTempGitRepo()
39
+ const result = execSync('node setup.js --deps', { cwd: testDir })
40
+ assert(fs.existsSync(path.join(testDir, '.github/dependabot.yml')))
41
+ ```
42
+
43
+ ### Real-World Data
44
+
45
+ Use real packages from the ecosystem, not toy examples:
46
+
47
+ ```javascript
48
+ const TOP_PYTHON_PACKAGES = [
49
+ 'django-cors-headers',
50
+ 'scikit-learn',
51
+ 'pytest-cov',
52
+ ]
53
+ ```
54
+
55
+ ## Pre-Release Validation
56
+
57
+ Always run before release:
58
+
59
+ ```bash
60
+ npm run prerelease # Runs docs:check + all tests
61
+ ```
@@ -0,0 +1,29 @@
1
+ # SOC 2 Starter (Preflight Checklist)
2
+
3
+ This starter doc is a lightweight preflight for teams using QA Architect. It is not a substitute for a real SOC 2 program, but it maps common CI/quality controls to SOC 2 CC/PII areas.
4
+
5
+ ## Controls to Wire First
6
+
7
+ - **Change Management (CC8.1):** Require PR review + Quality Checks workflow pass; enable branch protection on main.
8
+ - **Secure SDLC (CC6.1):** Keep ESLint security, gitleaks, dependency audit steps enabled; document exceptions in PRs.
9
+ - **Logging & Alerts (CC7.2):** Turn on Slack alerts via `--alerts-slack` and keep CI logs for 90 days.
10
+ - **Backup of Config (CC9.2):** Check in `.qualityrc.json`, `quality.yml`, and Dependabot configs; avoid secrets in repo.
11
+ - **Access (CC6.2):** Use least-privilege GitHub tokens; rotate `GITLEAKS_TOKEN`/`SEMGREP_APP_TOKEN` every 90 days.
12
+
13
+ ## Evidence You Can Collect Today
14
+
15
+ - CI run artifacts showing lint/test/security passes.
16
+ - Dependency audit reports (npm audit logs) and gitleaks scan results.
17
+ - Coverage reports (c8/Vitest/Jest) stored in artifacts.
18
+ - PR comments from quality workflow (when `--pr-comments` is enabled).
19
+
20
+ ## Gaps to plan for
21
+
22
+ - **SSO/SAML & RBAC:** Roadmap item (Enterprise); track in issue tracker.
23
+ - **Audit logging:** Add a central log sink (e.g., S3/CloudWatch) for CI events.
24
+ - **Vendor risk:** Document third-party actions; pin SHAs (already pinned in quality.yml) and review quarterly.
25
+
26
+ ## How to use this file
27
+
28
+ - Keep it checked in; edit per repo to note exceptions and waivers.
29
+ - Link it in onboarding docs so new contributors know the expected bar.
@@ -1,10 +1,16 @@
1
1
  'use strict'
2
2
 
3
- const Ajv = require('ajv')
4
- const addFormats = require('ajv-formats')
3
+ const AjvImport = require('ajv')
4
+ const addFormatsImport = require('ajv-formats')
5
5
  const fs = require('fs')
6
6
  const path = require('path')
7
7
 
8
+ // Handle CJS/ESM interop for Ajv and ajv-formats in JS type-checking
9
+ const Ajv = /** @type {any} */ (AjvImport.default || AjvImport)
10
+ const addFormats = /** @type {(ajv: any) => void} */ (
11
+ addFormatsImport.default || addFormatsImport
12
+ )
13
+
8
14
  function validateQualityConfig(configPath) {
9
15
  const result = {
10
16
  valid: false,
@@ -17,6 +17,7 @@ function hasNpmProject(projectPath) {
17
17
  /**
18
18
  * Generate basic Dependabot configuration (Free Tier)
19
19
  * Limited to npm only, no framework detection, basic settings
20
+ * Supports monorepo per-package directories
20
21
  */
21
22
  function generateBasicDependabotConfig(options = {}) {
22
23
  const {
@@ -24,49 +25,95 @@ function generateBasicDependabotConfig(options = {}) {
24
25
  schedule = 'weekly',
25
26
  day = 'monday',
26
27
  time = '09:00',
28
+ monorepoInfo = null, // Optional monorepo detection result
27
29
  } = options
28
30
 
29
31
  if (!hasNpmProject(projectPath)) {
30
32
  return null // Only npm projects supported in free tier
31
33
  }
32
34
 
33
- const config = {
34
- version: 2,
35
- updates: [
36
- {
35
+ const updates = []
36
+
37
+ // If monorepo with resolved packages, create per-package entries
38
+ if (
39
+ monorepoInfo &&
40
+ monorepoInfo.isMonorepo &&
41
+ monorepoInfo.resolvedPackages &&
42
+ monorepoInfo.resolvedPackages.length > 0
43
+ ) {
44
+ // Root package
45
+ updates.push({
46
+ 'package-ecosystem': 'npm',
47
+ directory: '/',
48
+ schedule: {
49
+ interval: schedule,
50
+ day: day,
51
+ time: time,
52
+ },
53
+ 'open-pull-requests-limit': 5,
54
+ labels: ['dependencies', 'root'],
55
+ 'commit-message': {
56
+ prefix: 'deps(root)',
57
+ include: 'scope',
58
+ },
59
+ })
60
+
61
+ // Per-package entries
62
+ for (const pkg of monorepoInfo.resolvedPackages) {
63
+ const dir = '/' + pkg.relativePath.replace(/\\/g, '/')
64
+ updates.push({
37
65
  'package-ecosystem': 'npm',
38
- directory: '/',
66
+ directory: dir,
39
67
  schedule: {
40
68
  interval: schedule,
41
69
  day: day,
42
70
  time: time,
43
71
  },
44
- 'open-pull-requests-limit': 5,
45
- labels: ['dependencies'],
72
+ 'open-pull-requests-limit': 3,
73
+ labels: ['dependencies', pkg.name],
46
74
  'commit-message': {
47
- prefix: 'deps',
75
+ prefix: `deps(${pkg.name})`,
48
76
  include: 'scope',
49
77
  },
50
- // Note: Dependabot will create PRs for all dependency updates.
51
- // To auto-merge specific updates (e.g., security patches), add a GitHub Actions
52
- // workflow with conditions like: if: contains(github.event.pull_request.labels.*.name, 'security')
53
- // See: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions
78
+ })
79
+ }
80
+ } else {
81
+ // Single package (non-monorepo)
82
+ updates.push({
83
+ 'package-ecosystem': 'npm',
84
+ directory: '/',
85
+ schedule: {
86
+ interval: schedule,
87
+ day: day,
88
+ time: time,
54
89
  },
55
- // GitHub Actions monitoring (free tier includes this)
56
- {
57
- 'package-ecosystem': 'github-actions',
58
- directory: '/',
59
- schedule: {
60
- interval: schedule,
61
- day: day,
62
- time: time,
63
- },
64
- labels: ['dependencies', 'github-actions'],
65
- 'commit-message': {
66
- prefix: 'deps(actions)',
67
- },
90
+ 'open-pull-requests-limit': 5,
91
+ labels: ['dependencies'],
92
+ 'commit-message': {
93
+ prefix: 'deps',
94
+ include: 'scope',
68
95
  },
69
- ],
96
+ })
97
+ }
98
+
99
+ // GitHub Actions monitoring (free tier includes this)
100
+ updates.push({
101
+ 'package-ecosystem': 'github-actions',
102
+ directory: '/',
103
+ schedule: {
104
+ interval: schedule,
105
+ day: day,
106
+ time: time,
107
+ },
108
+ labels: ['dependencies', 'github-actions'],
109
+ 'commit-message': {
110
+ prefix: 'deps(actions)',
111
+ },
112
+ })
113
+
114
+ const config = {
115
+ version: 2,
116
+ updates: updates,
70
117
  }
71
118
 
72
119
  return config