@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,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions Module Index
|
|
3
|
+
* Exports all permission verification functionality
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
extractAuthModel,
|
|
10
|
+
extractRolePatterns,
|
|
11
|
+
inferRoles,
|
|
12
|
+
buildRouteAuthMap
|
|
13
|
+
} = require("./auth-model");
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
buildAuthZMatrix,
|
|
17
|
+
detectViolations,
|
|
18
|
+
formatMatrix
|
|
19
|
+
} = require("./matrix-builder");
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
detectIDORCandidates,
|
|
23
|
+
buildIDORTestPlan,
|
|
24
|
+
executeIDORTest,
|
|
25
|
+
formatIDORPlan
|
|
26
|
+
} = require("./idor-prover");
|
|
27
|
+
|
|
28
|
+
module.exports = {
|
|
29
|
+
// Auth model extraction
|
|
30
|
+
extractAuthModel,
|
|
31
|
+
extractRolePatterns,
|
|
32
|
+
inferRoles,
|
|
33
|
+
buildRouteAuthMap,
|
|
34
|
+
|
|
35
|
+
// AuthZ matrix
|
|
36
|
+
buildAuthZMatrix,
|
|
37
|
+
detectViolations,
|
|
38
|
+
formatMatrix,
|
|
39
|
+
|
|
40
|
+
// IDOR detection
|
|
41
|
+
detectIDORCandidates,
|
|
42
|
+
buildIDORTestPlan,
|
|
43
|
+
executeIDORTest,
|
|
44
|
+
formatIDORPlan
|
|
45
|
+
};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuthZ Matrix Builder
|
|
3
|
+
* Builds authorization matrix from auth model and runtime verification
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const crypto = require("crypto");
|
|
9
|
+
|
|
10
|
+
function sha256(text) {
|
|
11
|
+
return crypto.createHash("sha256").update(text).digest("hex").slice(0, 16);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Build AuthZ matrix from auth model
|
|
16
|
+
*/
|
|
17
|
+
function buildAuthZMatrix(authModel, runtimeResults = null) {
|
|
18
|
+
const matrix = {
|
|
19
|
+
meta: {
|
|
20
|
+
version: "1.0.0",
|
|
21
|
+
generatedAt: new Date().toISOString()
|
|
22
|
+
},
|
|
23
|
+
roles: authModel.roles.map(r => r.name),
|
|
24
|
+
routes: [],
|
|
25
|
+
violations: []
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
for (const route of authModel.routes) {
|
|
29
|
+
const routeAuthZ = {
|
|
30
|
+
path: route.path,
|
|
31
|
+
method: route.method,
|
|
32
|
+
declared: route.declared,
|
|
33
|
+
actual: {
|
|
34
|
+
anon: null,
|
|
35
|
+
user: null,
|
|
36
|
+
admin: null
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Merge runtime results if available
|
|
41
|
+
if (runtimeResults) {
|
|
42
|
+
const runtimeForRoute = runtimeResults.filter(r =>
|
|
43
|
+
matchesRoute(route.path, r.path)
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
for (const result of runtimeForRoute) {
|
|
47
|
+
if (result.role === "anon") {
|
|
48
|
+
routeAuthZ.actual.anon = {
|
|
49
|
+
status: result.status,
|
|
50
|
+
redirected: result.redirected,
|
|
51
|
+
accessible: result.status >= 200 && result.status < 400 && !result.redirected
|
|
52
|
+
};
|
|
53
|
+
} else if (result.role === "user") {
|
|
54
|
+
routeAuthZ.actual.user = {
|
|
55
|
+
status: result.status,
|
|
56
|
+
redirected: result.redirected,
|
|
57
|
+
accessible: result.status >= 200 && result.status < 400 && !result.redirected
|
|
58
|
+
};
|
|
59
|
+
} else if (result.role === "admin") {
|
|
60
|
+
routeAuthZ.actual.admin = {
|
|
61
|
+
status: result.status,
|
|
62
|
+
redirected: result.redirected,
|
|
63
|
+
accessible: result.status >= 200 && result.status < 400 && !result.redirected
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
matrix.routes.push(routeAuthZ);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Detect violations
|
|
73
|
+
matrix.violations = detectViolations(matrix);
|
|
74
|
+
|
|
75
|
+
return matrix;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Detect authorization violations
|
|
80
|
+
*/
|
|
81
|
+
function detectViolations(matrix) {
|
|
82
|
+
const violations = [];
|
|
83
|
+
|
|
84
|
+
for (const route of matrix.routes) {
|
|
85
|
+
// Check: protected route accessible anonymously
|
|
86
|
+
if (route.declared.protected && route.actual.anon?.accessible) {
|
|
87
|
+
violations.push({
|
|
88
|
+
id: `AUTHZ_ANON_${sha256(route.path)}`,
|
|
89
|
+
severity: "BLOCK",
|
|
90
|
+
type: "anon_access",
|
|
91
|
+
route: route.path,
|
|
92
|
+
method: route.method,
|
|
93
|
+
expected: "protected (should require auth)",
|
|
94
|
+
actual: "accessible anonymously",
|
|
95
|
+
message: `Protected route ${route.path} accessible without authentication`,
|
|
96
|
+
evidence: []
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check: role mismatch (admin route accessible by user)
|
|
101
|
+
if (route.declared.roles?.includes("admin") &&
|
|
102
|
+
!route.declared.roles?.includes("user") &&
|
|
103
|
+
route.actual.user?.accessible) {
|
|
104
|
+
violations.push({
|
|
105
|
+
id: `AUTHZ_ROLE_${sha256(route.path)}`,
|
|
106
|
+
severity: "BLOCK",
|
|
107
|
+
type: "role_mismatch",
|
|
108
|
+
route: route.path,
|
|
109
|
+
method: route.method,
|
|
110
|
+
expected: "admin only",
|
|
111
|
+
actual: "accessible by user role",
|
|
112
|
+
message: `Admin route ${route.path} accessible by non-admin users`,
|
|
113
|
+
evidence: []
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Check: protected route blocked after login (broken auth)
|
|
118
|
+
if (route.declared.protected &&
|
|
119
|
+
route.actual.anon?.redirected &&
|
|
120
|
+
route.actual.user && !route.actual.user.accessible) {
|
|
121
|
+
violations.push({
|
|
122
|
+
id: `AUTHZ_BLOCKED_${sha256(route.path)}`,
|
|
123
|
+
severity: "WARN",
|
|
124
|
+
type: "blocked_after_auth",
|
|
125
|
+
route: route.path,
|
|
126
|
+
method: route.method,
|
|
127
|
+
expected: "accessible after auth",
|
|
128
|
+
actual: `blocked (status ${route.actual.user.status})`,
|
|
129
|
+
message: `Protected route ${route.path} not accessible after authentication`,
|
|
130
|
+
evidence: []
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return violations;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Format matrix for display
|
|
140
|
+
*/
|
|
141
|
+
function formatMatrix(matrix) {
|
|
142
|
+
const lines = [];
|
|
143
|
+
|
|
144
|
+
lines.push("# AuthZ Matrix\n");
|
|
145
|
+
lines.push(`Generated: ${matrix.meta.generatedAt}`);
|
|
146
|
+
lines.push(`Roles: ${matrix.roles.join(", ")}\n`);
|
|
147
|
+
|
|
148
|
+
// Build table header
|
|
149
|
+
const header = ["Route", "Method", "Declared", "Anon", "User", "Admin"];
|
|
150
|
+
lines.push(`| ${header.join(" | ")} |`);
|
|
151
|
+
lines.push(`| ${header.map(() => "---").join(" | ")} |`);
|
|
152
|
+
|
|
153
|
+
for (const route of matrix.routes) {
|
|
154
|
+
const declared = route.declared.protected ? "🔒" : "🌐";
|
|
155
|
+
const anon = formatAccess(route.actual.anon);
|
|
156
|
+
const user = formatAccess(route.actual.user);
|
|
157
|
+
const admin = formatAccess(route.actual.admin);
|
|
158
|
+
|
|
159
|
+
lines.push(`| ${route.path} | ${route.method} | ${declared} | ${anon} | ${user} | ${admin} |`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (matrix.violations.length > 0) {
|
|
163
|
+
lines.push("\n## Violations\n");
|
|
164
|
+
for (const v of matrix.violations) {
|
|
165
|
+
const icon = v.severity === "BLOCK" ? "🛑" : "⚠️";
|
|
166
|
+
lines.push(`${icon} **${v.type}**: ${v.message}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return lines.join("\n");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function formatAccess(result) {
|
|
174
|
+
if (!result) return "?";
|
|
175
|
+
if (result.accessible) return "✅";
|
|
176
|
+
if (result.redirected) return "↩️";
|
|
177
|
+
return `❌ ${result.status}`;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function matchesRoute(pattern, actual) {
|
|
181
|
+
const patternParts = pattern.split("/").filter(Boolean);
|
|
182
|
+
const actualParts = actual.split("/").filter(Boolean);
|
|
183
|
+
|
|
184
|
+
if (patternParts.length !== actualParts.length) return false;
|
|
185
|
+
|
|
186
|
+
for (let i = 0; i < patternParts.length; i++) {
|
|
187
|
+
const p = patternParts[i];
|
|
188
|
+
if (p.startsWith(":") || p.startsWith("*")) continue;
|
|
189
|
+
if (p !== actualParts[i]) return false;
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
module.exports = {
|
|
195
|
+
buildAuthZMatrix,
|
|
196
|
+
detectViolations,
|
|
197
|
+
formatMatrix
|
|
198
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// bin/runners/lib/pkgjson.js
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
function readPkg(root) {
|
|
6
|
+
const p = path.join(root, "package.json");
|
|
7
|
+
if (!fs.existsSync(p)) throw new Error("package.json not found");
|
|
8
|
+
return { path: p, json: JSON.parse(fs.readFileSync(p, "utf8")) };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function writePkg(pkgPath, json) {
|
|
12
|
+
fs.writeFileSync(pkgPath, JSON.stringify(json, null, 2) + "\n", "utf8");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function upsertScripts(pkg, scripts) {
|
|
16
|
+
pkg.scripts = pkg.scripts || {};
|
|
17
|
+
const changed = [];
|
|
18
|
+
|
|
19
|
+
for (const [k, v] of Object.entries(scripts)) {
|
|
20
|
+
if (pkg.scripts[k] === v) continue;
|
|
21
|
+
pkg.scripts[k] = v;
|
|
22
|
+
changed.push(k);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return changed;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = { readPkg, writePkg, upsertScripts };
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight checks - Run before any vibecheck command
|
|
3
|
+
*
|
|
4
|
+
* Validates:
|
|
5
|
+
* - Node version
|
|
6
|
+
* - Required dependencies
|
|
7
|
+
* - Project structure
|
|
8
|
+
* - Configuration
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
const fs = require("fs");
|
|
14
|
+
const path = require("path");
|
|
15
|
+
|
|
16
|
+
const MIN_NODE_VERSION = 18;
|
|
17
|
+
|
|
18
|
+
function checkNodeVersion() {
|
|
19
|
+
const version = process.version;
|
|
20
|
+
const major = parseInt(version.slice(1).split(".")[0], 10);
|
|
21
|
+
if (major < MIN_NODE_VERSION) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
message: `Node.js ${MIN_NODE_VERSION}+ required (you have ${version})`
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return { ok: true };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function checkPlaywright() {
|
|
31
|
+
try {
|
|
32
|
+
require.resolve("playwright");
|
|
33
|
+
return { ok: true };
|
|
34
|
+
} catch {
|
|
35
|
+
return {
|
|
36
|
+
ok: false,
|
|
37
|
+
optional: true,
|
|
38
|
+
message: "Playwright not installed. Reality mode requires: npm i -D playwright"
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function checkFastGlob() {
|
|
44
|
+
try {
|
|
45
|
+
require.resolve("fast-glob");
|
|
46
|
+
return { ok: true };
|
|
47
|
+
} catch {
|
|
48
|
+
return {
|
|
49
|
+
ok: false,
|
|
50
|
+
message: "fast-glob not installed. Run: npm install"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function checkProjectRoot(root) {
|
|
56
|
+
const pkgPath = path.join(root, "package.json");
|
|
57
|
+
if (!fs.existsSync(pkgPath)) {
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
message: "No package.json found. Are you in a project directory?"
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return { ok: true };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function checkGit(root) {
|
|
67
|
+
const gitPath = path.join(root, ".git");
|
|
68
|
+
if (!fs.existsSync(gitPath)) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
optional: true,
|
|
72
|
+
message: "Not a git repository. Some features may not work."
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { ok: true };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function checkWritable(root) {
|
|
79
|
+
const vibecheckDir = path.join(root, ".vibecheck");
|
|
80
|
+
try {
|
|
81
|
+
fs.mkdirSync(vibecheckDir, { recursive: true });
|
|
82
|
+
const testFile = path.join(vibecheckDir, ".write_test");
|
|
83
|
+
fs.writeFileSync(testFile, "test");
|
|
84
|
+
fs.unlinkSync(testFile);
|
|
85
|
+
return { ok: true };
|
|
86
|
+
} catch {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
message: "Cannot write to .vibecheck directory. Check permissions."
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function runPreflight(root, { silent = false, strict = false } = {}) {
|
|
95
|
+
const checks = [
|
|
96
|
+
{ name: "Node.js", check: checkNodeVersion },
|
|
97
|
+
{ name: "Project", check: () => checkProjectRoot(root) },
|
|
98
|
+
{ name: "Writable", check: () => checkWritable(root) },
|
|
99
|
+
{ name: "Git", check: () => checkGit(root) },
|
|
100
|
+
{ name: "fast-glob", check: checkFastGlob },
|
|
101
|
+
{ name: "Playwright", check: checkPlaywright },
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
const results = [];
|
|
105
|
+
let hasError = false;
|
|
106
|
+
|
|
107
|
+
for (const { name, check } of checks) {
|
|
108
|
+
const result = check();
|
|
109
|
+
results.push({ name, ...result });
|
|
110
|
+
|
|
111
|
+
if (!result.ok && !result.optional) {
|
|
112
|
+
hasError = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!silent && hasError) {
|
|
117
|
+
console.error("\n⚠️ Preflight checks failed:\n");
|
|
118
|
+
for (const r of results) {
|
|
119
|
+
if (!r.ok && !r.optional) {
|
|
120
|
+
console.error(` ✗ ${r.name}: ${r.message}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
console.error("");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!silent && !hasError) {
|
|
127
|
+
// Show optional warnings
|
|
128
|
+
const optionalWarnings = results.filter(r => !r.ok && r.optional);
|
|
129
|
+
if (optionalWarnings.length && process.env.VIBECHECK_VERBOSE) {
|
|
130
|
+
for (const r of optionalWarnings) {
|
|
131
|
+
console.warn(` ⚠ ${r.name}: ${r.message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
ok: !hasError,
|
|
138
|
+
results
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = { runPreflight, checkNodeVersion, checkPlaywright };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// bin/runners/lib/reality-findings.js
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
function loadLastReality(repoRoot, maxAgeHours = 12) {
|
|
6
|
+
const p = path.join(repoRoot, ".vibecheck", "reality", "last_reality.json");
|
|
7
|
+
if (!fs.existsSync(p)) return null;
|
|
8
|
+
|
|
9
|
+
const obj = JSON.parse(fs.readFileSync(p, "utf8"));
|
|
10
|
+
const finishedAt = obj?.meta?.finishedAt ? new Date(obj.meta.finishedAt).getTime() : 0;
|
|
11
|
+
if (!finishedAt) return null;
|
|
12
|
+
|
|
13
|
+
const ageMs = Date.now() - finishedAt;
|
|
14
|
+
if (ageMs > maxAgeHours * 3600 * 1000) return null; // stale
|
|
15
|
+
|
|
16
|
+
return obj;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function findingsFromReality(repoRoot) {
|
|
20
|
+
const r = loadLastReality(repoRoot);
|
|
21
|
+
if (!r) return [];
|
|
22
|
+
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const f of r.findings || []) {
|
|
25
|
+
// Preserve original category (DeadUI, AuthCoverage, etc.)
|
|
26
|
+
const category = f.category || "DeadUI";
|
|
27
|
+
|
|
28
|
+
// Generate appropriate fix hints based on category
|
|
29
|
+
let fixHints;
|
|
30
|
+
if (category === "AuthCoverage") {
|
|
31
|
+
fixHints = [
|
|
32
|
+
"Verify your Next.js matcher config protects this route.",
|
|
33
|
+
"Ensure middleware redirects unauthenticated users.",
|
|
34
|
+
"Check that session/auth state is being validated server-side."
|
|
35
|
+
];
|
|
36
|
+
} else {
|
|
37
|
+
fixHints = [
|
|
38
|
+
"Ensure the element has a real onClick/handler and it returns a real result.",
|
|
39
|
+
"If it calls /api/*, ensure the route exists and returns success only on res.ok.",
|
|
40
|
+
"If it's intentionally disabled, reflect that visually and remove the click affordance."
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
out.push({
|
|
45
|
+
id: `F_REALITY_${f.id}`,
|
|
46
|
+
severity: f.severity === "BLOCK" ? "BLOCK" : "WARN",
|
|
47
|
+
category,
|
|
48
|
+
title: f.title,
|
|
49
|
+
why: category === "AuthCoverage"
|
|
50
|
+
? "Reality Runner detected an auth boundary violation."
|
|
51
|
+
: "Reality Runner found a UI interaction that fails in the running app.",
|
|
52
|
+
confidence: "high",
|
|
53
|
+
evidence: [
|
|
54
|
+
{
|
|
55
|
+
id: `ev_${f.id}`,
|
|
56
|
+
file: f.page ? String(f.page).replace(/^https?:\/\//, "") : "runtime",
|
|
57
|
+
lines: "0-0",
|
|
58
|
+
snippetHash: (f.screenshot || "runtime").slice(0, 80),
|
|
59
|
+
reason: f.reason
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
fixHints
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// escalate raw runtime console errors into WARN
|
|
67
|
+
const ce = (r.consoleErrors || []).slice(0, 5);
|
|
68
|
+
if (ce.length) {
|
|
69
|
+
out.push({
|
|
70
|
+
id: "F_REALITY_CONSOLE_ERRORS",
|
|
71
|
+
severity: "WARN",
|
|
72
|
+
category: "DeadUI",
|
|
73
|
+
title: `Console errors observed during Reality run (${ce.length})`,
|
|
74
|
+
why: "Console errors often correlate with broken UI handlers or missing data paths.",
|
|
75
|
+
confidence: "med",
|
|
76
|
+
evidence: [],
|
|
77
|
+
fixHints: ["Open the Reality report and fix the first error in the consoleErrors list."]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { findingsFromReality };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// bin/runners/lib/redact.js
|
|
2
|
+
function redactString(s) {
|
|
3
|
+
if (typeof s !== "string") return s;
|
|
4
|
+
|
|
5
|
+
return s
|
|
6
|
+
.replace(/(api[_-]?key|secret|token|password)\s*[:=]\s*["']?([^"'\s]{6,})["']?/gi, "$1: [REDACTED]")
|
|
7
|
+
.replace(/(bearer)\s+([a-z0-9_\-\.=]{12,})/gi, "$1 [REDACTED]")
|
|
8
|
+
.replace(/sk-[a-z0-9]{16,}/gi, "[REDACTED]")
|
|
9
|
+
.replace(/[a-z0-9+\/=]{80,}/gi, "[REDACTED_BLOB]");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function redactObject(obj) {
|
|
13
|
+
if (obj == null) return obj;
|
|
14
|
+
if (typeof obj === "string") return redactString(obj);
|
|
15
|
+
if (typeof obj !== "object") return obj;
|
|
16
|
+
if (Array.isArray(obj)) return obj.map(redactObject);
|
|
17
|
+
|
|
18
|
+
const out = {};
|
|
19
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
20
|
+
if (/api[_-]?key|secret|token|password|private/i.test(k)) {
|
|
21
|
+
out[k] = "[REDACTED]";
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
out[k] = redactObject(v);
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = { redactObject };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replay Capsule Manager
|
|
3
|
+
* Handles saving, loading, and managing replay capsules
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs').promises;
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const { v4: uuidv4 } = require('uuid');
|
|
9
|
+
const crypto = require('crypto');
|
|
10
|
+
|
|
11
|
+
class CapsuleManager {
|
|
12
|
+
constructor(basePath) {
|
|
13
|
+
this.basePath = path.join(basePath, '.vibecheck', 'replays');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async init() {
|
|
17
|
+
await fs.mkdir(this.basePath, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async saveCapsule(capsule) {
|
|
21
|
+
const id = capsule.id || uuidv4();
|
|
22
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
23
|
+
const capsuleDir = path.join(this.basePath, `${timestamp}_${id}`);
|
|
24
|
+
|
|
25
|
+
await fs.mkdir(capsuleDir, { recursive: true });
|
|
26
|
+
|
|
27
|
+
// Save metadata
|
|
28
|
+
const metadata = {
|
|
29
|
+
id,
|
|
30
|
+
createdAt: new Date().toISOString(),
|
|
31
|
+
name: capsule.name || `Replay ${timestamp}`,
|
|
32
|
+
description: capsule.description || '',
|
|
33
|
+
tags: capsule.tags || [],
|
|
34
|
+
steps: capsule.steps ? capsule.steps.length : 0,
|
|
35
|
+
duration: capsule.duration || 0,
|
|
36
|
+
status: 'captured',
|
|
37
|
+
...capsule.metadata
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Save steps
|
|
41
|
+
const steps = capsule.steps || [];
|
|
42
|
+
|
|
43
|
+
// Generate deterministic hash for the capsule
|
|
44
|
+
const hash = crypto
|
|
45
|
+
.createHash('sha256')
|
|
46
|
+
.update(JSON.stringify({ metadata, steps }))
|
|
47
|
+
.digest('hex');
|
|
48
|
+
|
|
49
|
+
metadata.hash = hash;
|
|
50
|
+
|
|
51
|
+
await Promise.all([
|
|
52
|
+
fs.writeFile(
|
|
53
|
+
path.join(capsuleDir, 'metadata.json'),
|
|
54
|
+
JSON.stringify(metadata, null, 2),
|
|
55
|
+
'utf8'
|
|
56
|
+
),
|
|
57
|
+
fs.writeFile(
|
|
58
|
+
path.join(capsuleDir, 'steps.json'),
|
|
59
|
+
JSON.stringify(steps, null, 2),
|
|
60
|
+
'utf8'
|
|
61
|
+
)
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
return { id, path: capsuleDir, metadata };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async loadCapsule(capsuleId) {
|
|
68
|
+
const capsules = await this.listCapsules();
|
|
69
|
+
const capsule = capsules.find(c => c.id === capsuleId || c.metadata.id === capsuleId);
|
|
70
|
+
|
|
71
|
+
if (!capsule) {
|
|
72
|
+
throw new Error(`Capsule ${capsuleId} not found`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const [metadata, steps] = await Promise.all([
|
|
76
|
+
fs.readFile(path.join(capsule.path, 'metadata.json'), 'utf8')
|
|
77
|
+
.then(JSON.parse),
|
|
78
|
+
fs.readFile(path.join(capsule.path, 'steps.json'), 'utf8')
|
|
79
|
+
.then(JSON.parse)
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
return { metadata, steps };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async listCapsules() {
|
|
86
|
+
try {
|
|
87
|
+
const dirs = await fs.readdir(this.basePath, { withFileTypes: true });
|
|
88
|
+
const capsules = [];
|
|
89
|
+
|
|
90
|
+
for (const dir of dirs) {
|
|
91
|
+
if (!dir.isDirectory()) continue;
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const metadataPath = path.join(this.basePath, dir.name, 'metadata.json');
|
|
95
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf8'));
|
|
96
|
+
|
|
97
|
+
capsules.push({
|
|
98
|
+
id: metadata.id,
|
|
99
|
+
name: metadata.name,
|
|
100
|
+
path: path.join(this.basePath, dir.name),
|
|
101
|
+
metadata,
|
|
102
|
+
timestamp: new Date(metadata.createdAt).getTime()
|
|
103
|
+
});
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error(`Error loading capsule ${dir.name}:`, err.message);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Sort by timestamp, newest first
|
|
110
|
+
return capsules.sort((a, b) => b.timestamp - a.timestamp);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
if (err.code === 'ENOENT') {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async deleteCapsule(capsuleId) {
|
|
120
|
+
const capsules = await this.listCapsules();
|
|
121
|
+
const capsule = capsules.find(c => c.id === capsuleId || c.metadata.id === capsuleId);
|
|
122
|
+
|
|
123
|
+
if (!capsule) {
|
|
124
|
+
throw new Error(`Capsule ${capsuleId} not found`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
await fs.rm(capsule.path, { recursive: true, force: true });
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async exportCapsule(capsuleId, outputPath) {
|
|
132
|
+
const { metadata, steps } = await this.loadCapsule(capsuleId);
|
|
133
|
+
const exportData = { metadata, steps };
|
|
134
|
+
|
|
135
|
+
await fs.writeFile(
|
|
136
|
+
outputPath,
|
|
137
|
+
JSON.stringify(exportData, null, 2),
|
|
138
|
+
'utf8'
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
return outputPath;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async importCapsule(filePath) {
|
|
145
|
+
const data = JSON.parse(await fs.readFile(filePath, 'utf8'));
|
|
146
|
+
return this.saveCapsule({
|
|
147
|
+
...data.metadata,
|
|
148
|
+
steps: data.steps,
|
|
149
|
+
imported: true
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = CapsuleManager;
|