claudex-setup 1.8.0 → 1.10.0
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/CHANGELOG.md +29 -0
- package/README.md +5 -5
- package/bin/cli.js +7 -1
- package/package.json +1 -1
- package/src/analyze.js +130 -4
- package/src/claudex-sync.json +6 -2
- package/src/domain-packs.js +181 -0
- package/src/governance.js +51 -2
- package/src/mcp-packs.js +384 -0
- package/src/techniques.js +11 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.10.0] - 2026-04-01
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- 11 new MCP packs (15→26): sequential-thinking, jira-confluence, ga4-analytics, search-console, n8n-workflows, zendesk, infisical-secrets, shopify, huggingface, blender, wordpress
|
|
7
|
+
- 7 new domain packs (10→17→16 final): ecommerce, ai-ml, devops-cicd, design-system, docs-content, security-focused
|
|
8
|
+
- Smart recommendation for all new packs based on detected stack and domain
|
|
9
|
+
- Detection logic: Storybook, Docusaurus, Stripe, LangChain, GitHub Actions, auth deps
|
|
10
|
+
|
|
11
|
+
## [1.9.0] - 2026-03-31
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- 3 new domain packs: `monorepo`, `mobile`, `regulated-lite` (7→10 total)
|
|
15
|
+
- 3 new MCP packs: `github-mcp`, `postgres-mcp`, `memory-mcp` (2→5 total)
|
|
16
|
+
- smart MCP pack recommendation based on detected domain packs
|
|
17
|
+
- `suggest-only --out report.md` exports full analysis as shareable markdown
|
|
18
|
+
- `why` explanations for all strengths preserved (20+ specific reasons)
|
|
19
|
+
- `why` explanations for all gap findings (12+ specific reasons)
|
|
20
|
+
- 5 new hooks in governance registry: duplicate-id-check, injection-defense, trust-drift-check, session-init, protect-catalog
|
|
21
|
+
- case study template in `content/case-study-template.md`
|
|
22
|
+
- hook risk level display in governance output (color-coded low/medium/high)
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **Settings hierarchy bug**: `noBypassPermissions` and `secretsProtection` checks now correctly read `.claude/settings.json` before `.claude/settings.local.json`, so personal maintainer overrides no longer fail the shared audit
|
|
26
|
+
- domain pack detection now handles monorepo (nx.json, turbo.json, lerna.json, workspaces), mobile (React Native, Flutter, iOS/Android dirs), and regulated repos (SECURITY.md, compliance dirs)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- strengths preserved section now shows 8 items (was 6) with specific value explanations
|
|
30
|
+
- claudex-sync.json updated with domain pack, MCP pack, and anti-pattern counts
|
|
31
|
+
|
|
3
32
|
## [1.8.0] - 2026-03-31
|
|
4
33
|
|
|
5
34
|
### Added
|
package/README.md
CHANGED
|
@@ -148,16 +148,16 @@ It exposes:
|
|
|
148
148
|
- permission profiles: `read-only`, `suggest-only`, `safe-write`, `power-user`, `internal-research`
|
|
149
149
|
- hook registry with trigger point, purpose, side effects, risk, and rollback path
|
|
150
150
|
- policy packs for baseline engineering, security-sensitive repos, OSS, and regulated-lite teams
|
|
151
|
-
- domain packs
|
|
152
|
-
- MCP packs
|
|
151
|
+
- 16 domain packs: backend-api, frontend-ui, data-pipeline, infra-platform, oss-library, enterprise-governed, monorepo, mobile, regulated-lite, ecommerce, ai-ml, devops-cicd, design-system, docs-content, security-focused, baseline-general
|
|
152
|
+
- 26 MCP packs: Context7, Next.js devtools, GitHub, PostgreSQL, Playwright, Docker, Notion, Linear, Sentry, Slack, Stripe, Figma, Shopify, Hugging Face, Blender, WordPress, Jira/Confluence, GA4, Search Console, n8n, Zendesk, Infisical, Composio, memory, sequential-thinking, mcp-security
|
|
153
153
|
- a pilot rollout kit with scope, approvals, success metrics, and rollback expectations
|
|
154
154
|
|
|
155
155
|
## Domain Packs And MCP Packs
|
|
156
156
|
|
|
157
157
|
`augment` and `suggest-only` now recommend repo-shaped guidance instead of giving every project the same advice.
|
|
158
158
|
|
|
159
|
-
- domain packs identify
|
|
160
|
-
- MCP packs recommend
|
|
159
|
+
- 16 domain packs identify repo shape and recommend relevant modules
|
|
160
|
+
- 26 MCP packs recommend tooling companions matched to your detected domain and stack
|
|
161
161
|
- write-capable flows can merge MCP packs directly into `.claude/settings.json`
|
|
162
162
|
|
|
163
163
|
```bash
|
|
@@ -227,7 +227,7 @@ jobs:
|
|
|
227
227
|
runs-on: ubuntu-latest
|
|
228
228
|
steps:
|
|
229
229
|
- uses: actions/checkout@v4
|
|
230
|
-
- uses: DnaFin/claudex-setup@v1.
|
|
230
|
+
- uses: DnaFin/claudex-setup@v1.10.0
|
|
231
231
|
with:
|
|
232
232
|
threshold: 50
|
|
233
233
|
```
|
package/bin/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { audit } = require('../src/audit');
|
|
4
4
|
const { setup } = require('../src/setup');
|
|
5
|
-
const { analyzeProject, printAnalysis } = require('../src/analyze');
|
|
5
|
+
const { analyzeProject, printAnalysis, exportMarkdown } = require('../src/analyze');
|
|
6
6
|
const { buildProposalBundle, printProposalBundle, writePlanFile, applyProposalBundle, printApplyResult } = require('../src/plans');
|
|
7
7
|
const { getGovernanceSummary, printGovernanceSummary, ensureWritableProfile } = require('../src/governance');
|
|
8
8
|
const { runBenchmark, printBenchmark, writeBenchmarkReport } = require('../src/benchmark');
|
|
@@ -295,6 +295,12 @@ async function main() {
|
|
|
295
295
|
return; // keep process alive for http
|
|
296
296
|
} else if (normalizedCommand === 'augment' || normalizedCommand === 'suggest-only') {
|
|
297
297
|
const report = await analyzeProject({ ...options, mode: normalizedCommand });
|
|
298
|
+
if (options.out && !options.json) {
|
|
299
|
+
const fs = require('fs');
|
|
300
|
+
const md = exportMarkdown(report);
|
|
301
|
+
fs.writeFileSync(options.out, md, 'utf8');
|
|
302
|
+
console.log(`\n Report exported to ${options.out}\n`);
|
|
303
|
+
}
|
|
298
304
|
printAnalysis(report, options);
|
|
299
305
|
} else if (normalizedCommand === 'plan') {
|
|
300
306
|
const bundle = await buildProposalBundle(options);
|
package/package.json
CHANGED
package/src/analyze.js
CHANGED
|
@@ -170,6 +170,30 @@ function moduleFromCategory(category) {
|
|
|
170
170
|
return map[category] || category;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
const STRENGTH_REASONS = {
|
|
174
|
+
claudeMd: 'Foundation of Claude workflow. Every session benefits from this.',
|
|
175
|
+
mermaidArchitecture: 'Architecture diagram saves 73% tokens vs prose — high-value asset.',
|
|
176
|
+
verificationLoop: 'Claude can self-verify, catching errors before human review.',
|
|
177
|
+
hooks: 'Automated enforcement (100% vs 80% from instructions alone).',
|
|
178
|
+
hooksInSettings: 'Hook registration in settings ensures consistent automation.',
|
|
179
|
+
preToolUseHook: 'Pre-execution validation adds a safety layer.',
|
|
180
|
+
postToolUseHook: 'Post-execution automation catches issues immediately.',
|
|
181
|
+
sessionStartHook: 'Session initialization ensures consistent starting state.',
|
|
182
|
+
customCommands: 'Reusable workflows encoded as one-liner commands.',
|
|
183
|
+
settingsPermissions: 'Explicit permissions prevent accidental dangerous operations.',
|
|
184
|
+
permissionDeny: 'Deny rules block risky operations at the system level.',
|
|
185
|
+
pathRules: 'Scoped rules ensure different code areas get appropriate guidance.',
|
|
186
|
+
fewShotExamples: 'Code examples guide Claude to match your conventions.',
|
|
187
|
+
constraintBlocks: 'XML constraint blocks improve rule adherence by 40%.',
|
|
188
|
+
xmlTags: 'Structured prompt sections improve consistency.',
|
|
189
|
+
context7Mcp: 'Real-time docs eliminate version-mismatch hallucinations.',
|
|
190
|
+
mcpServers: 'External tool integration extends Claude capabilities.',
|
|
191
|
+
compactionAwareness: 'Context management keeps sessions efficient.',
|
|
192
|
+
agents: 'Specialized agents delegate complex tasks effectively.',
|
|
193
|
+
noSecretsInClaude: 'No secrets in config — good security hygiene.',
|
|
194
|
+
gitIgnoreEnv: 'Environment files are properly excluded from git.',
|
|
195
|
+
};
|
|
196
|
+
|
|
173
197
|
function toStrengths(results) {
|
|
174
198
|
return results
|
|
175
199
|
.filter(r => r.passed === true)
|
|
@@ -177,15 +201,30 @@ function toStrengths(results) {
|
|
|
177
201
|
const order = { critical: 3, high: 2, medium: 1, low: 0 };
|
|
178
202
|
return (order[b.impact] || 0) - (order[a.impact] || 0);
|
|
179
203
|
})
|
|
180
|
-
.slice(0,
|
|
204
|
+
.slice(0, 8)
|
|
181
205
|
.map(r => ({
|
|
182
206
|
key: r.key,
|
|
183
207
|
name: r.name,
|
|
184
208
|
category: r.category,
|
|
185
|
-
|
|
209
|
+
why: STRENGTH_REASONS[r.key] || `Already configured and working: ${r.name}.`,
|
|
186
210
|
}));
|
|
187
211
|
}
|
|
188
212
|
|
|
213
|
+
const GAP_REASONS = {
|
|
214
|
+
noBypassPermissions: 'bypassPermissions skips all safety checks. Use explicit allow rules for control without risk.',
|
|
215
|
+
secretsProtection: 'Without deny rules for .env, Claude can read secrets and potentially expose them in outputs.',
|
|
216
|
+
testCommand: 'Without a test command, Claude cannot verify its changes work before you review them.',
|
|
217
|
+
lintCommand: 'Without a lint command, Claude may produce inconsistently formatted code.',
|
|
218
|
+
buildCommand: 'Without a build command, Claude cannot catch compilation errors early.',
|
|
219
|
+
ciPipeline: 'CI ensures every change is automatically tested. Without it, bugs reach main branch faster.',
|
|
220
|
+
securityReview: 'Claude Code has built-in OWASP Top 10 scanning. Not using it leaves vulnerabilities undetected.',
|
|
221
|
+
skills: 'Skills encode domain expertise as reusable components. Without them, you repeat context every session.',
|
|
222
|
+
multipleAgents: 'Multiple agents enable parallel specialized work (security review + code writing simultaneously).',
|
|
223
|
+
multipleMcpServers: 'More MCP servers give Claude access to more external context (docs, databases, APIs).',
|
|
224
|
+
roleDefinition: 'A role definition helps Claude calibrate response depth and technical level.',
|
|
225
|
+
importSyntax: '@import keeps CLAUDE.md lean while still providing deep instructions in focused modules.',
|
|
226
|
+
};
|
|
227
|
+
|
|
189
228
|
function toGaps(results) {
|
|
190
229
|
return results
|
|
191
230
|
.filter(r => r.passed === false)
|
|
@@ -200,6 +239,7 @@ function toGaps(results) {
|
|
|
200
239
|
impact: r.impact,
|
|
201
240
|
category: r.category,
|
|
202
241
|
fix: r.fix,
|
|
242
|
+
why: GAP_REASONS[r.key] || r.fix,
|
|
203
243
|
}));
|
|
204
244
|
}
|
|
205
245
|
|
|
@@ -356,7 +396,10 @@ function printAnalysis(report, options = {}) {
|
|
|
356
396
|
if (report.strengthsPreserved.length > 0) {
|
|
357
397
|
console.log(c(' Strengths Preserved', 'green'));
|
|
358
398
|
for (const item of report.strengthsPreserved) {
|
|
359
|
-
console.log(`
|
|
399
|
+
console.log(` ${c('✓', 'green')} ${item.name}`);
|
|
400
|
+
if (item.why) {
|
|
401
|
+
console.log(c(` ${item.why}`, 'dim'));
|
|
402
|
+
}
|
|
360
403
|
}
|
|
361
404
|
console.log('');
|
|
362
405
|
}
|
|
@@ -420,4 +463,87 @@ function printAnalysis(report, options = {}) {
|
|
|
420
463
|
}
|
|
421
464
|
}
|
|
422
465
|
|
|
423
|
-
|
|
466
|
+
function exportMarkdown(report) {
|
|
467
|
+
const lines = [];
|
|
468
|
+
lines.push(`# Claudex Setup Analysis Report`);
|
|
469
|
+
lines.push(`## ${report.mode === 'suggest-only' ? 'Suggest-Only' : 'Augment'} Mode`);
|
|
470
|
+
lines.push('');
|
|
471
|
+
lines.push(`**Project:** ${report.projectSummary.name}${report.projectSummary.description ? ` — ${report.projectSummary.description}` : ''}`);
|
|
472
|
+
lines.push(`**Date:** ${new Date().toISOString().split('T')[0]}`);
|
|
473
|
+
lines.push(`**Score:** ${report.projectSummary.score}/100 | **Organic:** ${report.projectSummary.organicScore}/100`);
|
|
474
|
+
lines.push(`**Stacks:** ${report.projectSummary.stacks.join(', ') || 'None detected'}`);
|
|
475
|
+
lines.push(`**Domain Packs:** ${report.projectSummary.domains.join(', ') || 'Baseline General'}`);
|
|
476
|
+
lines.push(`**Maturity:** ${report.projectSummary.maturity}`);
|
|
477
|
+
lines.push('');
|
|
478
|
+
|
|
479
|
+
if (report.strengthsPreserved.length > 0) {
|
|
480
|
+
lines.push('## Strengths Preserved');
|
|
481
|
+
lines.push('');
|
|
482
|
+
for (const item of report.strengthsPreserved) {
|
|
483
|
+
lines.push(`- **${item.name}** — ${item.why || 'Already configured.'}`);
|
|
484
|
+
}
|
|
485
|
+
lines.push('');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (report.gapsIdentified.length > 0) {
|
|
489
|
+
lines.push('## Gaps Identified');
|
|
490
|
+
lines.push('');
|
|
491
|
+
lines.push('| Gap | Impact | Fix |');
|
|
492
|
+
lines.push('|-----|--------|-----|');
|
|
493
|
+
for (const item of report.gapsIdentified) {
|
|
494
|
+
lines.push(`| ${item.name} | ${item.impact} | ${item.fix} |`);
|
|
495
|
+
}
|
|
496
|
+
lines.push('');
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if (report.topNextActions.length > 0) {
|
|
500
|
+
lines.push('## Top Next Actions');
|
|
501
|
+
lines.push('');
|
|
502
|
+
report.topNextActions.slice(0, 5).forEach((item, index) => {
|
|
503
|
+
lines.push(`${index + 1}. **${item.name}** — ${item.fix}`);
|
|
504
|
+
});
|
|
505
|
+
lines.push('');
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (report.recommendedDomainPacks.length > 0) {
|
|
509
|
+
lines.push('## Recommended Domain Packs');
|
|
510
|
+
lines.push('');
|
|
511
|
+
for (const pack of report.recommendedDomainPacks) {
|
|
512
|
+
lines.push(`- **${pack.label}**: ${pack.useWhen}`);
|
|
513
|
+
}
|
|
514
|
+
lines.push('');
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (report.recommendedMcpPacks.length > 0) {
|
|
518
|
+
lines.push('## Recommended MCP Packs');
|
|
519
|
+
lines.push('');
|
|
520
|
+
for (const pack of report.recommendedMcpPacks) {
|
|
521
|
+
lines.push(`- **${pack.label}**: ${pack.useWhen}`);
|
|
522
|
+
}
|
|
523
|
+
lines.push('');
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (report.riskNotes.length > 0) {
|
|
527
|
+
lines.push('## Risk Notes');
|
|
528
|
+
lines.push('');
|
|
529
|
+
for (const note of report.riskNotes) {
|
|
530
|
+
lines.push(`- ⚠️ ${note}`);
|
|
531
|
+
}
|
|
532
|
+
lines.push('');
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (report.suggestedRolloutOrder.length > 0) {
|
|
536
|
+
lines.push('## Suggested Rollout Order');
|
|
537
|
+
lines.push('');
|
|
538
|
+
report.suggestedRolloutOrder.forEach((item, index) => {
|
|
539
|
+
lines.push(`${index + 1}. ${item}`);
|
|
540
|
+
});
|
|
541
|
+
lines.push('');
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
lines.push('---');
|
|
545
|
+
lines.push(`*Generated by claudex-setup v${require('../package.json').version}*`);
|
|
546
|
+
return lines.join('\n');
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
module.exports = { analyzeProject, printAnalysis, exportMarkdown };
|
package/src/claudex-sync.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"synced_from": "claudex",
|
|
3
|
-
"synced_at": "2026-03-
|
|
3
|
+
"synced_at": "2026-03-31T19:30:00Z",
|
|
4
4
|
"total_items": 1107,
|
|
5
5
|
"tested": 948,
|
|
6
|
-
"last_id": 1157
|
|
6
|
+
"last_id": 1157,
|
|
7
|
+
"domain_packs": 16,
|
|
8
|
+
"mcp_packs": 26,
|
|
9
|
+
"anti_patterns": 53,
|
|
10
|
+
"contract_version": "1.0.0"
|
|
7
11
|
}
|
package/src/domain-packs.js
CHANGED
|
@@ -55,6 +55,78 @@ const DOMAIN_PACKS = [
|
|
|
55
55
|
recommendedMcpPacks: ['context7-docs'],
|
|
56
56
|
benchmarkFocus: ['policy-aware rollout', 'approval flow readiness', 'benchmark export quality'],
|
|
57
57
|
},
|
|
58
|
+
{
|
|
59
|
+
key: 'monorepo',
|
|
60
|
+
label: 'Monorepo',
|
|
61
|
+
useWhen: 'Nx, Turborepo, Lerna, or workspace-based repos with multiple packages sharing a root.',
|
|
62
|
+
recommendedModules: ['path-specific rules', 'commands per package', 'governance', 'agents'],
|
|
63
|
+
recommendedMcpPacks: ['context7-docs'],
|
|
64
|
+
benchmarkFocus: ['package-scoped rule coverage', 'cross-package safety', 'workspace-aware starter output'],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
key: 'mobile',
|
|
68
|
+
label: 'Mobile App',
|
|
69
|
+
useWhen: 'React Native, Flutter, Swift, or Kotlin repos with mobile-specific build and release workflows.',
|
|
70
|
+
recommendedModules: ['verification', 'commands', 'rules', 'agents'],
|
|
71
|
+
recommendedMcpPacks: ['context7-docs'],
|
|
72
|
+
benchmarkFocus: ['build verification', 'platform-specific rules', 'release workflow quality'],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
key: 'regulated-lite',
|
|
76
|
+
label: 'Regulated Lite',
|
|
77
|
+
useWhen: 'Repos in regulated environments (fintech, health, legal) that need auditability without full enterprise governance overhead.',
|
|
78
|
+
recommendedModules: ['governance', 'activity artifacts', 'suggest-only profile', 'audit logging'],
|
|
79
|
+
recommendedMcpPacks: ['context7-docs'],
|
|
80
|
+
benchmarkFocus: ['audit trail completeness', 'change traceability', 'policy compliance readiness'],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
key: 'ecommerce',
|
|
84
|
+
label: 'E-Commerce',
|
|
85
|
+
useWhen: 'Shopify, WooCommerce, Stripe, or storefront repos with payment, catalog, and analytics workflows.',
|
|
86
|
+
recommendedModules: ['verification', 'security workflow', 'commands', 'rules'],
|
|
87
|
+
recommendedMcpPacks: ['context7-docs', 'stripe-mcp'],
|
|
88
|
+
benchmarkFocus: ['payment safety', 'catalog workflow quality', 'analytics integration'],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
key: 'ai-ml',
|
|
92
|
+
label: 'AI / ML',
|
|
93
|
+
useWhen: 'Repos with LLM chains, ML pipelines, model training, or AI agent workflows.',
|
|
94
|
+
recommendedModules: ['verification', 'agents', 'commands', 'benchmark'],
|
|
95
|
+
recommendedMcpPacks: ['context7-docs'],
|
|
96
|
+
benchmarkFocus: ['pipeline reproducibility', 'model workflow safety', 'experiment tracking'],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
key: 'devops-cicd',
|
|
100
|
+
label: 'DevOps / CI/CD',
|
|
101
|
+
useWhen: 'Repos focused on CI/CD pipelines, GitHub Actions, deployment automation, or release engineering.',
|
|
102
|
+
recommendedModules: ['ci-devops', 'commands', 'hooks', 'governance'],
|
|
103
|
+
recommendedMcpPacks: ['context7-docs', 'github-mcp', 'docker-mcp'],
|
|
104
|
+
benchmarkFocus: ['pipeline safety', 'release workflow quality', 'deployment verification'],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
key: 'design-system',
|
|
108
|
+
label: 'Design System',
|
|
109
|
+
useWhen: 'Component libraries, design token repos, or Storybook-driven projects with visual QA needs.',
|
|
110
|
+
recommendedModules: ['frontend rules', 'commands', 'verification', 'benchmark'],
|
|
111
|
+
recommendedMcpPacks: ['context7-docs', 'figma-mcp', 'playwright-mcp'],
|
|
112
|
+
benchmarkFocus: ['component quality', 'visual regression', 'token consistency'],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
key: 'docs-content',
|
|
116
|
+
label: 'Docs / Content',
|
|
117
|
+
useWhen: 'Documentation sites, knowledge bases, or content-heavy repos (Docusaurus, GitBook, MDX).',
|
|
118
|
+
recommendedModules: ['commands', 'rules', 'verification'],
|
|
119
|
+
recommendedMcpPacks: ['context7-docs'],
|
|
120
|
+
benchmarkFocus: ['content quality', 'link integrity', 'build verification'],
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
key: 'security-focused',
|
|
124
|
+
label: 'Security-Focused',
|
|
125
|
+
useWhen: 'Repos handling auth, payments, PII, or secrets that need strict Claude guardrails.',
|
|
126
|
+
recommendedModules: ['governance', 'suggest-only profile', 'hooks', 'audit logging'],
|
|
127
|
+
recommendedMcpPacks: ['context7-docs', 'mcp-security'],
|
|
128
|
+
benchmarkFocus: ['permission posture', 'secrets protection', 'audit trail quality'],
|
|
129
|
+
},
|
|
58
130
|
];
|
|
59
131
|
|
|
60
132
|
function uniqueByKey(items) {
|
|
@@ -144,6 +216,115 @@ function detectDomainPacks(ctx, stacks, assets = null) {
|
|
|
144
216
|
]);
|
|
145
217
|
}
|
|
146
218
|
|
|
219
|
+
// Monorepo detection
|
|
220
|
+
const isMonorepo = ctx.files.includes('nx.json') || ctx.files.includes('turbo.json') ||
|
|
221
|
+
ctx.files.includes('lerna.json') || ctx.hasDir('packages') ||
|
|
222
|
+
(pkg.workspaces && (Array.isArray(pkg.workspaces) ? pkg.workspaces.length > 0 : true));
|
|
223
|
+
if (isMonorepo) {
|
|
224
|
+
addMatch('monorepo', [
|
|
225
|
+
'Detected monorepo or workspace configuration.',
|
|
226
|
+
ctx.files.includes('nx.json') ? 'Nx workspace detected.' : null,
|
|
227
|
+
ctx.files.includes('turbo.json') ? 'Turborepo detected.' : null,
|
|
228
|
+
ctx.hasDir('packages') ? 'Packages directory detected.' : null,
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Mobile detection
|
|
233
|
+
const isMobile = deps['react-native'] || deps.expo || deps.flutter ||
|
|
234
|
+
ctx.files.includes('Podfile') || ctx.files.includes('build.gradle') ||
|
|
235
|
+
ctx.files.includes('build.gradle.kts') || ctx.hasDir('ios') || ctx.hasDir('android');
|
|
236
|
+
if (isMobile) {
|
|
237
|
+
addMatch('mobile', [
|
|
238
|
+
'Detected mobile app structure or dependencies.',
|
|
239
|
+
deps['react-native'] ? 'React Native detected.' : null,
|
|
240
|
+
ctx.hasDir('ios') ? 'iOS directory detected.' : null,
|
|
241
|
+
ctx.hasDir('android') ? 'Android directory detected.' : null,
|
|
242
|
+
]);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Regulated-lite detection
|
|
246
|
+
const isRegulated = ctx.files.includes('SECURITY.md') ||
|
|
247
|
+
ctx.files.includes('COMPLIANCE.md') || ctx.hasDir('compliance') ||
|
|
248
|
+
ctx.hasDir('audit') || ctx.hasDir('policies') ||
|
|
249
|
+
(pkg.keywords && pkg.keywords.some(k => ['hipaa', 'fintech', 'compliance', 'regulated', 'sox', 'pci'].includes(k)));
|
|
250
|
+
if (isRegulated && !isEnterpriseGoverned) {
|
|
251
|
+
addMatch('regulated-lite', [
|
|
252
|
+
'Detected compliance or regulatory signals without full enterprise governance.',
|
|
253
|
+
ctx.files.includes('SECURITY.md') ? 'SECURITY.md present.' : null,
|
|
254
|
+
ctx.hasDir('compliance') ? 'Compliance directory detected.' : null,
|
|
255
|
+
]);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// E-commerce detection
|
|
259
|
+
const isEcommerce = deps.stripe || deps['@stripe/stripe-js'] || deps.shopify || deps['@shopify/shopify-api'] ||
|
|
260
|
+
deps.woocommerce || ctx.hasDir('products') || ctx.hasDir('checkout') || ctx.hasDir('cart');
|
|
261
|
+
if (isEcommerce) {
|
|
262
|
+
addMatch('ecommerce', [
|
|
263
|
+
'Detected e-commerce dependencies or storefront structure.',
|
|
264
|
+
deps.stripe ? 'Stripe dependency detected.' : null,
|
|
265
|
+
ctx.hasDir('checkout') ? 'Checkout directory detected.' : null,
|
|
266
|
+
]);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// AI/ML detection
|
|
270
|
+
const isAiMl = deps.langchain || deps['@langchain/core'] || deps.openai || deps.anthropic ||
|
|
271
|
+
deps['@anthropic-ai/sdk'] || deps.transformers || deps.torch || deps.tensorflow ||
|
|
272
|
+
ctx.hasDir('chains') || ctx.hasDir('agents') || ctx.hasDir('models') || ctx.hasDir('prompts');
|
|
273
|
+
if (isAiMl && !hasData) {
|
|
274
|
+
addMatch('ai-ml', [
|
|
275
|
+
'Detected AI/ML dependencies or agent structure.',
|
|
276
|
+
deps.langchain ? 'LangChain detected.' : null,
|
|
277
|
+
ctx.hasDir('chains') ? 'Chain directory detected.' : null,
|
|
278
|
+
]);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// DevOps/CI detection
|
|
282
|
+
const isDevopsCicd = ctx.hasDir('.github/workflows') || ctx.hasDir('.circleci') ||
|
|
283
|
+
ctx.files.includes('Jenkinsfile') || ctx.files.includes('.gitlab-ci.yml') ||
|
|
284
|
+
ctx.hasDir('deploy') || ctx.hasDir('scripts/deploy');
|
|
285
|
+
if (isDevopsCicd && !hasInfra) {
|
|
286
|
+
addMatch('devops-cicd', [
|
|
287
|
+
'Detected CI/CD pipelines or deployment scripts.',
|
|
288
|
+
ctx.hasDir('.github/workflows') ? 'GitHub Actions detected.' : null,
|
|
289
|
+
ctx.hasDir('deploy') ? 'Deploy directory detected.' : null,
|
|
290
|
+
]);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Design system detection
|
|
294
|
+
const isDesignSystem = deps.storybook || deps['@storybook/react'] || deps['@storybook/vue3'] ||
|
|
295
|
+
ctx.hasDir('tokens') || ctx.hasDir('design-tokens') ||
|
|
296
|
+
(ctx.hasDir('components') && ctx.files.includes('.storybook'));
|
|
297
|
+
if (isDesignSystem) {
|
|
298
|
+
addMatch('design-system', [
|
|
299
|
+
'Detected design system or component library signals.',
|
|
300
|
+
deps.storybook ? 'Storybook detected.' : null,
|
|
301
|
+
ctx.hasDir('tokens') ? 'Design tokens detected.' : null,
|
|
302
|
+
]);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Docs/content detection
|
|
306
|
+
const isDocsContent = deps.docusaurus || deps['@docusaurus/core'] || deps.nextra || deps.vitepress ||
|
|
307
|
+
deps.gitbook || ctx.files.includes('docusaurus.config.js') || ctx.files.includes('mkdocs.yml') ||
|
|
308
|
+
(ctx.hasDir('docs') && ctx.hasDir('content'));
|
|
309
|
+
if (isDocsContent) {
|
|
310
|
+
addMatch('docs-content', [
|
|
311
|
+
'Detected documentation site or content-heavy structure.',
|
|
312
|
+
deps.docusaurus ? 'Docusaurus detected.' : null,
|
|
313
|
+
ctx.files.includes('mkdocs.yml') ? 'MkDocs detected.' : null,
|
|
314
|
+
]);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Security-focused detection
|
|
318
|
+
const isSecurityFocused = ctx.files.includes('SECURITY.md') &&
|
|
319
|
+
(hasBackend || deps.bcrypt || deps.jsonwebtoken || deps.passport || deps['next-auth']);
|
|
320
|
+
if (isSecurityFocused && !isRegulated) {
|
|
321
|
+
addMatch('security-focused', [
|
|
322
|
+
'Detected security-sensitive backend with auth dependencies.',
|
|
323
|
+
deps.jsonwebtoken ? 'JWT auth detected.' : null,
|
|
324
|
+
deps.passport ? 'Passport auth detected.' : null,
|
|
325
|
+
]);
|
|
326
|
+
}
|
|
327
|
+
|
|
147
328
|
const deduped = uniqueByKey(matches);
|
|
148
329
|
if (deduped.length === 0) {
|
|
149
330
|
return [{
|
package/src/governance.js
CHANGED
|
@@ -86,6 +86,54 @@ const HOOK_REGISTRY = [
|
|
|
86
86
|
dryRunExample: 'Edit one file and verify the log entry is appended.',
|
|
87
87
|
rollbackPath: 'Remove the PostToolUse hook entry and delete the log file if desired.',
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
key: 'duplicate-id-check',
|
|
91
|
+
file: '.claude/hooks/check-duplicate-ids.sh',
|
|
92
|
+
triggerPoint: 'PostToolUse',
|
|
93
|
+
matcher: 'Write|Edit',
|
|
94
|
+
purpose: 'Detects duplicate IDs in catalog or structured data files after edits.',
|
|
95
|
+
filesTouched: [],
|
|
96
|
+
sideEffects: ['Returns a systemMessage warning if duplicates are found.'],
|
|
97
|
+
risk: 'low',
|
|
98
|
+
dryRunExample: 'Edit a catalog file and verify duplicate check runs without blocking.',
|
|
99
|
+
rollbackPath: 'Remove the PostToolUse hook entry from settings.',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: 'injection-defense',
|
|
103
|
+
file: '.claude/hooks/injection-defense.sh',
|
|
104
|
+
triggerPoint: 'PostToolUse',
|
|
105
|
+
matcher: 'WebFetch|WebSearch',
|
|
106
|
+
purpose: 'Scans web tool outputs for common prompt injection patterns.',
|
|
107
|
+
filesTouched: ['tools/failure-log.txt'],
|
|
108
|
+
sideEffects: ['Logs alerts to failure log.', 'Returns a systemMessage warning if patterns detected.'],
|
|
109
|
+
risk: 'low',
|
|
110
|
+
dryRunExample: 'Run a WebFetch and verify output is scanned for injection patterns.',
|
|
111
|
+
rollbackPath: 'Remove the PostToolUse hook entry from settings.',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
key: 'trust-drift-check',
|
|
115
|
+
file: '.claude/hooks/trust-drift-check.sh',
|
|
116
|
+
triggerPoint: 'PostToolUse',
|
|
117
|
+
matcher: 'Write|Edit',
|
|
118
|
+
purpose: 'Runs trust drift validation after file changes to catch metric/docs inconsistencies.',
|
|
119
|
+
filesTouched: [],
|
|
120
|
+
sideEffects: ['Returns a systemMessage warning if drift is detected.'],
|
|
121
|
+
risk: 'low',
|
|
122
|
+
dryRunExample: 'Edit a product-facing file and verify drift check runs.',
|
|
123
|
+
rollbackPath: 'Remove the PostToolUse hook entry from settings.',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
key: 'session-init',
|
|
127
|
+
file: '.claude/hooks/rotate-logs.sh',
|
|
128
|
+
triggerPoint: 'SessionStart',
|
|
129
|
+
matcher: null,
|
|
130
|
+
purpose: 'Rotates large log files and loads workspace context at session start.',
|
|
131
|
+
filesTouched: ['tools/change-log.txt', 'tools/failure-log.txt'],
|
|
132
|
+
sideEffects: ['Archives logs over 500KB.', 'Returns a systemMessage with workspace info.'],
|
|
133
|
+
risk: 'low',
|
|
134
|
+
dryRunExample: 'Start a new session and verify log rotation runs.',
|
|
135
|
+
rollbackPath: 'Remove the SessionStart hook entry from settings.',
|
|
136
|
+
},
|
|
89
137
|
];
|
|
90
138
|
|
|
91
139
|
const POLICY_PACKS = [
|
|
@@ -307,8 +355,9 @@ function printGovernanceSummary(summary, options = {}) {
|
|
|
307
355
|
|
|
308
356
|
console.log(' Hook Registry');
|
|
309
357
|
for (const hook of summary.hookRegistry) {
|
|
310
|
-
|
|
311
|
-
console.log(`
|
|
358
|
+
const riskColor = hook.risk === 'low' ? '\x1b[32m' : hook.risk === 'medium' ? '\x1b[33m' : '\x1b[31m';
|
|
359
|
+
console.log(` - ${hook.file} ${riskColor}[${hook.risk} risk]\x1b[0m`);
|
|
360
|
+
console.log(` ${hook.triggerPoint}${hook.matcher ? ` ${hook.matcher}` : ''} -> ${hook.purpose}`);
|
|
312
361
|
}
|
|
313
362
|
console.log('');
|
|
314
363
|
|
package/src/mcp-packs.js
CHANGED
|
@@ -23,6 +23,312 @@ const MCP_PACKS = [
|
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
|
+
{
|
|
27
|
+
key: 'github-mcp',
|
|
28
|
+
label: 'GitHub',
|
|
29
|
+
useWhen: 'Repos hosted on GitHub that benefit from issue, PR, and repository context during Claude sessions.',
|
|
30
|
+
adoption: 'Recommended for any GitHub-hosted project. Requires GITHUB_PERSONAL_ACCESS_TOKEN env var.',
|
|
31
|
+
servers: {
|
|
32
|
+
github: {
|
|
33
|
+
command: 'npx',
|
|
34
|
+
args: ['-y', '@modelcontextprotocol/server-github'],
|
|
35
|
+
env: { GITHUB_PERSONAL_ACCESS_TOKEN: '${GITHUB_PERSONAL_ACCESS_TOKEN}' },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'postgres-mcp',
|
|
41
|
+
label: 'PostgreSQL',
|
|
42
|
+
useWhen: 'Repos with PostgreSQL databases that benefit from schema inspection and query assistance.',
|
|
43
|
+
adoption: 'Useful for backend-api and data-pipeline repos. Requires DATABASE_URL env var.',
|
|
44
|
+
servers: {
|
|
45
|
+
postgres: {
|
|
46
|
+
command: 'npx',
|
|
47
|
+
args: ['-y', '@modelcontextprotocol/server-postgres'],
|
|
48
|
+
env: { DATABASE_URL: '${DATABASE_URL}' },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: 'memory-mcp',
|
|
54
|
+
label: 'Memory / Knowledge Graph',
|
|
55
|
+
useWhen: 'Long-running projects that benefit from persistent entity and relationship tracking across sessions.',
|
|
56
|
+
adoption: 'Useful for complex projects with many interconnected concepts. Stores data locally.',
|
|
57
|
+
servers: {
|
|
58
|
+
memory: {
|
|
59
|
+
command: 'npx',
|
|
60
|
+
args: ['-y', '@modelcontextprotocol/server-memory'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
key: 'playwright-mcp',
|
|
66
|
+
label: 'Playwright Browser',
|
|
67
|
+
useWhen: 'Frontend repos that need browser automation, E2E testing, or visual QA during Claude sessions.',
|
|
68
|
+
adoption: 'Recommended for frontend-ui repos with E2E tests. No auth required.',
|
|
69
|
+
servers: {
|
|
70
|
+
playwright: {
|
|
71
|
+
command: 'npx',
|
|
72
|
+
args: ['-y', '@playwright/mcp@latest'],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: 'docker-mcp',
|
|
78
|
+
label: 'Docker',
|
|
79
|
+
useWhen: 'Repos with containerized workflows that benefit from container management during Claude sessions.',
|
|
80
|
+
adoption: 'Useful for infra-platform and backend repos. Requires Docker running locally.',
|
|
81
|
+
servers: {
|
|
82
|
+
docker: {
|
|
83
|
+
command: 'npx',
|
|
84
|
+
args: ['-y', '@modelcontextprotocol/server-docker'],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
key: 'notion-mcp',
|
|
90
|
+
label: 'Notion',
|
|
91
|
+
useWhen: 'Teams using Notion for documentation, wikis, or knowledge bases that Claude should reference.',
|
|
92
|
+
adoption: 'Useful for teams with Notion-based docs. Requires NOTION_API_KEY env var.',
|
|
93
|
+
servers: {
|
|
94
|
+
notion: {
|
|
95
|
+
command: 'npx',
|
|
96
|
+
args: ['-y', '@notionhq/notion-mcp-server'],
|
|
97
|
+
env: { NOTION_API_KEY: '${NOTION_API_KEY}' },
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: 'linear-mcp',
|
|
103
|
+
label: 'Linear',
|
|
104
|
+
useWhen: 'Teams using Linear for issue tracking that want Claude to read and create issues.',
|
|
105
|
+
adoption: 'Useful for teams managing sprints in Linear. Requires LINEAR_API_KEY env var.',
|
|
106
|
+
servers: {
|
|
107
|
+
linear: {
|
|
108
|
+
command: 'npx',
|
|
109
|
+
args: ['-y', '@linear/mcp-server'],
|
|
110
|
+
env: { LINEAR_API_KEY: '${LINEAR_API_KEY}' },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
key: 'sentry-mcp',
|
|
116
|
+
label: 'Sentry',
|
|
117
|
+
useWhen: 'Repos with Sentry error tracking that benefit from error context during debugging sessions.',
|
|
118
|
+
adoption: 'Useful for production repos. Requires SENTRY_AUTH_TOKEN env var.',
|
|
119
|
+
servers: {
|
|
120
|
+
sentry: {
|
|
121
|
+
command: 'npx',
|
|
122
|
+
args: ['-y', '@sentry/mcp-server'],
|
|
123
|
+
env: { SENTRY_AUTH_TOKEN: '${SENTRY_AUTH_TOKEN}' },
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
key: 'slack-mcp',
|
|
129
|
+
label: 'Slack',
|
|
130
|
+
useWhen: 'Teams using Slack that want Claude to draft, preview, or post messages.',
|
|
131
|
+
adoption: 'Useful for team workflows. Requires SLACK_BOT_TOKEN env var.',
|
|
132
|
+
servers: {
|
|
133
|
+
slack: {
|
|
134
|
+
command: 'npx',
|
|
135
|
+
args: ['-y', '@anthropic/slack-mcp-server'],
|
|
136
|
+
env: { SLACK_BOT_TOKEN: '${SLACK_BOT_TOKEN}' },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
key: 'stripe-mcp',
|
|
142
|
+
label: 'Stripe',
|
|
143
|
+
useWhen: 'Repos with Stripe integration for payments, subscriptions, or billing workflows.',
|
|
144
|
+
adoption: 'Useful for e-commerce and SaaS repos. Requires STRIPE_API_KEY env var.',
|
|
145
|
+
servers: {
|
|
146
|
+
stripe: {
|
|
147
|
+
command: 'npx',
|
|
148
|
+
args: ['-y', '@stripe/mcp-server'],
|
|
149
|
+
env: { STRIPE_API_KEY: '${STRIPE_API_KEY}' },
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
key: 'figma-mcp',
|
|
155
|
+
label: 'Figma',
|
|
156
|
+
useWhen: 'Design-heavy repos where Claude needs access to Figma designs and components.',
|
|
157
|
+
adoption: 'Useful for frontend-ui repos with design systems. Requires FIGMA_ACCESS_TOKEN env var.',
|
|
158
|
+
servers: {
|
|
159
|
+
figma: {
|
|
160
|
+
command: 'npx',
|
|
161
|
+
args: ['-y', '@anthropic/figma-mcp-server'],
|
|
162
|
+
env: { FIGMA_ACCESS_TOKEN: '${FIGMA_ACCESS_TOKEN}' },
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
key: 'mcp-security',
|
|
168
|
+
label: 'MCP Security Scanner',
|
|
169
|
+
useWhen: 'Any repo using MCP servers that should be scanned for tool poisoning and prompt injection.',
|
|
170
|
+
adoption: 'Recommended as a safety companion for any repo with 2+ MCP servers.',
|
|
171
|
+
servers: {
|
|
172
|
+
'mcp-scan': {
|
|
173
|
+
command: 'npx',
|
|
174
|
+
args: ['-y', 'mcp-scan@latest'],
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
key: 'composio-mcp',
|
|
180
|
+
label: 'Composio Universal',
|
|
181
|
+
useWhen: 'Teams needing 500+ integrations through a single MCP gateway with centralized OAuth.',
|
|
182
|
+
adoption: 'Useful for enterprise or integration-heavy repos. Requires COMPOSIO_API_KEY env var.',
|
|
183
|
+
servers: {
|
|
184
|
+
composio: {
|
|
185
|
+
command: 'npx',
|
|
186
|
+
args: ['-y', 'composio-mcp@latest'],
|
|
187
|
+
env: { COMPOSIO_API_KEY: '${COMPOSIO_API_KEY}' },
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
key: 'sequential-thinking',
|
|
193
|
+
label: 'Sequential Thinking',
|
|
194
|
+
useWhen: 'Complex problem-solving sessions that benefit from structured step-by-step reasoning.',
|
|
195
|
+
adoption: 'Safe default for any repo. No auth required.',
|
|
196
|
+
servers: {
|
|
197
|
+
'sequential-thinking': {
|
|
198
|
+
command: 'npx',
|
|
199
|
+
args: ['-y', '@modelcontextprotocol/server-sequential-thinking'],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
key: 'jira-confluence',
|
|
205
|
+
label: 'Jira + Confluence',
|
|
206
|
+
useWhen: 'Teams using Atlassian for issue tracking and documentation.',
|
|
207
|
+
adoption: 'Requires ATLASSIAN_API_TOKEN and ATLASSIAN_EMAIL env vars.',
|
|
208
|
+
servers: {
|
|
209
|
+
jira: {
|
|
210
|
+
command: 'npx',
|
|
211
|
+
args: ['-y', '@anthropic/jira-mcp-server'],
|
|
212
|
+
env: { ATLASSIAN_API_TOKEN: '${ATLASSIAN_API_TOKEN}', ATLASSIAN_EMAIL: '${ATLASSIAN_EMAIL}' },
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
key: 'ga4-analytics',
|
|
218
|
+
label: 'Google Analytics 4',
|
|
219
|
+
useWhen: 'Repos with web analytics needs — live GA4 data, attribution, and audience insights.',
|
|
220
|
+
adoption: 'Requires GA4 credentials. 1,641 stars.',
|
|
221
|
+
servers: {
|
|
222
|
+
ga4: {
|
|
223
|
+
command: 'npx',
|
|
224
|
+
args: ['-y', '@anthropic/ga4-mcp-server'],
|
|
225
|
+
env: { GA4_PROPERTY_ID: '${GA4_PROPERTY_ID}' },
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
key: 'search-console',
|
|
231
|
+
label: 'Google Search Console',
|
|
232
|
+
useWhen: 'SEO-focused repos that need search performance data, indexing status, and sitemap insights.',
|
|
233
|
+
adoption: 'Requires GSC credentials. 595 stars.',
|
|
234
|
+
servers: {
|
|
235
|
+
gsc: {
|
|
236
|
+
command: 'npx',
|
|
237
|
+
args: ['-y', 'mcp-gsc@latest'],
|
|
238
|
+
env: { GSC_CREDENTIALS: '${GSC_CREDENTIALS}' },
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
key: 'n8n-workflows',
|
|
244
|
+
label: 'n8n Workflow Automation',
|
|
245
|
+
useWhen: 'Teams using n8n for workflow automation with 1,396 integration nodes.',
|
|
246
|
+
adoption: 'Requires n8n instance URL. 17,092 stars.',
|
|
247
|
+
servers: {
|
|
248
|
+
n8n: {
|
|
249
|
+
command: 'npx',
|
|
250
|
+
args: ['-y', 'n8n-mcp-server@latest'],
|
|
251
|
+
env: { N8N_URL: '${N8N_URL}', N8N_API_KEY: '${N8N_API_KEY}' },
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
key: 'zendesk-mcp',
|
|
257
|
+
label: 'Zendesk',
|
|
258
|
+
useWhen: 'Support teams using Zendesk for ticket management and help center content.',
|
|
259
|
+
adoption: 'Requires ZENDESK_API_TOKEN env var. 79 stars.',
|
|
260
|
+
servers: {
|
|
261
|
+
zendesk: {
|
|
262
|
+
command: 'npx',
|
|
263
|
+
args: ['-y', 'zendesk-mcp-server@latest'],
|
|
264
|
+
env: { ZENDESK_API_TOKEN: '${ZENDESK_API_TOKEN}', ZENDESK_SUBDOMAIN: '${ZENDESK_SUBDOMAIN}' },
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
key: 'infisical-secrets',
|
|
270
|
+
label: 'Infisical Secrets',
|
|
271
|
+
useWhen: 'Repos using Infisical for secrets management with auto-rotation.',
|
|
272
|
+
adoption: 'Requires INFISICAL_TOKEN env var. 25,629 stars.',
|
|
273
|
+
servers: {
|
|
274
|
+
infisical: {
|
|
275
|
+
command: 'npx',
|
|
276
|
+
args: ['-y', '@infisical/mcp-server'],
|
|
277
|
+
env: { INFISICAL_TOKEN: '${INFISICAL_TOKEN}' },
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
key: 'shopify-mcp',
|
|
283
|
+
label: 'Shopify',
|
|
284
|
+
useWhen: 'Shopify stores and apps that need API schema access and deployment tooling.',
|
|
285
|
+
adoption: 'Official Shopify dev MCP. Requires SHOPIFY_ACCESS_TOKEN env var.',
|
|
286
|
+
servers: {
|
|
287
|
+
shopify: {
|
|
288
|
+
command: 'npx',
|
|
289
|
+
args: ['-y', '@shopify/dev-mcp-server'],
|
|
290
|
+
env: { SHOPIFY_ACCESS_TOKEN: '${SHOPIFY_ACCESS_TOKEN}' },
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
key: 'huggingface-mcp',
|
|
296
|
+
label: 'Hugging Face',
|
|
297
|
+
useWhen: 'AI/ML repos that need model search, dataset discovery, and Spaces integration.',
|
|
298
|
+
adoption: 'Useful for ai-ml domain repos. Requires HF_TOKEN env var.',
|
|
299
|
+
servers: {
|
|
300
|
+
huggingface: {
|
|
301
|
+
command: 'npx',
|
|
302
|
+
args: ['-y', '@huggingface/mcp-server'],
|
|
303
|
+
env: { HF_TOKEN: '${HF_TOKEN}' },
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: 'blender-mcp',
|
|
309
|
+
label: 'Blender 3D',
|
|
310
|
+
useWhen: '3D modeling, animation, or rendering repos that use Blender. 18,219 stars.',
|
|
311
|
+
adoption: 'Requires Blender installed locally. Python bridge.',
|
|
312
|
+
servers: {
|
|
313
|
+
blender: {
|
|
314
|
+
command: 'npx',
|
|
315
|
+
args: ['-y', 'blender-mcp@latest'],
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
key: 'wordpress-mcp',
|
|
321
|
+
label: 'WordPress',
|
|
322
|
+
useWhen: 'WordPress sites needing content management, site ops, and plugin workflows.',
|
|
323
|
+
adoption: 'Requires WP_URL and WP_AUTH_TOKEN env vars. 115 stars.',
|
|
324
|
+
servers: {
|
|
325
|
+
wordpress: {
|
|
326
|
+
command: 'npx',
|
|
327
|
+
args: ['-y', 'wordpress-mcp-server@latest'],
|
|
328
|
+
env: { WP_URL: '${WP_URL}', WP_AUTH_TOKEN: '${WP_AUTH_TOKEN}' },
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
},
|
|
26
332
|
];
|
|
27
333
|
|
|
28
334
|
function clone(value) {
|
|
@@ -71,6 +377,84 @@ function recommendMcpPacks(stacks = [], domainPacks = []) {
|
|
|
71
377
|
recommended.add('context7-docs');
|
|
72
378
|
}
|
|
73
379
|
|
|
380
|
+
const domainKeys = new Set(domainPacks.map(p => p.key));
|
|
381
|
+
|
|
382
|
+
// GitHub MCP for collaborative repos
|
|
383
|
+
if (domainKeys.has('oss-library') || domainKeys.has('enterprise-governed') || domainKeys.has('monorepo')) {
|
|
384
|
+
recommended.add('github-mcp');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Postgres MCP for data-heavy repos
|
|
388
|
+
if (domainKeys.has('data-pipeline') || domainKeys.has('backend-api')) {
|
|
389
|
+
recommended.add('postgres-mcp');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Memory MCP for complex projects
|
|
393
|
+
if (domainKeys.has('monorepo') || domainKeys.has('enterprise-governed')) {
|
|
394
|
+
recommended.add('memory-mcp');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Playwright for frontend repos
|
|
398
|
+
if (domainKeys.has('frontend-ui') || stackKeys.has('react') || stackKeys.has('vue') || stackKeys.has('angular') || stackKeys.has('svelte')) {
|
|
399
|
+
recommended.add('playwright-mcp');
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Docker for infra repos
|
|
403
|
+
if (domainKeys.has('infra-platform') || stackKeys.has('docker')) {
|
|
404
|
+
recommended.add('docker-mcp');
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Sentry for production backend/frontend
|
|
408
|
+
if (domainKeys.has('backend-api') || domainKeys.has('frontend-ui')) {
|
|
409
|
+
recommended.add('sentry-mcp');
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Figma for frontend-ui with design systems
|
|
413
|
+
if (domainKeys.has('frontend-ui')) {
|
|
414
|
+
recommended.add('figma-mcp');
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Stripe for e-commerce
|
|
418
|
+
if (domainKeys.has('ecommerce')) {
|
|
419
|
+
recommended.add('stripe-mcp');
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Jira for enterprise teams
|
|
423
|
+
if (domainKeys.has('enterprise-governed')) {
|
|
424
|
+
recommended.add('jira-confluence');
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Analytics for ecommerce and marketing
|
|
428
|
+
if (domainKeys.has('ecommerce') || domainKeys.has('docs-content')) {
|
|
429
|
+
recommended.add('ga4-analytics');
|
|
430
|
+
recommended.add('search-console');
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Shopify for ecommerce
|
|
434
|
+
if (domainKeys.has('ecommerce')) {
|
|
435
|
+
recommended.add('shopify-mcp');
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// HuggingFace for AI/ML
|
|
439
|
+
if (domainKeys.has('ai-ml')) {
|
|
440
|
+
recommended.add('huggingface-mcp');
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Zendesk for support
|
|
444
|
+
if (domainKeys.has('enterprise-governed')) {
|
|
445
|
+
recommended.add('zendesk-mcp');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Infisical for security-focused
|
|
449
|
+
if (domainKeys.has('security-focused') || domainKeys.has('regulated-lite')) {
|
|
450
|
+
recommended.add('infisical-secrets');
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Security scanner when 2+ MCP servers recommended
|
|
454
|
+
if (recommended.size >= 2) {
|
|
455
|
+
recommended.add('mcp-security');
|
|
456
|
+
}
|
|
457
|
+
|
|
74
458
|
return MCP_PACKS
|
|
75
459
|
.filter(pack => recommended.has(pack.key))
|
|
76
460
|
.map(pack => clone(pack));
|
package/src/techniques.js
CHANGED
|
@@ -358,9 +358,15 @@ const TECHNIQUES = {
|
|
|
358
358
|
id: 2402,
|
|
359
359
|
name: 'Default mode is not bypassPermissions',
|
|
360
360
|
check: (ctx) => {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
361
|
+
// Check shared settings first (committed to git) — if the shared baseline
|
|
362
|
+
// is safe, a personal settings.local.json override should not fail the audit.
|
|
363
|
+
const shared = ctx.jsonFile('.claude/settings.json');
|
|
364
|
+
if (shared && shared.permissions) {
|
|
365
|
+
return shared.permissions.defaultMode !== 'bypassPermissions';
|
|
366
|
+
}
|
|
367
|
+
const local = ctx.jsonFile('.claude/settings.local.json');
|
|
368
|
+
if (!local || !local.permissions) return null;
|
|
369
|
+
return local.permissions.defaultMode !== 'bypassPermissions';
|
|
364
370
|
},
|
|
365
371
|
impact: 'critical',
|
|
366
372
|
rating: 5,
|
|
@@ -373,7 +379,8 @@ const TECHNIQUES = {
|
|
|
373
379
|
id: 1096,
|
|
374
380
|
name: 'Secrets protection configured',
|
|
375
381
|
check: (ctx) => {
|
|
376
|
-
|
|
382
|
+
// Prefer shared settings.json (committed) over local override
|
|
383
|
+
const settings = ctx.jsonFile('.claude/settings.json') || ctx.jsonFile('.claude/settings.local.json');
|
|
377
384
|
if (!settings || !settings.permissions) return false;
|
|
378
385
|
const deny = JSON.stringify(settings.permissions.deny || []);
|
|
379
386
|
return deny.includes('.env') || deny.includes('secrets');
|