@vibecheckai/cli 3.5.0 → 3.5.2
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/bin/registry.js +214 -237
- package/bin/runners/cli-utils.js +33 -2
- package/bin/runners/context/analyzer.js +52 -1
- package/bin/runners/context/generators/cursor.js +2 -49
- package/bin/runners/context/git-context.js +3 -1
- package/bin/runners/context/team-conventions.js +33 -7
- package/bin/runners/lib/analysis-core.js +25 -5
- package/bin/runners/lib/analyzers.js +431 -481
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/doctor/modules/security.js +3 -1
- package/bin/runners/lib/engine/ast-cache.js +210 -0
- package/bin/runners/lib/engine/auth-extractor.js +211 -0
- package/bin/runners/lib/engine/billing-extractor.js +112 -0
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
- package/bin/runners/lib/engine/env-extractor.js +207 -0
- package/bin/runners/lib/engine/express-extractor.js +208 -0
- package/bin/runners/lib/engine/extractors.js +849 -0
- package/bin/runners/lib/engine/index.js +207 -0
- package/bin/runners/lib/engine/repo-index.js +514 -0
- package/bin/runners/lib/engine/types.js +124 -0
- package/bin/runners/lib/engines/accessibility-engine.js +18 -218
- package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
- package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
- package/bin/runners/lib/engines/mock-data-engine.js +10 -53
- package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
- package/bin/runners/lib/engines/type-aware-engine.js +39 -263
- package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/entitlements-v2.js +73 -97
- package/bin/runners/lib/error-handler.js +44 -3
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +7 -1
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/html-proof-report.js +700 -350
- package/bin/runners/lib/missions/plan.js +6 -46
- package/bin/runners/lib/missions/templates.js +0 -232
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/route-detection.js +137 -68
- package/bin/runners/lib/scan-output.js +91 -76
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
- package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
- package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
- package/bin/runners/lib/schemas/run-request.schema.json +108 -0
- package/bin/runners/lib/schemas/validator.js +27 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -0
- package/bin/runners/lib/ship-output-enterprise.js +23 -23
- package/bin/runners/lib/ship-output.js +75 -31
- package/bin/runners/lib/terminal-ui.js +6 -113
- package/bin/runners/lib/truth.js +351 -10
- package/bin/runners/lib/unified-cli-output.js +430 -603
- package/bin/runners/lib/unified-output.js +13 -9
- package/bin/runners/runAIAgent.js +10 -5
- package/bin/runners/runAgent.js +0 -3
- package/bin/runners/runAllowlist.js +389 -0
- package/bin/runners/runApprove.js +0 -33
- package/bin/runners/runAuth.js +73 -45
- package/bin/runners/runCheckpoint.js +51 -11
- package/bin/runners/runClassify.js +85 -21
- package/bin/runners/runContext.js +0 -3
- package/bin/runners/runDoctor.js +41 -28
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.js +0 -3
- package/bin/runners/runFirewallHook.js +0 -3
- package/bin/runners/runFix.js +66 -76
- package/bin/runners/runGuard.js +18 -411
- package/bin/runners/runInit.js +113 -30
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runMcp.js +19 -25
- package/bin/runners/runPolish.js +64 -240
- package/bin/runners/runPromptFirewall.js +12 -5
- package/bin/runners/runProve.js +57 -22
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +59 -68
- package/bin/runners/runReport.js +38 -33
- package/bin/runners/runRuntime.js +8 -5
- package/bin/runners/runScan.js +1413 -190
- package/bin/runners/runShip.js +113 -719
- package/bin/runners/runTruth.js +0 -3
- package/bin/runners/runValidate.js +13 -9
- package/bin/runners/runWatch.js +23 -14
- package/bin/scan.js +6 -1
- package/bin/vibecheck.js +204 -185
- package/mcp-server/deprecation-middleware.js +282 -0
- package/mcp-server/handlers/index.ts +15 -0
- package/mcp-server/handlers/tool-handler.ts +554 -0
- package/mcp-server/index-v1.js +698 -0
- package/mcp-server/index.js +210 -238
- package/mcp-server/lib/cache-wrapper.cjs +383 -0
- package/mcp-server/lib/error-envelope.js +138 -0
- package/mcp-server/lib/executor.ts +499 -0
- package/mcp-server/lib/index.ts +19 -0
- package/mcp-server/lib/rate-limiter.js +166 -0
- package/mcp-server/lib/sandbox.test.ts +519 -0
- package/mcp-server/lib/sandbox.ts +395 -0
- package/mcp-server/lib/types.ts +267 -0
- package/mcp-server/package.json +12 -3
- package/mcp-server/registry/tool-registry.js +794 -0
- package/mcp-server/registry/tools.json +605 -0
- package/mcp-server/registry.test.ts +334 -0
- package/mcp-server/tests/tier-gating.test.js +297 -0
- package/mcp-server/tier-auth.js +378 -45
- package/mcp-server/tools-v3.js +353 -442
- package/mcp-server/tsconfig.json +37 -0
- package/mcp-server/vibecheck-2.0-tools.js +14 -1
- package/package.json +1 -1
- package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
- package/bin/runners/lib/audit-logger.js +0 -532
- package/bin/runners/lib/authority/authorities/architecture.js +0 -364
- package/bin/runners/lib/authority/authorities/compliance.js +0 -341
- package/bin/runners/lib/authority/authorities/human.js +0 -343
- package/bin/runners/lib/authority/authorities/quality.js +0 -420
- package/bin/runners/lib/authority/authorities/security.js +0 -228
- package/bin/runners/lib/authority/index.js +0 -293
- package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
- package/bin/runners/lib/cli-charts.js +0 -368
- package/bin/runners/lib/cli-config-display.js +0 -405
- package/bin/runners/lib/cli-demo.js +0 -275
- package/bin/runners/lib/cli-errors.js +0 -438
- package/bin/runners/lib/cli-help-formatter.js +0 -439
- package/bin/runners/lib/cli-interactive-menu.js +0 -509
- package/bin/runners/lib/cli-prompts.js +0 -441
- package/bin/runners/lib/cli-scan-cards.js +0 -362
- package/bin/runners/lib/compliance-reporter.js +0 -710
- package/bin/runners/lib/conductor/index.js +0 -671
- package/bin/runners/lib/easy/README.md +0 -123
- package/bin/runners/lib/easy/index.js +0 -140
- package/bin/runners/lib/easy/interactive-wizard.js +0 -788
- package/bin/runners/lib/easy/one-click-firewall.js +0 -564
- package/bin/runners/lib/easy/zero-config-reality.js +0 -714
- package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
- package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
- package/bin/runners/lib/engines/confidence-scoring.js +0 -276
- package/bin/runners/lib/engines/context-detection.js +0 -264
- package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
- package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
- package/bin/runners/lib/engines/env-variables-engine.js +0 -458
- package/bin/runners/lib/engines/error-handling-engine.js +0 -437
- package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
- package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
- package/bin/runners/lib/engines/framework-detection.js +0 -508
- package/bin/runners/lib/engines/import-order-engine.js +0 -429
- package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
- package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
- package/bin/runners/lib/engines/orchestrator.js +0 -334
- package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
- package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
- package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
- package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
- package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
- package/bin/runners/lib/enhanced-features/index.js +0 -305
- package/bin/runners/lib/enhanced-output.js +0 -631
- package/bin/runners/lib/enterprise.js +0 -300
- package/bin/runners/lib/firewall/command-validator.js +0 -351
- package/bin/runners/lib/firewall/config.js +0 -341
- package/bin/runners/lib/firewall/content-validator.js +0 -519
- package/bin/runners/lib/firewall/index.js +0 -101
- package/bin/runners/lib/firewall/path-validator.js +0 -256
- package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
- package/bin/runners/lib/mcp-utils.js +0 -425
- package/bin/runners/lib/output/index.js +0 -1022
- package/bin/runners/lib/policy-engine.js +0 -652
- package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
- package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
- package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
- package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
- package/bin/runners/lib/polish/autofix/index.js +0 -200
- package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
- package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
- package/bin/runners/lib/polish/backend-checks.js +0 -148
- package/bin/runners/lib/polish/documentation-checks.js +0 -111
- package/bin/runners/lib/polish/frontend-checks.js +0 -168
- package/bin/runners/lib/polish/index.js +0 -71
- package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
- package/bin/runners/lib/polish/library-detection.js +0 -175
- package/bin/runners/lib/polish/performance-checks.js +0 -100
- package/bin/runners/lib/polish/security-checks.js +0 -148
- package/bin/runners/lib/polish/utils.js +0 -203
- package/bin/runners/lib/prompt-builder.js +0 -540
- package/bin/runners/lib/proof-certificate.js +0 -634
- package/bin/runners/lib/reality/accessibility-audit.js +0 -946
- package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
- package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
- package/bin/runners/lib/reality/performance-tracker.js +0 -1077
- package/bin/runners/lib/reality/scenario-generator.js +0 -1404
- package/bin/runners/lib/reality/visual-regression.js +0 -852
- package/bin/runners/lib/reality-profiler.js +0 -717
- package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
- package/bin/runners/lib/review/ai-code-review.js +0 -832
- package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
- package/bin/runners/lib/sbom-generator.js +0 -641
- package/bin/runners/lib/scan-output-enhanced.js +0 -512
- package/bin/runners/lib/security/owasp-scanner.js +0 -939
- package/bin/runners/lib/validators/contract-validator.js +0 -283
- package/bin/runners/lib/validators/dead-export-detector.js +0 -279
- package/bin/runners/lib/validators/dep-audit.js +0 -245
- package/bin/runners/lib/validators/env-validator.js +0 -319
- package/bin/runners/lib/validators/index.js +0 -120
- package/bin/runners/lib/validators/license-checker.js +0 -252
- package/bin/runners/lib/validators/route-validator.js +0 -290
- package/bin/runners/runAuthority.js +0 -528
- package/bin/runners/runConductor.js +0 -772
- package/bin/runners/runContainer.js +0 -366
- package/bin/runners/runEasy.js +0 -410
- package/bin/runners/runIaC.js +0 -372
- package/bin/runners/runVibe.js +0 -791
- package/mcp-server/tools.js +0 -495
package/mcp-server/index.js
CHANGED
|
@@ -63,7 +63,7 @@ const __dirname = path.dirname(__filename);
|
|
|
63
63
|
// CENTRALIZED CONFIGURATION
|
|
64
64
|
// ============================================================================
|
|
65
65
|
const CONFIG = {
|
|
66
|
-
VERSION: "2.
|
|
66
|
+
VERSION: "2.1.0",
|
|
67
67
|
BIN_PATH: path.join(__dirname, "..", "bin", "vibecheck.js"),
|
|
68
68
|
OUTPUT_DIR: ".vibecheck",
|
|
69
69
|
ENV_DEFAULTS: { VIBECHECK_SKIP_AUTH: "1" },
|
|
@@ -526,11 +526,25 @@ const CONTEXT_ATTRIBUTION = "🧠 Context enhanced by vibecheck";
|
|
|
526
526
|
// Import Consolidated Tools (15 focused tools - recommended surface)
|
|
527
527
|
import { CONSOLIDATED_TOOLS, handleConsolidatedTool } from "./consolidated-tools.js";
|
|
528
528
|
|
|
529
|
-
// Import v3 Tools (
|
|
529
|
+
// Import v3 Tools (2-tier model: FREE tools for inspect & observe, PRO for fix/prove/enforce)
|
|
530
530
|
import { MCP_TOOLS_V3, handleToolV3, TOOL_TIERS as V3_TOOL_TIERS } from "./tools-v3.js";
|
|
531
531
|
|
|
532
532
|
// Import tier auth for entitlement checking
|
|
533
|
-
import { getFeatureAccessStatus } from "./tier-auth.js";
|
|
533
|
+
import { getFeatureAccessStatus, getTierFromApiKey } from "./tier-auth.js";
|
|
534
|
+
|
|
535
|
+
// Import new production modules
|
|
536
|
+
const {
|
|
537
|
+
validateToolInput,
|
|
538
|
+
validateToolOutput,
|
|
539
|
+
getToolTimeout,
|
|
540
|
+
getToolTier,
|
|
541
|
+
} = require('./registry/tool-registry.js');
|
|
542
|
+
const {
|
|
543
|
+
executeWithEnvelope,
|
|
544
|
+
createErrorEnvelope,
|
|
545
|
+
createSuccessEnvelope,
|
|
546
|
+
} = require('./lib/error-envelope.js');
|
|
547
|
+
const { rateLimiter } = require('./lib/rate-limiter.js');
|
|
534
548
|
|
|
535
549
|
// Import Agent Firewall Interceptor - ENABLED BY DEFAULT
|
|
536
550
|
// The Agent Firewall is the core gatekeeper that validates AI changes against reality
|
|
@@ -901,117 +915,29 @@ class VibecheckMCP {
|
|
|
901
915
|
return '## Error: Invalid summary data\n';
|
|
902
916
|
}
|
|
903
917
|
|
|
904
|
-
// Safely extract values with defaults
|
|
905
|
-
const score = sanitizeNumber(
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
);
|
|
909
|
-
const grade = sanitizeString(summary.grade || summary.verdict?.grade, 10) || 'N/A';
|
|
910
|
-
const verdict = summary.verdict?.verdict || summary.verdict || (score >= 80 ? 'SHIP' : score >= 50 ? 'WARN' : 'BLOCK');
|
|
911
|
-
const canShip = verdict === 'SHIP' || Boolean(summary.canShip);
|
|
912
|
-
const findings = sanitizeArray(summary.findings || summary.report?.findings || [], 500);
|
|
913
|
-
|
|
914
|
-
// Get severity counts
|
|
915
|
-
const sevCounts = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
916
|
-
for (const f of findings) {
|
|
917
|
-
const sev = (f.severity || 'medium').toLowerCase();
|
|
918
|
-
if (sev === 'block' || sev === 'critical') sevCounts.critical++;
|
|
919
|
-
else if (sev === 'high') sevCounts.high++;
|
|
920
|
-
else if (sev === 'warn' || sev === 'warning' || sev === 'medium') sevCounts.medium++;
|
|
921
|
-
else sevCounts.low++;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
// Build structured output
|
|
925
|
-
let output = '';
|
|
926
|
-
|
|
927
|
-
// Header with verdict
|
|
928
|
-
const verdictEmoji = verdict === 'SHIP' ? '✅' : verdict === 'WARN' ? '⚠️' : '🚫';
|
|
929
|
-
output += `## ${verdictEmoji} VERDICT: ${verdict}\n\n`;
|
|
930
|
-
output += `**Health Score:** ${score}/100 (${grade})\n\n`;
|
|
918
|
+
// Safely extract values with defaults
|
|
919
|
+
const score = sanitizeNumber(summary.score, 0, 100, 0);
|
|
920
|
+
const grade = sanitizeString(summary.grade, 10) || 'N/A';
|
|
921
|
+
const canShip = Boolean(summary.canShip);
|
|
931
922
|
|
|
932
|
-
|
|
933
|
-
output +=
|
|
934
|
-
|
|
935
|
-
output += `- **Critical:** ${sevCounts.critical}\n`;
|
|
936
|
-
output += `- **High:** ${sevCounts.high}\n`;
|
|
937
|
-
output += `- **Medium:** ${sevCounts.medium}\n`;
|
|
938
|
-
output += `- **Low:** ${sevCounts.low}\n\n`;
|
|
939
|
-
|
|
940
|
-
// Category breakdown
|
|
923
|
+
let output = `## Score: ${score}/100 (${grade})\n\n`;
|
|
924
|
+
output += `**Verdict:** ${canShip ? "✅ SHIP" : "🚫 NO-SHIP"}\n\n`;
|
|
925
|
+
|
|
941
926
|
if (summary.counts && typeof summary.counts === 'object') {
|
|
942
|
-
output += "###
|
|
943
|
-
output += "| Category |
|
|
927
|
+
output += "### Checks\n\n";
|
|
928
|
+
output += "| Category | Issues |\n|----------|--------|\n";
|
|
944
929
|
|
|
945
|
-
|
|
930
|
+
// Limit to 50 categories to prevent output bloat
|
|
931
|
+
const entries = Object.entries(summary.counts).slice(0, 50);
|
|
946
932
|
for (const [key, count] of entries) {
|
|
947
933
|
const safeKey = sanitizeString(key, 50);
|
|
948
934
|
const safeCount = sanitizeNumber(count, 0, 999999, 0);
|
|
949
935
|
const icon = safeCount === 0 ? "✅" : "⚠️";
|
|
950
|
-
output += `| ${
|
|
936
|
+
output += `| ${icon} ${safeKey} | ${safeCount} |\n`;
|
|
951
937
|
}
|
|
952
|
-
output += '\n';
|
|
953
938
|
}
|
|
954
939
|
|
|
955
|
-
|
|
956
|
-
if (findings.length > 0) {
|
|
957
|
-
output += "### Top Issues to Fix\n\n";
|
|
958
|
-
|
|
959
|
-
// Sort by severity (critical first)
|
|
960
|
-
const sortedFindings = findings
|
|
961
|
-
.sort((a, b) => {
|
|
962
|
-
const sevOrder = { critical: 0, block: 0, high: 1, warn: 2, warning: 2, medium: 2, low: 3, info: 4 };
|
|
963
|
-
const aOrder = sevOrder[(a.severity || 'medium').toLowerCase()] || 2;
|
|
964
|
-
const bOrder = sevOrder[(b.severity || 'medium').toLowerCase()] || 2;
|
|
965
|
-
return aOrder - bOrder;
|
|
966
|
-
})
|
|
967
|
-
.slice(0, 15);
|
|
968
|
-
|
|
969
|
-
for (let i = 0; i < sortedFindings.length; i++) {
|
|
970
|
-
const f = sortedFindings[i];
|
|
971
|
-
const sev = sanitizeString(f.severity || 'medium', 20).toUpperCase();
|
|
972
|
-
const sevEmoji = sev === 'CRITICAL' || sev === 'BLOCK' ? '🔴' : sev === 'HIGH' ? '🟠' : '🟡';
|
|
973
|
-
const title = sanitizeString(f.title || f.message || f.why || 'Unknown issue', 100);
|
|
974
|
-
const category = sanitizeString(f.category || f.type || 'Other', 30);
|
|
975
|
-
const file = sanitizeString(f.file || (f.evidence && f.evidence[0]?.file) || '', 150);
|
|
976
|
-
const line = f.line || (f.evidence && f.evidence[0]?.lines) || '';
|
|
977
|
-
|
|
978
|
-
output += `**${i + 1}. ${sevEmoji} [${sev}] ${title}**\n`;
|
|
979
|
-
output += ` - Category: \`${category}\`\n`;
|
|
980
|
-
if (file) {
|
|
981
|
-
output += ` - File: \`${file}\`${line ? `:${line}` : ''}\n`;
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
// Include fix hints if available
|
|
985
|
-
const fixHint = f.fixHints?.[0] || f.fixHint || f.fix;
|
|
986
|
-
if (fixHint) {
|
|
987
|
-
output += ` - **Fix:** ${sanitizeString(fixHint, 200)}\n`;
|
|
988
|
-
}
|
|
989
|
-
output += '\n';
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
if (findings.length > 15) {
|
|
993
|
-
output += `_...and ${findings.length - 15} more issues. See full report for details._\n\n`;
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
// Next steps based on verdict
|
|
998
|
-
output += "### Recommended Actions\n\n";
|
|
999
|
-
if (verdict === 'SHIP') {
|
|
1000
|
-
output += "- ✅ Code is clean and ready to ship\n";
|
|
1001
|
-
output += "- Consider running `vibecheck ship --badge` to generate a status badge\n";
|
|
1002
|
-
} else if (verdict === 'WARN') {
|
|
1003
|
-
output += "- Review the warnings above before shipping\n";
|
|
1004
|
-
output += "- Run `vibecheck fix --plan` to see fix suggestions\n";
|
|
1005
|
-
output += "- Consider using `vibecheck fix --apply` (PRO) to auto-fix issues\n";
|
|
1006
|
-
} else {
|
|
1007
|
-
output += "- 🚫 Critical issues must be fixed before shipping\n";
|
|
1008
|
-
output += "- Run `vibecheck fix --plan` to see detailed fix suggestions\n";
|
|
1009
|
-
output += "- Address critical issues first, then re-scan\n";
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
output += `\n📄 **Full Report:** ${CONFIG.OUTPUT_DIR}/report.html\n`;
|
|
1013
|
-
output += `📊 **JSON Results:** ${CONFIG.OUTPUT_DIR}/results/latest.json\n`;
|
|
1014
|
-
|
|
940
|
+
output += `\n📄 **Report:** ${CONFIG.OUTPUT_DIR}/report.html\n`;
|
|
1015
941
|
return output;
|
|
1016
942
|
}
|
|
1017
943
|
|
|
@@ -1141,25 +1067,101 @@ class VibecheckMCP {
|
|
|
1141
1067
|
});
|
|
1142
1068
|
}
|
|
1143
1069
|
|
|
1144
|
-
// Handle v3 tools (
|
|
1070
|
+
// Handle v3 tools (2-tier: FREE/PRO aligned with CLI entitlements)
|
|
1145
1071
|
if (USE_V3_TOOLS && V3_TOOL_TIERS[toolName]) {
|
|
1146
|
-
//
|
|
1147
|
-
//
|
|
1148
|
-
//
|
|
1072
|
+
// ================================================================
|
|
1073
|
+
// PRODUCTION HARDENING: Integrated validation, rate limiting, timeout
|
|
1074
|
+
// ================================================================
|
|
1075
|
+
|
|
1076
|
+
// 1. Get user tier from API key (never trust client-provided tier)
|
|
1149
1077
|
const { getMcpToolAccess } = await import('./tier-auth.js');
|
|
1150
|
-
const access = await getMcpToolAccess(toolName, apiKey);
|
|
1078
|
+
const access = await getMcpToolAccess(toolName, apiKey, args);
|
|
1151
1079
|
const userTier = access.tier || 'free';
|
|
1152
|
-
const result = await handleToolV3(toolName, args, { tier: userTier });
|
|
1153
1080
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1081
|
+
// 2. Check per-user rate limit
|
|
1082
|
+
const userId = apiKey ? hashKeyForRateLimit(apiKey) : '__anonymous__';
|
|
1083
|
+
const rateCheck = rateLimiter.check(userId, userTier);
|
|
1084
|
+
if (!rateCheck.allowed) {
|
|
1085
|
+
const errorEnvelope = createErrorEnvelope(
|
|
1086
|
+
'RATE_LIMITED',
|
|
1087
|
+
`Rate limit exceeded. Try again in ${rateCheck.retryAfter} seconds`,
|
|
1088
|
+
{ retryAfter: rateCheck.retryAfter, limit: rateCheck.limit }
|
|
1089
|
+
);
|
|
1090
|
+
return this.error(errorEnvelope.error.message, {
|
|
1091
|
+
code: errorEnvelope.error.code,
|
|
1092
|
+
retryAfter: rateCheck.retryAfter,
|
|
1093
|
+
});
|
|
1156
1094
|
}
|
|
1157
1095
|
|
|
1158
|
-
//
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1096
|
+
// 3. Validate input schema
|
|
1097
|
+
const validation = validateToolInput(toolName, args);
|
|
1098
|
+
if (!validation.valid) {
|
|
1099
|
+
const errorEnvelope = createErrorEnvelope(
|
|
1100
|
+
'VALIDATION_ERROR',
|
|
1101
|
+
'Invalid tool input',
|
|
1102
|
+
{ errors: validation.errors }
|
|
1103
|
+
);
|
|
1104
|
+
return this.error(errorEnvelope.error.message, {
|
|
1105
|
+
code: errorEnvelope.error.code,
|
|
1106
|
+
errors: validation.errors,
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// 4. Check tier access (already done above, but ensure it's checked)
|
|
1111
|
+
if (!access.hasAccess) {
|
|
1112
|
+
return this.error(access.error?.message || 'Access denied', {
|
|
1113
|
+
code: access.error?.code || 'TIER_REQUIRED',
|
|
1114
|
+
tier: access.tier,
|
|
1115
|
+
required: access.error?.required,
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// 5. Execute with timeout and cancellation support
|
|
1120
|
+
const timeout = getToolTimeout(toolName);
|
|
1121
|
+
const controller = new AbortController();
|
|
1122
|
+
|
|
1123
|
+
// Register job for cancellation (if needed)
|
|
1124
|
+
const jobId = `${toolName}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1125
|
+
if (typeof global !== 'undefined') {
|
|
1126
|
+
if (!global.activeJobs) global.activeJobs = new Map();
|
|
1127
|
+
global.activeJobs.set(jobId, controller);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
try {
|
|
1131
|
+
const result = await executeWithEnvelope(
|
|
1132
|
+
toolName,
|
|
1133
|
+
async (signal) => {
|
|
1134
|
+
return await handleToolV3(toolName, args, {
|
|
1135
|
+
tier: userTier,
|
|
1136
|
+
signal, // Pass abort signal to tool handler
|
|
1137
|
+
});
|
|
1138
|
+
},
|
|
1139
|
+
{ timeout }
|
|
1140
|
+
);
|
|
1141
|
+
|
|
1142
|
+
// Cleanup job registration
|
|
1143
|
+
if (typeof global !== 'undefined' && global.activeJobs) {
|
|
1144
|
+
global.activeJobs.delete(jobId);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
// 6. Validate output schema (warn on mismatch, don't fail)
|
|
1148
|
+
const outputValidation = validateToolOutput(toolName, result.data || result);
|
|
1149
|
+
if (!outputValidation.valid) {
|
|
1150
|
+
console.warn(`[MCP] Tool ${toolName} output validation warnings:`, outputValidation.errors);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// 7. Return sanitized output
|
|
1154
|
+
const outputText = truncateOutput(redactSensitive(JSON.stringify(result, null, 2)));
|
|
1155
|
+
return {
|
|
1156
|
+
content: [{ type: "text", text: outputText }],
|
|
1157
|
+
};
|
|
1158
|
+
} catch (error) {
|
|
1159
|
+
// Cleanup on error
|
|
1160
|
+
if (typeof global !== 'undefined' && global.activeJobs) {
|
|
1161
|
+
global.activeJobs.delete(jobId);
|
|
1162
|
+
}
|
|
1163
|
+
throw error;
|
|
1164
|
+
}
|
|
1163
1165
|
}
|
|
1164
1166
|
|
|
1165
1167
|
// 1. Check tool registry first (local CLI handlers)
|
|
@@ -1284,12 +1286,6 @@ class VibecheckMCP {
|
|
|
1284
1286
|
// Resources
|
|
1285
1287
|
this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
1286
1288
|
resources: [
|
|
1287
|
-
{
|
|
1288
|
-
uri: "vibecheck://status",
|
|
1289
|
-
name: "Server Status",
|
|
1290
|
-
description: "Current MCP server health, version, and rate limits",
|
|
1291
|
-
mimeType: "application/json",
|
|
1292
|
-
},
|
|
1293
1289
|
{
|
|
1294
1290
|
uri: "vibecheck://config",
|
|
1295
1291
|
name: "vibecheck Config",
|
|
@@ -1338,12 +1334,6 @@ class VibecheckMCP {
|
|
|
1338
1334
|
description: "Last prove loop results (ctx → reality → ship → fix)",
|
|
1339
1335
|
mimeType: "application/json",
|
|
1340
1336
|
},
|
|
1341
|
-
{
|
|
1342
|
-
uri: "vibecheck://registry",
|
|
1343
|
-
name: "Command Registry",
|
|
1344
|
-
description: "Available commands and their tiers",
|
|
1345
|
-
mimeType: "application/json",
|
|
1346
|
-
},
|
|
1347
1337
|
],
|
|
1348
1338
|
}));
|
|
1349
1339
|
|
|
@@ -1490,82 +1480,6 @@ class VibecheckMCP {
|
|
|
1490
1480
|
return await safeReadResource(provePath, "No prove results. Run vibecheck.prove first.");
|
|
1491
1481
|
}
|
|
1492
1482
|
|
|
1493
|
-
// Server status resource - live health check
|
|
1494
|
-
if (uri === "vibecheck://status") {
|
|
1495
|
-
const rateCheck = checkRateLimit(null);
|
|
1496
|
-
const circuitCheck = checkCircuitBreaker();
|
|
1497
|
-
|
|
1498
|
-
const status = {
|
|
1499
|
-
server: {
|
|
1500
|
-
version: CONFIG.VERSION,
|
|
1501
|
-
uptime: Math.floor(process.uptime()),
|
|
1502
|
-
transport: 'stdio',
|
|
1503
|
-
nodeVersion: process.version,
|
|
1504
|
-
},
|
|
1505
|
-
health: {
|
|
1506
|
-
status: circuitCheck.allowed ? 'healthy' : 'degraded',
|
|
1507
|
-
circuitBreaker: circuitBreakerState.state,
|
|
1508
|
-
failureCount: circuitBreakerState.failures,
|
|
1509
|
-
},
|
|
1510
|
-
rateLimit: {
|
|
1511
|
-
remaining: rateCheck.remaining,
|
|
1512
|
-
resetIn: rateCheck.resetIn || 0,
|
|
1513
|
-
limit: CONFIG.LIMITS.RATE_LIMIT_MAX_CALLS,
|
|
1514
|
-
window: CONFIG.LIMITS.RATE_LIMIT_WINDOW_MS,
|
|
1515
|
-
},
|
|
1516
|
-
features: {
|
|
1517
|
-
hardening: true,
|
|
1518
|
-
auditLogging: true,
|
|
1519
|
-
secretRedaction: true,
|
|
1520
|
-
pathSecurity: true,
|
|
1521
|
-
},
|
|
1522
|
-
timestamp: new Date().toISOString(),
|
|
1523
|
-
};
|
|
1524
|
-
|
|
1525
|
-
return {
|
|
1526
|
-
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(status, null, 2) }],
|
|
1527
|
-
};
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
|
-
// Registry resource - available commands and tiers
|
|
1531
|
-
if (uri === "vibecheck://registry") {
|
|
1532
|
-
const registry = {
|
|
1533
|
-
version: CONFIG.VERSION,
|
|
1534
|
-
tiers: {
|
|
1535
|
-
free: {
|
|
1536
|
-
name: 'FREE',
|
|
1537
|
-
price: '$0',
|
|
1538
|
-
description: 'Inspect & Observe',
|
|
1539
|
-
},
|
|
1540
|
-
pro: {
|
|
1541
|
-
name: 'PRO',
|
|
1542
|
-
price: '$69/mo',
|
|
1543
|
-
description: 'Fix, Prove & Enforce',
|
|
1544
|
-
},
|
|
1545
|
-
},
|
|
1546
|
-
tools: Object.entries(V3_TOOL_TIERS).map(([name, tier]) => ({
|
|
1547
|
-
name,
|
|
1548
|
-
tier,
|
|
1549
|
-
})),
|
|
1550
|
-
resources: [
|
|
1551
|
-
'vibecheck://status',
|
|
1552
|
-
'vibecheck://config',
|
|
1553
|
-
'vibecheck://summary',
|
|
1554
|
-
'vibecheck://truthpack',
|
|
1555
|
-
'vibecheck://missions',
|
|
1556
|
-
'vibecheck://reality',
|
|
1557
|
-
'vibecheck://findings',
|
|
1558
|
-
'vibecheck://share',
|
|
1559
|
-
'vibecheck://prove',
|
|
1560
|
-
'vibecheck://registry',
|
|
1561
|
-
],
|
|
1562
|
-
};
|
|
1563
|
-
|
|
1564
|
-
return {
|
|
1565
|
-
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(registry, null, 2) }],
|
|
1566
|
-
};
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
1483
|
return {
|
|
1570
1484
|
contents: [{
|
|
1571
1485
|
uri,
|
|
@@ -1842,16 +1756,24 @@ class VibecheckMCP {
|
|
|
1842
1756
|
}
|
|
1843
1757
|
|
|
1844
1758
|
// ============================================================================
|
|
1845
|
-
// GATE
|
|
1759
|
+
// GATE - PRO tier required (CI/CD enforcement)
|
|
1846
1760
|
// ============================================================================
|
|
1847
1761
|
async handleGate(projectPath, args) {
|
|
1848
|
-
// Check tier access (
|
|
1849
|
-
const access = await getFeatureAccessStatus("gate", args?.apiKey);
|
|
1762
|
+
// Check tier access (PRO tier required - aligned with CLI entitlements-v2.js)
|
|
1763
|
+
const access = await getFeatureAccessStatus("vibecheck.gate", args?.apiKey, args);
|
|
1850
1764
|
if (!access.hasAccess) {
|
|
1851
1765
|
return {
|
|
1852
1766
|
content: [{
|
|
1853
1767
|
type: "text",
|
|
1854
|
-
text:
|
|
1768
|
+
text: JSON.stringify({
|
|
1769
|
+
ok: false,
|
|
1770
|
+
error: access.error || {
|
|
1771
|
+
code: 'NOT_ENTITLED',
|
|
1772
|
+
message: 'Requires PRO',
|
|
1773
|
+
userAction: 'Open billing',
|
|
1774
|
+
retryable: false,
|
|
1775
|
+
},
|
|
1776
|
+
}, null, 2)
|
|
1855
1777
|
}],
|
|
1856
1778
|
isError: true
|
|
1857
1779
|
};
|
|
@@ -1881,21 +1803,27 @@ class VibecheckMCP {
|
|
|
1881
1803
|
}
|
|
1882
1804
|
|
|
1883
1805
|
// ============================================================================
|
|
1884
|
-
// FIX MISSIONS v1
|
|
1806
|
+
// FIX MISSIONS v1 - PRO tier required (aligned with CLI entitlements-v2.js)
|
|
1885
1807
|
// ============================================================================
|
|
1886
1808
|
async handleFix(projectPath, args) {
|
|
1887
|
-
// Check tier access
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1809
|
+
// Check tier access - vibecheck.fix is PRO (all modes: plan, apply, autopilot)
|
|
1810
|
+
const access = await getFeatureAccessStatus("vibecheck.fix", args?.apiKey, args);
|
|
1811
|
+
if (!access.hasAccess) {
|
|
1812
|
+
return {
|
|
1813
|
+
content: [{
|
|
1814
|
+
type: "text",
|
|
1815
|
+
text: JSON.stringify({
|
|
1816
|
+
ok: false,
|
|
1817
|
+
error: access.error || {
|
|
1818
|
+
code: 'NOT_ENTITLED',
|
|
1819
|
+
message: 'Requires PRO',
|
|
1820
|
+
userAction: 'Open billing',
|
|
1821
|
+
retryable: false,
|
|
1822
|
+
},
|
|
1823
|
+
}, null, 2)
|
|
1824
|
+
}],
|
|
1825
|
+
isError: true
|
|
1826
|
+
};
|
|
1899
1827
|
}
|
|
1900
1828
|
|
|
1901
1829
|
const mode = args?.autopilot ? "Autopilot" :
|
|
@@ -2057,16 +1985,24 @@ class VibecheckMCP {
|
|
|
2057
1985
|
}
|
|
2058
1986
|
|
|
2059
1987
|
// ============================================================================
|
|
2060
|
-
// PROVE - One Command Reality Proof
|
|
1988
|
+
// PROVE - One Command Reality Proof (PRO tier required)
|
|
2061
1989
|
// ============================================================================
|
|
2062
1990
|
async handleProve(projectPath, args) {
|
|
2063
|
-
// Check tier access (PRO tier required)
|
|
2064
|
-
const access = await getFeatureAccessStatus("prove", args?.apiKey);
|
|
1991
|
+
// Check tier access (PRO tier required - aligned with CLI entitlements-v2.js)
|
|
1992
|
+
const access = await getFeatureAccessStatus("vibecheck.prove", args?.apiKey, args);
|
|
2065
1993
|
if (!access.hasAccess) {
|
|
2066
1994
|
return {
|
|
2067
1995
|
content: [{
|
|
2068
1996
|
type: "text",
|
|
2069
|
-
text:
|
|
1997
|
+
text: JSON.stringify({
|
|
1998
|
+
ok: false,
|
|
1999
|
+
error: access.error || {
|
|
2000
|
+
code: 'NOT_ENTITLED',
|
|
2001
|
+
message: 'Requires PRO',
|
|
2002
|
+
userAction: 'Open billing',
|
|
2003
|
+
retryable: false,
|
|
2004
|
+
},
|
|
2005
|
+
}, null, 2)
|
|
2070
2006
|
}],
|
|
2071
2007
|
isError: true
|
|
2072
2008
|
};
|
|
@@ -2261,9 +2197,29 @@ class VibecheckMCP {
|
|
|
2261
2197
|
}
|
|
2262
2198
|
|
|
2263
2199
|
// ============================================================================
|
|
2264
|
-
// SHIP -
|
|
2200
|
+
// SHIP - Verdict engine (PRO tier required - aligned with CLI entitlements-v2.js)
|
|
2265
2201
|
// ============================================================================
|
|
2266
2202
|
async handleShip(projectPath, args) {
|
|
2203
|
+
// Check tier access (PRO tier required)
|
|
2204
|
+
const access = await getFeatureAccessStatus("vibecheck.ship", args?.apiKey, args);
|
|
2205
|
+
if (!access.hasAccess) {
|
|
2206
|
+
return {
|
|
2207
|
+
content: [{
|
|
2208
|
+
type: "text",
|
|
2209
|
+
text: JSON.stringify({
|
|
2210
|
+
ok: false,
|
|
2211
|
+
error: access.error || {
|
|
2212
|
+
code: 'NOT_ENTITLED',
|
|
2213
|
+
message: 'Requires PRO',
|
|
2214
|
+
userAction: 'Open billing',
|
|
2215
|
+
retryable: false,
|
|
2216
|
+
},
|
|
2217
|
+
}, null, 2)
|
|
2218
|
+
}],
|
|
2219
|
+
isError: true
|
|
2220
|
+
};
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2267
2223
|
// HARDENING: Validate project path
|
|
2268
2224
|
const validation = this.validateProjectPath(projectPath);
|
|
2269
2225
|
if (!validation.valid) {
|
|
@@ -2588,16 +2544,24 @@ class VibecheckMCP {
|
|
|
2588
2544
|
}
|
|
2589
2545
|
|
|
2590
2546
|
// ============================================================================
|
|
2591
|
-
// AUTOPILOT PLAN - Generate fix plan (PRO tier)
|
|
2547
|
+
// AUTOPILOT PLAN - Generate fix plan (PRO tier required)
|
|
2592
2548
|
// ============================================================================
|
|
2593
2549
|
async handleAutopilotPlan(projectPath, args) {
|
|
2594
|
-
// Check tier access (PRO tier required)
|
|
2595
|
-
const access = await getFeatureAccessStatus("fix
|
|
2550
|
+
// Check tier access (PRO tier required - aligned with CLI entitlements-v2.js)
|
|
2551
|
+
const access = await getFeatureAccessStatus("vibecheck.fix", args?.apiKey, args);
|
|
2596
2552
|
if (!access.hasAccess) {
|
|
2597
2553
|
return {
|
|
2598
2554
|
content: [{
|
|
2599
2555
|
type: "text",
|
|
2600
|
-
text:
|
|
2556
|
+
text: JSON.stringify({
|
|
2557
|
+
ok: false,
|
|
2558
|
+
error: access.error || {
|
|
2559
|
+
code: 'NOT_ENTITLED',
|
|
2560
|
+
message: 'Requires PRO',
|
|
2561
|
+
userAction: 'Open billing',
|
|
2562
|
+
retryable: false,
|
|
2563
|
+
},
|
|
2564
|
+
}, null, 2)
|
|
2601
2565
|
}],
|
|
2602
2566
|
isError: true
|
|
2603
2567
|
};
|
|
@@ -2675,11 +2639,11 @@ class VibecheckMCP {
|
|
|
2675
2639
|
}
|
|
2676
2640
|
|
|
2677
2641
|
// ============================================================================
|
|
2678
|
-
// AUTOPILOT APPLY - Apply fixes (PRO tier)
|
|
2642
|
+
// AUTOPILOT APPLY - Apply fixes (PRO tier required)
|
|
2679
2643
|
// ============================================================================
|
|
2680
2644
|
async handleAutopilotApply(projectPath, args) {
|
|
2681
|
-
// Check tier access (PRO tier required)
|
|
2682
|
-
const access = await getFeatureAccessStatus("fix
|
|
2645
|
+
// Check tier access (PRO tier required - aligned with CLI entitlements-v2.js)
|
|
2646
|
+
const access = await getFeatureAccessStatus("vibecheck.fix", args?.apiKey, args);
|
|
2683
2647
|
if (!access.hasAccess) {
|
|
2684
2648
|
return {
|
|
2685
2649
|
content: [{
|
|
@@ -2736,16 +2700,24 @@ class VibecheckMCP {
|
|
|
2736
2700
|
}
|
|
2737
2701
|
|
|
2738
2702
|
// ============================================================================
|
|
2739
|
-
// BADGE - Generate ship badge
|
|
2703
|
+
// BADGE - Generate ship badge (PRO tier required)
|
|
2740
2704
|
// ============================================================================
|
|
2741
2705
|
async handleBadge(projectPath, args) {
|
|
2742
|
-
// Check tier access (
|
|
2743
|
-
const access = await getFeatureAccessStatus("badge", args?.apiKey);
|
|
2706
|
+
// Check tier access (PRO tier required - aligned with CLI entitlements-v2.js)
|
|
2707
|
+
const access = await getFeatureAccessStatus("vibecheck.badge", args?.apiKey, args);
|
|
2744
2708
|
if (!access.hasAccess) {
|
|
2745
2709
|
return {
|
|
2746
2710
|
content: [{
|
|
2747
2711
|
type: "text",
|
|
2748
|
-
text:
|
|
2712
|
+
text: JSON.stringify({
|
|
2713
|
+
ok: false,
|
|
2714
|
+
error: access.error || {
|
|
2715
|
+
code: 'NOT_ENTITLED',
|
|
2716
|
+
message: 'Requires PRO',
|
|
2717
|
+
userAction: 'Open billing',
|
|
2718
|
+
retryable: false,
|
|
2719
|
+
},
|
|
2720
|
+
}, null, 2)
|
|
2749
2721
|
}],
|
|
2750
2722
|
isError: true
|
|
2751
2723
|
};
|