vibecheck-ai 2.0.1 → 5.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/bin/.generated +25 -0
- package/bin/_deprecations.js +463 -0
- package/bin/_router.js +46 -0
- package/bin/cli-hygiene.js +241 -0
- package/bin/dev/run-v2-torture.js +30 -0
- package/bin/registry.js +656 -0
- package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
- package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
- package/bin/runners/REPORT_AUDIT.md +64 -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 +513 -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-enhanced.js +2525 -0
- package/bin/runners/context/generators/cursor.js +514 -0
- package/bin/runners/context/generators/mcp.js +169 -0
- package/bin/runners/context/generators/windsurf.js +180 -0
- package/bin/runners/context/git-context.js +304 -0
- package/bin/runners/context/index.js +1110 -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 +1264 -0
- package/bin/runners/context/security-scanner.js +541 -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 +336 -0
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
- package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
- package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
- package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
- package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
- package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
- package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
- package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
- package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
- package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
- package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
- package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
- package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
- package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
- package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
- package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
- package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
- package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
- package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
- package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
- package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
- package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
- package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
- package/bin/runners/lib/agent-firewall/index.js +200 -0
- package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
- package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
- package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
- package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
- package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
- package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
- package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
- package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
- package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
- package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
- package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
- package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
- package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
- package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
- package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
- package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
- package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
- package/bin/runners/lib/agent-firewall/session/index.js +26 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
- package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
- package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
- package/bin/runners/lib/ai-bridge.js +416 -0
- package/bin/runners/lib/analysis-core.js +309 -0
- package/bin/runners/lib/analyzers.js +2500 -0
- package/bin/runners/lib/api-client.js +269 -0
- package/bin/runners/lib/approve-output.js +235 -0
- package/bin/runners/lib/artifact-envelope.js +540 -0
- package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
- package/bin/runners/lib/audit-bridge.js +391 -0
- package/bin/runners/lib/auth-shared.js +977 -0
- package/bin/runners/lib/auth-truth.js +193 -0
- package/bin/runners/lib/auth.js +215 -0
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/backup.js +62 -0
- package/bin/runners/lib/billing.js +107 -0
- package/bin/runners/lib/checkpoint.js +941 -0
- package/bin/runners/lib/claims.js +118 -0
- package/bin/runners/lib/classify-output.js +204 -0
- package/bin/runners/lib/cleanup/engine.js +571 -0
- package/bin/runners/lib/cleanup/index.js +53 -0
- package/bin/runners/lib/cleanup/output.js +375 -0
- package/bin/runners/lib/cleanup/rules.js +1060 -0
- package/bin/runners/lib/cli-output.js +400 -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 +202 -0
- package/bin/runners/lib/contracts/env-contract.js +181 -0
- package/bin/runners/lib/contracts/external-contract.js +206 -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 +199 -0
- package/bin/runners/lib/contracts.js +804 -0
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/detect.js +89 -0
- package/bin/runners/lib/detectors-v2.js +622 -0
- package/bin/runners/lib/doctor/autofix.js +254 -0
- package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
- package/bin/runners/lib/doctor/failure-signatures.js +526 -0
- package/bin/runners/lib/doctor/fix-script.js +336 -0
- package/bin/runners/lib/doctor/index.js +37 -0
- package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
- package/bin/runners/lib/doctor/modules/index.js +105 -0
- package/bin/runners/lib/doctor/modules/network.js +250 -0
- package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
- package/bin/runners/lib/doctor/modules/project.js +312 -0
- package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
- package/bin/runners/lib/doctor/modules/runtime.js +224 -0
- package/bin/runners/lib/doctor/modules/security.js +350 -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/safe-repair.js +384 -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-output.js +226 -0
- package/bin/runners/lib/doctor-v2.js +608 -0
- package/bin/runners/lib/drift.js +425 -0
- package/bin/runners/lib/enforcement.js +72 -0
- package/bin/runners/lib/engine/ast-cache.js +210 -0
- package/bin/runners/lib/engine/auth-extractor.js +211 -0
- package/bin/runners/lib/engine/billing-extractor.js +112 -0
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
- package/bin/runners/lib/engine/env-extractor.js +207 -0
- package/bin/runners/lib/engine/express-extractor.js +208 -0
- package/bin/runners/lib/engine/extractors.js +849 -0
- package/bin/runners/lib/engine/index.js +207 -0
- package/bin/runners/lib/engine/repo-index.js +514 -0
- package/bin/runners/lib/engine/types.js +124 -0
- package/bin/runners/lib/engines/accessibility-engine.js +190 -0
- package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
- package/bin/runners/lib/engines/ast-cache.js +99 -0
- package/bin/runners/lib/engines/attack-detector.js +1192 -0
- package/bin/runners/lib/engines/code-quality-engine.js +255 -0
- package/bin/runners/lib/engines/console-logs-engine.js +115 -0
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
- package/bin/runners/lib/engines/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
- package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
- package/bin/runners/lib/engines/file-filter.js +131 -0
- package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
- package/bin/runners/lib/engines/mock-data-engine.js +272 -0
- package/bin/runners/lib/engines/parallel-processor.js +71 -0
- package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
- package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
- package/bin/runners/lib/engines/type-aware-engine.js +152 -0
- package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
- package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
- package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -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 +265 -0
- package/bin/runners/lib/entitlements.generated.js +0 -0
- package/bin/runners/lib/entitlements.js +340 -0
- package/bin/runners/lib/env-resolver.js +417 -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 +368 -0
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +684 -0
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/extractors/client-calls.js +990 -0
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
- package/bin/runners/lib/extractors/fastify-routes.js +426 -0
- package/bin/runners/lib/extractors/index.js +363 -0
- package/bin/runners/lib/extractors/next-routes.js +524 -0
- package/bin/runners/lib/extractors/proof-graph.js +431 -0
- package/bin/runners/lib/extractors/route-matcher.js +451 -0
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
- package/bin/runners/lib/extractors/ui-bindings.js +547 -0
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/findings-schema.js +281 -0
- package/bin/runners/lib/fingerprint.js +377 -0
- package/bin/runners/lib/firewall-prompt.js +50 -0
- package/bin/runners/lib/fix-output.js +228 -0
- package/bin/runners/lib/global-flags.js +250 -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/help-formatter.js +413 -0
- package/bin/runners/lib/html-proof-report.js +913 -0
- package/bin/runners/lib/html-report.js +650 -0
- package/bin/runners/lib/init-wizard.js +601 -0
- package/bin/runners/lib/interactive-menu.js +1496 -0
- package/bin/runners/lib/json-output.js +76 -0
- package/bin/runners/lib/llm.js +75 -0
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/meter.js +61 -0
- package/bin/runners/lib/missions/briefing.js +427 -0
- package/bin/runners/lib/missions/checkpoint.js +753 -0
- package/bin/runners/lib/missions/evidence.js +126 -0
- package/bin/runners/lib/missions/hardening.js +851 -0
- package/bin/runners/lib/missions/plan.js +648 -0
- package/bin/runners/lib/missions/safety-gates.js +645 -0
- package/bin/runners/lib/missions/schema.js +478 -0
- package/bin/runners/lib/missions/templates.js +317 -0
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/packs/bundle.js +675 -0
- package/bin/runners/lib/packs/evidence-pack.js +671 -0
- package/bin/runners/lib/packs/pack-factory.js +837 -0
- package/bin/runners/lib/packs/permissions-pack.js +686 -0
- package/bin/runners/lib/packs/proof-graph-pack.js +779 -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/policy.js +295 -0
- package/bin/runners/lib/polish/accessibility.js +62 -0
- package/bin/runners/lib/polish/analyzer.js +93 -0
- package/bin/runners/lib/polish/backend.js +87 -0
- package/bin/runners/lib/polish/configuration.js +83 -0
- package/bin/runners/lib/polish/documentation.js +83 -0
- package/bin/runners/lib/polish/frontend.js +817 -0
- package/bin/runners/lib/polish/index.js +27 -0
- package/bin/runners/lib/polish/infrastructure.js +80 -0
- package/bin/runners/lib/polish/internationalization.js +85 -0
- package/bin/runners/lib/polish/libraries.js +180 -0
- package/bin/runners/lib/polish/observability.js +75 -0
- package/bin/runners/lib/polish/performance.js +64 -0
- package/bin/runners/lib/polish/privacy.js +110 -0
- package/bin/runners/lib/polish/resilience.js +92 -0
- package/bin/runners/lib/polish/security.js +78 -0
- package/bin/runners/lib/polish/seo.js +71 -0
- package/bin/runners/lib/polish/styles.js +62 -0
- package/bin/runners/lib/polish/utils.js +104 -0
- package/bin/runners/lib/preflight.js +142 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/prove-output.js +220 -0
- package/bin/runners/lib/reality/correlation-detectors.js +359 -0
- package/bin/runners/lib/reality/index.js +318 -0
- package/bin/runners/lib/reality/request-hashing.js +416 -0
- package/bin/runners/lib/reality/request-mapper.js +453 -0
- package/bin/runners/lib/reality/safety-rails.js +463 -0
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
- package/bin/runners/lib/reality/toast-detector.js +393 -0
- package/bin/runners/lib/reality-findings.js +84 -0
- package/bin/runners/lib/reality-output.js +231 -0
- package/bin/runners/lib/receipts.js +179 -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 +626 -0
- package/bin/runners/lib/report-html.js +1233 -0
- package/bin/runners/lib/report-output.js +366 -0
- package/bin/runners/lib/report-templates.js +967 -0
- package/bin/runners/lib/report.js +135 -0
- package/bin/runners/lib/route-detection.js +1209 -0
- package/bin/runners/lib/route-truth.js +1322 -0
- package/bin/runners/lib/safelist/index.js +96 -0
- package/bin/runners/lib/safelist/integration.js +334 -0
- package/bin/runners/lib/safelist/matcher.js +696 -0
- package/bin/runners/lib/safelist/schema.js +948 -0
- package/bin/runners/lib/safelist/store.js +438 -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/scan-output.js +631 -0
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schema-validator.js +350 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/contracts.schema.json +160 -0
- package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
- package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
- package/bin/runners/lib/schemas/finding.schema.json +100 -0
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -0
- package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
- package/bin/runners/lib/schemas/run-request.schema.json +108 -0
- package/bin/runners/lib/schemas/share-pack.schema.json +180 -0
- package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
- package/bin/runners/lib/schemas/validator.js +465 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -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/ship-gate.js +832 -0
- package/bin/runners/lib/ship-manifest.js +1153 -0
- package/bin/runners/lib/ship-output-enterprise.js +239 -0
- package/bin/runners/lib/ship-output.js +1128 -0
- package/bin/runners/lib/snippets.js +67 -0
- package/bin/runners/lib/status-output.js +340 -0
- package/bin/runners/lib/terminal-ui.js +356 -0
- package/bin/runners/lib/truth.js +1691 -0
- package/bin/runners/lib/ui.js +562 -0
- package/bin/runners/lib/unified-cli-output.js +947 -0
- package/bin/runners/lib/unified-output.js +197 -0
- package/bin/runners/lib/upsell.js +410 -0
- package/bin/runners/lib/usage.js +153 -0
- package/bin/runners/lib/validate-patch.js +156 -0
- package/bin/runners/lib/verdict-engine.js +628 -0
- package/bin/runners/lib/verification.js +345 -0
- package/bin/runners/lib/why-tree.js +650 -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 +229 -0
- package/bin/runners/runAgent.d.ts +5 -0
- package/bin/runners/runAgent.js +161 -0
- package/bin/runners/runAllowlist.js +418 -0
- package/bin/runners/runApprove.js +320 -0
- package/bin/runners/runAudit.js +692 -0
- package/bin/runners/runAuth.js +731 -0
- package/bin/runners/runCI.js +353 -0
- package/bin/runners/runCheckpoint.js +530 -0
- package/bin/runners/runClassify.js +928 -0
- package/bin/runners/runCleanup.js +343 -0
- package/bin/runners/runContext.d.ts +4 -0
- package/bin/runners/runContext.js +175 -0
- package/bin/runners/runDoctor.js +877 -0
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.d.ts +5 -0
- package/bin/runners/runFirewall.js +134 -0
- package/bin/runners/runFirewallHook.d.ts +5 -0
- package/bin/runners/runFirewallHook.js +56 -0
- package/bin/runners/runFix.js +1355 -0
- package/bin/runners/runForge.js +451 -0
- package/bin/runners/runGuard.js +262 -0
- package/bin/runners/runInit.js +1927 -0
- package/bin/runners/runIntent.js +906 -0
- package/bin/runners/runKickoff.js +878 -0
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runLaunch.js +2000 -0
- package/bin/runners/runLink.js +785 -0
- package/bin/runners/runMcp.js +1875 -0
- package/bin/runners/runPacks.js +2089 -0
- package/bin/runners/runPolish.d.ts +4 -0
- package/bin/runners/runPolish.js +390 -0
- package/bin/runners/runPromptFirewall.js +211 -0
- package/bin/runners/runProve.js +1411 -0
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +2260 -0
- package/bin/runners/runReport.js +726 -0
- package/bin/runners/runRuntime.js +110 -0
- package/bin/runners/runSafelist.js +1190 -0
- package/bin/runners/runScan.js +688 -0
- package/bin/runners/runShield.js +1282 -0
- package/bin/runners/runShip.js +1660 -0
- package/bin/runners/runTruth.d.ts +5 -0
- package/bin/runners/runTruth.js +101 -0
- package/bin/runners/runValidate.js +179 -0
- package/bin/runners/runWatch.js +478 -0
- package/bin/runners/utils.js +360 -0
- package/bin/scan.js +617 -0
- package/bin/vibecheck.js +1617 -0
- package/dist/guardrail/index.d.ts +2405 -0
- package/dist/guardrail/index.js +9747 -0
- package/dist/guardrail/index.js.map +1 -0
- package/dist/scanner/index.d.ts +282 -0
- package/dist/scanner/index.js +3395 -0
- package/dist/scanner/index.js.map +1 -0
- package/package.json +123 -104
- package/README.md +0 -491
- package/dist/index.js +0 -99711
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,906 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vibecheck intent - Intent Declaration CLI
|
|
3
|
+
*
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* AGENT FIREWALL™ - INTENT DECLARATION COMMAND
|
|
6
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
+
*
|
|
8
|
+
* Manage intent declarations for the Agent Firewall.
|
|
9
|
+
* Intent MUST be declared before AI code generation.
|
|
10
|
+
* If intent is missing → Agent Firewall defaults to BLOCK.
|
|
11
|
+
*
|
|
12
|
+
* Subcommands:
|
|
13
|
+
* set - Declare a new intent
|
|
14
|
+
* show - Show current intent
|
|
15
|
+
* clear - Clear current intent
|
|
16
|
+
* history - View intent history
|
|
17
|
+
* verify - Verify intent integrity
|
|
18
|
+
*
|
|
19
|
+
* @module runIntent
|
|
20
|
+
* @version 2.0.0
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
"use strict";
|
|
24
|
+
|
|
25
|
+
const path = require("path");
|
|
26
|
+
const fs = require("fs");
|
|
27
|
+
|
|
28
|
+
// Lazy imports
|
|
29
|
+
let _globalFlags = null;
|
|
30
|
+
let _exitCodes = null;
|
|
31
|
+
let _cliOutput = null;
|
|
32
|
+
let _intentModule = null;
|
|
33
|
+
|
|
34
|
+
function getGlobalFlags() {
|
|
35
|
+
if (!_globalFlags) {
|
|
36
|
+
_globalFlags = require("./lib/global-flags");
|
|
37
|
+
}
|
|
38
|
+
return _globalFlags;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getExitCodes() {
|
|
42
|
+
if (!_exitCodes) {
|
|
43
|
+
_exitCodes = require("./lib/exit-codes");
|
|
44
|
+
}
|
|
45
|
+
return _exitCodes;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getCliOutput() {
|
|
49
|
+
if (!_cliOutput) {
|
|
50
|
+
_cliOutput = require("./lib/unified-cli-output");
|
|
51
|
+
}
|
|
52
|
+
return _cliOutput;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getIntentModule() {
|
|
56
|
+
if (!_intentModule) {
|
|
57
|
+
_intentModule = require("./lib/agent-firewall/intent");
|
|
58
|
+
}
|
|
59
|
+
return _intentModule;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
63
|
+
// CONSTANTS
|
|
64
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
65
|
+
|
|
66
|
+
const INTENT_VERSION = "2.0.0";
|
|
67
|
+
|
|
68
|
+
const SUBCOMMANDS = {
|
|
69
|
+
set: { description: "Declare a new intent", pro: false },
|
|
70
|
+
show: { description: "Show current intent", pro: false },
|
|
71
|
+
clear: { description: "Clear current intent (archives to history)", pro: false },
|
|
72
|
+
history: { description: "View intent history", pro: false },
|
|
73
|
+
verify: { description: "Verify intent integrity", pro: false },
|
|
74
|
+
template: { description: "Show intent templates", pro: false },
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
78
|
+
// HELP
|
|
79
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
80
|
+
|
|
81
|
+
function printHelp() {
|
|
82
|
+
const { ansi } = getCliOutput();
|
|
83
|
+
|
|
84
|
+
console.log(`
|
|
85
|
+
${ansi.bold}${ansi.cyan}╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
86
|
+
║ ║
|
|
87
|
+
║ ${ansi.reset}${ansi.bold}INTENT DECLARATION${ansi.cyan} ║
|
|
88
|
+
║ ${ansi.reset}${ansi.dim}Agent Firewall™ Intent System${ansi.cyan} ║
|
|
89
|
+
║ ║
|
|
90
|
+
╚═══════════════════════════════════════════════════════════════════════════════╝${ansi.reset}
|
|
91
|
+
|
|
92
|
+
${ansi.bold}USAGE${ansi.reset}
|
|
93
|
+
${ansi.cyan}vibecheck i${ansi.reset} "summary" ${ansi.dim}Quick intent (auto-infers everything)${ansi.reset}
|
|
94
|
+
${ansi.cyan}vibecheck intent${ansi.reset} <subcommand> [options]
|
|
95
|
+
|
|
96
|
+
${ansi.dim}Declare your intent BEFORE AI code generation.
|
|
97
|
+
In observe mode, changes are logged for later approval.${ansi.reset}
|
|
98
|
+
|
|
99
|
+
${ansi.bold}SUBCOMMANDS${ansi.reset}
|
|
100
|
+
${ansi.cyan}set${ansi.reset} Declare a new intent
|
|
101
|
+
${ansi.cyan}show${ansi.reset} Show current intent
|
|
102
|
+
${ansi.cyan}clear${ansi.reset} Clear current intent
|
|
103
|
+
${ansi.cyan}history${ansi.reset} View intent history
|
|
104
|
+
${ansi.cyan}verify${ansi.reset} Verify intent integrity
|
|
105
|
+
${ansi.cyan}template${ansi.reset} Show intent templates
|
|
106
|
+
|
|
107
|
+
${ansi.bold}SET OPTIONS${ansi.reset}
|
|
108
|
+
${ansi.cyan}--summary, -s <text>${ansi.reset} Intent summary (required)
|
|
109
|
+
${ansi.cyan}--constraint, -c <text>${ansi.reset} Add constraint (repeatable)
|
|
110
|
+
${ansi.cyan}--allow-file <path>${ansi.reset} Allow file modification (repeatable)
|
|
111
|
+
${ansi.cyan}--allow-route <route>${ansi.reset} Allow route addition (repeatable)
|
|
112
|
+
${ansi.cyan}--allow-env <var>${ansi.reset} Allow env var (repeatable)
|
|
113
|
+
${ansi.cyan}--scope-dir <dir>${ansi.reset} Restrict to directory (repeatable)
|
|
114
|
+
${ansi.cyan}--scope-domain <domain>${ansi.reset} Restrict to domain (repeatable)
|
|
115
|
+
${ansi.cyan}--expires <duration>${ansi.reset} Set expiration (e.g., "1h", "30m")
|
|
116
|
+
${ansi.cyan}--from-file <path>${ansi.reset} Load intent from JSON file
|
|
117
|
+
|
|
118
|
+
${ansi.bold}EXAMPLES${ansi.reset}
|
|
119
|
+
${ansi.dim}# Simple intent${ansi.reset}
|
|
120
|
+
vibecheck intent set -s "Fix login button styling"
|
|
121
|
+
|
|
122
|
+
${ansi.dim}# Intent with constraints${ansi.reset}
|
|
123
|
+
vibecheck intent set -s "Add user profile endpoint" \\
|
|
124
|
+
-c "No auth changes" \\
|
|
125
|
+
-c "Tests required" \\
|
|
126
|
+
--allow-file "src/routes/users.ts" \\
|
|
127
|
+
--allow-route "GET /api/users/:id"
|
|
128
|
+
|
|
129
|
+
${ansi.dim}# Scoped intent${ansi.reset}
|
|
130
|
+
vibecheck intent set -s "Refactor auth module" \\
|
|
131
|
+
--scope-dir "src/auth/" \\
|
|
132
|
+
--scope-domain "auth"
|
|
133
|
+
|
|
134
|
+
${ansi.dim}# From file${ansi.reset}
|
|
135
|
+
vibecheck intent set --from-file intent.json
|
|
136
|
+
|
|
137
|
+
${ansi.dim}# Show current${ansi.reset}
|
|
138
|
+
vibecheck intent show
|
|
139
|
+
|
|
140
|
+
${ansi.dim}# Clear${ansi.reset}
|
|
141
|
+
vibecheck intent clear
|
|
142
|
+
|
|
143
|
+
${ansi.bold}DOMAINS${ansi.reset}
|
|
144
|
+
auth, payments, routes, contracts, ui, database, config, general
|
|
145
|
+
|
|
146
|
+
${ansi.dim}────────────────────────────────────────────────────────────────────${ansi.reset}
|
|
147
|
+
${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/intent${ansi.reset}
|
|
148
|
+
${ansi.dim}Version: ${INTENT_VERSION}${ansi.reset}
|
|
149
|
+
`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
153
|
+
// MAIN ENTRY
|
|
154
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Main intent command handler
|
|
158
|
+
* @param {string[]} args - Command arguments
|
|
159
|
+
* @param {Object} context - Execution context
|
|
160
|
+
* @returns {Promise<number>} Exit code
|
|
161
|
+
*/
|
|
162
|
+
async function runIntent(args = [], context = {}) {
|
|
163
|
+
const { parseGlobalFlags, shouldSuppressOutput, isJsonMode } = getGlobalFlags();
|
|
164
|
+
const { EXIT } = getExitCodes();
|
|
165
|
+
|
|
166
|
+
const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
|
|
167
|
+
const quiet = shouldSuppressOutput(globalFlags);
|
|
168
|
+
const json = isJsonMode(globalFlags) || args.includes("--json");
|
|
169
|
+
const projectRoot = context.repoRoot || globalFlags.path || process.cwd();
|
|
170
|
+
|
|
171
|
+
// Handle help
|
|
172
|
+
if (globalFlags.help || args.includes("--help") || args.includes("-h")) {
|
|
173
|
+
printHelp();
|
|
174
|
+
return EXIT.SUCCESS;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Check for QUICK INTENT MODE: vibecheck i "summary text"
|
|
178
|
+
// If first arg is a quoted string (not a subcommand), treat as quick intent
|
|
179
|
+
const firstArg = cleanArgs[0];
|
|
180
|
+
const isQuickMode = firstArg &&
|
|
181
|
+
!SUBCOMMANDS[firstArg] &&
|
|
182
|
+
!firstArg.startsWith("-") &&
|
|
183
|
+
firstArg.length > 2;
|
|
184
|
+
|
|
185
|
+
if (isQuickMode) {
|
|
186
|
+
// Quick intent: vibecheck i "fix login bug"
|
|
187
|
+
const ctx = {
|
|
188
|
+
projectRoot,
|
|
189
|
+
json,
|
|
190
|
+
quiet,
|
|
191
|
+
args: cleanArgs,
|
|
192
|
+
originalArgs: args,
|
|
193
|
+
quickMode: true,
|
|
194
|
+
};
|
|
195
|
+
return await handleQuickSet(ctx);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Parse subcommand
|
|
199
|
+
const subcommand = firstArg || "show";
|
|
200
|
+
const subArgs = cleanArgs.slice(1);
|
|
201
|
+
|
|
202
|
+
// Create context
|
|
203
|
+
const ctx = {
|
|
204
|
+
projectRoot,
|
|
205
|
+
json,
|
|
206
|
+
quiet,
|
|
207
|
+
args: subArgs,
|
|
208
|
+
originalArgs: args,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
switch (subcommand) {
|
|
213
|
+
case "set":
|
|
214
|
+
return await handleSet(ctx);
|
|
215
|
+
case "show":
|
|
216
|
+
return await handleShow(ctx);
|
|
217
|
+
case "clear":
|
|
218
|
+
return await handleClear(ctx);
|
|
219
|
+
case "history":
|
|
220
|
+
return await handleHistory(ctx);
|
|
221
|
+
case "verify":
|
|
222
|
+
return await handleVerify(ctx);
|
|
223
|
+
case "template":
|
|
224
|
+
return await handleTemplate(ctx);
|
|
225
|
+
default:
|
|
226
|
+
return handleUnknown(subcommand, ctx);
|
|
227
|
+
}
|
|
228
|
+
} catch (error) {
|
|
229
|
+
return handleError(error, ctx);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
234
|
+
// HANDLERS
|
|
235
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Handle QUICK set - vibecheck i "summary text"
|
|
239
|
+
* Auto-infers constraints, scope, and allowed files from context
|
|
240
|
+
*/
|
|
241
|
+
async function handleQuickSet(ctx) {
|
|
242
|
+
const { EXIT } = getExitCodes();
|
|
243
|
+
const { ansi, renderSuccess, renderError } = getCliOutput();
|
|
244
|
+
const { createIntent, IntentStore } = getIntentModule();
|
|
245
|
+
|
|
246
|
+
// Import auto-detect module
|
|
247
|
+
let autoDetect;
|
|
248
|
+
try {
|
|
249
|
+
autoDetect = require("./lib/agent-firewall/intent/auto-detect");
|
|
250
|
+
} catch (e) {
|
|
251
|
+
if (ctx.json) {
|
|
252
|
+
console.log(JSON.stringify({ success: false, error: "Auto-detect module not available" }));
|
|
253
|
+
} else {
|
|
254
|
+
renderError("Auto-detect module not available");
|
|
255
|
+
}
|
|
256
|
+
return EXIT.INTERNAL_ERROR;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Get the summary from args - join all non-flag args
|
|
260
|
+
const summaryParts = ctx.args.filter(a => !a.startsWith("-"));
|
|
261
|
+
const userSummary = summaryParts.join(" ").trim();
|
|
262
|
+
|
|
263
|
+
if (!userSummary) {
|
|
264
|
+
if (ctx.json) {
|
|
265
|
+
console.log(JSON.stringify({ success: false, error: "Summary required" }));
|
|
266
|
+
} else {
|
|
267
|
+
renderError("Summary required");
|
|
268
|
+
console.log(`\n ${ansi.dim}Example: ${ansi.cyan}vibecheck i "fix login bug"${ansi.reset}\n`);
|
|
269
|
+
}
|
|
270
|
+
return EXIT.USER_ERROR;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Auto-detect context
|
|
274
|
+
const detected = autoDetect.autoDetectIntent(ctx.projectRoot, userSummary);
|
|
275
|
+
|
|
276
|
+
// Create and store intent
|
|
277
|
+
const intent = createIntent(detected);
|
|
278
|
+
const store = new IntentStore(ctx.projectRoot);
|
|
279
|
+
const result = store.store(intent);
|
|
280
|
+
|
|
281
|
+
if (ctx.json) {
|
|
282
|
+
console.log(JSON.stringify({
|
|
283
|
+
success: result.success,
|
|
284
|
+
quick_mode: true,
|
|
285
|
+
intent: {
|
|
286
|
+
hash: intent.hash,
|
|
287
|
+
summary: intent.summary,
|
|
288
|
+
constraints: intent.constraints,
|
|
289
|
+
allowed_changes: intent.allowed_changes?.length || 0,
|
|
290
|
+
scope: intent.scope,
|
|
291
|
+
created_at: intent.created_at,
|
|
292
|
+
},
|
|
293
|
+
auto_detected: detected._context,
|
|
294
|
+
error: result.error,
|
|
295
|
+
}, null, 2));
|
|
296
|
+
} else if (!ctx.quiet) {
|
|
297
|
+
if (result.success) {
|
|
298
|
+
console.log(`
|
|
299
|
+
${ansi.green}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
|
|
300
|
+
║ ║
|
|
301
|
+
║ ✓ QUICK INTENT SET ║
|
|
302
|
+
║ ║
|
|
303
|
+
╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
|
|
304
|
+
|
|
305
|
+
${ansi.bold}Summary${ansi.reset}
|
|
306
|
+
${intent.summary}`);
|
|
307
|
+
|
|
308
|
+
if (intent.constraints.length > 0) {
|
|
309
|
+
console.log(`\n ${ansi.bold}Auto-Inferred Constraints${ansi.reset}`);
|
|
310
|
+
for (const c of intent.constraints) {
|
|
311
|
+
console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (intent.allowed_changes && intent.allowed_changes.length > 0) {
|
|
316
|
+
console.log(`\n ${ansi.bold}Auto-Allowed Files${ansi.reset} ${ansi.dim}(from git status)${ansi.reset}`);
|
|
317
|
+
for (const ac of intent.allowed_changes.slice(0, 5)) {
|
|
318
|
+
console.log(` ${ansi.green}✓${ansi.reset} ${ac.target}`);
|
|
319
|
+
}
|
|
320
|
+
if (intent.allowed_changes.length > 5) {
|
|
321
|
+
console.log(` ${ansi.dim}... and ${intent.allowed_changes.length - 5} more${ansi.reset}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (intent.scope) {
|
|
326
|
+
console.log(`\n ${ansi.bold}Auto-Detected Scope${ansi.reset}`);
|
|
327
|
+
if (intent.scope.directories) {
|
|
328
|
+
console.log(` ${ansi.dim}Directories:${ansi.reset} ${intent.scope.directories.join(", ")}`);
|
|
329
|
+
}
|
|
330
|
+
if (intent.scope.domains) {
|
|
331
|
+
console.log(` ${ansi.dim}Domains:${ansi.reset} ${intent.scope.domains.join(", ")}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Show context used
|
|
336
|
+
const ctx_info = detected._context;
|
|
337
|
+
if (ctx_info) {
|
|
338
|
+
console.log(`\n ${ansi.dim}Context: ${ctx_info.branch ? `branch=${ctx_info.branch}` : ""}${ctx_info.stagedFiles ? ` staged=${ctx_info.stagedFiles}` : ""}${ctx_info.modifiedFiles ? ` modified=${ctx_info.modifiedFiles}` : ""} type=${ctx_info.inferredType}${ansi.reset}`);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
console.log(`
|
|
342
|
+
${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
|
|
343
|
+
|
|
344
|
+
${ansi.bold}You're ready to vibe.${ansi.reset} ${ansi.dim}AI changes will be checked against this intent.${ansi.reset}
|
|
345
|
+
`);
|
|
346
|
+
} else {
|
|
347
|
+
renderError(result.error || "Failed to store intent");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return result.success ? EXIT.SUCCESS : EXIT.INTERNAL_ERROR;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Handle set subcommand
|
|
356
|
+
*/
|
|
357
|
+
async function handleSet(ctx) {
|
|
358
|
+
const { EXIT } = getExitCodes();
|
|
359
|
+
const { ansi, renderSuccess, renderError } = getCliOutput();
|
|
360
|
+
const { createIntent, IntentStore, CONSTRAINT_TEMPLATES } = getIntentModule();
|
|
361
|
+
|
|
362
|
+
const args = ctx.originalArgs;
|
|
363
|
+
|
|
364
|
+
// Check for --from-file
|
|
365
|
+
const fromFile = getArgValue(args, "--from-file");
|
|
366
|
+
|
|
367
|
+
let intentData;
|
|
368
|
+
|
|
369
|
+
if (fromFile) {
|
|
370
|
+
// Load from file
|
|
371
|
+
const filePath = path.resolve(ctx.projectRoot, fromFile);
|
|
372
|
+
if (!fs.existsSync(filePath)) {
|
|
373
|
+
if (ctx.json) {
|
|
374
|
+
console.log(JSON.stringify({ success: false, error: `File not found: ${fromFile}` }));
|
|
375
|
+
} else {
|
|
376
|
+
renderError(`File not found: ${fromFile}`);
|
|
377
|
+
}
|
|
378
|
+
return EXIT.USER_ERROR;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
try {
|
|
382
|
+
intentData = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
383
|
+
} catch (e) {
|
|
384
|
+
if (ctx.json) {
|
|
385
|
+
console.log(JSON.stringify({ success: false, error: `Invalid JSON: ${e.message}` }));
|
|
386
|
+
} else {
|
|
387
|
+
renderError(`Invalid JSON in ${fromFile}: ${e.message}`);
|
|
388
|
+
}
|
|
389
|
+
return EXIT.USER_ERROR;
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
// Build from CLI args
|
|
393
|
+
const summary = getArgValue(args, "--summary") || getArgValue(args, "-s");
|
|
394
|
+
|
|
395
|
+
if (!summary) {
|
|
396
|
+
if (ctx.json) {
|
|
397
|
+
console.log(JSON.stringify({ success: false, error: "Summary required. Use --summary or -s" }));
|
|
398
|
+
} else {
|
|
399
|
+
renderError("Summary required. Use --summary or -s");
|
|
400
|
+
console.log(`\n ${ansi.dim}Example: vibecheck intent set -s "Add user profile endpoint"${ansi.reset}\n`);
|
|
401
|
+
}
|
|
402
|
+
return EXIT.USER_ERROR;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const constraints = getAllArgValues(args, "--constraint", "-c");
|
|
406
|
+
const allowFiles = getAllArgValues(args, "--allow-file");
|
|
407
|
+
const allowRoutes = getAllArgValues(args, "--allow-route");
|
|
408
|
+
const allowEnvs = getAllArgValues(args, "--allow-env");
|
|
409
|
+
const scopeDirs = getAllArgValues(args, "--scope-dir");
|
|
410
|
+
const scopeDomains = getAllArgValues(args, "--scope-domain");
|
|
411
|
+
const expires = getArgValue(args, "--expires");
|
|
412
|
+
|
|
413
|
+
// Build allowed_changes
|
|
414
|
+
const allowed_changes = [];
|
|
415
|
+
|
|
416
|
+
for (const file of allowFiles) {
|
|
417
|
+
allowed_changes.push({ type: "file_modify", target: file });
|
|
418
|
+
}
|
|
419
|
+
for (const route of allowRoutes) {
|
|
420
|
+
allowed_changes.push({ type: "route_add", target: route });
|
|
421
|
+
}
|
|
422
|
+
for (const env of allowEnvs) {
|
|
423
|
+
allowed_changes.push({ type: "env_add", target: env });
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Build scope
|
|
427
|
+
let scope = null;
|
|
428
|
+
if (scopeDirs.length > 0 || scopeDomains.length > 0) {
|
|
429
|
+
scope = {};
|
|
430
|
+
if (scopeDirs.length > 0) scope.directories = scopeDirs;
|
|
431
|
+
if (scopeDomains.length > 0) scope.domains = scopeDomains;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
intentData = {
|
|
435
|
+
summary,
|
|
436
|
+
constraints,
|
|
437
|
+
allowed_changes: allowed_changes.length > 0 ? allowed_changes : undefined,
|
|
438
|
+
scope,
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
// Handle expiration
|
|
442
|
+
if (expires) {
|
|
443
|
+
const ms = parseDuration(expires);
|
|
444
|
+
if (ms) {
|
|
445
|
+
intentData.expires_at = new Date(Date.now() + ms).toISOString();
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Create and store intent
|
|
451
|
+
const intent = createIntent(intentData);
|
|
452
|
+
const store = new IntentStore(ctx.projectRoot);
|
|
453
|
+
const result = store.store(intent);
|
|
454
|
+
|
|
455
|
+
if (ctx.json) {
|
|
456
|
+
console.log(JSON.stringify({
|
|
457
|
+
success: result.success,
|
|
458
|
+
intent: {
|
|
459
|
+
hash: intent.hash,
|
|
460
|
+
summary: intent.summary,
|
|
461
|
+
constraints: intent.constraints,
|
|
462
|
+
created_at: intent.created_at,
|
|
463
|
+
},
|
|
464
|
+
error: result.error,
|
|
465
|
+
}, null, 2));
|
|
466
|
+
} else if (!ctx.quiet) {
|
|
467
|
+
if (result.success) {
|
|
468
|
+
console.log(`
|
|
469
|
+
${ansi.green}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
|
|
470
|
+
║ ║
|
|
471
|
+
║ ✓ INTENT DECLARED ║
|
|
472
|
+
║ ║
|
|
473
|
+
╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
|
|
474
|
+
|
|
475
|
+
${ansi.bold}Summary${ansi.reset}
|
|
476
|
+
${intent.summary}
|
|
477
|
+
|
|
478
|
+
${ansi.bold}Constraints${ansi.reset}`);
|
|
479
|
+
|
|
480
|
+
if (intent.constraints.length > 0) {
|
|
481
|
+
for (const c of intent.constraints) {
|
|
482
|
+
console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
|
|
483
|
+
}
|
|
484
|
+
} else {
|
|
485
|
+
console.log(` ${ansi.dim}(none)${ansi.reset}`);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (intent.allowed_changes && intent.allowed_changes.length > 0) {
|
|
489
|
+
console.log(`\n ${ansi.bold}Allowed Changes${ansi.reset}`);
|
|
490
|
+
for (const ac of intent.allowed_changes) {
|
|
491
|
+
console.log(` ${ansi.green}✓${ansi.reset} [${ac.type}] ${ac.target || ac.pattern}`);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (intent.scope) {
|
|
496
|
+
console.log(`\n ${ansi.bold}Scope${ansi.reset}`);
|
|
497
|
+
if (intent.scope.directories) {
|
|
498
|
+
console.log(` ${ansi.dim}Directories:${ansi.reset} ${intent.scope.directories.join(", ")}`);
|
|
499
|
+
}
|
|
500
|
+
if (intent.scope.domains) {
|
|
501
|
+
console.log(` ${ansi.dim}Domains:${ansi.reset} ${intent.scope.domains.join(", ")}`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
console.log(`
|
|
506
|
+
${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
|
|
507
|
+
${ansi.dim}Created: ${intent.created_at}${ansi.reset}
|
|
508
|
+
|
|
509
|
+
${ansi.bold}The Agent Firewall will now enforce this intent.${ansi.reset}
|
|
510
|
+
${ansi.dim}Changes outside this intent will be BLOCKED.${ansi.reset}
|
|
511
|
+
`);
|
|
512
|
+
} else {
|
|
513
|
+
renderError(result.error || "Failed to store intent");
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return result.success ? EXIT.SUCCESS : EXIT.INTERNAL_ERROR;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Handle show subcommand
|
|
522
|
+
*/
|
|
523
|
+
async function handleShow(ctx) {
|
|
524
|
+
const { EXIT } = getExitCodes();
|
|
525
|
+
const { ansi, renderWarning } = getCliOutput();
|
|
526
|
+
const { IntentStore, verifyIntentIntegrity, isIntentExpired } = getIntentModule();
|
|
527
|
+
|
|
528
|
+
const store = new IntentStore(ctx.projectRoot);
|
|
529
|
+
const intent = store.getCurrent({ allowMissing: true });
|
|
530
|
+
|
|
531
|
+
if (!intent) {
|
|
532
|
+
if (ctx.json) {
|
|
533
|
+
console.log(JSON.stringify({ intent: null, message: "No intent declared" }));
|
|
534
|
+
} else if (!ctx.quiet) {
|
|
535
|
+
renderWarning("No intent declared");
|
|
536
|
+
console.log(`
|
|
537
|
+
${ansi.dim}The Agent Firewall will BLOCK all AI changes.${ansi.reset}
|
|
538
|
+
${ansi.dim}Declare an intent: ${ansi.cyan}vibecheck intent set -s "Your intent"${ansi.reset}
|
|
539
|
+
`);
|
|
540
|
+
}
|
|
541
|
+
return EXIT.SUCCESS;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Check if it's the blocking intent
|
|
545
|
+
const isBlocking = intent.summary?.includes("NO INTENT DECLARED");
|
|
546
|
+
|
|
547
|
+
// Verify integrity
|
|
548
|
+
const integrity = verifyIntentIntegrity(intent);
|
|
549
|
+
const expired = isIntentExpired(intent);
|
|
550
|
+
|
|
551
|
+
if (ctx.json) {
|
|
552
|
+
console.log(JSON.stringify({
|
|
553
|
+
intent,
|
|
554
|
+
status: {
|
|
555
|
+
valid: integrity.valid && !expired && !isBlocking,
|
|
556
|
+
integrity: integrity.valid,
|
|
557
|
+
expired,
|
|
558
|
+
isBlocking,
|
|
559
|
+
},
|
|
560
|
+
}, null, 2));
|
|
561
|
+
} else if (!ctx.quiet) {
|
|
562
|
+
if (isBlocking) {
|
|
563
|
+
console.log(`
|
|
564
|
+
${ansi.yellow}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
|
|
565
|
+
║ ║
|
|
566
|
+
║ ⚠ NO INTENT DECLARED ║
|
|
567
|
+
║ ║
|
|
568
|
+
╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
|
|
569
|
+
|
|
570
|
+
${ansi.yellow}All AI changes are currently BLOCKED.${ansi.reset}
|
|
571
|
+
${ansi.dim}Declare an intent to allow specific changes.${ansi.reset}
|
|
572
|
+
|
|
573
|
+
${ansi.bold}Example:${ansi.reset}
|
|
574
|
+
${ansi.cyan}vibecheck intent set -s "Fix login button" --allow-file "src/Login.tsx"${ansi.reset}
|
|
575
|
+
`);
|
|
576
|
+
} else {
|
|
577
|
+
const statusColor = integrity.valid && !expired ? ansi.green : ansi.red;
|
|
578
|
+
const statusText = integrity.valid && !expired ? "ACTIVE" : expired ? "EXPIRED" : "INVALID";
|
|
579
|
+
|
|
580
|
+
console.log(`
|
|
581
|
+
${ansi.cyan}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
|
|
582
|
+
║ ║
|
|
583
|
+
║ CURRENT INTENT ║
|
|
584
|
+
║ ║
|
|
585
|
+
╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
|
|
586
|
+
|
|
587
|
+
${ansi.bold}Status${ansi.reset}
|
|
588
|
+
${statusColor}${statusText}${ansi.reset}${expired ? ` ${ansi.dim}(expired at ${intent.expires_at})${ansi.reset}` : ""}
|
|
589
|
+
|
|
590
|
+
${ansi.bold}Summary${ansi.reset}
|
|
591
|
+
${intent.summary}
|
|
592
|
+
|
|
593
|
+
${ansi.bold}Constraints${ansi.reset}`);
|
|
594
|
+
|
|
595
|
+
if (intent.constraints && intent.constraints.length > 0) {
|
|
596
|
+
for (const c of intent.constraints) {
|
|
597
|
+
console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
|
|
598
|
+
}
|
|
599
|
+
} else {
|
|
600
|
+
console.log(` ${ansi.dim}(none)${ansi.reset}`);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if (intent.allowed_changes && intent.allowed_changes.length > 0) {
|
|
604
|
+
console.log(`\n ${ansi.bold}Allowed Changes${ansi.reset}`);
|
|
605
|
+
for (const ac of intent.allowed_changes) {
|
|
606
|
+
console.log(` ${ansi.green}✓${ansi.reset} [${ac.type}] ${ac.target || ac.pattern}`);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (intent.scope) {
|
|
611
|
+
console.log(`\n ${ansi.bold}Scope${ansi.reset}`);
|
|
612
|
+
if (intent.scope.directories) {
|
|
613
|
+
console.log(` ${ansi.dim}Directories:${ansi.reset} ${intent.scope.directories.join(", ")}`);
|
|
614
|
+
}
|
|
615
|
+
if (intent.scope.domains) {
|
|
616
|
+
console.log(` ${ansi.dim}Domains:${ansi.reset} ${intent.scope.domains.join(", ")}`);
|
|
617
|
+
}
|
|
618
|
+
if (intent.scope.excluded_paths) {
|
|
619
|
+
console.log(` ${ansi.dim}Excluded:${ansi.reset} ${intent.scope.excluded_paths.join(", ")}`);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
console.log(`
|
|
624
|
+
${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
|
|
625
|
+
${ansi.dim}Version: ${intent.version || 1}${ansi.reset}
|
|
626
|
+
${ansi.dim}Created: ${intent.created_at}${ansi.reset}
|
|
627
|
+
`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
return EXIT.SUCCESS;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Handle clear subcommand
|
|
636
|
+
*/
|
|
637
|
+
async function handleClear(ctx) {
|
|
638
|
+
const { EXIT } = getExitCodes();
|
|
639
|
+
const { ansi, renderSuccess, renderWarning } = getCliOutput();
|
|
640
|
+
const { IntentStore } = getIntentModule();
|
|
641
|
+
|
|
642
|
+
const store = new IntentStore(ctx.projectRoot);
|
|
643
|
+
|
|
644
|
+
if (!store.hasIntent()) {
|
|
645
|
+
if (ctx.json) {
|
|
646
|
+
console.log(JSON.stringify({ success: true, message: "No intent to clear" }));
|
|
647
|
+
} else if (!ctx.quiet) {
|
|
648
|
+
renderWarning("No intent to clear");
|
|
649
|
+
}
|
|
650
|
+
return EXIT.SUCCESS;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
store.clear();
|
|
654
|
+
|
|
655
|
+
if (ctx.json) {
|
|
656
|
+
console.log(JSON.stringify({ success: true, message: "Intent cleared and archived" }));
|
|
657
|
+
} else if (!ctx.quiet) {
|
|
658
|
+
renderSuccess("Intent cleared");
|
|
659
|
+
console.log(`
|
|
660
|
+
${ansi.dim}The previous intent has been archived to history.${ansi.reset}
|
|
661
|
+
${ansi.yellow}The Agent Firewall will now BLOCK all AI changes.${ansi.reset}
|
|
662
|
+
|
|
663
|
+
${ansi.dim}View history: ${ansi.cyan}vibecheck intent history${ansi.reset}
|
|
664
|
+
`);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return EXIT.SUCCESS;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Handle history subcommand
|
|
672
|
+
*/
|
|
673
|
+
async function handleHistory(ctx) {
|
|
674
|
+
const { EXIT } = getExitCodes();
|
|
675
|
+
const { ansi } = getCliOutput();
|
|
676
|
+
const { IntentStore } = getIntentModule();
|
|
677
|
+
|
|
678
|
+
const store = new IntentStore(ctx.projectRoot);
|
|
679
|
+
const history = store.getHistory(10);
|
|
680
|
+
|
|
681
|
+
if (ctx.json) {
|
|
682
|
+
console.log(JSON.stringify({ history }, null, 2));
|
|
683
|
+
} else if (!ctx.quiet) {
|
|
684
|
+
console.log(`
|
|
685
|
+
${ansi.bold}Intent History${ansi.reset} ${ansi.dim}(last 10)${ansi.reset}
|
|
686
|
+
`);
|
|
687
|
+
|
|
688
|
+
if (history.length === 0) {
|
|
689
|
+
console.log(` ${ansi.dim}No history found${ansi.reset}\n`);
|
|
690
|
+
} else {
|
|
691
|
+
for (const intent of history) {
|
|
692
|
+
const date = new Date(intent.archived_at || intent.created_at).toLocaleString();
|
|
693
|
+
console.log(` ${ansi.dim}${date}${ansi.reset}`);
|
|
694
|
+
console.log(` ${intent.summary}`);
|
|
695
|
+
console.log(` ${ansi.dim}Hash: ${intent.hash.slice(0, 12)}... | v${intent.version || 1}${ansi.reset}`);
|
|
696
|
+
console.log();
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return EXIT.SUCCESS;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Handle verify subcommand
|
|
706
|
+
*/
|
|
707
|
+
async function handleVerify(ctx) {
|
|
708
|
+
const { EXIT } = getExitCodes();
|
|
709
|
+
const { ansi, renderSuccess, renderError } = getCliOutput();
|
|
710
|
+
const { IntentStore, verifyIntentIntegrity, isIntentExpired } = getIntentModule();
|
|
711
|
+
|
|
712
|
+
const store = new IntentStore(ctx.projectRoot);
|
|
713
|
+
const intent = store.getCurrent({ allowMissing: true });
|
|
714
|
+
|
|
715
|
+
if (!intent) {
|
|
716
|
+
if (ctx.json) {
|
|
717
|
+
console.log(JSON.stringify({ valid: false, reason: "NO_INTENT" }));
|
|
718
|
+
} else {
|
|
719
|
+
renderError("No intent to verify");
|
|
720
|
+
}
|
|
721
|
+
return EXIT.WARNINGS;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const integrity = verifyIntentIntegrity(intent);
|
|
725
|
+
const expired = isIntentExpired(intent);
|
|
726
|
+
const isBlocking = intent.summary?.includes("NO INTENT DECLARED");
|
|
727
|
+
|
|
728
|
+
const result = {
|
|
729
|
+
valid: integrity.valid && !expired && !isBlocking,
|
|
730
|
+
integrity: integrity.valid,
|
|
731
|
+
integrityReason: integrity.reason,
|
|
732
|
+
expired,
|
|
733
|
+
isBlocking,
|
|
734
|
+
hash: intent.hash,
|
|
735
|
+
computed_hash: integrity.computed_hash,
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
if (ctx.json) {
|
|
739
|
+
console.log(JSON.stringify(result, null, 2));
|
|
740
|
+
} else if (!ctx.quiet) {
|
|
741
|
+
if (result.valid) {
|
|
742
|
+
renderSuccess("Intent verified");
|
|
743
|
+
console.log(`
|
|
744
|
+
${ansi.green}✓${ansi.reset} Integrity: ${integrity.reason}
|
|
745
|
+
${ansi.green}✓${ansi.reset} Not expired
|
|
746
|
+
${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
|
|
747
|
+
`);
|
|
748
|
+
} else {
|
|
749
|
+
renderError("Intent verification failed");
|
|
750
|
+
console.log(`
|
|
751
|
+
${!integrity.valid ? `${ansi.red}✗${ansi.reset} Integrity: ${integrity.reason}` : `${ansi.green}✓${ansi.reset} Integrity: OK`}
|
|
752
|
+
${expired ? `${ansi.red}✗${ansi.reset} Expired` : `${ansi.green}✓${ansi.reset} Not expired`}
|
|
753
|
+
${isBlocking ? `${ansi.yellow}!${ansi.reset} Blocking intent (no user intent declared)` : ""}
|
|
754
|
+
`);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
return result.valid ? EXIT.SUCCESS : EXIT.WARNINGS;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Handle template subcommand
|
|
763
|
+
*/
|
|
764
|
+
async function handleTemplate(ctx) {
|
|
765
|
+
const { EXIT } = getExitCodes();
|
|
766
|
+
const { ansi } = getCliOutput();
|
|
767
|
+
const { CONSTRAINT_TEMPLATES } = getIntentModule();
|
|
768
|
+
|
|
769
|
+
const templates = {
|
|
770
|
+
STRICT_BUGFIX: {
|
|
771
|
+
description: "For minimal, focused bug fixes",
|
|
772
|
+
constraints: CONSTRAINT_TEMPLATES.STRICT_BUGFIX,
|
|
773
|
+
example: 'vibecheck intent set -s "Fix login button" -c "No new routes" -c "Changes limited to specified file(s)" --allow-file "src/Login.tsx"',
|
|
774
|
+
},
|
|
775
|
+
FEATURE_ADDITION: {
|
|
776
|
+
description: "For adding new features",
|
|
777
|
+
constraints: CONSTRAINT_TEMPLATES.FEATURE_ADDITION,
|
|
778
|
+
example: 'vibecheck intent set -s "Add user profile endpoint" -c "Tests required" --allow-route "GET /api/users/:id"',
|
|
779
|
+
},
|
|
780
|
+
REFACTOR: {
|
|
781
|
+
description: "For refactoring without behavior changes",
|
|
782
|
+
constraints: CONSTRAINT_TEMPLATES.REFACTOR,
|
|
783
|
+
example: 'vibecheck intent set -s "Refactor auth module" -c "No behavior changes" --scope-dir "src/auth/"',
|
|
784
|
+
},
|
|
785
|
+
SECURITY_PATCH: {
|
|
786
|
+
description: "For security-sensitive changes",
|
|
787
|
+
constraints: CONSTRAINT_TEMPLATES.SECURITY_PATCH,
|
|
788
|
+
example: 'vibecheck intent set -s "Fix XSS vulnerability" -c "No permission relaxation" -c "Review required"',
|
|
789
|
+
},
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
if (ctx.json) {
|
|
793
|
+
console.log(JSON.stringify(templates, null, 2));
|
|
794
|
+
} else if (!ctx.quiet) {
|
|
795
|
+
console.log(`
|
|
796
|
+
${ansi.bold}Intent Templates${ansi.reset}
|
|
797
|
+
`);
|
|
798
|
+
|
|
799
|
+
for (const [name, template] of Object.entries(templates)) {
|
|
800
|
+
console.log(`${ansi.cyan}${ansi.bold}${name}${ansi.reset}`);
|
|
801
|
+
console.log(` ${ansi.dim}${template.description}${ansi.reset}`);
|
|
802
|
+
console.log(` ${ansi.bold}Constraints:${ansi.reset}`);
|
|
803
|
+
for (const c of template.constraints) {
|
|
804
|
+
console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
|
|
805
|
+
}
|
|
806
|
+
console.log(` ${ansi.bold}Example:${ansi.reset}`);
|
|
807
|
+
console.log(` ${ansi.dim}${template.example}${ansi.reset}`);
|
|
808
|
+
console.log();
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
return EXIT.SUCCESS;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Handle unknown subcommand
|
|
817
|
+
*/
|
|
818
|
+
function handleUnknown(subcommand, ctx) {
|
|
819
|
+
const { EXIT } = getExitCodes();
|
|
820
|
+
const { ansi } = getCliOutput();
|
|
821
|
+
|
|
822
|
+
if (ctx.json) {
|
|
823
|
+
console.log(JSON.stringify({
|
|
824
|
+
success: false,
|
|
825
|
+
error: `Unknown subcommand: ${subcommand}`,
|
|
826
|
+
available: Object.keys(SUBCOMMANDS),
|
|
827
|
+
}));
|
|
828
|
+
} else {
|
|
829
|
+
console.log(`
|
|
830
|
+
${ansi.red}Error: Unknown subcommand '${subcommand}'${ansi.reset}
|
|
831
|
+
|
|
832
|
+
${ansi.dim}Available subcommands:${ansi.reset}
|
|
833
|
+
${Object.keys(SUBCOMMANDS).map(s => ` ${ansi.cyan}${s}${ansi.reset}`).join("\n")}
|
|
834
|
+
|
|
835
|
+
Run ${ansi.cyan}vibecheck intent --help${ansi.reset} for usage.
|
|
836
|
+
`);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
return EXIT.USER_ERROR;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Handle error
|
|
844
|
+
*/
|
|
845
|
+
function handleError(error, ctx) {
|
|
846
|
+
const { EXIT } = getExitCodes();
|
|
847
|
+
const { renderError } = getCliOutput();
|
|
848
|
+
|
|
849
|
+
if (ctx.json) {
|
|
850
|
+
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
851
|
+
} else {
|
|
852
|
+
renderError(`Intent error: ${error.message}`);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
return EXIT.INTERNAL_ERROR;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
859
|
+
// UTILITIES
|
|
860
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
861
|
+
|
|
862
|
+
function getArgValue(args, ...flags) {
|
|
863
|
+
for (const flag of flags) {
|
|
864
|
+
const index = args.indexOf(flag);
|
|
865
|
+
if (index !== -1 && args[index + 1] && !args[index + 1].startsWith("-")) {
|
|
866
|
+
return args[index + 1];
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function getAllArgValues(args, ...flags) {
|
|
873
|
+
const values = [];
|
|
874
|
+
for (let i = 0; i < args.length; i++) {
|
|
875
|
+
if (flags.includes(args[i]) && args[i + 1] && !args[i + 1].startsWith("-")) {
|
|
876
|
+
values.push(args[i + 1]);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return values;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
function parseDuration(str) {
|
|
883
|
+
const match = str.match(/^(\d+)(s|m|h|d)$/);
|
|
884
|
+
if (!match) return null;
|
|
885
|
+
|
|
886
|
+
const value = parseInt(match[1], 10);
|
|
887
|
+
const unit = match[2];
|
|
888
|
+
|
|
889
|
+
const multipliers = {
|
|
890
|
+
s: 1000,
|
|
891
|
+
m: 60 * 1000,
|
|
892
|
+
h: 60 * 60 * 1000,
|
|
893
|
+
d: 24 * 60 * 60 * 1000,
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
return value * multipliers[unit];
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
900
|
+
// EXPORTS
|
|
901
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
902
|
+
|
|
903
|
+
module.exports = {
|
|
904
|
+
runIntent,
|
|
905
|
+
SUBCOMMANDS,
|
|
906
|
+
};
|