@vibecheckai/cli 2.8.2 → 3.0.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/README.md +8 -8
- package/bin/_deprecations.js +35 -0
- package/bin/_router.js +46 -0
- package/bin/cli-hygiene.js +241 -0
- package/bin/guardrail.js +834 -0
- package/bin/runners/cli-utils.js +1070 -0
- package/bin/runners/context/ai-task-decomposer.js +337 -0
- package/bin/runners/context/analyzer.js +462 -0
- package/bin/runners/context/api-contracts.js +427 -0
- package/bin/runners/context/context-diff.js +342 -0
- package/bin/runners/context/context-pruner.js +291 -0
- package/bin/runners/context/dependency-graph.js +414 -0
- package/bin/runners/context/generators/claude.js +107 -0
- package/bin/runners/context/generators/codex.js +108 -0
- package/bin/runners/context/generators/copilot.js +119 -0
- package/bin/runners/context/generators/cursor.js +514 -0
- package/bin/runners/context/generators/mcp.js +151 -0
- package/bin/runners/context/generators/windsurf.js +180 -0
- package/bin/runners/context/git-context.js +302 -0
- package/bin/runners/context/index.js +1042 -0
- package/bin/runners/context/insights.js +173 -0
- package/bin/runners/context/mcp-server/generate-rules.js +337 -0
- package/bin/runners/context/mcp-server/index.js +1176 -0
- package/bin/runners/context/mcp-server/package.json +24 -0
- package/bin/runners/context/memory.js +200 -0
- package/bin/runners/context/monorepo.js +215 -0
- package/bin/runners/context/multi-repo-federation.js +404 -0
- package/bin/runners/context/patterns.js +253 -0
- package/bin/runners/context/proof-context.js +972 -0
- package/bin/runners/context/security-scanner.js +303 -0
- package/bin/runners/context/semantic-search.js +350 -0
- package/bin/runners/context/shared.js +264 -0
- package/bin/runners/context/team-conventions.js +310 -0
- package/bin/runners/lib/ai-bridge.js +416 -0
- package/bin/runners/lib/analysis-core.js +271 -0
- package/bin/runners/lib/analyzers.js +541 -0
- package/bin/runners/lib/audit-bridge.js +391 -0
- package/bin/runners/lib/auth-truth.js +193 -0
- package/bin/runners/lib/auth.js +215 -0
- package/bin/runners/lib/backup.js +62 -0
- package/bin/runners/lib/billing.js +107 -0
- package/bin/runners/lib/claims.js +118 -0
- package/bin/runners/lib/cli-ui.js +540 -0
- package/bin/runners/lib/compliance-bridge-new.js +0 -0
- package/bin/runners/lib/compliance-bridge.js +165 -0
- package/bin/runners/lib/contracts/auth-contract.js +194 -0
- package/bin/runners/lib/contracts/env-contract.js +178 -0
- package/bin/runners/lib/contracts/external-contract.js +198 -0
- package/bin/runners/lib/contracts/guard.js +168 -0
- package/bin/runners/lib/contracts/index.js +89 -0
- package/bin/runners/lib/contracts/plan-validator.js +311 -0
- package/bin/runners/lib/contracts/route-contract.js +192 -0
- package/bin/runners/lib/detect.js +89 -0
- package/bin/runners/lib/doctor/autofix.js +254 -0
- package/bin/runners/lib/doctor/index.js +37 -0
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
- package/bin/runners/lib/doctor/modules/index.js +46 -0
- package/bin/runners/lib/doctor/modules/network.js +250 -0
- package/bin/runners/lib/doctor/modules/project.js +312 -0
- package/bin/runners/lib/doctor/modules/runtime.js +224 -0
- package/bin/runners/lib/doctor/modules/security.js +348 -0
- package/bin/runners/lib/doctor/modules/system.js +213 -0
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
- package/bin/runners/lib/doctor/reporter.js +262 -0
- package/bin/runners/lib/doctor/service.js +262 -0
- package/bin/runners/lib/doctor/types.js +113 -0
- package/bin/runners/lib/doctor/ui.js +263 -0
- package/bin/runners/lib/doctor-enhanced.js +233 -0
- package/bin/runners/lib/doctor-v2.js +608 -0
- package/bin/runners/lib/enforcement.js +72 -0
- package/bin/runners/lib/enterprise-detect.js +603 -0
- package/bin/runners/lib/enterprise-init.js +942 -0
- package/bin/runners/lib/entitlements-v2.js +381 -0
- package/bin/runners/lib/entitlements.generated.js +0 -0
- package/bin/runners/lib/entitlements.js +332 -0
- package/bin/runners/lib/env-template.js +66 -0
- package/bin/runners/lib/env.js +189 -0
- package/bin/runners/lib/error-handler.js +320 -0
- package/bin/runners/lib/firewall-prompt.js +50 -0
- package/bin/runners/lib/graph/graph-builder.js +265 -0
- package/bin/runners/lib/graph/html-renderer.js +413 -0
- package/bin/runners/lib/graph/index.js +32 -0
- package/bin/runners/lib/graph/runtime-collector.js +215 -0
- package/bin/runners/lib/graph/static-extractor.js +518 -0
- package/bin/runners/lib/init-wizard.js +308 -0
- package/bin/runners/lib/json-output.js +76 -0
- package/bin/runners/lib/llm.js +75 -0
- package/bin/runners/lib/meter.js +61 -0
- package/bin/runners/lib/missions/evidence.js +126 -0
- package/bin/runners/lib/missions/plan.js +69 -0
- package/bin/runners/lib/missions/templates.js +147 -0
- package/bin/runners/lib/patch.js +40 -0
- package/bin/runners/lib/permissions/auth-model.js +213 -0
- package/bin/runners/lib/permissions/idor-prover.js +205 -0
- package/bin/runners/lib/permissions/index.js +45 -0
- package/bin/runners/lib/permissions/matrix-builder.js +198 -0
- package/bin/runners/lib/pkgjson.js +28 -0
- package/bin/runners/lib/preflight.js +142 -0
- package/bin/runners/lib/reality-findings.js +84 -0
- package/bin/runners/lib/redact.js +29 -0
- package/bin/runners/lib/replay/capsule-manager.js +154 -0
- package/bin/runners/lib/replay/index.js +263 -0
- package/bin/runners/lib/replay/player.js +348 -0
- package/bin/runners/lib/replay/recorder.js +331 -0
- package/bin/runners/lib/report-engine.js +447 -0
- package/bin/runners/lib/report-html.js +1117 -0
- package/bin/runners/lib/report-templates.js +964 -0
- package/bin/runners/lib/route-detection.js +1140 -0
- package/bin/runners/lib/route-truth.js +477 -0
- package/bin/runners/lib/sandbox/index.js +59 -0
- package/bin/runners/lib/sandbox/proof-chain.js +399 -0
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
- package/bin/runners/lib/sandbox/worktree.js +174 -0
- package/bin/runners/lib/scan-cache.js +330 -0
- package/bin/runners/lib/scan-output-schema.js +344 -0
- package/bin/runners/lib/score-history.js +282 -0
- package/bin/runners/lib/security-bridge.js +249 -0
- package/bin/runners/lib/server-usage.js +513 -0
- package/bin/runners/lib/share-pack.js +239 -0
- package/bin/runners/lib/snippets.js +67 -0
- package/bin/runners/lib/truth.js +667 -0
- package/bin/runners/lib/unified-output.js +189 -0
- package/bin/runners/lib/validate-patch.js +156 -0
- package/bin/runners/lib/verification.js +345 -0
- package/bin/runners/reality/engine.js +917 -0
- package/bin/runners/reality/flows.js +122 -0
- package/bin/runners/reality/report.js +378 -0
- package/bin/runners/reality/session.js +193 -0
- package/bin/runners/runAIAgent.js +2 -0
- package/bin/runners/runAudit.js +2 -0
- package/bin/runners/runAuth.js +106 -0
- package/bin/runners/runAutopilot.js +2 -0
- package/bin/runners/runBadge.js +2 -0
- package/bin/runners/runCertify.js +2 -0
- package/bin/runners/runClaimVerifier.js +483 -0
- package/bin/runners/runContext.js +56 -0
- package/bin/runners/runContextCompiler.js +385 -0
- package/bin/runners/runCtx.js +187 -0
- package/bin/runners/runCtxGuard.js +176 -0
- package/bin/runners/runCtxSync.js +116 -0
- package/bin/runners/runDashboard.js +10 -0
- package/bin/runners/runDoctor.js +245 -0
- package/bin/runners/runEnhancedShip.js +2 -0
- package/bin/runners/runFix.js +735 -0
- package/bin/runners/runFixPacks.js +2 -0
- package/bin/runners/runGate.js +17 -0
- package/bin/runners/runGraph.js +283 -0
- package/bin/runners/runInit.js +260 -0
- package/bin/runners/runInitGha.js +101 -0
- package/bin/runners/runInstall.js +76 -0
- package/bin/runners/runInteractive.js +388 -0
- package/bin/runners/runLaunch.js +2 -0
- package/bin/runners/runMcp.js +19 -0
- package/bin/runners/runMdc.js +2 -0
- package/bin/runners/runMissionGenerator.js +282 -0
- package/bin/runners/runNaturalLanguage.js +3 -0
- package/bin/runners/runPR.js +96 -0
- package/bin/runners/runPermissions.js +290 -0
- package/bin/runners/runPromptFirewall.js +211 -0
- package/bin/runners/runProof.js +2 -0
- package/bin/runners/runProve.js +392 -0
- package/bin/runners/runReality.js +489 -0
- package/bin/runners/runRealitySniff.js +2 -0
- package/bin/runners/runReplay.js +469 -0
- package/bin/runners/runReport.js +478 -0
- package/bin/runners/runScan.js +835 -0
- package/bin/runners/runShare.js +34 -0
- package/bin/runners/runShip.js +1062 -0
- package/bin/runners/runStatus.js +136 -0
- package/bin/runners/runTruthpack.js +634 -0
- package/bin/runners/runUpgrade.js +2 -0
- package/bin/runners/runValidate.js +2 -0
- package/bin/runners/runVerifyAgentOutput.js +2 -0
- package/bin/runners/runWatch.js +230 -0
- package/bin/runners/utils.js +360 -0
- package/bin/scan.js +612 -0
- package/bin/vibecheck.js +834 -0
- package/package.json +11 -11
- package/dist/autopatch/verified-autopatch.d.ts +0 -111
- package/dist/autopatch/verified-autopatch.d.ts.map +0 -1
- package/dist/autopatch/verified-autopatch.js +0 -503
- package/dist/autopatch/verified-autopatch.js.map +0 -1
- package/dist/bundles/index.js +0 -8
- package/dist/bundles/vibecheck-core.js +0 -25799
- package/dist/bundles/vibecheck-security.js +0 -208693
- package/dist/bundles/vibecheck-ship.js +0 -2318
- package/dist/commands/baseline.d.ts +0 -7
- package/dist/commands/baseline.d.ts.map +0 -1
- package/dist/commands/baseline.js +0 -79
- package/dist/commands/baseline.js.map +0 -1
- package/dist/commands/cache.d.ts +0 -13
- package/dist/commands/cache.d.ts.map +0 -1
- package/dist/commands/cache.js +0 -165
- package/dist/commands/cache.js.map +0 -1
- package/dist/commands/checkpoint.d.ts +0 -8
- package/dist/commands/checkpoint.d.ts.map +0 -1
- package/dist/commands/checkpoint.js +0 -35
- package/dist/commands/checkpoint.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -17
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js +0 -226
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/evidence.d.ts +0 -45
- package/dist/commands/evidence.d.ts.map +0 -1
- package/dist/commands/evidence.js +0 -197
- package/dist/commands/evidence.js.map +0 -1
- package/dist/commands/explain.d.ts +0 -8
- package/dist/commands/explain.d.ts.map +0 -1
- package/dist/commands/explain.js +0 -52
- package/dist/commands/explain.js.map +0 -1
- package/dist/commands/fix-consolidated.d.ts +0 -19
- package/dist/commands/fix-consolidated.d.ts.map +0 -1
- package/dist/commands/fix-consolidated.js +0 -165
- package/dist/commands/fix-consolidated.js.map +0 -1
- package/dist/commands/index.d.ts +0 -8
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -15
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/init.d.ts +0 -8
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -125
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/launcher.d.ts +0 -10
- package/dist/commands/launcher.d.ts.map +0 -1
- package/dist/commands/launcher.js +0 -174
- package/dist/commands/launcher.js.map +0 -1
- package/dist/commands/on.d.ts +0 -8
- package/dist/commands/on.d.ts.map +0 -1
- package/dist/commands/on.js +0 -123
- package/dist/commands/on.js.map +0 -1
- package/dist/commands/replay.d.ts +0 -8
- package/dist/commands/replay.d.ts.map +0 -1
- package/dist/commands/replay.js +0 -52
- package/dist/commands/replay.js.map +0 -1
- package/dist/commands/scan-consolidated.d.ts +0 -61
- package/dist/commands/scan-consolidated.d.ts.map +0 -1
- package/dist/commands/scan-consolidated.js +0 -243
- package/dist/commands/scan-consolidated.js.map +0 -1
- package/dist/commands/scan-secrets.d.ts +0 -47
- package/dist/commands/scan-secrets.d.ts.map +0 -1
- package/dist/commands/scan-secrets.js +0 -225
- package/dist/commands/scan-secrets.js.map +0 -1
- package/dist/commands/scan-vulnerabilities-enhanced.d.ts +0 -41
- package/dist/commands/scan-vulnerabilities-enhanced.d.ts.map +0 -1
- package/dist/commands/scan-vulnerabilities-enhanced.js +0 -368
- package/dist/commands/scan-vulnerabilities-enhanced.js.map +0 -1
- package/dist/commands/scan-vulnerabilities-osv.d.ts +0 -58
- package/dist/commands/scan-vulnerabilities-osv.d.ts.map +0 -1
- package/dist/commands/scan-vulnerabilities-osv.js +0 -722
- package/dist/commands/scan-vulnerabilities-osv.js.map +0 -1
- package/dist/commands/scan-vulnerabilities.d.ts +0 -32
- package/dist/commands/scan-vulnerabilities.d.ts.map +0 -1
- package/dist/commands/scan-vulnerabilities.js +0 -283
- package/dist/commands/scan-vulnerabilities.js.map +0 -1
- package/dist/commands/secrets-allowlist.d.ts +0 -7
- package/dist/commands/secrets-allowlist.d.ts.map +0 -1
- package/dist/commands/secrets-allowlist.js +0 -85
- package/dist/commands/secrets-allowlist.js.map +0 -1
- package/dist/commands/ship-consolidated.d.ts +0 -58
- package/dist/commands/ship-consolidated.d.ts.map +0 -1
- package/dist/commands/ship-consolidated.js +0 -515
- package/dist/commands/ship-consolidated.js.map +0 -1
- package/dist/commands/stats.d.ts +0 -8
- package/dist/commands/stats.d.ts.map +0 -1
- package/dist/commands/stats.js +0 -134
- package/dist/commands/stats.js.map +0 -1
- package/dist/commands/upgrade.d.ts +0 -8
- package/dist/commands/upgrade.d.ts.map +0 -1
- package/dist/commands/upgrade.js +0 -30
- package/dist/commands/upgrade.js.map +0 -1
- package/dist/fix/applicator.d.ts +0 -44
- package/dist/fix/applicator.d.ts.map +0 -1
- package/dist/fix/applicator.js +0 -144
- package/dist/fix/applicator.js.map +0 -1
- package/dist/fix/backup.d.ts +0 -38
- package/dist/fix/backup.d.ts.map +0 -1
- package/dist/fix/backup.js +0 -154
- package/dist/fix/backup.js.map +0 -1
- package/dist/fix/engine.d.ts +0 -55
- package/dist/fix/engine.d.ts.map +0 -1
- package/dist/fix/engine.js +0 -285
- package/dist/fix/engine.js.map +0 -1
- package/dist/fix/index.d.ts +0 -5
- package/dist/fix/index.d.ts.map +0 -1
- package/dist/fix/index.js +0 -12
- package/dist/fix/index.js.map +0 -1
- package/dist/fix/interactive.d.ts +0 -22
- package/dist/fix/interactive.d.ts.map +0 -1
- package/dist/fix/interactive.js +0 -172
- package/dist/fix/interactive.js.map +0 -1
- package/dist/formatters/index.d.ts +0 -6
- package/dist/formatters/index.d.ts.map +0 -1
- package/dist/formatters/index.js +0 -11
- package/dist/formatters/index.js.map +0 -1
- package/dist/formatters/sarif-enhanced.d.ts +0 -78
- package/dist/formatters/sarif-enhanced.d.ts.map +0 -1
- package/dist/formatters/sarif-enhanced.js +0 -144
- package/dist/formatters/sarif-enhanced.js.map +0 -1
- package/dist/formatters/sarif-v2.d.ts +0 -121
- package/dist/formatters/sarif-v2.d.ts.map +0 -1
- package/dist/formatters/sarif-v2.js +0 -356
- package/dist/formatters/sarif-v2.js.map +0 -1
- package/dist/formatters/sarif.d.ts +0 -72
- package/dist/formatters/sarif.d.ts.map +0 -1
- package/dist/formatters/sarif.js +0 -146
- package/dist/formatters/sarif.js.map +0 -1
- package/dist/index.d.ts +0 -61
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -4388
- package/dist/index.js.map +0 -1
- package/dist/init/ci-generator.d.ts +0 -18
- package/dist/init/ci-generator.d.ts.map +0 -1
- package/dist/init/ci-generator.js +0 -317
- package/dist/init/ci-generator.js.map +0 -1
- package/dist/init/detect-framework.d.ts +0 -15
- package/dist/init/detect-framework.d.ts.map +0 -1
- package/dist/init/detect-framework.js +0 -301
- package/dist/init/detect-framework.js.map +0 -1
- package/dist/init/hooks-installer.d.ts +0 -22
- package/dist/init/hooks-installer.d.ts.map +0 -1
- package/dist/init/hooks-installer.js +0 -310
- package/dist/init/hooks-installer.js.map +0 -1
- package/dist/init/index.d.ts +0 -8
- package/dist/init/index.d.ts.map +0 -1
- package/dist/init/index.js +0 -22
- package/dist/init/index.js.map +0 -1
- package/dist/init/templates.d.ts +0 -402
- package/dist/init/templates.d.ts.map +0 -1
- package/dist/init/templates.js +0 -240
- package/dist/init/templates.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -12
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -42
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/telemetry.d.ts +0 -40
- package/dist/mcp/telemetry.d.ts.map +0 -1
- package/dist/mcp/telemetry.js +0 -98
- package/dist/mcp/telemetry.js.map +0 -1
- package/dist/reality/no-dead-buttons/button-sweep-generator.d.ts +0 -32
- package/dist/reality/no-dead-buttons/button-sweep-generator.d.ts.map +0 -1
- package/dist/reality/no-dead-buttons/button-sweep-generator.js +0 -236
- package/dist/reality/no-dead-buttons/button-sweep-generator.js.map +0 -1
- package/dist/reality/no-dead-buttons/index.d.ts +0 -11
- package/dist/reality/no-dead-buttons/index.d.ts.map +0 -1
- package/dist/reality/no-dead-buttons/index.js +0 -18
- package/dist/reality/no-dead-buttons/index.js.map +0 -1
- package/dist/reality/no-dead-buttons/static-scanner.d.ts +0 -34
- package/dist/reality/no-dead-buttons/static-scanner.d.ts.map +0 -1
- package/dist/reality/no-dead-buttons/static-scanner.js +0 -230
- package/dist/reality/no-dead-buttons/static-scanner.js.map +0 -1
- package/dist/reality/reality-graph.d.ts +0 -192
- package/dist/reality/reality-graph.d.ts.map +0 -1
- package/dist/reality/reality-graph.js +0 -600
- package/dist/reality/reality-graph.js.map +0 -1
- package/dist/reality/reality-runner.d.ts +0 -89
- package/dist/reality/reality-runner.d.ts.map +0 -1
- package/dist/reality/reality-runner.js +0 -540
- package/dist/reality/reality-runner.js.map +0 -1
- package/dist/reality/receipt-generator.d.ts +0 -152
- package/dist/reality/receipt-generator.d.ts.map +0 -1
- package/dist/reality/receipt-generator.js +0 -495
- package/dist/reality/receipt-generator.js.map +0 -1
- package/dist/reality/runtime-tracer.d.ts +0 -75
- package/dist/reality/runtime-tracer.d.ts.map +0 -1
- package/dist/reality/runtime-tracer.js +0 -109
- package/dist/reality/runtime-tracer.js.map +0 -1
- package/dist/runtime/auth-utils.d.ts +0 -43
- package/dist/runtime/auth-utils.d.ts.map +0 -1
- package/dist/runtime/auth-utils.js +0 -130
- package/dist/runtime/auth-utils.js.map +0 -1
- package/dist/runtime/client.d.ts +0 -74
- package/dist/runtime/client.d.ts.map +0 -1
- package/dist/runtime/client.js +0 -222
- package/dist/runtime/client.js.map +0 -1
- package/dist/runtime/creds.d.ts +0 -48
- package/dist/runtime/creds.d.ts.map +0 -1
- package/dist/runtime/creds.js +0 -245
- package/dist/runtime/creds.js.map +0 -1
- package/dist/runtime/exit-codes.d.ts +0 -49
- package/dist/runtime/exit-codes.d.ts.map +0 -1
- package/dist/runtime/exit-codes.js +0 -93
- package/dist/runtime/exit-codes.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -9
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js +0 -25
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/json-output.d.ts +0 -42
- package/dist/runtime/json-output.d.ts.map +0 -1
- package/dist/runtime/json-output.js +0 -59
- package/dist/runtime/json-output.js.map +0 -1
- package/dist/runtime/semver.d.ts +0 -37
- package/dist/runtime/semver.d.ts.map +0 -1
- package/dist/runtime/semver.js +0 -110
- package/dist/runtime/semver.js.map +0 -1
- package/dist/scan/dead-ui-detector.d.ts +0 -48
- package/dist/scan/dead-ui-detector.d.ts.map +0 -1
- package/dist/scan/dead-ui-detector.js +0 -170
- package/dist/scan/dead-ui-detector.js.map +0 -1
- package/dist/scan/playwright-sweep.d.ts +0 -40
- package/dist/scan/playwright-sweep.d.ts.map +0 -1
- package/dist/scan/playwright-sweep.js +0 -216
- package/dist/scan/playwright-sweep.js.map +0 -1
- package/dist/scan/proof-bundle.d.ts +0 -25
- package/dist/scan/proof-bundle.d.ts.map +0 -1
- package/dist/scan/proof-bundle.js +0 -203
- package/dist/scan/proof-bundle.js.map +0 -1
- package/dist/scan/proof-graph.d.ts +0 -59
- package/dist/scan/proof-graph.d.ts.map +0 -1
- package/dist/scan/proof-graph.js +0 -64
- package/dist/scan/proof-graph.js.map +0 -1
- package/dist/scan/reality-sniff.d.ts +0 -56
- package/dist/scan/reality-sniff.d.ts.map +0 -1
- package/dist/scan/reality-sniff.js +0 -200
- package/dist/scan/reality-sniff.js.map +0 -1
- package/dist/scan/structural-verifier.d.ts +0 -20
- package/dist/scan/structural-verifier.d.ts.map +0 -1
- package/dist/scan/structural-verifier.js +0 -112
- package/dist/scan/structural-verifier.js.map +0 -1
- package/dist/scan/verification-engine.d.ts +0 -47
- package/dist/scan/verification-engine.d.ts.map +0 -1
- package/dist/scan/verification-engine.js +0 -141
- package/dist/scan/verification-engine.js.map +0 -1
- package/dist/scanner/baseline.d.ts +0 -52
- package/dist/scanner/baseline.d.ts.map +0 -1
- package/dist/scanner/baseline.js +0 -85
- package/dist/scanner/baseline.js.map +0 -1
- package/dist/scanner/incremental.d.ts +0 -30
- package/dist/scanner/incremental.d.ts.map +0 -1
- package/dist/scanner/incremental.js +0 -82
- package/dist/scanner/incremental.js.map +0 -1
- package/dist/scanner/parallel.d.ts +0 -43
- package/dist/scanner/parallel.d.ts.map +0 -1
- package/dist/scanner/parallel.js +0 -99
- package/dist/scanner/parallel.js.map +0 -1
- package/dist/standalone.d.ts +0 -1
- package/dist/standalone.d.ts.map +0 -1
- package/dist/standalone.js +0 -1
- package/dist/standalone.js.map +0 -1
- package/dist/truth-pack/index.d.ts +0 -102
- package/dist/truth-pack/index.d.ts.map +0 -1
- package/dist/truth-pack/index.js +0 -694
- package/dist/truth-pack/index.js.map +0 -1
- package/dist/ui/frame.d.ts +0 -68
- package/dist/ui/frame.d.ts.map +0 -1
- package/dist/ui/frame.js +0 -165
- package/dist/ui/frame.js.map +0 -1
- package/dist/ui/index.d.ts +0 -5
- package/dist/ui/index.d.ts.map +0 -1
- package/dist/ui/index.js +0 -16
- package/dist/ui/index.js.map +0 -1
- package/dist/ui.d.ts +0 -36
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js +0 -45
- package/dist/ui.js.map +0 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entitlements v2 - Signed Receipts
|
|
3
|
+
*
|
|
4
|
+
* Proper server-side metering with signed receipts:
|
|
5
|
+
* 1. Every ship check requests a signed usage receipt from API
|
|
6
|
+
* 2. Receipt includes: {userId, tier, remainingShipChecks, expiresAt, signature}
|
|
7
|
+
* 3. CLI caches receipt in .vibecheck/.entitlements.json
|
|
8
|
+
* 4. Offline grace: 24h using last valid receipt
|
|
9
|
+
*
|
|
10
|
+
* Spec tiers:
|
|
11
|
+
* - Free: $0, 10 ship checks/month
|
|
12
|
+
* - Pro: $39/mo, unlimited ship + reality + fix + share
|
|
13
|
+
* - Team: $99/mo, + PR gating + CI automation
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
"use strict";
|
|
17
|
+
|
|
18
|
+
const fs = require("fs");
|
|
19
|
+
const path = require("path");
|
|
20
|
+
const os = require("os");
|
|
21
|
+
const crypto = require("crypto");
|
|
22
|
+
|
|
23
|
+
// Constants
|
|
24
|
+
const FREE_SHIP_CHECKS_PER_MONTH = 10;
|
|
25
|
+
const RECEIPT_GRACE_HOURS = 24;
|
|
26
|
+
const API_BASE_URL = process.env.VIBECHECK_API_URL || "https://api.vibecheckai.dev";
|
|
27
|
+
|
|
28
|
+
// Public key for receipt verification (would be fetched from API in production)
|
|
29
|
+
const VIBECHECK_PUBLIC_KEY = process.env.VIBECHECK_PUBLIC_KEY || `-----BEGIN PUBLIC KEY-----
|
|
30
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Z3VS5JJcds3xfn/ygWb
|
|
31
|
+
rAnr6J6WvLW3YNHQZ8vJqUvBcl3L9S2gKj3wBi3M8N9pYhEj5Y5h5gJq5v5l5n5o
|
|
32
|
+
placeholder-key-for-development
|
|
33
|
+
AQIDAQAB
|
|
34
|
+
-----END PUBLIC KEY-----`;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get entitlements cache path (project-local)
|
|
38
|
+
*/
|
|
39
|
+
function getEntitlementsCachePath(projectPath) {
|
|
40
|
+
return path.join(projectPath || process.cwd(), ".vibecheck", ".entitlements.json");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get global config path (user home)
|
|
45
|
+
*/
|
|
46
|
+
function getGlobalConfigPath() {
|
|
47
|
+
const home = os.homedir();
|
|
48
|
+
if (process.platform === "win32") {
|
|
49
|
+
return path.join(
|
|
50
|
+
process.env.APPDATA || path.join(home, "AppData", "Roaming"),
|
|
51
|
+
"vibecheck",
|
|
52
|
+
"config.json"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return path.join(home, ".config", "vibecheck", "config.json");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Load cached entitlements receipt
|
|
60
|
+
*/
|
|
61
|
+
function loadCachedReceipt(projectPath) {
|
|
62
|
+
const cachePath = getEntitlementsCachePath(projectPath);
|
|
63
|
+
try {
|
|
64
|
+
if (fs.existsSync(cachePath)) {
|
|
65
|
+
return JSON.parse(fs.readFileSync(cachePath, "utf8"));
|
|
66
|
+
}
|
|
67
|
+
} catch {}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Save entitlements receipt to cache
|
|
73
|
+
*/
|
|
74
|
+
function saveCachedReceipt(projectPath, receipt) {
|
|
75
|
+
const cachePath = getEntitlementsCachePath(projectPath);
|
|
76
|
+
const dir = path.dirname(cachePath);
|
|
77
|
+
if (!fs.existsSync(dir)) {
|
|
78
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
fs.writeFileSync(cachePath, JSON.stringify(receipt, null, 2), { mode: 0o600 });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Verify receipt signature (HMAC-SHA256 for simplicity, RSA in production)
|
|
85
|
+
*/
|
|
86
|
+
function verifyReceiptSignature(receipt) {
|
|
87
|
+
if (!receipt || !receipt.signature || !receipt.data) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// In production: use RSA signature verification with public key
|
|
92
|
+
// For now: use HMAC with a shared secret (server would use same secret)
|
|
93
|
+
const secret = process.env.VIBECHECK_RECEIPT_SECRET || "vibecheck-receipt-v1";
|
|
94
|
+
const dataStr = JSON.stringify(receipt.data);
|
|
95
|
+
const expectedSig = crypto.createHmac("sha256", secret).update(dataStr).digest("hex");
|
|
96
|
+
|
|
97
|
+
return receipt.signature === expectedSig;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Check if receipt is within grace period
|
|
102
|
+
*/
|
|
103
|
+
function isReceiptInGrace(receipt) {
|
|
104
|
+
if (!receipt || !receipt.data || !receipt.data.issuedAt) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const issuedAt = new Date(receipt.data.issuedAt).getTime();
|
|
109
|
+
const graceMs = RECEIPT_GRACE_HOURS * 3600 * 1000;
|
|
110
|
+
return Date.now() - issuedAt < graceMs;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get current month key (YYYY-MM)
|
|
115
|
+
*/
|
|
116
|
+
function getCurrentMonthKey() {
|
|
117
|
+
const now = new Date();
|
|
118
|
+
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Request ship usage from server
|
|
123
|
+
* Returns signed receipt with updated usage
|
|
124
|
+
*/
|
|
125
|
+
async function requestShipUsage(apiKey, projectPath) {
|
|
126
|
+
if (!apiKey) {
|
|
127
|
+
return { error: "No API key" };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
const res = await fetch(`${API_BASE_URL}/v1/ship/use`, {
|
|
132
|
+
method: "POST",
|
|
133
|
+
headers: {
|
|
134
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
135
|
+
"Content-Type": "application/json"
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify({
|
|
138
|
+
projectPath: projectPath ? path.basename(projectPath) : "unknown",
|
|
139
|
+
timestamp: new Date().toISOString()
|
|
140
|
+
}),
|
|
141
|
+
signal: AbortSignal.timeout(10000)
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
if (res.status === 429) {
|
|
146
|
+
return { error: "rate_limited", message: "Ship check limit reached" };
|
|
147
|
+
}
|
|
148
|
+
if (res.status === 401) {
|
|
149
|
+
return { error: "unauthorized", message: "Invalid API key" };
|
|
150
|
+
}
|
|
151
|
+
return { error: "api_error", message: `API returned ${res.status}` };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const receipt = await res.json();
|
|
155
|
+
|
|
156
|
+
// Validate receipt signature
|
|
157
|
+
if (!verifyReceiptSignature(receipt)) {
|
|
158
|
+
console.warn("Warning: Receipt signature invalid, proceeding with caution");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Cache receipt
|
|
162
|
+
saveCachedReceipt(projectPath, receipt);
|
|
163
|
+
|
|
164
|
+
return receipt;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
// Network error - try to use cached receipt
|
|
167
|
+
const cached = loadCachedReceipt(projectPath);
|
|
168
|
+
if (cached && isReceiptInGrace(cached)) {
|
|
169
|
+
console.log(" (offline mode - using cached entitlements)");
|
|
170
|
+
return { ...cached, offline: true };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { error: "network", message: error.message };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Check if user can run ship (main entitlement check)
|
|
179
|
+
*/
|
|
180
|
+
async function canShip(projectPath, options = {}) {
|
|
181
|
+
const { apiKey, skipMeter = false } = options;
|
|
182
|
+
|
|
183
|
+
// Demo/owner mode bypass
|
|
184
|
+
if (process.env.VIBECHECK_DEMO === "1" || process.env.VIBECHECK_OWNER === "1") {
|
|
185
|
+
return {
|
|
186
|
+
allowed: true,
|
|
187
|
+
tier: "enterprise",
|
|
188
|
+
reason: "Demo/owner mode",
|
|
189
|
+
remaining: Infinity
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// If no API key, use free tier with local metering
|
|
194
|
+
if (!apiKey) {
|
|
195
|
+
return checkFreeTierLocal(projectPath, skipMeter);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Request usage from server (meters the ship check)
|
|
199
|
+
if (!skipMeter) {
|
|
200
|
+
const receipt = await requestShipUsage(apiKey, projectPath);
|
|
201
|
+
|
|
202
|
+
if (receipt.error) {
|
|
203
|
+
// If network error but within grace, allow
|
|
204
|
+
if (receipt.offline && receipt.data) {
|
|
205
|
+
return {
|
|
206
|
+
allowed: true,
|
|
207
|
+
tier: receipt.data.tier || "free",
|
|
208
|
+
reason: "Offline grace period",
|
|
209
|
+
remaining: receipt.data.remainingShipChecks || 0,
|
|
210
|
+
offline: true
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Rate limited
|
|
215
|
+
if (receipt.error === "rate_limited") {
|
|
216
|
+
return {
|
|
217
|
+
allowed: false,
|
|
218
|
+
tier: "free",
|
|
219
|
+
reason: "Ship check limit reached for this month",
|
|
220
|
+
remaining: 0
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Other errors - fall back to free tier
|
|
225
|
+
return checkFreeTierLocal(projectPath, skipMeter);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Valid receipt from server
|
|
229
|
+
const data = receipt.data || receipt;
|
|
230
|
+
return {
|
|
231
|
+
allowed: true,
|
|
232
|
+
tier: data.tier || "pro",
|
|
233
|
+
reason: "Authenticated",
|
|
234
|
+
remaining: data.remainingShipChecks,
|
|
235
|
+
receipt
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Skip meter - just check tier
|
|
240
|
+
const cached = loadCachedReceipt(projectPath);
|
|
241
|
+
if (cached && cached.data) {
|
|
242
|
+
return {
|
|
243
|
+
allowed: true,
|
|
244
|
+
tier: cached.data.tier || "pro",
|
|
245
|
+
reason: "Cached entitlements",
|
|
246
|
+
remaining: cached.data.remainingShipChecks
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return { allowed: true, tier: "pro", reason: "API key provided" };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Check free tier with local metering (fallback)
|
|
255
|
+
*/
|
|
256
|
+
function checkFreeTierLocal(projectPath, skipMeter = false) {
|
|
257
|
+
const cachePath = getEntitlementsCachePath(projectPath);
|
|
258
|
+
const currentMonth = getCurrentMonthKey();
|
|
259
|
+
|
|
260
|
+
let usage = { month: currentMonth, shipChecks: 0 };
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
const cached = loadCachedReceipt(projectPath);
|
|
264
|
+
if (cached && cached.freeUsage && cached.freeUsage.month === currentMonth) {
|
|
265
|
+
usage = cached.freeUsage;
|
|
266
|
+
}
|
|
267
|
+
} catch {}
|
|
268
|
+
|
|
269
|
+
const remaining = FREE_SHIP_CHECKS_PER_MONTH - usage.shipChecks;
|
|
270
|
+
|
|
271
|
+
if (remaining <= 0) {
|
|
272
|
+
return {
|
|
273
|
+
allowed: false,
|
|
274
|
+
tier: "free",
|
|
275
|
+
reason: `Free tier limit reached (${FREE_SHIP_CHECKS_PER_MONTH}/month)`,
|
|
276
|
+
remaining: 0,
|
|
277
|
+
upgradeUrl: "https://vibecheckai.dev/pricing"
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Increment usage if not skipping meter
|
|
282
|
+
if (!skipMeter) {
|
|
283
|
+
usage.shipChecks++;
|
|
284
|
+
try {
|
|
285
|
+
saveCachedReceipt(projectPath, {
|
|
286
|
+
freeUsage: usage,
|
|
287
|
+
data: { tier: "free", remainingShipChecks: remaining - 1 },
|
|
288
|
+
issuedAt: new Date().toISOString()
|
|
289
|
+
});
|
|
290
|
+
} catch {}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
allowed: true,
|
|
295
|
+
tier: "free",
|
|
296
|
+
reason: "Free tier",
|
|
297
|
+
remaining: remaining - (skipMeter ? 0 : 1)
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Check if user has access to a specific feature
|
|
303
|
+
*/
|
|
304
|
+
async function hasFeatureAccess(feature, projectPath, apiKey) {
|
|
305
|
+
const entitlement = await canShip(projectPath, { apiKey, skipMeter: true });
|
|
306
|
+
|
|
307
|
+
const featureTiers = {
|
|
308
|
+
// Free features
|
|
309
|
+
ship: ["free", "pro", "team", "enterprise"],
|
|
310
|
+
scan: ["free", "pro", "team", "enterprise"],
|
|
311
|
+
ctx: ["free", "pro", "team", "enterprise"],
|
|
312
|
+
install: ["free", "pro", "team", "enterprise"],
|
|
313
|
+
|
|
314
|
+
// Pro features
|
|
315
|
+
reality: ["pro", "team", "enterprise"],
|
|
316
|
+
fix_autopilot: ["pro", "team", "enterprise"],
|
|
317
|
+
share: ["pro", "team", "enterprise"],
|
|
318
|
+
|
|
319
|
+
// Team features
|
|
320
|
+
pr_gate: ["team", "enterprise"],
|
|
321
|
+
ci_automation: ["team", "enterprise"]
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
const allowedTiers = featureTiers[feature] || ["enterprise"];
|
|
325
|
+
const hasAccess = allowedTiers.includes(entitlement.tier);
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
allowed: hasAccess,
|
|
329
|
+
tier: entitlement.tier,
|
|
330
|
+
requiredTier: allowedTiers[0],
|
|
331
|
+
upgradeUrl: hasAccess ? null : "https://vibecheckai.dev/pricing"
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Get usage stats for display
|
|
337
|
+
*/
|
|
338
|
+
function getUsageStats(projectPath) {
|
|
339
|
+
const cached = loadCachedReceipt(projectPath);
|
|
340
|
+
const currentMonth = getCurrentMonthKey();
|
|
341
|
+
|
|
342
|
+
if (!cached) {
|
|
343
|
+
return {
|
|
344
|
+
tier: "free",
|
|
345
|
+
shipChecksUsed: 0,
|
|
346
|
+
shipChecksRemaining: FREE_SHIP_CHECKS_PER_MONTH,
|
|
347
|
+
month: currentMonth
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (cached.freeUsage && cached.freeUsage.month === currentMonth) {
|
|
352
|
+
return {
|
|
353
|
+
tier: "free",
|
|
354
|
+
shipChecksUsed: cached.freeUsage.shipChecks,
|
|
355
|
+
shipChecksRemaining: FREE_SHIP_CHECKS_PER_MONTH - cached.freeUsage.shipChecks,
|
|
356
|
+
month: currentMonth
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (cached.data) {
|
|
361
|
+
return {
|
|
362
|
+
tier: cached.data.tier || "unknown",
|
|
363
|
+
shipChecksRemaining: cached.data.remainingShipChecks,
|
|
364
|
+
month: currentMonth,
|
|
365
|
+
issuedAt: cached.data.issuedAt
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return { tier: "unknown", month: currentMonth };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
module.exports = {
|
|
373
|
+
canShip,
|
|
374
|
+
hasFeatureAccess,
|
|
375
|
+
getUsageStats,
|
|
376
|
+
loadCachedReceipt,
|
|
377
|
+
saveCachedReceipt,
|
|
378
|
+
requestShipUsage,
|
|
379
|
+
FREE_SHIP_CHECKS_PER_MONTH,
|
|
380
|
+
RECEIPT_GRACE_HOURS
|
|
381
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entitlements System - CLI Wrapper
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY
|
|
5
|
+
*
|
|
6
|
+
* This file wraps the canonical entitlements implementation from @vibecheck/core.
|
|
7
|
+
* The source of truth is packages/core/src/entitlements.ts
|
|
8
|
+
*
|
|
9
|
+
* To modify entitlements logic, edit packages/core/src/entitlements.ts
|
|
10
|
+
* then run `pnpm build` in packages/core.
|
|
11
|
+
*
|
|
12
|
+
* This wrapper exists to:
|
|
13
|
+
* 1. Provide CommonJS exports for CLI runners
|
|
14
|
+
* 2. Add CLI-specific functionality (server-usage integration)
|
|
15
|
+
* 3. Maintain backward compatibility with existing CLI code
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
"use strict";
|
|
19
|
+
|
|
20
|
+
// Import from compiled @vibecheck/core
|
|
21
|
+
let coreEntitlements;
|
|
22
|
+
try {
|
|
23
|
+
coreEntitlements = require("@vibecheck/core");
|
|
24
|
+
} catch (e) {
|
|
25
|
+
// Fallback for development: try direct path
|
|
26
|
+
try {
|
|
27
|
+
coreEntitlements = require("../../../packages/dist-core/index.js");
|
|
28
|
+
} catch (e2) {
|
|
29
|
+
console.error(
|
|
30
|
+
"[entitlements] Failed to load @vibecheck/core. Run `pnpm build` in packages/core first.",
|
|
31
|
+
);
|
|
32
|
+
// Provide minimal fallback
|
|
33
|
+
coreEntitlements = {
|
|
34
|
+
TIER_CONFIG: {},
|
|
35
|
+
SEAT_PRICING: {},
|
|
36
|
+
entitlements: {
|
|
37
|
+
getCurrentTier: async () => "free",
|
|
38
|
+
checkFeature: async () => ({ allowed: true }),
|
|
39
|
+
checkLimit: async () => ({ allowed: true }),
|
|
40
|
+
enforceFeature: async () => {},
|
|
41
|
+
enforceLimit: async () => {},
|
|
42
|
+
trackUsage: async () => {},
|
|
43
|
+
getUsageSummary: async () => "Usage summary unavailable",
|
|
44
|
+
getTierConfig: () => ({}),
|
|
45
|
+
checkSeatLimit: () => ({ allowed: true, effectiveSeats: 1 }),
|
|
46
|
+
},
|
|
47
|
+
calculateEffectiveSeats: () => 1,
|
|
48
|
+
canAddMember: () => ({ allowed: true }),
|
|
49
|
+
formatSeatInfo: () => "1 seat",
|
|
50
|
+
validateSeatReduction: () => ({ safe: true }),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Import server-usage for CLI-specific server-authoritative enforcement
|
|
56
|
+
const { serverUsage } = require("./server-usage");
|
|
57
|
+
|
|
58
|
+
// Re-export everything from core
|
|
59
|
+
const {
|
|
60
|
+
TIER_CONFIG,
|
|
61
|
+
SEAT_PRICING,
|
|
62
|
+
entitlements,
|
|
63
|
+
calculateEffectiveSeats,
|
|
64
|
+
canAddMember,
|
|
65
|
+
formatSeatInfo,
|
|
66
|
+
validateSeatReduction,
|
|
67
|
+
isValidTier,
|
|
68
|
+
getTierConfig,
|
|
69
|
+
getMinimumTierForFeature,
|
|
70
|
+
} = coreEntitlements;
|
|
71
|
+
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// CLI-SPECIFIC WRAPPER
|
|
74
|
+
// ============================================================================
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* CLI Entitlements Manager
|
|
78
|
+
* Wraps core entitlements with CLI-specific server-authoritative checks
|
|
79
|
+
*/
|
|
80
|
+
class CLIEntitlementsManager {
|
|
81
|
+
constructor(coreManager) {
|
|
82
|
+
this._core = coreManager;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async getCurrentTier() {
|
|
86
|
+
return this._core.getCurrentTier();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async checkFeature(feature) {
|
|
90
|
+
return this._core.checkFeature(feature);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check usage limits - SERVER-AUTHORITATIVE for CLI
|
|
95
|
+
*/
|
|
96
|
+
async checkLimit(limitType) {
|
|
97
|
+
// Map old limit types to new action types
|
|
98
|
+
const actionMap = {
|
|
99
|
+
scans: "scan",
|
|
100
|
+
realityRuns: "reality",
|
|
101
|
+
aiAgentRuns: "agent",
|
|
102
|
+
};
|
|
103
|
+
const actionType = actionMap[limitType] || limitType;
|
|
104
|
+
|
|
105
|
+
// Use server-authoritative check
|
|
106
|
+
try {
|
|
107
|
+
const result = await serverUsage.checkUsage(actionType);
|
|
108
|
+
|
|
109
|
+
if (result.allowed) {
|
|
110
|
+
return {
|
|
111
|
+
allowed: true,
|
|
112
|
+
usage: result.current,
|
|
113
|
+
limit: result.limit === -1 ? Infinity : result.limit,
|
|
114
|
+
source: result.source,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const tier = await this.getCurrentTier();
|
|
119
|
+
return {
|
|
120
|
+
allowed: false,
|
|
121
|
+
reason:
|
|
122
|
+
result.reason ||
|
|
123
|
+
`Monthly ${limitType} limit reached (${result.current}/${result.limit})`,
|
|
124
|
+
usage: result.current,
|
|
125
|
+
limit: result.limit,
|
|
126
|
+
upgradePrompt: this._core.formatLimitUpgradePrompt(
|
|
127
|
+
tier,
|
|
128
|
+
limitType,
|
|
129
|
+
result.current,
|
|
130
|
+
result.limit,
|
|
131
|
+
),
|
|
132
|
+
source: result.source,
|
|
133
|
+
};
|
|
134
|
+
} catch (error) {
|
|
135
|
+
// Fallback to core check if server is unreachable
|
|
136
|
+
return this._core.checkLimit(limitType);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Track usage - SERVER-AUTHORITATIVE for CLI
|
|
142
|
+
*/
|
|
143
|
+
async trackUsage(type, count = 1) {
|
|
144
|
+
// Map old types to new action types
|
|
145
|
+
const actionMap = {
|
|
146
|
+
scans: "scan",
|
|
147
|
+
realityRuns: "reality",
|
|
148
|
+
aiAgentRuns: "agent",
|
|
149
|
+
gateRuns: "gate",
|
|
150
|
+
fixRuns: "fix",
|
|
151
|
+
};
|
|
152
|
+
const actionType = actionMap[type] || type;
|
|
153
|
+
|
|
154
|
+
// Record on server (authoritative)
|
|
155
|
+
try {
|
|
156
|
+
const result = await serverUsage.recordUsage(actionType, count);
|
|
157
|
+
// Also update local via core
|
|
158
|
+
await this._core.trackUsage(type, count);
|
|
159
|
+
return result;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
// Still update local, mark as unsynced
|
|
162
|
+
await this._core.trackUsage(type, count);
|
|
163
|
+
return { success: false, error: error.message, queued: true };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async enforceFeature(feature) {
|
|
168
|
+
return this._core.enforceFeature(feature);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Enforce usage limits - SERVER-AUTHORITATIVE for CLI
|
|
173
|
+
*/
|
|
174
|
+
async enforceLimit(limitType) {
|
|
175
|
+
// Check if sync is required first
|
|
176
|
+
const needsSync = await serverUsage.requiresSync();
|
|
177
|
+
if (needsSync) {
|
|
178
|
+
const syncResult = await serverUsage.syncOfflineUsage();
|
|
179
|
+
if (syncResult.error) {
|
|
180
|
+
// Allow offline mode by default - CLI should work without internet
|
|
181
|
+
console.warn(
|
|
182
|
+
"\x1b[33mWarning: Could not connect to vibecheck API, using offline mode\x1b[0m\n",
|
|
183
|
+
);
|
|
184
|
+
return { allowed: true, source: "offline" };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const check = await this.checkLimit(limitType);
|
|
189
|
+
if (!check.allowed) {
|
|
190
|
+
const error = new Error(check.reason);
|
|
191
|
+
error.code = "LIMIT_EXCEEDED";
|
|
192
|
+
error.upgradePrompt = check.upgradePrompt;
|
|
193
|
+
error.usage = check.usage;
|
|
194
|
+
error.limit = check.limit;
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return check;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async getUsageSummary() {
|
|
202
|
+
// Try to get server-authoritative summary
|
|
203
|
+
try {
|
|
204
|
+
const serverSummary = await serverUsage.getUsageSummary();
|
|
205
|
+
|
|
206
|
+
if (serverSummary.success !== false && serverSummary.usage) {
|
|
207
|
+
const tier = serverSummary.tier || (await this.getCurrentTier());
|
|
208
|
+
const config = TIER_CONFIG[tier];
|
|
209
|
+
const limits = serverSummary.limits || config.limits;
|
|
210
|
+
|
|
211
|
+
const formatLimit = (current, limit) => {
|
|
212
|
+
if (limit === -1) return `${current} (unlimited)`;
|
|
213
|
+
const pct = Math.round((current / limit) * 100);
|
|
214
|
+
const bar = this.progressBar(pct);
|
|
215
|
+
return `${current}/${limit} ${bar} ${pct}%`;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const lines = [
|
|
219
|
+
"",
|
|
220
|
+
`\x1b[1m📊 Usage Summary\x1b[0m (\x1b[36m${config.name}\x1b[0m tier - $${config.price}/mo)`,
|
|
221
|
+
"\x1b[90m" + "─".repeat(50) + "\x1b[0m",
|
|
222
|
+
`Scans: ${formatLimit(serverSummary.usage.scan || 0, limits.scans || limits.scansPerMonth)}`,
|
|
223
|
+
`Reality Runs: ${formatLimit(serverSummary.usage.reality || 0, limits.reality || limits.realityRunsPerMonth)}`,
|
|
224
|
+
`AI Agent: ${formatLimit(serverSummary.usage.agent || 0, limits.agent || limits.aiAgentRunsPerMonth)}`,
|
|
225
|
+
`Team Seats: ${formatSeatInfo(tier)}`,
|
|
226
|
+
"\x1b[90m" + "─".repeat(50) + "\x1b[0m",
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
if (serverSummary.period) {
|
|
230
|
+
lines.push(
|
|
231
|
+
`Period: ${serverSummary.period.start.split("T")[0]} to ${serverSummary.period.end.split("T")[0]}`,
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (serverSummary.pendingOffline > 0) {
|
|
236
|
+
lines.push(
|
|
237
|
+
`\x1b[33m⚠ ${serverSummary.pendingOffline} action(s) pending sync\x1b[0m`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
lines.push(
|
|
242
|
+
`\x1b[90mSource: ${serverSummary.source || "server"}\x1b[0m`,
|
|
243
|
+
);
|
|
244
|
+
lines.push("");
|
|
245
|
+
|
|
246
|
+
return lines.join("\n");
|
|
247
|
+
}
|
|
248
|
+
} catch {
|
|
249
|
+
// Fall through to core summary
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return this._core.getUsageSummary();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
getTierConfig(tier) {
|
|
256
|
+
return this._core.getTierConfig(tier);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
getAllTiers() {
|
|
260
|
+
return this._core.getAllTiers();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Seat management
|
|
264
|
+
checkSeatLimit(tier, currentMemberCount, purchasedExtraSeats) {
|
|
265
|
+
return this._core.checkSeatLimit(
|
|
266
|
+
tier,
|
|
267
|
+
currentMemberCount,
|
|
268
|
+
purchasedExtraSeats,
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
getOrganizationSeats(tier, purchasedExtraSeats, currentMembers) {
|
|
273
|
+
return this._core.getOrganizationSeats(
|
|
274
|
+
tier,
|
|
275
|
+
purchasedExtraSeats,
|
|
276
|
+
currentMembers,
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
progressBar(percent) {
|
|
281
|
+
const filled = Math.min(10, Math.round(percent / 10));
|
|
282
|
+
const empty = 10 - filled;
|
|
283
|
+
return `[${"█".repeat(filled)}${"░".repeat(empty)}]`;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Create CLI-specific wrapper
|
|
288
|
+
const cliEntitlements = new CLIEntitlementsManager(entitlements);
|
|
289
|
+
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// EXPORTS
|
|
292
|
+
// ============================================================================
|
|
293
|
+
|
|
294
|
+
module.exports = {
|
|
295
|
+
// Main entitlements instance (CLI wrapper)
|
|
296
|
+
entitlements: cliEntitlements,
|
|
297
|
+
|
|
298
|
+
// Tier configuration
|
|
299
|
+
TIER_CONFIG,
|
|
300
|
+
SEAT_PRICING,
|
|
301
|
+
|
|
302
|
+
// Convenience functions
|
|
303
|
+
checkFeature: (feature) => cliEntitlements.checkFeature(feature),
|
|
304
|
+
checkLimit: (limitType) => cliEntitlements.checkLimit(limitType),
|
|
305
|
+
enforceFeature: (feature) => cliEntitlements.enforceFeature(feature),
|
|
306
|
+
enforceLimit: (limitType) => cliEntitlements.enforceLimit(limitType),
|
|
307
|
+
trackUsage: (type, count) => cliEntitlements.trackUsage(type, count),
|
|
308
|
+
getCurrentTier: () => cliEntitlements.getCurrentTier(),
|
|
309
|
+
getUsageSummary: () => cliEntitlements.getUsageSummary(),
|
|
310
|
+
getTierConfig: (tier) => cliEntitlements.getTierConfig(tier),
|
|
311
|
+
|
|
312
|
+
// Seat management
|
|
313
|
+
checkSeatLimit: (tier, currentMemberCount, purchasedExtraSeats) =>
|
|
314
|
+
cliEntitlements.checkSeatLimit(
|
|
315
|
+
tier,
|
|
316
|
+
currentMemberCount,
|
|
317
|
+
purchasedExtraSeats,
|
|
318
|
+
),
|
|
319
|
+
calculateEffectiveSeats,
|
|
320
|
+
canAddMember,
|
|
321
|
+
formatSeatInfo,
|
|
322
|
+
validateSeatReduction,
|
|
323
|
+
|
|
324
|
+
// Tier helpers
|
|
325
|
+
isValidTier,
|
|
326
|
+
getMinimumTierForFeature,
|
|
327
|
+
|
|
328
|
+
// Server-authoritative usage enforcement
|
|
329
|
+
serverUsage,
|
|
330
|
+
syncOfflineUsage: () => serverUsage.syncOfflineUsage(),
|
|
331
|
+
requiresSync: () => serverUsage.requiresSync(),
|
|
332
|
+
};
|