@vibecheckai/cli 3.2.5 → 3.3.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/bin/.generated +25 -25
- package/bin/dev/run-v2-torture.js +30 -30
- package/bin/registry.js +192 -5
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -295
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/analyzers.js +81 -18
- package/bin/runners/lib/api-client.js +269 -0
- package/bin/runners/lib/auth-truth.js +193 -193
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/backup.js +62 -62
- package/bin/runners/lib/billing.js +107 -107
- package/bin/runners/lib/claims.js +118 -118
- package/bin/runners/lib/cli-output.js +7 -1
- package/bin/runners/lib/cli-ui.js +540 -540
- package/bin/runners/lib/contracts/auth-contract.js +202 -202
- package/bin/runners/lib/contracts/env-contract.js +181 -181
- package/bin/runners/lib/contracts/external-contract.js +206 -206
- package/bin/runners/lib/contracts/guard.js +168 -168
- package/bin/runners/lib/contracts/index.js +89 -89
- package/bin/runners/lib/contracts/plan-validator.js +311 -311
- package/bin/runners/lib/contracts/route-contract.js +199 -199
- package/bin/runners/lib/contracts.js +804 -804
- package/bin/runners/lib/detect.js +89 -89
- package/bin/runners/lib/doctor/autofix.js +254 -254
- package/bin/runners/lib/doctor/index.js +37 -37
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -325
- package/bin/runners/lib/doctor/modules/index.js +46 -46
- package/bin/runners/lib/doctor/modules/network.js +250 -250
- package/bin/runners/lib/doctor/modules/project.js +312 -312
- package/bin/runners/lib/doctor/modules/runtime.js +224 -224
- package/bin/runners/lib/doctor/modules/security.js +348 -348
- package/bin/runners/lib/doctor/modules/system.js +213 -213
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -394
- package/bin/runners/lib/doctor/reporter.js +262 -262
- package/bin/runners/lib/doctor/service.js +262 -262
- package/bin/runners/lib/doctor/types.js +113 -113
- package/bin/runners/lib/doctor/ui.js +263 -263
- package/bin/runners/lib/doctor-v2.js +608 -608
- package/bin/runners/lib/drift.js +425 -425
- package/bin/runners/lib/enforcement.js +72 -72
- package/bin/runners/lib/enterprise-detect.js +603 -603
- package/bin/runners/lib/enterprise-init.js +942 -942
- package/bin/runners/lib/env-resolver.js +417 -417
- package/bin/runners/lib/env-template.js +66 -66
- package/bin/runners/lib/env.js +189 -189
- package/bin/runners/lib/error-handler.js +16 -9
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/extractors/client-calls.js +990 -990
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -573
- package/bin/runners/lib/extractors/fastify-routes.js +426 -426
- package/bin/runners/lib/extractors/index.js +363 -363
- package/bin/runners/lib/extractors/next-routes.js +524 -524
- package/bin/runners/lib/extractors/proof-graph.js +431 -431
- package/bin/runners/lib/extractors/route-matcher.js +451 -451
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -377
- package/bin/runners/lib/extractors/ui-bindings.js +547 -547
- package/bin/runners/lib/findings-schema.js +281 -281
- package/bin/runners/lib/firewall-prompt.js +50 -50
- package/bin/runners/lib/global-flags.js +37 -0
- package/bin/runners/lib/graph/graph-builder.js +265 -265
- package/bin/runners/lib/graph/html-renderer.js +413 -413
- package/bin/runners/lib/graph/index.js +32 -32
- package/bin/runners/lib/graph/runtime-collector.js +215 -215
- package/bin/runners/lib/graph/static-extractor.js +518 -518
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/html-report.js +650 -650
- package/bin/runners/lib/llm.js +75 -75
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/meter.js +61 -61
- package/bin/runners/lib/missions/evidence.js +126 -126
- package/bin/runners/lib/patch.js +40 -40
- package/bin/runners/lib/permissions/auth-model.js +213 -213
- package/bin/runners/lib/permissions/idor-prover.js +205 -205
- package/bin/runners/lib/permissions/index.js +45 -45
- package/bin/runners/lib/permissions/matrix-builder.js +198 -198
- package/bin/runners/lib/pkgjson.js +28 -28
- package/bin/runners/lib/policy.js +295 -295
- package/bin/runners/lib/preflight.js +142 -142
- package/bin/runners/lib/reality/correlation-detectors.js +359 -359
- package/bin/runners/lib/reality/index.js +318 -318
- package/bin/runners/lib/reality/request-hashing.js +416 -416
- package/bin/runners/lib/reality/request-mapper.js +453 -453
- package/bin/runners/lib/reality/safety-rails.js +463 -463
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -408
- package/bin/runners/lib/reality/toast-detector.js +393 -393
- package/bin/runners/lib/reality-findings.js +84 -84
- package/bin/runners/lib/receipts.js +179 -179
- package/bin/runners/lib/redact.js +29 -29
- package/bin/runners/lib/replay/capsule-manager.js +154 -154
- package/bin/runners/lib/replay/index.js +263 -263
- package/bin/runners/lib/replay/player.js +348 -348
- package/bin/runners/lib/replay/recorder.js +331 -331
- package/bin/runners/lib/report.js +135 -135
- package/bin/runners/lib/route-detection.js +1140 -1140
- package/bin/runners/lib/sandbox/index.js +59 -59
- package/bin/runners/lib/sandbox/proof-chain.js +399 -399
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -205
- package/bin/runners/lib/sandbox/worktree.js +174 -174
- package/bin/runners/lib/schema-validator.js +350 -350
- package/bin/runners/lib/schemas/contracts.schema.json +160 -160
- package/bin/runners/lib/schemas/finding.schema.json +100 -100
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -206
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -176
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -162
- package/bin/runners/lib/schemas/share-pack.schema.json +180 -180
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -117
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -303
- package/bin/runners/lib/schemas/validator.js +438 -438
- package/bin/runners/lib/score-history.js +282 -282
- package/bin/runners/lib/share-pack.js +239 -239
- package/bin/runners/lib/snippets.js +67 -67
- package/bin/runners/lib/unified-cli-output.js +604 -0
- package/bin/runners/lib/upsell.js +658 -510
- package/bin/runners/lib/usage.js +153 -153
- package/bin/runners/lib/validate-patch.js +156 -156
- package/bin/runners/lib/verdict-engine.js +628 -628
- package/bin/runners/reality/engine.js +917 -917
- package/bin/runners/reality/flows.js +122 -122
- package/bin/runners/reality/report.js +378 -378
- package/bin/runners/reality/session.js +193 -193
- package/bin/runners/runAgent.d.ts +5 -0
- package/bin/runners/runApprove.js +1200 -0
- package/bin/runners/runAuth.js +324 -95
- package/bin/runners/runCheckpoint.js +39 -21
- package/bin/runners/runClassify.js +859 -0
- package/bin/runners/runContext.js +136 -24
- package/bin/runners/runDoctor.js +108 -68
- package/bin/runners/runFirewall.d.ts +5 -0
- package/bin/runners/runFirewallHook.d.ts +5 -0
- package/bin/runners/runFix.js +6 -5
- package/bin/runners/runGuard.js +262 -168
- package/bin/runners/runInit.js +3 -2
- package/bin/runners/runMcp.js +130 -52
- package/bin/runners/runPolish.js +43 -20
- package/bin/runners/runProve.js +1 -2
- package/bin/runners/runReport.js +3 -2
- package/bin/runners/runScan.js +145 -44
- package/bin/runners/runShip.js +3 -4
- package/bin/runners/runTruth.d.ts +5 -0
- package/bin/runners/runValidate.js +19 -2
- package/bin/runners/runWatch.js +104 -53
- package/bin/vibecheck.js +106 -19
- package/mcp-server/HARDENING_SUMMARY.md +299 -0
- package/mcp-server/agent-firewall-interceptor.js +367 -31
- package/mcp-server/authority-tools.js +569 -0
- package/mcp-server/conductor/conflict-resolver.js +588 -0
- package/mcp-server/conductor/execution-planner.js +544 -0
- package/mcp-server/conductor/index.js +377 -0
- package/mcp-server/conductor/lock-manager.js +615 -0
- package/mcp-server/conductor/request-queue.js +550 -0
- package/mcp-server/conductor/session-manager.js +500 -0
- package/mcp-server/conductor/tools.js +510 -0
- package/mcp-server/index.js +1199 -208
- package/mcp-server/lib/api-client.cjs +305 -0
- package/mcp-server/lib/logger.cjs +30 -0
- package/mcp-server/logger.js +173 -0
- package/mcp-server/package.json +2 -2
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/tier-auth.js +351 -136
- package/mcp-server/tools/index.js +72 -72
- package/mcp-server/truth-firewall-tools.js +145 -15
- package/mcp-server/vibecheck-tools.js +2 -2
- package/package.json +2 -3
- package/mcp-server/index.old.js +0 -4137
- package/mcp-server/package-lock.json +0 -165
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tools Index - Single Entry Point for All Tools
|
|
3
|
-
*
|
|
4
|
-
* This module exports all MCP tools in a unified structure.
|
|
5
|
-
* Internal modules are organized by category but presented as one toolset.
|
|
6
|
-
*
|
|
7
|
-
* Tool Categories:
|
|
8
|
-
* - Core: scan, ship, reality, fix, prove, report
|
|
9
|
-
* - Truth: ctx, guard, validate_claim, compile_context
|
|
10
|
-
* - AI: checkpoint, architect, intelligence
|
|
11
|
-
*
|
|
12
|
-
* Usage:
|
|
13
|
-
* import { ALL_TOOLS, handleTool } from './tools/index.js';
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
// Re-export consolidated tools as the primary interface
|
|
17
|
-
export { CONSOLIDATED_TOOLS, handleConsolidatedTool } from '../consolidated-tools.js';
|
|
18
|
-
|
|
19
|
-
// Re-export truth firewall (hallucination stopper)
|
|
20
|
-
export { TRUTH_FIREWALL_TOOLS, handleTruthFirewallTool } from '../truth-firewall-tools.js';
|
|
21
|
-
|
|
22
|
-
// Re-export truth context
|
|
23
|
-
export { TRUTH_CONTEXT_TOOLS, handleTruthContextTool } from '../truth-context.js';
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Get all recommended tools (consolidated + truth firewall)
|
|
27
|
-
*/
|
|
28
|
-
export function getRecommendedTools() {
|
|
29
|
-
const { CONSOLIDATED_TOOLS } = require('../consolidated-tools.js');
|
|
30
|
-
const { TRUTH_FIREWALL_TOOLS } = require('../truth-firewall-tools.js');
|
|
31
|
-
return [...CONSOLIDATED_TOOLS, ...TRUTH_FIREWALL_TOOLS];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Handle any tool call by routing to the appropriate handler
|
|
36
|
-
*/
|
|
37
|
-
export async function handleToolCall(toolName, args) {
|
|
38
|
-
// Route to consolidated handler first
|
|
39
|
-
const { handleConsolidatedTool, CONSOLIDATED_TOOLS } = await import('../consolidated-tools.js');
|
|
40
|
-
const consolidatedNames = CONSOLIDATED_TOOLS.map(t => t.name);
|
|
41
|
-
|
|
42
|
-
if (consolidatedNames.includes(toolName)) {
|
|
43
|
-
return handleConsolidatedTool(toolName, args);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Route to truth firewall
|
|
47
|
-
const { handleTruthFirewallTool, TRUTH_FIREWALL_TOOLS } = await import('../truth-firewall-tools.js');
|
|
48
|
-
const firewallNames = TRUTH_FIREWALL_TOOLS.map(t => t.name);
|
|
49
|
-
|
|
50
|
-
if (firewallNames.includes(toolName)) {
|
|
51
|
-
return handleTruthFirewallTool(toolName, args);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Route to truth context
|
|
55
|
-
const { handleTruthContextTool, TRUTH_CONTEXT_TOOLS } = await import('../truth-context.js');
|
|
56
|
-
const contextNames = TRUTH_CONTEXT_TOOLS.map(t => t.name);
|
|
57
|
-
|
|
58
|
-
if (contextNames.includes(toolName)) {
|
|
59
|
-
return handleTruthContextTool(toolName, args);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
throw new Error(`Unknown tool: ${toolName}`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Tool categories for documentation
|
|
67
|
-
*/
|
|
68
|
-
export const TOOL_CATEGORIES = {
|
|
69
|
-
core: ['vibecheck.scan', 'vibecheck.ship', 'vibecheck.reality', 'vibecheck.fix', 'vibecheck.prove', 'vibecheck.report'],
|
|
70
|
-
truth: ['vibecheck.ctx', 'vibecheck.get_truthpack', 'vibecheck.validate_claim', 'vibecheck.compile_context'],
|
|
71
|
-
guard: ['vibecheck.guard', 'vibecheck.check_route', 'vibecheck.check_env', 'vibecheck.check_auth'],
|
|
72
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools Index - Single Entry Point for All Tools
|
|
3
|
+
*
|
|
4
|
+
* This module exports all MCP tools in a unified structure.
|
|
5
|
+
* Internal modules are organized by category but presented as one toolset.
|
|
6
|
+
*
|
|
7
|
+
* Tool Categories:
|
|
8
|
+
* - Core: scan, ship, reality, fix, prove, report
|
|
9
|
+
* - Truth: ctx, guard, validate_claim, compile_context
|
|
10
|
+
* - AI: checkpoint, architect, intelligence
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* import { ALL_TOOLS, handleTool } from './tools/index.js';
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Re-export consolidated tools as the primary interface
|
|
17
|
+
export { CONSOLIDATED_TOOLS, handleConsolidatedTool } from '../consolidated-tools.js';
|
|
18
|
+
|
|
19
|
+
// Re-export truth firewall (hallucination stopper)
|
|
20
|
+
export { TRUTH_FIREWALL_TOOLS, handleTruthFirewallTool } from '../truth-firewall-tools.js';
|
|
21
|
+
|
|
22
|
+
// Re-export truth context
|
|
23
|
+
export { TRUTH_CONTEXT_TOOLS, handleTruthContextTool } from '../truth-context.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get all recommended tools (consolidated + truth firewall)
|
|
27
|
+
*/
|
|
28
|
+
export function getRecommendedTools() {
|
|
29
|
+
const { CONSOLIDATED_TOOLS } = require('../consolidated-tools.js');
|
|
30
|
+
const { TRUTH_FIREWALL_TOOLS } = require('../truth-firewall-tools.js');
|
|
31
|
+
return [...CONSOLIDATED_TOOLS, ...TRUTH_FIREWALL_TOOLS];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Handle any tool call by routing to the appropriate handler
|
|
36
|
+
*/
|
|
37
|
+
export async function handleToolCall(toolName, args) {
|
|
38
|
+
// Route to consolidated handler first
|
|
39
|
+
const { handleConsolidatedTool, CONSOLIDATED_TOOLS } = await import('../consolidated-tools.js');
|
|
40
|
+
const consolidatedNames = CONSOLIDATED_TOOLS.map(t => t.name);
|
|
41
|
+
|
|
42
|
+
if (consolidatedNames.includes(toolName)) {
|
|
43
|
+
return handleConsolidatedTool(toolName, args);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Route to truth firewall
|
|
47
|
+
const { handleTruthFirewallTool, TRUTH_FIREWALL_TOOLS } = await import('../truth-firewall-tools.js');
|
|
48
|
+
const firewallNames = TRUTH_FIREWALL_TOOLS.map(t => t.name);
|
|
49
|
+
|
|
50
|
+
if (firewallNames.includes(toolName)) {
|
|
51
|
+
return handleTruthFirewallTool(toolName, args);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Route to truth context
|
|
55
|
+
const { handleTruthContextTool, TRUTH_CONTEXT_TOOLS } = await import('../truth-context.js');
|
|
56
|
+
const contextNames = TRUTH_CONTEXT_TOOLS.map(t => t.name);
|
|
57
|
+
|
|
58
|
+
if (contextNames.includes(toolName)) {
|
|
59
|
+
return handleTruthContextTool(toolName, args);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Tool categories for documentation
|
|
67
|
+
*/
|
|
68
|
+
export const TOOL_CATEGORIES = {
|
|
69
|
+
core: ['vibecheck.scan', 'vibecheck.ship', 'vibecheck.reality', 'vibecheck.fix', 'vibecheck.prove', 'vibecheck.report'],
|
|
70
|
+
truth: ['vibecheck.ctx', 'vibecheck.get_truthpack', 'vibecheck.validate_claim', 'vibecheck.compile_context'],
|
|
71
|
+
guard: ['vibecheck.guard', 'vibecheck.check_route', 'vibecheck.check_env', 'vibecheck.check_auth'],
|
|
72
|
+
};
|
|
@@ -570,8 +570,47 @@ export function enforceClaimResult(result, policy = "strict") {
|
|
|
570
570
|
return { allowed: true, confidence: derived };
|
|
571
571
|
}
|
|
572
572
|
|
|
573
|
+
// =============================================================================
|
|
574
|
+
// CLAIM VALIDATION WITH RACE CONDITION PROTECTION
|
|
575
|
+
//
|
|
576
|
+
// SECURITY FIX: Previous implementation had a TOCTOU race condition:
|
|
577
|
+
// 1. Thread A: hasRecentClaimValidation() returns true
|
|
578
|
+
// 2. Thread B: invalidates the claim (file change, etc.)
|
|
579
|
+
// 3. Thread A: proceeds with stale claim → invalid state
|
|
580
|
+
//
|
|
581
|
+
// New implementation uses atomic check-and-consume pattern with per-project locks.
|
|
582
|
+
// =============================================================================
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Per-project validation locks to prevent concurrent operations
|
|
586
|
+
* from using the same validation state.
|
|
587
|
+
*/
|
|
588
|
+
const validationLocks = new Map(); // Map<projectPath, { locked: boolean, queue: Promise }>
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Acquire a validation lock for a project (serializes validation checks).
|
|
592
|
+
*/
|
|
593
|
+
function acquireValidationLock(projectPath) {
|
|
594
|
+
let lockState = validationLocks.get(projectPath);
|
|
595
|
+
if (!lockState) {
|
|
596
|
+
lockState = { locked: false, queue: Promise.resolve() };
|
|
597
|
+
validationLocks.set(projectPath, lockState);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const acquirePromise = lockState.queue.then(() => {
|
|
601
|
+
lockState.locked = true;
|
|
602
|
+
return () => {
|
|
603
|
+
lockState.locked = false;
|
|
604
|
+
};
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
lockState.queue = acquirePromise.catch(() => {});
|
|
608
|
+
return acquirePromise;
|
|
609
|
+
}
|
|
610
|
+
|
|
573
611
|
/**
|
|
574
|
-
*
|
|
612
|
+
* Check claim validation freshness (basic check, no lock).
|
|
613
|
+
* Use checkAndConsumeClaimValidation for atomic operations.
|
|
575
614
|
*/
|
|
576
615
|
export function hasRecentClaimValidation(projectPath, policy = "strict") {
|
|
577
616
|
const last = state.lastValidationByProject.get(projectPath);
|
|
@@ -580,6 +619,56 @@ export function hasRecentClaimValidation(projectPath, policy = "strict") {
|
|
|
580
619
|
return Date.now() - last <= ttl;
|
|
581
620
|
}
|
|
582
621
|
|
|
622
|
+
/**
|
|
623
|
+
* Atomic check-and-consume claim validation.
|
|
624
|
+
*
|
|
625
|
+
* SECURITY: Use this for operations that depend on claim validation.
|
|
626
|
+
* It ensures no other operation can use the same validation state concurrently.
|
|
627
|
+
*
|
|
628
|
+
* @param {string} projectPath - Project path
|
|
629
|
+
* @param {string} policy - Policy name (strict/balanced/permissive)
|
|
630
|
+
* @param {string} operationId - Unique ID for this operation (for audit)
|
|
631
|
+
* @returns {Promise<{ valid: boolean, consumedAt?: number, reason?: string }>}
|
|
632
|
+
*/
|
|
633
|
+
export async function checkAndConsumeClaimValidation(projectPath, policy = "strict", operationId = null) {
|
|
634
|
+
const release = await acquireValidationLock(projectPath);
|
|
635
|
+
|
|
636
|
+
try {
|
|
637
|
+
const last = state.lastValidationByProject.get(projectPath);
|
|
638
|
+
const now = Date.now();
|
|
639
|
+
|
|
640
|
+
if (typeof last !== "number") {
|
|
641
|
+
return {
|
|
642
|
+
valid: false,
|
|
643
|
+
reason: "No claim validation found for this project"
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
const ttl = getPolicyConfig(policy).validationTTL;
|
|
648
|
+
const age = now - last;
|
|
649
|
+
|
|
650
|
+
if (age > ttl) {
|
|
651
|
+
return {
|
|
652
|
+
valid: false,
|
|
653
|
+
reason: `Claim validation expired (age: ${Math.round(age / 1000)}s, TTL: ${Math.round(ttl / 1000)}s)`
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Mark this validation as consumed by updating the timestamp
|
|
658
|
+
// This prevents replay/reuse of the same validation
|
|
659
|
+
state.lastValidationByProject.set(projectPath, now);
|
|
660
|
+
|
|
661
|
+
return {
|
|
662
|
+
valid: true,
|
|
663
|
+
consumedAt: now,
|
|
664
|
+
operationId,
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
} finally {
|
|
668
|
+
release();
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
583
672
|
// =============================================================================
|
|
584
673
|
// FINGERPRINT + WRAPPER
|
|
585
674
|
// =============================================================================
|
|
@@ -1069,22 +1158,63 @@ async function proposePatch(projectPath, args) {
|
|
|
1069
1158
|
return patch;
|
|
1070
1159
|
}
|
|
1071
1160
|
|
|
1161
|
+
/**
|
|
1162
|
+
* Validate command against strict allowlist.
|
|
1163
|
+
*
|
|
1164
|
+
* SECURITY FIX: Previous allowlist was too permissive, allowing arbitrary code execution:
|
|
1165
|
+
* - "node -e 'require(\"child_process\").exec(\"rm -rf /\")'" would pass
|
|
1166
|
+
* - "npm exec malicious-package" would pass
|
|
1167
|
+
* - "pnpm dlx evil-tool" would pass
|
|
1168
|
+
*
|
|
1169
|
+
* New allowlist only permits specific safe subcommands.
|
|
1170
|
+
*/
|
|
1072
1171
|
function commandAllowlisted(cmd) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1172
|
+
const trimmed = cmd.trim();
|
|
1173
|
+
|
|
1174
|
+
// Reject commands with shell metacharacters that could enable injection
|
|
1175
|
+
// These are dangerous even in "safe" commands: ; | & $ ` \ ( ) { } < > \n
|
|
1176
|
+
if (/[;|&$`\\(){}<>\n]/.test(trimmed)) {
|
|
1177
|
+
return false;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// Reject commands that use flags commonly used for code execution
|
|
1181
|
+
if (/\s-[eEc]\s|\s--eval\s|\s--exec\s/i.test(trimmed)) {
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
// Strict allowlist: only specific commands with specific safe subcommands
|
|
1186
|
+
const strictAllow = [
|
|
1187
|
+
// Vibecheck CLI - only specific safe commands
|
|
1188
|
+
/^vibecheck\s+(ship|scan|ctx|lint|status)\b/,
|
|
1189
|
+
/^vibecheck\s+--help\b/,
|
|
1190
|
+
/^vibecheck\s+--version\b/,
|
|
1191
|
+
|
|
1192
|
+
// Package managers - only test/build/lint (no exec, dlx, or install scripts)
|
|
1193
|
+
/^pnpm\s+(test|build|lint|typecheck|check|run\s+(test|build|lint|typecheck))\b/,
|
|
1194
|
+
/^npm\s+(test|run\s+(test|build|lint|typecheck))\b/,
|
|
1195
|
+
/^yarn\s+(test|build|lint|typecheck|run\s+(test|build|lint|typecheck))\b/,
|
|
1196
|
+
/^bun\s+(test|run\s+(test|build|lint))\b/,
|
|
1197
|
+
|
|
1198
|
+
// TypeScript compiler - only type checking (no emit)
|
|
1199
|
+
/^tsc\s+(--noEmit|--build)\b/,
|
|
1200
|
+
/^tsc$/, // Default tsc with no args is safe
|
|
1201
|
+
|
|
1202
|
+
// Linters - safe read-only operations
|
|
1203
|
+
/^eslint\s+/, // ESLint with any args (read-only)
|
|
1204
|
+
/^eslint$/,
|
|
1205
|
+
|
|
1206
|
+
// Test runners - only run tests
|
|
1207
|
+
/^vitest\s*(run|--run)?\b/,
|
|
1208
|
+
/^vitest$/,
|
|
1209
|
+
/^jest\s*(--ci|--coverage|--passWithNoTests)?\b/,
|
|
1210
|
+
/^jest$/,
|
|
1211
|
+
|
|
1212
|
+
// Playwright - only test mode (no codegen which opens browsers)
|
|
1213
|
+
/^playwright\s+test\b/,
|
|
1214
|
+
/^npx\s+playwright\s+test\b/,
|
|
1086
1215
|
];
|
|
1087
|
-
|
|
1216
|
+
|
|
1217
|
+
return strictAllow.some((re) => re.test(trimmed));
|
|
1088
1218
|
}
|
|
1089
1219
|
|
|
1090
1220
|
async function verifyPatch(projectPath, args) {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import path from "path";
|
|
14
14
|
import fs from "fs/promises";
|
|
15
15
|
import { execSync } from "child_process";
|
|
16
|
-
import { withTierCheck,
|
|
16
|
+
import { withTierCheck, getFeatureAccessStatus } from "./tier-auth.js";
|
|
17
17
|
|
|
18
18
|
// ============================================================================
|
|
19
19
|
// TOOL DEFINITIONS
|
|
@@ -292,7 +292,7 @@ export async function handleVibecheckTool(toolName, args) {
|
|
|
292
292
|
|
|
293
293
|
const requiredFeature = featureMap[toolName];
|
|
294
294
|
if (requiredFeature) {
|
|
295
|
-
const access = await
|
|
295
|
+
const access = await getFeatureAccessStatus(requiredFeature, args?.apiKey);
|
|
296
296
|
if (!access.hasAccess) {
|
|
297
297
|
return {
|
|
298
298
|
content: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibecheckai/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Vibecheck CLI - Ship with confidence. One verdict: SHIP | WARN | BLOCK.",
|
|
5
5
|
"main": "bin/vibecheck.js",
|
|
6
6
|
"bin": {
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"js-yaml": "^4.1.0",
|
|
38
38
|
"ora": "^8.0.0",
|
|
39
39
|
"uuid": "^9.0.0",
|
|
40
|
-
"yaml": "^2.3.0",
|
|
41
40
|
"zod": "^3.23.0"
|
|
42
41
|
},
|
|
43
42
|
"optionalDependencies": {
|
|
@@ -77,7 +76,7 @@
|
|
|
77
76
|
"url": "https://github.com/vibecheck-oss/vibecheck/issues"
|
|
78
77
|
},
|
|
79
78
|
"engines": {
|
|
80
|
-
"node": ">=
|
|
79
|
+
"node": ">=20.11"
|
|
81
80
|
},
|
|
82
81
|
"publishConfig": {
|
|
83
82
|
"access": "public"
|