@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,634 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Truth Pack Generator v1
|
|
4
|
+
*
|
|
5
|
+
* Generates .vibecheck/truth/truthpack.json from codebase analysis.
|
|
6
|
+
* This is the ground truth that agents must reference.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* vibecheck ctx - Generate truthpack.json
|
|
10
|
+
* vibecheck ctx --snapshot - Write to snapshots/<commit>.json
|
|
11
|
+
* vibecheck ctx --md - Also generate truthpack.md
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from 'fs/promises';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
import crypto from 'crypto';
|
|
17
|
+
import { execSync } from 'child_process';
|
|
18
|
+
import { RouteIndex, resolveNextRoutes, resolveFastifyRoutes } from './lib/route-truth.js';
|
|
19
|
+
|
|
20
|
+
const VERSION = '1.0.0';
|
|
21
|
+
|
|
22
|
+
// Evidence counter for unique IDs
|
|
23
|
+
let evidenceCounter = 0;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Main entry point
|
|
27
|
+
*/
|
|
28
|
+
export async function runTruthpack(projectPath = process.cwd(), options = {}) {
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
console.log('📦 Generating Truth Pack...\n');
|
|
31
|
+
|
|
32
|
+
// Ensure .vibecheck/truth directory exists
|
|
33
|
+
const truthDir = path.join(projectPath, '.vibecheck', 'truth');
|
|
34
|
+
await fs.mkdir(truthDir, { recursive: true });
|
|
35
|
+
|
|
36
|
+
// Reset evidence counter
|
|
37
|
+
evidenceCounter = 0;
|
|
38
|
+
const allEvidence = [];
|
|
39
|
+
|
|
40
|
+
// Build truth pack
|
|
41
|
+
const truthpack = {
|
|
42
|
+
meta: await buildMeta(projectPath),
|
|
43
|
+
project: await extractProject(projectPath),
|
|
44
|
+
routes: await extractRoutes(projectPath, allEvidence),
|
|
45
|
+
env: await extractEnv(projectPath, allEvidence),
|
|
46
|
+
auth: await extractAuth(projectPath, allEvidence),
|
|
47
|
+
billing: await extractBilling(projectPath, allEvidence),
|
|
48
|
+
integrations: await extractIntegrations(projectPath, allEvidence),
|
|
49
|
+
index: {
|
|
50
|
+
evidenceRefs: allEvidence,
|
|
51
|
+
hashes: {
|
|
52
|
+
truthpackHash: '', // Will be computed after serialization
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Compute truthpack hash
|
|
58
|
+
const truthpackJson = JSON.stringify(truthpack, null, 2);
|
|
59
|
+
truthpack.index.hashes.truthpackHash = crypto.createHash('sha256').update(truthpackJson).digest('hex');
|
|
60
|
+
|
|
61
|
+
// Write truthpack.json
|
|
62
|
+
const truthpackPath = path.join(truthDir, 'truthpack.json');
|
|
63
|
+
await fs.writeFile(truthpackPath, JSON.stringify(truthpack, null, 2));
|
|
64
|
+
console.log(`✅ Wrote ${truthpackPath}`);
|
|
65
|
+
|
|
66
|
+
// Write evidence.index.json
|
|
67
|
+
const evidenceIndex = {
|
|
68
|
+
meta: {
|
|
69
|
+
commit: truthpack.meta.commit.sha,
|
|
70
|
+
generatedAt: truthpack.meta.generatedAt,
|
|
71
|
+
},
|
|
72
|
+
evidence: allEvidence,
|
|
73
|
+
};
|
|
74
|
+
const evidencePath = path.join(truthDir, 'evidence.index.json');
|
|
75
|
+
await fs.writeFile(evidencePath, JSON.stringify(evidenceIndex, null, 2));
|
|
76
|
+
console.log(`✅ Wrote ${evidencePath}`);
|
|
77
|
+
|
|
78
|
+
// Optionally write snapshot
|
|
79
|
+
if (options.snapshot) {
|
|
80
|
+
const snapshotsDir = path.join(truthDir, 'snapshots');
|
|
81
|
+
await fs.mkdir(snapshotsDir, { recursive: true });
|
|
82
|
+
const snapshotPath = path.join(snapshotsDir, `truthpack.${truthpack.meta.commit.sha.slice(0, 8)}.json`);
|
|
83
|
+
await fs.writeFile(snapshotPath, JSON.stringify(truthpack, null, 2));
|
|
84
|
+
console.log(`✅ Wrote snapshot: ${snapshotPath}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Optionally generate markdown
|
|
88
|
+
if (options.md !== false) {
|
|
89
|
+
const mdPath = path.join(truthDir, 'truthpack.md');
|
|
90
|
+
await fs.writeFile(mdPath, generateMarkdown(truthpack));
|
|
91
|
+
console.log(`✅ Wrote ${mdPath}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const duration = Date.now() - startTime;
|
|
95
|
+
console.log(`\n📦 Truth Pack complete in ${duration}ms`);
|
|
96
|
+
console.log(` Routes: ${truthpack.routes.server.length} server, ${truthpack.routes.clientRefs.length} client refs`);
|
|
97
|
+
console.log(` Env vars: ${truthpack.env.vars.length}`);
|
|
98
|
+
console.log(` Evidence: ${allEvidence.length} refs`);
|
|
99
|
+
|
|
100
|
+
return truthpack;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Build metadata section
|
|
105
|
+
*/
|
|
106
|
+
async function buildMeta(projectPath) {
|
|
107
|
+
let sha = 'unknown';
|
|
108
|
+
let branch = 'unknown';
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
sha = execSync('git rev-parse HEAD', { cwd: projectPath, encoding: 'utf8' }).trim();
|
|
112
|
+
branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: projectPath, encoding: 'utf8' }).trim();
|
|
113
|
+
} catch {}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
version: VERSION,
|
|
117
|
+
generatedAt: new Date().toISOString(),
|
|
118
|
+
repoRoot: projectPath,
|
|
119
|
+
commit: { sha, branch },
|
|
120
|
+
tool: { name: 'vibecheck', version: VERSION },
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Extract project structure
|
|
126
|
+
*/
|
|
127
|
+
async function extractProject(projectPath) {
|
|
128
|
+
const frameworks = [];
|
|
129
|
+
const workspaces = [];
|
|
130
|
+
const entrypoints = [];
|
|
131
|
+
const scripts = {};
|
|
132
|
+
|
|
133
|
+
// Detect frameworks from package.json
|
|
134
|
+
try {
|
|
135
|
+
const pkgPath = path.join(projectPath, 'package.json');
|
|
136
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'));
|
|
137
|
+
|
|
138
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
139
|
+
if (deps.next) frameworks.push('nextjs');
|
|
140
|
+
if (deps.express) frameworks.push('express');
|
|
141
|
+
if (deps.fastify) frameworks.push('fastify');
|
|
142
|
+
if (deps.react) frameworks.push('react');
|
|
143
|
+
if (deps.vue) frameworks.push('vue');
|
|
144
|
+
if (deps['@nestjs/core']) frameworks.push('nestjs');
|
|
145
|
+
if (deps.prisma || deps['@prisma/client']) frameworks.push('prisma');
|
|
146
|
+
|
|
147
|
+
// Extract scripts
|
|
148
|
+
if (pkg.scripts) {
|
|
149
|
+
Object.assign(scripts, pkg.scripts);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Check for workspaces
|
|
153
|
+
if (pkg.workspaces) {
|
|
154
|
+
const wsPatterns = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages || [];
|
|
155
|
+
for (const pattern of wsPatterns) {
|
|
156
|
+
const wsPath = pattern.replace('/*', '');
|
|
157
|
+
try {
|
|
158
|
+
const entries = await fs.readdir(path.join(projectPath, wsPath), { withFileTypes: true });
|
|
159
|
+
for (const entry of entries) {
|
|
160
|
+
if (entry.isDirectory()) {
|
|
161
|
+
workspaces.push({
|
|
162
|
+
name: entry.name,
|
|
163
|
+
path: path.join(wsPath, entry.name),
|
|
164
|
+
type: detectWorkspaceType(entry.name),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} catch {}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} catch {}
|
|
172
|
+
|
|
173
|
+
// Detect entrypoints
|
|
174
|
+
const potentialEntrypoints = [
|
|
175
|
+
{ kind: 'api', paths: ['apps/api/src/index.ts', 'src/server.ts', 'server/index.ts', 'api/index.ts'] },
|
|
176
|
+
{ kind: 'web', paths: ['apps/web/app/page.tsx', 'src/pages/index.tsx', 'pages/index.tsx', 'app/page.tsx'] },
|
|
177
|
+
{ kind: 'cli', paths: ['bin/cli.js', 'src/cli.ts', 'cli/index.ts'] },
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
for (const ep of potentialEntrypoints) {
|
|
181
|
+
for (const p of ep.paths) {
|
|
182
|
+
try {
|
|
183
|
+
await fs.access(path.join(projectPath, p));
|
|
184
|
+
entrypoints.push({ kind: ep.kind, path: p });
|
|
185
|
+
break;
|
|
186
|
+
} catch {}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return { frameworks, workspaces, entrypoints, scripts };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Extract server routes and client route references using Route Truth v1
|
|
195
|
+
*/
|
|
196
|
+
async function extractRoutes(projectPath, allEvidence) {
|
|
197
|
+
// Use Route Truth v1 resolvers for high-confidence extraction
|
|
198
|
+
const routeIndex = new RouteIndex();
|
|
199
|
+
await routeIndex.build(projectPath);
|
|
200
|
+
|
|
201
|
+
const routeMap = routeIndex.getRouteMap();
|
|
202
|
+
const serverRoutes = routeMap.server.map(route => ({
|
|
203
|
+
method: route.method,
|
|
204
|
+
path: route.path,
|
|
205
|
+
handler: route.handler,
|
|
206
|
+
middlewares: route.middlewares || [],
|
|
207
|
+
authRequired: route.authRequired || 'unknown',
|
|
208
|
+
confidence: route.confidence,
|
|
209
|
+
evidence: route.evidence,
|
|
210
|
+
}));
|
|
211
|
+
|
|
212
|
+
// Add evidence to allEvidence
|
|
213
|
+
for (const route of routeMap.server) {
|
|
214
|
+
if (route.evidence) allEvidence.push(...route.evidence);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Extract client route references (fetch/axios calls)
|
|
218
|
+
const clientRefs = [];
|
|
219
|
+
const files = await findSourceFiles(projectPath);
|
|
220
|
+
|
|
221
|
+
// Client route reference patterns
|
|
222
|
+
const clientPatterns = [
|
|
223
|
+
/fetch\s*\(\s*['"`]([^'"`]+)['"`]/gi,
|
|
224
|
+
/axios\.(get|post|put|patch|delete)\s*\(\s*['"`]([^'"`]+)['"`]/gi,
|
|
225
|
+
/api\s*\.\s*(get|post|put|delete)\s*\(\s*['"`]([^'"`]+)['"`]/gi,
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
for (const file of files) {
|
|
229
|
+
try {
|
|
230
|
+
const content = await fs.readFile(file, 'utf8');
|
|
231
|
+
const relPath = path.relative(projectPath, file);
|
|
232
|
+
const lines = content.split('\n');
|
|
233
|
+
|
|
234
|
+
// Extract client route references only (server routes handled by Route Truth)
|
|
235
|
+
for (const pattern of clientPatterns) {
|
|
236
|
+
let match;
|
|
237
|
+
pattern.lastIndex = 0;
|
|
238
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
239
|
+
const routePath = match[2] || match[1];
|
|
240
|
+
if (!routePath.startsWith('/api') && !routePath.startsWith('http')) continue;
|
|
241
|
+
|
|
242
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
243
|
+
const snippet = lines[lineNum - 1];
|
|
244
|
+
|
|
245
|
+
const evidence = createEvidence(relPath, `${lineNum}`, snippet, 'Client route reference');
|
|
246
|
+
allEvidence.push(evidence);
|
|
247
|
+
|
|
248
|
+
clientRefs.push({
|
|
249
|
+
method: match[1]?.toUpperCase() || 'GET',
|
|
250
|
+
path: routePath,
|
|
251
|
+
source: `${relPath}:${lineNum}`,
|
|
252
|
+
confidence: routePath.includes('${') ? 'low' : 'high',
|
|
253
|
+
evidence: [evidence],
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
} catch {}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return { server: serverRoutes, clientRefs };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Extract environment variables
|
|
265
|
+
*/
|
|
266
|
+
async function extractEnv(projectPath, allEvidence) {
|
|
267
|
+
const vars = new Map();
|
|
268
|
+
|
|
269
|
+
// Check .env.example for declarations
|
|
270
|
+
const envFiles = ['.env.example', '.env.local.example', '.env.sample', 'env.example'];
|
|
271
|
+
for (const envFile of envFiles) {
|
|
272
|
+
try {
|
|
273
|
+
const content = await fs.readFile(path.join(projectPath, envFile), 'utf8');
|
|
274
|
+
const lines = content.split('\n');
|
|
275
|
+
|
|
276
|
+
for (let i = 0; i < lines.length; i++) {
|
|
277
|
+
const match = lines[i].match(/^([A-Z][A-Z0-9_]*)=/);
|
|
278
|
+
if (match) {
|
|
279
|
+
const name = match[1];
|
|
280
|
+
if (!vars.has(name)) {
|
|
281
|
+
vars.set(name, {
|
|
282
|
+
name,
|
|
283
|
+
required: !lines[i].includes('optional'),
|
|
284
|
+
references: [],
|
|
285
|
+
defaultValueHint: lines[i].includes('=') ? lines[i].split('=')[1]?.trim() : undefined,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
} catch {}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Find process.env usage in code
|
|
294
|
+
const files = await findSourceFiles(projectPath);
|
|
295
|
+
for (const file of files.slice(0, 100)) {
|
|
296
|
+
try {
|
|
297
|
+
const content = await fs.readFile(file, 'utf8');
|
|
298
|
+
const relPath = path.relative(projectPath, file);
|
|
299
|
+
const lines = content.split('\n');
|
|
300
|
+
|
|
301
|
+
const pattern = /process\.env\.([A-Z][A-Z0-9_]*)/g;
|
|
302
|
+
let match;
|
|
303
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
304
|
+
const name = match[1];
|
|
305
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
306
|
+
const snippet = lines[lineNum - 1];
|
|
307
|
+
|
|
308
|
+
const evidence = createEvidence(relPath, `${lineNum}`, snippet, `Usage of ${name}`);
|
|
309
|
+
allEvidence.push(evidence);
|
|
310
|
+
|
|
311
|
+
if (!vars.has(name)) {
|
|
312
|
+
vars.set(name, { name, required: true, references: [] });
|
|
313
|
+
}
|
|
314
|
+
vars.get(name).references.push(evidence);
|
|
315
|
+
}
|
|
316
|
+
} catch {}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return { vars: Array.from(vars.values()) };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Extract auth model and protected surfaces
|
|
324
|
+
*/
|
|
325
|
+
async function extractAuth(projectPath, allEvidence) {
|
|
326
|
+
const signals = [];
|
|
327
|
+
const protectedSurfaces = [];
|
|
328
|
+
const gaps = [];
|
|
329
|
+
let authType = 'unknown';
|
|
330
|
+
|
|
331
|
+
const files = await findSourceFiles(projectPath);
|
|
332
|
+
|
|
333
|
+
// Auth type detection patterns
|
|
334
|
+
const authPatterns = {
|
|
335
|
+
jwt: /jsonwebtoken|jwt\.verify|jwt\.sign/i,
|
|
336
|
+
session: /express-session|cookie-session/i,
|
|
337
|
+
nextauth: /next-auth|NextAuth/i,
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// Auth middleware patterns
|
|
341
|
+
const middlewarePatterns = [
|
|
342
|
+
/(?:export\s+)?(?:const|function)\s+(\w*[Aa]uth\w*Middleware|\w*[Gg]uard\w*)/g,
|
|
343
|
+
/requireAuth|isAuthenticated|verifyToken|checkAuth/gi,
|
|
344
|
+
];
|
|
345
|
+
|
|
346
|
+
for (const file of files.slice(0, 100)) {
|
|
347
|
+
try {
|
|
348
|
+
const content = await fs.readFile(file, 'utf8');
|
|
349
|
+
const relPath = path.relative(projectPath, file);
|
|
350
|
+
const lines = content.split('\n');
|
|
351
|
+
|
|
352
|
+
// Detect auth type
|
|
353
|
+
for (const [type, pattern] of Object.entries(authPatterns)) {
|
|
354
|
+
if (pattern.test(content)) {
|
|
355
|
+
authType = type;
|
|
356
|
+
const match = content.match(pattern);
|
|
357
|
+
if (match) {
|
|
358
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
359
|
+
const evidence = createEvidence(relPath, `${lineNum}`, lines[lineNum - 1], `${type} auth signal`);
|
|
360
|
+
allEvidence.push(evidence);
|
|
361
|
+
signals.push({ name: type, evidence: [evidence] });
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Find auth middleware/guards
|
|
367
|
+
for (const pattern of middlewarePatterns) {
|
|
368
|
+
let match;
|
|
369
|
+
pattern.lastIndex = 0;
|
|
370
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
371
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
372
|
+
const evidence = createEvidence(relPath, `${lineNum}`, lines[lineNum - 1], 'Auth middleware');
|
|
373
|
+
allEvidence.push(evidence);
|
|
374
|
+
signals.push({ name: match[1] || match[0], evidence: [evidence] });
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Find protected routes
|
|
379
|
+
if (content.includes('auth') || content.includes('protect')) {
|
|
380
|
+
const routePattern = /\.(get|post|put|patch|delete)\s*\(\s*['"`]([^'"`]+)['"`].*(?:auth|protect|guard)/gi;
|
|
381
|
+
let match;
|
|
382
|
+
while ((match = routePattern.exec(content)) !== null) {
|
|
383
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
384
|
+
const evidence = createEvidence(relPath, `${lineNum}`, lines[lineNum - 1], 'Protected route');
|
|
385
|
+
allEvidence.push(evidence);
|
|
386
|
+
|
|
387
|
+
protectedSurfaces.push({
|
|
388
|
+
surface: match[2],
|
|
389
|
+
kind: 'route',
|
|
390
|
+
enforcedBy: ['middleware'],
|
|
391
|
+
evidence: [evidence],
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
} catch {}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
model: { type: authType, signals },
|
|
400
|
+
protectedSurfaces,
|
|
401
|
+
gaps,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Extract billing signals and paid surfaces
|
|
407
|
+
*/
|
|
408
|
+
async function extractBilling(projectPath, allEvidence) {
|
|
409
|
+
const signals = [];
|
|
410
|
+
const paidSurfaces = [];
|
|
411
|
+
const gaps = [];
|
|
412
|
+
const bypassSignals = [];
|
|
413
|
+
|
|
414
|
+
const files = await findSourceFiles(projectPath);
|
|
415
|
+
|
|
416
|
+
// Billing signal patterns
|
|
417
|
+
const billingPatterns = [
|
|
418
|
+
/stripe|Stripe/g,
|
|
419
|
+
/subscription|Subscription/g,
|
|
420
|
+
/isPro|isEnterprise|tier|Tier/g,
|
|
421
|
+
/checkEntitlement|hasFeature|canAccess/g,
|
|
422
|
+
];
|
|
423
|
+
|
|
424
|
+
// Bypass patterns (ship killers)
|
|
425
|
+
const bypassPatterns = [
|
|
426
|
+
{ pattern: /SKIP_BILLING|BYPASS_PAYMENT/g, severity: 'block' },
|
|
427
|
+
{ pattern: /isPro\s*=\s*true\s*\/\//g, severity: 'block' },
|
|
428
|
+
{ pattern: /tier\s*=\s*['"]enterprise['"]\s*\/\/\s*dev/gi, severity: 'warn' },
|
|
429
|
+
];
|
|
430
|
+
|
|
431
|
+
for (const file of files.slice(0, 100)) {
|
|
432
|
+
try {
|
|
433
|
+
const content = await fs.readFile(file, 'utf8');
|
|
434
|
+
const relPath = path.relative(projectPath, file);
|
|
435
|
+
const lines = content.split('\n');
|
|
436
|
+
|
|
437
|
+
// Find billing signals
|
|
438
|
+
for (const pattern of billingPatterns) {
|
|
439
|
+
let match;
|
|
440
|
+
pattern.lastIndex = 0;
|
|
441
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
442
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
443
|
+
const evidence = createEvidence(relPath, `${lineNum}`, lines[lineNum - 1], 'Billing signal');
|
|
444
|
+
allEvidence.push(evidence);
|
|
445
|
+
signals.push({ name: match[0], evidence: [evidence] });
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Find bypass signals
|
|
450
|
+
for (const { pattern, severity } of bypassPatterns) {
|
|
451
|
+
let match;
|
|
452
|
+
pattern.lastIndex = 0;
|
|
453
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
454
|
+
const lineNum = content.substring(0, match.index).split('\n').length;
|
|
455
|
+
const evidence = createEvidence(relPath, `${lineNum}`, lines[lineNum - 1], 'Billing bypass signal');
|
|
456
|
+
allEvidence.push(evidence);
|
|
457
|
+
bypassSignals.push({ pattern: match[0], severity, evidence: [evidence] });
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
} catch {}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return { signals, paidSurfaces, gaps, bypassSignals };
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Extract integrations (Stripe, Resend, etc.)
|
|
468
|
+
*/
|
|
469
|
+
async function extractIntegrations(projectPath, allEvidence) {
|
|
470
|
+
const services = [];
|
|
471
|
+
const integrationPatterns = {
|
|
472
|
+
stripe: /new Stripe\(|stripe\.customers|stripe\.subscriptions/gi,
|
|
473
|
+
resend: /new Resend\(|resend\.emails/gi,
|
|
474
|
+
prisma: /new PrismaClient\(|prisma\./gi,
|
|
475
|
+
supabase: /createClient.*supabase|supabaseClient/gi,
|
|
476
|
+
openai: /new OpenAI\(|openai\./gi,
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
const files = await findSourceFiles(projectPath);
|
|
480
|
+
|
|
481
|
+
for (const file of files.slice(0, 100)) {
|
|
482
|
+
try {
|
|
483
|
+
const content = await fs.readFile(file, 'utf8');
|
|
484
|
+
const relPath = path.relative(projectPath, file);
|
|
485
|
+
|
|
486
|
+
for (const [name, pattern] of Object.entries(integrationPatterns)) {
|
|
487
|
+
if (pattern.test(content)) {
|
|
488
|
+
const existing = services.find(s => s.name === name);
|
|
489
|
+
if (existing) {
|
|
490
|
+
existing.clientFiles.push(relPath);
|
|
491
|
+
} else {
|
|
492
|
+
services.push({ name, clientFiles: [relPath], evidence: [] });
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
} catch {}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return { services };
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// =============================================================================
|
|
503
|
+
// HELPERS
|
|
504
|
+
// =============================================================================
|
|
505
|
+
|
|
506
|
+
function createEvidence(file, lines, snippet, reason) {
|
|
507
|
+
evidenceCounter++;
|
|
508
|
+
const id = `ev_${String(evidenceCounter).padStart(4, '0')}`;
|
|
509
|
+
const snippetHash = `sha256:${crypto.createHash('sha256').update(snippet || '').digest('hex').slice(0, 16)}`;
|
|
510
|
+
|
|
511
|
+
return { id, file, lines, snippetHash, reason };
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function extractMiddlewares(content, lineNum) {
|
|
515
|
+
// Simple middleware extraction - look for function calls before the handler
|
|
516
|
+
const lines = content.split('\n');
|
|
517
|
+
const line = lines[lineNum - 1] || '';
|
|
518
|
+
const middlewares = [];
|
|
519
|
+
|
|
520
|
+
const mwPattern = /(\w+Middleware|\w+Guard|\w+Auth)/g;
|
|
521
|
+
let match;
|
|
522
|
+
while ((match = mwPattern.exec(line)) !== null) {
|
|
523
|
+
middlewares.push(match[1]);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return middlewares;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function detectAuthRequired(content, lineNum) {
|
|
530
|
+
const lines = content.split('\n');
|
|
531
|
+
const context = lines.slice(Math.max(0, lineNum - 5), lineNum + 5).join('\n');
|
|
532
|
+
|
|
533
|
+
if (/auth|protect|guard|require.*auth/i.test(context)) return 'yes';
|
|
534
|
+
if (/public|no.*auth/i.test(context)) return 'no';
|
|
535
|
+
return 'unknown';
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function detectWorkspaceType(name) {
|
|
539
|
+
if (/api|server|backend/i.test(name)) return 'service';
|
|
540
|
+
if (/web|app|frontend|ui/i.test(name)) return 'app';
|
|
541
|
+
if (/package|lib|shared|common/i.test(name)) return 'package';
|
|
542
|
+
return 'unknown';
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
async function findSourceFiles(projectPath) {
|
|
546
|
+
const files = [];
|
|
547
|
+
const extensions = ['.ts', '.tsx', '.js', '.jsx'];
|
|
548
|
+
const ignoreDirs = ['node_modules', 'dist', 'build', '.git', '.next', 'coverage', '.vibecheck'];
|
|
549
|
+
|
|
550
|
+
async function walk(dir) {
|
|
551
|
+
try {
|
|
552
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
553
|
+
for (const entry of entries) {
|
|
554
|
+
const fullPath = path.join(dir, entry.name);
|
|
555
|
+
if (entry.isDirectory()) {
|
|
556
|
+
if (!ignoreDirs.includes(entry.name) && !entry.name.startsWith('.')) {
|
|
557
|
+
await walk(fullPath);
|
|
558
|
+
}
|
|
559
|
+
} else if (entry.isFile()) {
|
|
560
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
561
|
+
if (extensions.includes(ext)) {
|
|
562
|
+
files.push(fullPath);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
} catch {}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
await walk(projectPath);
|
|
570
|
+
return files;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function generateMarkdown(truthpack) {
|
|
574
|
+
const lines = [
|
|
575
|
+
'# Truth Pack',
|
|
576
|
+
'',
|
|
577
|
+
`Generated: ${truthpack.meta.generatedAt}`,
|
|
578
|
+
`Commit: ${truthpack.meta.commit.sha} (${truthpack.meta.commit.branch})`,
|
|
579
|
+
'',
|
|
580
|
+
'## Project',
|
|
581
|
+
'',
|
|
582
|
+
`**Frameworks:** ${truthpack.project.frameworks.join(', ') || 'none detected'}`,
|
|
583
|
+
'',
|
|
584
|
+
'### Workspaces',
|
|
585
|
+
'',
|
|
586
|
+
...truthpack.project.workspaces.map(w => `- \`${w.path}\` (${w.type})`),
|
|
587
|
+
'',
|
|
588
|
+
'### Entrypoints',
|
|
589
|
+
'',
|
|
590
|
+
...truthpack.project.entrypoints.map(e => `- \`${e.path}\` (${e.kind})`),
|
|
591
|
+
'',
|
|
592
|
+
'## Routes',
|
|
593
|
+
'',
|
|
594
|
+
`**Server Routes:** ${truthpack.routes.server.length}`,
|
|
595
|
+
`**Client Refs:** ${truthpack.routes.clientRefs.length}`,
|
|
596
|
+
'',
|
|
597
|
+
'### Server Routes',
|
|
598
|
+
'',
|
|
599
|
+
'| Method | Path | Handler | Auth |',
|
|
600
|
+
'|--------|------|---------|------|',
|
|
601
|
+
...truthpack.routes.server.slice(0, 50).map(r =>
|
|
602
|
+
`| ${r.method} | \`${r.path}\` | ${r.handler} | ${r.authRequired} |`
|
|
603
|
+
),
|
|
604
|
+
'',
|
|
605
|
+
'## Environment',
|
|
606
|
+
'',
|
|
607
|
+
`**Variables:** ${truthpack.env.vars.length}`,
|
|
608
|
+
'',
|
|
609
|
+
...truthpack.env.vars.slice(0, 30).map(v =>
|
|
610
|
+
`- \`${v.name}\` ${v.required ? '(required)' : '(optional)'} - ${v.references.length} refs`
|
|
611
|
+
),
|
|
612
|
+
'',
|
|
613
|
+
'## Auth',
|
|
614
|
+
'',
|
|
615
|
+
`**Type:** ${truthpack.auth.model.type}`,
|
|
616
|
+
`**Signals:** ${truthpack.auth.model.signals.length}`,
|
|
617
|
+
`**Protected Surfaces:** ${truthpack.auth.protectedSurfaces.length}`,
|
|
618
|
+
'',
|
|
619
|
+
'## Billing',
|
|
620
|
+
'',
|
|
621
|
+
`**Signals:** ${truthpack.billing.signals.length}`,
|
|
622
|
+
`**Bypass Signals:** ${truthpack.billing.bypassSignals.length}`,
|
|
623
|
+
'',
|
|
624
|
+
'## Index',
|
|
625
|
+
'',
|
|
626
|
+
`**Evidence Refs:** ${truthpack.index.evidenceRefs.length}`,
|
|
627
|
+
`**Hash:** ${truthpack.index.hashes.truthpackHash}`,
|
|
628
|
+
'',
|
|
629
|
+
];
|
|
630
|
+
|
|
631
|
+
return lines.join('\n');
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export default runTruthpack;
|