@viberaven/cli 1.0.6 → 1.1.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/dist/cli.js CHANGED
@@ -31,9 +31,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  ));
32
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
33
 
34
- // ../../node_modules/picocolors/picocolors.js
34
+ // ../../../../node_modules/picocolors/picocolors.js
35
35
  var require_picocolors = __commonJS({
36
- "../../node_modules/picocolors/picocolors.js"(exports2, module2) {
36
+ "../../../../node_modules/picocolors/picocolors.js"(exports2, module2) {
37
37
  var p2 = process || {};
38
38
  var argv = p2.argv || [];
39
39
  var env = p2.env || {};
@@ -103,9 +103,9 @@ var require_picocolors = __commonJS({
103
103
  }
104
104
  });
105
105
 
106
- // ../../node_modules/sisteransi/src/index.js
106
+ // ../../../../node_modules/sisteransi/src/index.js
107
107
  var require_src = __commonJS({
108
- "../../node_modules/sisteransi/src/index.js"(exports2, module2) {
108
+ "../../../../node_modules/sisteransi/src/index.js"(exports2, module2) {
109
109
  "use strict";
110
110
  var ESC = "\x1B";
111
111
  var CSI = `${ESC}[`;
@@ -167,12 +167,11 @@ __export(cli_exports, {
167
167
  parseArgs: () => parseArgs,
168
168
  printHelp: () => printHelp,
169
169
  resolveDefaultEntrypointMode: () => resolveDefaultEntrypointMode,
170
- resolveLaunchPermissionMode: () => resolveLaunchPermissionMode,
171
170
  runScanCommand: () => runScanCommand
172
171
  });
173
172
  module.exports = __toCommonJS(cli_exports);
174
173
  var import_promises19 = require("node:fs/promises");
175
- var import_node_path25 = require("node:path");
174
+ var import_node_path26 = require("node:path");
176
175
 
177
176
  // src/config.ts
178
177
  var import_node_os = require("node:os");
@@ -8855,7 +8854,7 @@ function buildProviderAction(gap, provider2) {
8855
8854
  // Use step title as the done signal
8856
8855
  doneSignal: `${step.title} step completed`,
8857
8856
  verifyCommand: PUBLIC_VERIFY_COMMAND,
8858
- actionClass: "provider_write",
8857
+ actionClass: "manual_provider_step",
8859
8858
  approvalRequired: true,
8860
8859
  manualFallback: `Open ${step.openUrl ?? `https://${provider2}.com`} and complete: ${step.instruction}`,
8861
8860
  copyValues: []
@@ -9412,385 +9411,155 @@ function sanitizeArtifactForDisk(artifact) {
9412
9411
  return redactUnknown(artifact);
9413
9412
  }
9414
9413
 
9415
- // src/providerMcpBridge.ts
9416
- var import_node_fs7 = require("node:fs");
9417
- var import_node_os2 = require("node:os");
9414
+ // src/version.ts
9415
+ var VERSION = "1.1.0";
9416
+
9417
+ // src/prp/buildPrp.ts
9418
9418
  var import_node_path8 = require("node:path");
9419
- var UPGRADE_URL4 = "https://viberaven.dev/pricing";
9420
- var FALLBACK_COMMAND = "npx -y viberaven audit --vercel-supabase --json";
9421
- var SUPPORTED_PROVIDERS = /* @__PURE__ */ new Set(["supabase", "vercel"]);
9422
- var configPathsOverride;
9423
- function defaultMcpConfigPaths() {
9424
- const home = (0, import_node_os2.homedir)();
9425
- return [
9426
- (0, import_node_path8.join)(home, ".config", "claude", "claude_desktop_config.json"),
9427
- (0, import_node_path8.join)(home, ".cursor", "mcp.json"),
9428
- (0, import_node_path8.join)(home, ".gemini", "antigravity", "mcp_config.json")
9429
- ];
9430
- }
9431
- function resolveConfigPaths() {
9432
- return configPathsOverride ?? defaultMcpConfigPaths();
9433
- }
9434
- function parseMcpServers(raw) {
9435
- if (!raw || typeof raw !== "object") {
9436
- return void 0;
9437
- }
9438
- const obj = raw;
9439
- if (obj.mcpServers && typeof obj.mcpServers === "object") {
9440
- return obj.mcpServers;
9441
- }
9442
- if (obj.servers && typeof obj.servers === "object") {
9443
- return obj.servers;
9444
- }
9445
- return void 0;
9419
+
9420
+ // src/prp/types.ts
9421
+ var PRP_SCHEMA_URL = "https://schemas.viberaven.dev/prp/v0.1/schema.json";
9422
+ var PRP_PROTOCOL = "viberaven-production-protocol";
9423
+ var PRP_PROTOCOL_VERSION = "0.1.0";
9424
+
9425
+ // src/prp/buildPrp.ts
9426
+ var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
9427
+ var REDACTED = "<redacted>";
9428
+ var SENSITIVE_JSON_KEY_PATTERN = /secret|token|api[_-]?key|apikey|password|private[_-]?key|database[_-]?url|connection[_-]?string|service[_-]?role|role[_-]?key/i;
9429
+ function buildProductionProtocolReport(options) {
9430
+ const profile = options.profile ?? "launch";
9431
+ const generatedAt = options.artifact.scannedAt;
9432
+ const expiresAt = new Date(new Date(generatedAt).getTime() + ONE_DAY_MS).toISOString();
9433
+ const evidence = buildEvidence(options.artifact);
9434
+ const nextActions = buildNextActions(options.tasks);
9435
+ const findings = buildFindings(options.artifact, nextActions);
9436
+ return {
9437
+ $schema: PRP_SCHEMA_URL,
9438
+ protocol: PRP_PROTOCOL,
9439
+ protocolVersion: PRP_PROTOCOL_VERSION,
9440
+ producer: {
9441
+ name: "viberaven",
9442
+ version: options.producerVersion
9443
+ },
9444
+ subject: {
9445
+ projectName: sanitizePrpText((0, import_node_path8.basename)(options.artifact.workspacePath) || "workspace"),
9446
+ framework: sanitizePrpText(options.artifact.archetype || "unknown"),
9447
+ packageManager: "unknown",
9448
+ deploymentTarget: sanitizePrpText(options.artifact.selectedProviders?.deployment ?? "unknown"),
9449
+ environment: "production"
9450
+ },
9451
+ profile,
9452
+ decision: {
9453
+ status: resolveDecisionStatus(options.artifact),
9454
+ generatedAt,
9455
+ expiresAt,
9456
+ summary: summarizeDecision(options.artifact)
9457
+ },
9458
+ findings,
9459
+ evidence,
9460
+ nextActions,
9461
+ agentInstructions: {
9462
+ mustRead: [".viberaven/prp.json", ".viberaven/mission-map.md", ".viberaven/context-map.json"],
9463
+ doNotDeployUntil: [
9464
+ "decision.status is not blocked",
9465
+ "critical nextActions are resolved or explicitly accepted"
9466
+ ]
9467
+ }
9468
+ };
9446
9469
  }
9447
- function findServerEntry(servers, provider2) {
9448
- if (servers[provider2]) {
9449
- return servers[provider2];
9450
- }
9451
- const key = Object.keys(servers).find((candidate) => candidate.toLowerCase() === provider2);
9452
- return key ? servers[key] : void 0;
9470
+ function resolveDecisionStatus(artifact) {
9471
+ if (artifact.gaps.some((gap) => gap.severity === "critical")) return "blocked";
9472
+ if (artifact.gaps.some((gap) => gap.severity === "warning")) return "warning";
9473
+ return "clear";
9453
9474
  }
9454
- function findProviderMcpConfig(provider2, configPaths) {
9455
- const paths = configPaths ?? resolveConfigPaths();
9456
- for (const path of paths) {
9457
- if (!(0, import_node_fs7.existsSync)(path)) {
9458
- continue;
9459
- }
9460
- try {
9461
- const raw = JSON.parse((0, import_node_fs7.readFileSync)(path, "utf8"));
9462
- const servers = parseMcpServers(raw);
9463
- if (!servers) {
9464
- continue;
9465
- }
9466
- const entry = findServerEntry(servers, provider2);
9467
- if (!entry || typeof entry !== "object") {
9468
- continue;
9469
- }
9470
- const server = entry;
9471
- return {
9472
- command: typeof server.command === "string" ? server.command : void 0,
9473
- args: Array.isArray(server.args) ? server.args.filter((arg) => typeof arg === "string") : void 0,
9474
- url: typeof server.url === "string" ? server.url : void 0,
9475
- source: path
9476
- };
9477
- } catch {
9478
- continue;
9479
- }
9480
- }
9481
- return void 0;
9475
+ function summarizeDecision(artifact) {
9476
+ const critical = artifact.gaps.filter((gap) => gap.severity === "critical").length;
9477
+ const warning = artifact.gaps.filter((gap) => gap.severity === "warning").length;
9478
+ if (critical > 0) return `${critical} production blocker${critical === 1 ? "" : "s"} found`;
9479
+ if (warning > 0) return `${warning} production warning${warning === 1 ? "" : "s"} found`;
9480
+ return "No production blockers found";
9482
9481
  }
9483
- async function verifyProviderGap(options) {
9484
- if (options.plan !== "pro") {
9485
- return {
9486
- verified: false,
9487
- reason: "pro-required",
9488
- upgradeUrl: UPGRADE_URL4
9489
- };
9490
- }
9491
- const provider2 = options.provider.toLowerCase().trim();
9492
- if (!SUPPORTED_PROVIDERS.has(provider2)) {
9482
+ function buildEvidence(artifact) {
9483
+ return artifact.gaps.map((gap) => {
9484
+ const gapId = safePrpId(gap.id);
9493
9485
  return {
9494
- verified: false,
9495
- reason: "unsupported-provider"
9486
+ id: `evidence.${gapId}.repo`,
9487
+ kind: "repo",
9488
+ status: evidenceStatusForGapSeverity(gap.severity),
9489
+ source: sanitizePrpText(String(gap.file ?? gap.primaryMapCategory ?? "repo")),
9490
+ summary: sanitizePrpText(gap.detail || gap.title || gap.id)
9496
9491
  };
9497
- }
9498
- const mcpConfig = findProviderMcpConfig(provider2);
9499
- if (!mcpConfig) {
9500
- return {
9501
- verified: false,
9502
- mcpUnavailable: true,
9503
- fallbackCommand: FALLBACK_COMMAND
9504
- };
9505
- }
9506
- return {
9507
- verified: false,
9508
- mcpUnavailable: true,
9509
- fallbackCommand: FALLBACK_COMMAND
9510
- };
9492
+ });
9511
9493
  }
9512
- function defaultProviderDashboardUrl(provider2) {
9513
- const normalized = provider2.toLowerCase();
9514
- if (normalized === "vercel") return "https://vercel.com/dashboard";
9515
- if (normalized === "supabase") return "https://supabase.com/dashboard/projects";
9516
- if (normalized === "stripe") return "https://dashboard.stripe.com/webhooks";
9517
- if (normalized === "posthog") return "https://us.posthog.com/project/settings";
9518
- return void 0;
9494
+ function evidenceStatusForGapSeverity(severity) {
9495
+ if (severity === "critical" || severity === "warning") return "missing";
9496
+ return "inconclusive";
9519
9497
  }
9520
-
9521
- // src/launch/providerAutomation.ts
9522
- function buildProviderAutomationOptions(options) {
9523
- const provider2 = options.provider.toLowerCase();
9524
- const result = [];
9525
- if (options.mcpConfig) {
9526
- result.push({
9527
- kind: "mcp",
9528
- provider: provider2,
9529
- available: true,
9530
- label: `${provider2} MCP configured`,
9531
- source: options.mcpConfig.source,
9532
- openUrl: options.mcpConfig.url
9533
- });
9534
- }
9535
- if (options.cli?.available) {
9536
- result.push({
9537
- kind: "cli",
9538
- provider: provider2,
9539
- available: true,
9540
- label: options.cli.authenticated ? `${options.cli.command} CLI authenticated` : `${options.cli.command} CLI needs login`,
9541
- command: options.cli.authenticated ? options.cli.command : `${options.cli.command} login`,
9542
- reason: options.cli.detail
9543
- });
9544
- }
9545
- const dashboardUrl = defaultProviderDashboardUrl(provider2);
9546
- if (dashboardUrl) {
9547
- result.push({
9548
- kind: "dashboard",
9549
- provider: provider2,
9550
- available: true,
9551
- label: `Open ${provider2} dashboard`,
9552
- openUrl: dashboardUrl
9553
- });
9554
- }
9555
- result.push({
9556
- kind: "manual",
9557
- provider: provider2,
9558
- available: true,
9559
- label: `Show manual ${provider2} setup steps`,
9560
- reason: "Manual fallback is always available"
9498
+ function buildFindings(artifact, nextActions) {
9499
+ return artifact.gaps.map((gap) => {
9500
+ const gapId = safePrpId(gap.id);
9501
+ return {
9502
+ id: gapId,
9503
+ severity: gap.severity,
9504
+ category: sanitizePrpText(String(gap.primaryMapCategory ?? "unknown")),
9505
+ summary: sanitizePrpText(gap.title || gap.id),
9506
+ evidenceRefs: [`evidence.${gapId}.repo`],
9507
+ nextActionRefs: nextActions.some((action) => action.gapId === sanitizePrpText(gap.id)) ? [`action.${gapId}`] : []
9508
+ };
9561
9509
  });
9562
- return result;
9563
9510
  }
9564
-
9565
- // src/launch/providerActions.ts
9566
- var VERIFY_COMMAND = "npx -y viberaven --verify";
9567
- function buildLaunchProviderActions(options) {
9568
- const actions = [];
9569
- const providers = new Set(options.recipe.providers);
9570
- if (providers.has("vercel")) {
9571
- actions.push({
9572
- provider: "vercel",
9573
- actionClass: "preview_deploy",
9574
- title: "Create a Vercel preview URL",
9575
- detail: "Run a preview deploy so the vibe coder can see the app live before production promotion.",
9576
- openUrl: "https://vercel.com/new",
9577
- command: "vercel deploy",
9578
- copyValues: [],
9579
- verifyCommand: VERIFY_COMMAND,
9580
- approvalRequired: true,
9581
- manualFallback: "Open Vercel, import or link this project, then create a preview deployment.",
9582
- automation: buildProviderAutomationOptions({ provider: "vercel" })
9583
- });
9584
- }
9585
- if (providers.has("supabase")) {
9586
- actions.push({
9587
- provider: "supabase",
9588
- actionClass: "provider_write",
9589
- title: "Connect Supabase project and env values",
9590
- detail: "Connect the production Supabase project, then verify env wiring, migrations, auth, and RLS evidence.",
9591
- openUrl: defaultProviderDashboardUrl("supabase"),
9592
- copyValues: [
9593
- { label: "Public URL env name", value: "NEXT_PUBLIC_SUPABASE_URL", secret: false },
9594
- { label: "Anon key env name", value: "NEXT_PUBLIC_SUPABASE_ANON_KEY", secret: false }
9595
- ],
9596
- verifyCommand: VERIFY_COMMAND,
9597
- approvalRequired: true,
9598
- manualFallback: "Open Supabase project settings, copy the project URL and anon key, then add them to Vercel preview and production env vars.",
9599
- automation: buildProviderAutomationOptions({ provider: "supabase" })
9600
- });
9601
- }
9602
- if (providers.has("stripe")) {
9603
- const baseUrl = options.productionDomain ?? "https://<production-domain>";
9604
- actions.push({
9605
- provider: "stripe",
9606
- actionClass: "provider_write",
9607
- title: "Finish Stripe products and webhook setup",
9608
- detail: "Configure Stripe products/prices and add the production webhook endpoint with required billing events.",
9609
- openUrl: defaultProviderDashboardUrl("stripe"),
9610
- copyValues: [
9611
- { label: "Webhook endpoint", value: `${baseUrl}/api/stripe/webhook`, secret: false },
9612
- { label: "Required event", value: "checkout.session.completed", secret: false },
9613
- { label: "Required event", value: "customer.subscription.updated", secret: false },
9614
- { label: "Required event", value: "customer.subscription.deleted", secret: false },
9615
- { label: "Required event", value: "invoice.payment_failed", secret: false },
9616
- { label: "Webhook secret env name", value: "STRIPE_WEBHOOK_SECRET", secret: false }
9617
- ],
9618
- verifyCommand: VERIFY_COMMAND,
9619
- approvalRequired: true,
9620
- manualFallback: "Open Stripe Webhooks, add the endpoint URL, select the listed events, then store the signing secret as STRIPE_WEBHOOK_SECRET.",
9621
- automation: buildProviderAutomationOptions({ provider: "stripe" })
9622
- });
9623
- }
9624
- return actions;
9625
- }
9626
-
9627
- // src/launch/recipes.ts
9628
- function textIncludes(text, token) {
9629
- return text.toLowerCase().includes(token.toLowerCase());
9511
+ function buildNextActions(tasks) {
9512
+ return tasks.map((task) => ({
9513
+ id: `action.${safePrpId(task.gapId)}`,
9514
+ title: sanitizePrpText(task.title),
9515
+ actionClass: actionClassForTask(task),
9516
+ requiresUserAction: task.requiresUserAction,
9517
+ approvalRequired: task.requiresUserAction,
9518
+ verifyCommand: sanitizePrpText(task.verifyCommand || PUBLIC_VERIFY_COMMAND),
9519
+ gapId: sanitizePrpText(task.gapId),
9520
+ provider: sanitizeOptionalPrpText(task.providerAction?.provider),
9521
+ dashboardUrl: sanitizeOptionalPrpText(task.providerAction?.dashboardUrl),
9522
+ manualFallback: sanitizeOptionalPrpText(task.providerAction?.exactStep ?? task.action),
9523
+ mcpTool: sanitizeOptionalPrpText(task.mcpTool),
9524
+ mcpArgs: sanitizePrpJsonObject(task.mcpArgs)
9525
+ }));
9630
9526
  }
9631
- function selectedProviderSet(artifact) {
9632
- return new Set(Object.values(artifact.selectedProviders ?? {}).map((value) => value.toLowerCase()));
9527
+ function actionClassForTask(task) {
9528
+ if (task.fixType === "repo-code") return "local_repo_write";
9529
+ if (task.fixType === "provider-action") return "manual_provider_step";
9530
+ if (task.fixType === "manual-verify") return "local_repo_read";
9531
+ return "manual_provider_step";
9633
9532
  }
9634
- function hasProvider(artifact, provider2) {
9635
- const selected = selectedProviderSet(artifact);
9636
- return selected.has(provider2);
9533
+ function safeId(value) {
9534
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "unknown";
9637
9535
  }
9638
- function isNextLike(artifact) {
9639
- const text = [artifact.archetype, artifact.summary].join(" ");
9640
- return textIncludes(text, "next") || textIncludes(text, "nextjs") || textIncludes(text, "next.js");
9536
+ function safePrpId(value) {
9537
+ return safeId(sanitizePrpText(value));
9641
9538
  }
9642
- function detectLaunchRecipe(artifact) {
9643
- const next = isNextLike(artifact);
9644
- const vercel = hasProvider(artifact, "vercel");
9645
- const supabase = hasProvider(artifact, "supabase");
9646
- const stripe = hasProvider(artifact, "stripe");
9647
- if (next && supabase && stripe && vercel) {
9648
- return {
9649
- id: "nextjs-supabase-stripe-vercel",
9650
- label: "Next.js + Supabase + Stripe + Vercel SaaS",
9651
- confidence: "high",
9652
- goal: "preview-first",
9653
- providers: ["vercel", "supabase", "stripe"],
9654
- reasons: ["Next.js/Vercel evidence detected", "Supabase evidence detected", "Stripe billing evidence detected"]
9655
- };
9656
- }
9657
- if (next && supabase && vercel) {
9658
- return {
9659
- id: "nextjs-supabase-vercel",
9660
- label: "Next.js + Supabase + Vercel app",
9661
- confidence: "high",
9662
- goal: "preview-first",
9663
- providers: ["vercel", "supabase"],
9664
- reasons: ["Next.js/Vercel evidence detected", "Supabase evidence detected"]
9665
- };
9666
- }
9667
- if (next && vercel) {
9668
- return {
9669
- id: "nextjs-vercel",
9670
- label: "Next.js + Vercel app",
9671
- confidence: "medium",
9672
- goal: "preview-first",
9673
- providers: ["vercel"],
9674
- reasons: ["Next.js/Vercel evidence detected"]
9675
- };
9676
- }
9677
- return {
9678
- id: "generic-preview-first",
9679
- label: "Generic preview-first launch",
9680
- confidence: "low",
9681
- goal: "preview-first",
9682
- providers: vercel ? ["vercel"] : [],
9683
- reasons: ["Provider evidence is incomplete, so VibeRaven will use a conservative preview-first path"]
9684
- };
9539
+ function sanitizeOptionalPrpText(value) {
9540
+ return value === void 0 ? void 0 : sanitizePrpText(value);
9685
9541
  }
9686
-
9687
- // src/launch/buildLaunchPlan.ts
9688
- function isSafeRepoTask(task) {
9689
- return task.fixType === "repo-code" && task.requiresUserAction === false;
9542
+ function sanitizePrpJsonObject(value) {
9543
+ return value === void 0 ? void 0 : sanitizePrpJsonValue(value);
9690
9544
  }
9691
- function providerActionFromTask(task) {
9692
- if (task.fixType !== "provider-action" || !task.providerAction) {
9693
- return void 0;
9694
- }
9695
- const providerAction = task.providerAction;
9696
- return {
9697
- provider: providerAction.provider,
9698
- actionClass: providerAction.actionClass,
9699
- title: task.title,
9700
- detail: providerAction.exactStep,
9701
- openUrl: providerAction.dashboardUrl,
9702
- copyValues: providerAction.copyValues,
9703
- verifyCommand: providerAction.verifyCommand,
9704
- approvalRequired: providerAction.approvalRequired,
9705
- manualFallback: providerAction.manualFallback,
9706
- automation: buildProviderAutomationOptions({ provider: providerAction.provider })
9707
- };
9708
- }
9709
- function mergeTaskProviderActions(recipeActions, tasks) {
9710
- const actions = [...recipeActions];
9711
- for (const task of tasks) {
9712
- const taskAction = providerActionFromTask(task);
9713
- if (!taskAction) continue;
9714
- const alreadyCovered = actions.some(
9715
- (action) => action.provider === taskAction.provider && action.actionClass === taskAction.actionClass
9545
+ function sanitizePrpJsonValue(value) {
9546
+ if (typeof value === "string") return sanitizePrpText(value);
9547
+ if (Array.isArray(value)) return value.map((item3) => sanitizePrpJsonValue(item3));
9548
+ if (value && typeof value === "object") {
9549
+ return Object.fromEntries(
9550
+ Object.entries(value).map(([key, item3]) => [
9551
+ sanitizePrpText(key),
9552
+ SENSITIVE_JSON_KEY_PATTERN.test(key) ? REDACTED : sanitizePrpJsonValue(item3)
9553
+ ])
9716
9554
  );
9717
- if (!alreadyCovered) {
9718
- actions.push(taskAction);
9719
- }
9720
9555
  }
9721
- return actions;
9556
+ return value;
9722
9557
  }
9723
- function selectNextAction(options) {
9724
- const safeRepoTask = options.safeRepoTasks[0];
9725
- if (safeRepoTask) {
9726
- return {
9727
- type: "safe_repo_gap",
9728
- title: safeRepoTask.title,
9729
- detail: safeRepoTask.exactFix ?? "Apply the supported VibeRaven safe repo fix, then verify after the batch.",
9730
- actionClass: "local_repo_write",
9731
- gapId: safeRepoTask.gapId,
9732
- approvalRequired: false,
9733
- manualFallback: "Use VIBERAVEN_NEXT_ACTION or viberaven_heal_apply for the supported safe repo fix, then run verify after the batch."
9734
- };
9735
- }
9736
- const preview = options.providerActions.find((action) => action.actionClass === "preview_deploy");
9737
- if (preview) {
9738
- return {
9739
- type: "preview_deploy",
9740
- title: preview.title,
9741
- detail: preview.detail,
9742
- actionClass: "preview_deploy",
9743
- provider: preview.provider,
9744
- approvalRequired: preview.approvalRequired,
9745
- openUrl: preview.openUrl,
9746
- command: preview.command,
9747
- manualFallback: preview.manualFallback
9748
- };
9749
- }
9750
- const provider2 = options.providerActions[0];
9751
- if (provider2) {
9752
- return {
9753
- type: "provider_setup",
9754
- title: provider2.title,
9755
- detail: provider2.detail,
9756
- actionClass: provider2.actionClass,
9757
- provider: provider2.provider,
9758
- approvalRequired: provider2.approvalRequired,
9759
- openUrl: provider2.openUrl,
9760
- command: provider2.command,
9761
- manualFallback: provider2.manualFallback
9762
- };
9763
- }
9764
- return {
9765
- type: "done",
9766
- title: "Launch path is clear",
9767
- detail: "No launch action is currently required. Run verify before claiming production readiness.",
9768
- actionClass: "local_repo_read",
9769
- approvalRequired: false
9770
- };
9771
- }
9772
- function buildLaunchPlan(options) {
9773
- const permissionMode = options.permissionMode ?? "ask";
9774
- const recipe = detectLaunchRecipe(options.artifact);
9775
- const tasks = options.tasks ?? buildTaskList(options.artifact);
9776
- const safeRepoTasks = tasks.filter(isSafeRepoTask);
9777
- const providerActions = mergeTaskProviderActions(buildLaunchProviderActions({ recipe }), tasks);
9778
- const criticalGaps = options.artifact.gaps.filter((gap) => gap.severity === "critical");
9779
- return {
9780
- version: 1,
9781
- generatedAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
9782
- permissionMode,
9783
- recipe,
9784
- usageLine: options.artifact.usageLine,
9785
- safeRepoTasks,
9786
- providerActions,
9787
- nextAction: selectNextAction({ safeRepoTasks, providerActions }),
9788
- previewFirst: true,
9789
- productionGate: {
9790
- status: criticalGaps.length > 0 ? "blocked" : "unknown",
9791
- reasons: criticalGaps.length > 0 ? ["Critical launch gaps remain"] : ["Preview deploy should be verified before production promotion"]
9792
- }
9793
- };
9558
+ function sanitizePrpText(value) {
9559
+ return value.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, REDACTED).replace(/\b[a-z][a-z0-9+.-]*:\/\/[^\s/@]+:[^\s/@]+@[^\s,;)]+/gi, REDACTED).replace(/\b(?:postgres(?:ql)?|mongodb(?:\+srv)?|redis(?:s)?|mysql|mariadb):\/\/[^\s/@:]+:[^\s/@]+@[^\s,;)]+/gi, REDACTED).replace(/\b(?:redis(?:s)?):\/\/:[^\s/@]+@[^\s,;)]+/gi, REDACTED).replace(
9560
+ /\b([A-Za-z_][A-Za-z0-9_]*(?:SECRET|TOKEN|PASSWORD|PRIVATE[_-]?KEY|API[_-]?KEY|APIKEY|SERVICE[_-]?ROLE|DATABASE[_-]?URL|CONNECTION[_-]?STRING)[A-Za-z0-9_]*)\s*=\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,
9561
+ `$1=${REDACTED}`
9562
+ ).replace(/\bBearer\s+[A-Za-z0-9._~+/=-]{8,}/gi, `Bearer ${REDACTED}`).replace(/(^|[^A-Za-z0-9])whsec_[A-Za-z0-9_]+/g, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9])sk_(live|test)_[A-Za-z0-9_]+/g, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9])pk_(live|test)_[A-Za-z0-9_]+/g, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{8,}/g, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9])gh[oprsu]_[A-Za-z0-9_]{16,}/g, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9])github_pat_[A-Za-z0-9_]{16,}/g, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9])(sb|supabase|vercel|stripe)_[A-Za-z0-9_]*\d[A-Za-z0-9_]{15,}/gi, `$1${REDACTED}`).replace(/(^|[^A-Za-z0-9_-])[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}(?=$|[^A-Za-z0-9_-])/g, `$1${REDACTED}`).replace(/\b[A-Za-z0-9+/]{32,}={0,2}\b/g, REDACTED);
9794
9563
  }
9795
9564
 
9796
9565
  // src/artifacts.ts
@@ -9801,35 +9570,6 @@ async function copyReportAssets(reportAssetsDir) {
9801
9570
  await (0, import_promises5.copyFile)((0, import_node_path9.join)(sourceDir, rel), (0, import_node_path9.join)(reportAssetsDir, rel));
9802
9571
  }
9803
9572
  }
9804
- function renderLaunchTasklist(plan) {
9805
- const lines = [
9806
- "# VibeRaven Launch Autopilot",
9807
- "",
9808
- `Recipe: ${plan.recipe.label}`,
9809
- `Goal: preview URL first, production gate second`,
9810
- `Mode: ${plan.permissionMode}`,
9811
- "",
9812
- `Safe repo tasks: ${plan.safeRepoTasks.length}`,
9813
- `Provider actions: ${plan.providerActions.length}`,
9814
- "",
9815
- "## Best Next Move",
9816
- "",
9817
- `**Type:** ${plan.nextAction.type}`,
9818
- `**Title:** ${plan.nextAction.title}`,
9819
- `**Detail:** ${plan.nextAction.detail}`,
9820
- `**Approval required:** ${plan.nextAction.approvalRequired}`
9821
- ];
9822
- if (plan.nextAction.openUrl) lines.push(`**Open:** ${plan.nextAction.openUrl}`);
9823
- if (plan.nextAction.command) lines.push(`**Command:** \`${plan.nextAction.command}\``);
9824
- if (plan.nextAction.manualFallback) lines.push(`**Manual fallback:** ${plan.nextAction.manualFallback}`);
9825
- lines.push("", "## Production Gate", "");
9826
- lines.push(`Status: ${plan.productionGate.status}`);
9827
- for (const reason of plan.productionGate.reasons) {
9828
- lines.push(`- ${reason}`);
9829
- }
9830
- return `${lines.join("\n")}
9831
- `;
9832
- }
9833
9573
  async function writeScanArtifacts(options) {
9834
9574
  const cwd = options.cwd ?? options.artifact.workspacePath;
9835
9575
  const dir = getProjectArtifactsDir(cwd);
@@ -9838,33 +9578,27 @@ async function writeScanArtifacts(options) {
9838
9578
  const gateResultPath = (0, import_node_path9.join)(dir, "gate-result.json");
9839
9579
  const contextMapPath = (0, import_node_path9.join)(dir, "context-map.json");
9840
9580
  const gapsDir = (0, import_node_path9.join)(dir, "gaps");
9581
+ const prpPath = (0, import_node_path9.join)(dir, "prp.json");
9841
9582
  const tasklistPath = (0, import_node_path9.join)(dir, "agent-tasklist.md");
9842
9583
  const summaryPath = (0, import_node_path9.join)(dir, "agent-summary.md");
9843
9584
  const playbookPath = (0, import_node_path9.join)(dir, "launch-playbook.md");
9844
- const launchPlanPath = (0, import_node_path9.join)(dir, "launch-plan.json");
9845
- const launchTasklistPath = (0, import_node_path9.join)(dir, "launch-tasklist.md");
9846
- const providerActionsPath = (0, import_node_path9.join)(dir, "provider-actions.json");
9847
9585
  const reportPath = (0, import_node_path9.join)(dir, "report.html");
9848
9586
  const reportAssetsDir = (0, import_node_path9.join)(dir, "report");
9849
9587
  await (0, import_promises5.mkdir)(gapsDir, { recursive: true });
9850
9588
  const safe = sanitizeArtifactForDisk(options.artifact);
9851
- const tasks = buildTaskList(safe);
9852
- const launchPlan = buildLaunchPlan({
9853
- artifact: safe,
9854
- tasks,
9855
- permissionMode: options.launchPermissionMode
9856
- });
9857
- const launchPlanJson = `${JSON.stringify(launchPlan, null, 2)}
9858
- `;
9859
- const launchTasklist = renderLaunchTasklist(launchPlan);
9860
- const providerActionsJson = `${JSON.stringify({ providerActions: launchPlan.providerActions }, null, 2)}
9861
- `;
9862
9589
  const json = `${JSON.stringify(safe, null, 2)}
9863
9590
  `;
9864
9591
  const summary = generateAgentSummary(safe);
9865
9592
  const playbook = generateLaunchPlaybook(safe);
9866
9593
  const html = generateReportHtml(safe);
9594
+ const tasks = buildTaskList(safe);
9867
9595
  const tasklist = buildTaskListMarkdown(tasks);
9596
+ const prp = `${JSON.stringify(buildProductionProtocolReport({
9597
+ artifact: safe,
9598
+ tasks,
9599
+ producerVersion: VERSION
9600
+ }), null, 2)}
9601
+ `;
9868
9602
  const gateResult = `${JSON.stringify(generateGateResult(safe), null, 2)}
9869
9603
  `;
9870
9604
  const contextMap = `${JSON.stringify(generateContextMap(safe), null, 2)}
@@ -9877,9 +9611,7 @@ async function writeScanArtifacts(options) {
9877
9611
  await (0, import_promises5.writeFile)((0, import_node_path9.join)(dir, "gaps", `${gap.content.id}.json`), `${JSON.stringify(gap.content, null, 2)}
9878
9612
  `, "utf-8");
9879
9613
  }
9880
- await (0, import_promises5.writeFile)(launchPlanPath, launchPlanJson, "utf-8");
9881
- await (0, import_promises5.writeFile)(launchTasklistPath, launchTasklist, "utf-8");
9882
- await (0, import_promises5.writeFile)(providerActionsPath, providerActionsJson, "utf-8");
9614
+ await (0, import_promises5.writeFile)(prpPath, prp, "utf-8");
9883
9615
  await (0, import_promises5.writeFile)(tasklistPath, tasklist, "utf-8");
9884
9616
  await (0, import_promises5.writeFile)(jsonPath, json, "utf-8");
9885
9617
  await (0, import_promises5.writeFile)(summaryPath, summary, "utf-8");
@@ -9891,16 +9623,12 @@ async function writeScanArtifacts(options) {
9891
9623
  gateResultPath,
9892
9624
  contextMapPath,
9893
9625
  gapsDir,
9626
+ prpPath,
9894
9627
  tasklistPath,
9895
9628
  summaryPath,
9896
9629
  playbookPath,
9897
- launchPlanPath,
9898
- launchTasklistPath,
9899
- providerActionsPath,
9900
9630
  reportPath,
9901
- reportAssetsDir,
9902
- tasks,
9903
- launchPlan
9631
+ reportAssetsDir
9904
9632
  };
9905
9633
  }
9906
9634
 
@@ -9931,6 +9659,28 @@ function renderJsonlEvents(result) {
9931
9659
  `;
9932
9660
  }
9933
9661
 
9662
+ // src/output/prpSummary.ts
9663
+ function renderProductionProtocolSummary(prp) {
9664
+ const nextAction = prp.nextActions[0];
9665
+ const lines = [
9666
+ "",
9667
+ "VibeRaven Production Protocol",
9668
+ "",
9669
+ `Profile: ${prp.profile}`,
9670
+ `Decision: ${prp.decision.status.toUpperCase()}`,
9671
+ "Canonical artifact: .viberaven/prp.json",
9672
+ ""
9673
+ ];
9674
+ if (nextAction) {
9675
+ lines.push("Next action:", nextAction.title, "");
9676
+ lines.push("Why:", prp.decision.summary);
9677
+ } else {
9678
+ lines.push("Next action:", "No production blockers found.", "");
9679
+ lines.push("Why:", prp.decision.summary);
9680
+ }
9681
+ return lines.join("\n");
9682
+ }
9683
+
9934
9684
  // src/commands/strictGate.ts
9935
9685
  function exitCodeForStrictGate(result, options = {}) {
9936
9686
  if (result.gate.status === "error") return 2;
@@ -10236,11 +9986,11 @@ function validateSafeFixRelativePath(path) {
10236
9986
  if (segments.some((segment) => segment === ".git" || segment === "node_modules")) {
10237
9987
  return { ok: false, reason: "Safe fix path targets a blocked directory." };
10238
9988
  }
10239
- const basename3 = segments.at(-1)?.toLowerCase() ?? "";
10240
- if (basename3 !== ".env.example" && (basename3 === ".env" || basename3.startsWith(".env."))) {
9989
+ const basename4 = segments.at(-1)?.toLowerCase() ?? "";
9990
+ if (basename4 !== ".env.example" && (basename4 === ".env" || basename4.startsWith(".env."))) {
10241
9991
  return { ok: false, reason: "Safe fix path targets an environment secret file." };
10242
9992
  }
10243
- if (isSecretLikeFilename(basename3)) {
9993
+ if (isSecretLikeFilename(basename4)) {
10244
9994
  return { ok: false, reason: "Safe fix path targets a secret-like file." };
10245
9995
  }
10246
9996
  if (!isAllowedSafeFixPath(normalized)) {
@@ -11080,7 +10830,7 @@ function isRecord6(value) {
11080
10830
  // src/tui/runInteractive.ts
11081
10831
  var import_node_path15 = require("node:path");
11082
10832
 
11083
- // ../../node_modules/@clack/core/dist/index.mjs
10833
+ // ../../../../node_modules/@clack/core/dist/index.mjs
11084
10834
  var import_sisteransi = __toESM(require_src(), 1);
11085
10835
  var import_node_process = require("node:process");
11086
10836
  var g = __toESM(require("node:readline"), 1);
@@ -11438,7 +11188,7 @@ var LD = class extends x {
11438
11188
  }
11439
11189
  };
11440
11190
 
11441
- // ../../node_modules/@clack/prompts/dist/index.mjs
11191
+ // ../../../../node_modules/@clack/prompts/dist/index.mjs
11442
11192
  var import_node_process2 = __toESM(require("node:process"), 1);
11443
11193
  var import_picocolors2 = __toESM(require_picocolors(), 1);
11444
11194
  var import_sisteransi2 = __toESM(require_src(), 1);
@@ -11664,9 +11414,6 @@ function buildAgentFixPrompt(artifact, gap) {
11664
11414
  ].join("\n");
11665
11415
  }
11666
11416
 
11667
- // src/version.ts
11668
- var VERSION = "1.0.6";
11669
-
11670
11417
  // src/commands/guide.ts
11671
11418
  var import_picocolors3 = __toESM(require_picocolors());
11672
11419
  function formatPasteTarget(step) {
@@ -11951,6 +11698,15 @@ Maps repo evidence to OWASP LLM Top 10 launch risks. Supports SAFECode-style dep
11951
11698
  var STACK_FRAMING = `Stack context for this repo: Next.js, Supabase, Vercel, VibeRaven.
11952
11699
  Do NOT deploy to Vercel or ship to production users without running \`${PUBLIC_AGENT_MODE_COMMAND}\`.
11953
11700
  Do NOT rely on manual production checklists when VibeRaven gate artifacts exist in \`.viberaven/\`.`;
11701
+ var PRODUCTION_PROTOCOL_RULES = `## VibeRaven Production Protocol
11702
+
11703
+ Before making deploy, auth, database, payment, API, or scaling changes:
11704
+
11705
+ 1. Read \`.viberaven/prp.json\`.
11706
+ 2. Follow \`.viberaven/mission-map.md\`.
11707
+ 3. Do not deploy if \`decision.status\` is \`blocked\`.
11708
+ 4. Fix \`nextActions\` in order.
11709
+ 5. Re-run \`${PUBLIC_AGENT_MODE_COMMAND}\`.`;
11954
11710
  var AGENT_NEGATIVE_CONSTRAINTS = `## Event-Triggered Production Verification
11955
11711
 
11956
11712
  Trigger: modifications to \`package.json\`, \`vercel.json\`, \`supabase/migrations/**/*\`, \`.env.example\`, auth/billing/webhook paths, or deploy workflow files.
@@ -11976,6 +11732,8 @@ var AGENT_RULES_BODY = `${AGENT_RULES_PREAMBLE}
11976
11732
 
11977
11733
  ${STACK_FRAMING}
11978
11734
 
11735
+ ${PRODUCTION_PROTOCOL_RULES}
11736
+
11979
11737
  ${AGENT_NEGATIVE_CONSTRAINTS}
11980
11738
 
11981
11739
  ## VibeRaven Production-Readiness Gate
@@ -12025,10 +11783,11 @@ var AGENT_CONTEXT_BODY = `${AGENT_RULES_PREAMBLE}
12025
11783
 
12026
11784
  After \`--agent-mode\`, read these artifacts in order:
12027
11785
 
12028
- 1. \`.viberaven/mission-map.md\`
12029
- 2. \`.viberaven/agent-tasklist.md\`
12030
- 3. \`.viberaven/gate-result.json\`
12031
- 4. \`.viberaven/context-map.json\``;
11786
+ 1. \`.viberaven/prp.json\`
11787
+ 2. \`.viberaven/mission-map.md\`
11788
+ 3. \`.viberaven/agent-tasklist.md\`
11789
+ 4. \`.viberaven/gate-result.json\`
11790
+ 5. \`.viberaven/context-map.json\``;
12032
11791
  var MISSION_MAP_BODY = `${AGENT_RULES_PREAMBLE}
12033
11792
 
12034
11793
  ## Mission Map loop
@@ -12372,7 +12131,7 @@ function getAgentRulesTargets(value) {
12372
12131
  }
12373
12132
 
12374
12133
  // src/commands/seedPackageJsonScripts.ts
12375
- var import_node_fs8 = require("node:fs");
12134
+ var import_node_fs7 = require("node:fs");
12376
12135
  var import_promises9 = require("node:fs/promises");
12377
12136
  var import_node_path13 = require("node:path");
12378
12137
  var VIBERAVEN_PACKAGE_JSON_SCRIPTS = {
@@ -12382,7 +12141,7 @@ var VIBERAVEN_PACKAGE_JSON_SCRIPTS = {
12382
12141
  };
12383
12142
  async function seedPackageJsonScripts(options) {
12384
12143
  const packageJsonPath = (0, import_node_path13.join)(options.cwd, "package.json");
12385
- if (!(0, import_node_fs8.existsSync)(packageJsonPath)) {
12144
+ if (!(0, import_node_fs7.existsSync)(packageJsonPath)) {
12386
12145
  return null;
12387
12146
  }
12388
12147
  const raw = await (0, import_promises9.readFile)(packageJsonPath, "utf-8");
@@ -12892,7 +12651,7 @@ async function runCondenseCommand(options) {
12892
12651
 
12893
12652
  // src/heal/apply.ts
12894
12653
  var import_promises13 = require("node:fs/promises");
12895
- var import_node_fs11 = require("node:fs");
12654
+ var import_node_fs10 = require("node:fs");
12896
12655
  var import_node_path20 = require("node:path");
12897
12656
 
12898
12657
  // src/heal/pathSafety.ts
@@ -12924,7 +12683,7 @@ function applyEmptyCatchRecipe(source) {
12924
12683
  }
12925
12684
 
12926
12685
  // src/heal/recipes/index.ts
12927
- var import_node_fs10 = require("node:fs");
12686
+ var import_node_fs9 = require("node:fs");
12928
12687
  var import_promises12 = require("node:fs/promises");
12929
12688
  var import_node_path19 = require("node:path");
12930
12689
 
@@ -13307,7 +13066,7 @@ function applyRateLimitRecipe(source, hasUpstash) {
13307
13066
  }
13308
13067
 
13309
13068
  // src/heal/recipes/eslintRestrictedImports.ts
13310
- var import_node_fs9 = require("node:fs");
13069
+ var import_node_fs8 = require("node:fs");
13311
13070
  var import_node_path18 = require("node:path");
13312
13071
  var VIBERAVEN_ESLINT_MARKER = "VibeRaven heal: eslint_restricted_imports";
13313
13072
  var RESTRICTED_IMPORTS_MESSAGE = `Restricted import. Run ${PUBLIC_AGENT_MODE_COMMAND} before substituting packages.`;
@@ -13338,7 +13097,7 @@ var ESLINT_CONFIG_CANDIDATES = [
13338
13097
  ];
13339
13098
  function detectEslintConfigFile(cwd) {
13340
13099
  for (const candidate of ESLINT_CONFIG_CANDIDATES) {
13341
- if ((0, import_node_fs9.existsSync)((0, import_node_path18.join)(cwd, candidate))) {
13100
+ if ((0, import_node_fs8.existsSync)((0, import_node_path18.join)(cwd, candidate))) {
13342
13101
  return candidate;
13343
13102
  }
13344
13103
  }
@@ -13513,13 +13272,13 @@ function defaultTargetFile(gapId) {
13513
13272
  return map[gapId];
13514
13273
  }
13515
13274
  async function readSourceOrEmpty(absolutePath) {
13516
- if (!(0, import_node_fs10.existsSync)(absolutePath)) return "";
13275
+ if (!(0, import_node_fs9.existsSync)(absolutePath)) return "";
13517
13276
  return (0, import_promises12.readFile)(absolutePath, "utf8");
13518
13277
  }
13519
13278
  async function detectUpstash(cwd) {
13520
13279
  try {
13521
13280
  const pkgPath = (0, import_node_path19.join)(cwd, "package.json");
13522
- if (!(0, import_node_fs10.existsSync)(pkgPath)) return false;
13281
+ if (!(0, import_node_fs9.existsSync)(pkgPath)) return false;
13523
13282
  const raw = await (0, import_promises12.readFile)(pkgPath, "utf8");
13524
13283
  const pkg = JSON.parse(raw);
13525
13284
  const deps = {
@@ -13586,7 +13345,7 @@ async function dispatchRecipeByGapId(gapId, cwd, explicitTarget) {
13586
13345
  if (gapId === "missing_csp_header") {
13587
13346
  let configFile = "next.config.js";
13588
13347
  let absolutePath = (0, import_node_path19.join)(cwd, configFile);
13589
- if (!(0, import_node_fs10.existsSync)(absolutePath)) {
13348
+ if (!(0, import_node_fs9.existsSync)(absolutePath)) {
13590
13349
  configFile = "next.config.mjs";
13591
13350
  absolutePath = (0, import_node_path19.join)(cwd, configFile);
13592
13351
  }
@@ -13702,7 +13461,7 @@ async function applyHeal(options) {
13702
13461
  await (0, import_promises13.mkdir)((0, import_node_path20.dirname)(absoluteTarget), { recursive: true });
13703
13462
  const healDir2 = (0, import_node_path20.join)(options.cwd, ".viberaven", "heal", id);
13704
13463
  await (0, import_promises13.mkdir)((0, import_node_path20.join)(healDir2, "before"), { recursive: true });
13705
- const beforeContent = (0, import_node_fs11.existsSync)(absoluteTarget) ? await (0, import_promises13.readFile)(absoluteTarget, "utf8") : "";
13464
+ const beforeContent = (0, import_node_fs10.existsSync)(absoluteTarget) ? await (0, import_promises13.readFile)(absoluteTarget, "utf8") : "";
13706
13465
  await (0, import_promises13.writeFile)((0, import_node_path20.join)(healDir2, "before", "target.txt"), beforeContent, "utf8");
13707
13466
  await (0, import_promises13.writeFile)(absoluteTarget, dispatched.output, "utf8");
13708
13467
  const patch2 = [
@@ -13973,7 +13732,7 @@ async function runHealCommand(options) {
13973
13732
 
13974
13733
  // src/stackRecommend.ts
13975
13734
  var import_promises17 = require("node:fs/promises");
13976
- var import_node_fs12 = require("node:fs");
13735
+ var import_node_fs11 = require("node:fs");
13977
13736
  var import_node_path23 = require("node:path");
13978
13737
  var DEFAULT_STACK = {
13979
13738
  frontend: "react",
@@ -13986,7 +13745,7 @@ var DEFAULT_STACK = {
13986
13745
  };
13987
13746
  async function recommendStack(cwd = process.cwd()) {
13988
13747
  const pkgPath = (0, import_node_path23.join)(cwd, "package.json");
13989
- if (!(0, import_node_fs12.existsSync)(pkgPath)) {
13748
+ if (!(0, import_node_fs11.existsSync)(pkgPath)) {
13990
13749
  return DEFAULT_STACK;
13991
13750
  }
13992
13751
  const pkg = JSON.parse(await (0, import_promises17.readFile)(pkgPath, "utf-8"));
@@ -14446,10 +14205,10 @@ function buildProviderActionBlock(task) {
14446
14205
  doneSignal: pa.doneSignal,
14447
14206
  verifyCommand: task.verifyCommand,
14448
14207
  mcpAlternative: task.mcpTool ?? pa.mcpAlternative ?? null,
14449
- actionClass: pa.actionClass,
14450
- approvalRequired: pa.approvalRequired,
14451
- manualFallback: pa.manualFallback,
14452
- copyValues: pa.copyValues
14208
+ actionClass: pa.actionClass ?? "manual_provider_step",
14209
+ approvalRequired: pa.approvalRequired ?? true,
14210
+ manualFallback: pa.manualFallback ?? pa.exactStep,
14211
+ copyValues: pa.copyValues ?? []
14453
14212
  }
14454
14213
  };
14455
14214
  }
@@ -14470,53 +14229,103 @@ function printNextActionBlock(block) {
14470
14229
  console.log(NEXT_ACTION_END);
14471
14230
  }
14472
14231
 
14473
- // src/output/launchActionBlock.ts
14474
- var LAUNCH_ACTION_START = "VIBERAVEN_LAUNCH_ACTION_START";
14475
- var LAUNCH_ACTION_END = "VIBERAVEN_LAUNCH_ACTION_END";
14476
- function renderLaunchSummary(plan) {
14477
- const lines = [
14478
- "",
14479
- "VibeRaven Launch Autopilot",
14480
- "",
14481
- `Recipe: ${plan.recipe.label}`,
14482
- "Goal: preview URL first, production gate second",
14483
- `Mode: ${plan.permissionMode}`
14232
+ // src/providerMcpBridge.ts
14233
+ var import_node_fs12 = require("node:fs");
14234
+ var import_node_os2 = require("node:os");
14235
+ var import_node_path25 = require("node:path");
14236
+ var UPGRADE_URL4 = "https://viberaven.dev/pricing";
14237
+ var FALLBACK_COMMAND = "npx -y viberaven audit --vercel-supabase --json";
14238
+ var SUPPORTED_PROVIDERS = /* @__PURE__ */ new Set(["supabase", "vercel"]);
14239
+ var configPathsOverride;
14240
+ function defaultMcpConfigPaths() {
14241
+ const home = (0, import_node_os2.homedir)();
14242
+ return [
14243
+ (0, import_node_path25.join)(home, ".config", "claude", "claude_desktop_config.json"),
14244
+ (0, import_node_path25.join)(home, ".cursor", "mcp.json"),
14245
+ (0, import_node_path25.join)(home, ".gemini", "antigravity", "mcp_config.json")
14484
14246
  ];
14485
- if (plan.usageLine) {
14486
- lines.push(`Scan usage: ${plan.usageLine}`);
14247
+ }
14248
+ function resolveConfigPaths() {
14249
+ return configPathsOverride ?? defaultMcpConfigPaths();
14250
+ }
14251
+ function parseMcpServers(raw) {
14252
+ if (!raw || typeof raw !== "object") {
14253
+ return void 0;
14487
14254
  }
14488
- lines.push(
14489
- "",
14490
- `Auto-close queue: ${plan.safeRepoTasks.length} safe repo task${plan.safeRepoTasks.length === 1 ? "" : "s"}`,
14491
- `Provider actions: ${plan.providerActions.length}`,
14492
- "",
14493
- "Best next move:",
14494
- plan.nextAction.title,
14495
- plan.nextAction.detail
14496
- );
14497
- if (plan.nextAction.openUrl) {
14498
- lines.push(`Open: ${plan.nextAction.openUrl}`);
14255
+ const obj = raw;
14256
+ if (obj.mcpServers && typeof obj.mcpServers === "object") {
14257
+ return obj.mcpServers;
14499
14258
  }
14500
- if (plan.nextAction.command) {
14501
- lines.push(`Command: ${plan.nextAction.command}`);
14259
+ if (obj.servers && typeof obj.servers === "object") {
14260
+ return obj.servers;
14502
14261
  }
14503
- lines.push(`Approval required: ${plan.nextAction.approvalRequired ? "yes" : "no"}`);
14504
- return lines.join("\n");
14262
+ return void 0;
14505
14263
  }
14506
- function printLaunchActionBlock(plan) {
14507
- console.log(LAUNCH_ACTION_START);
14508
- console.log(
14509
- JSON.stringify(
14510
- {
14511
- VIBERAVEN_LAUNCH_ACTION: plan.nextAction
14264
+ function findServerEntry(servers, provider2) {
14265
+ if (servers[provider2]) {
14266
+ return servers[provider2];
14267
+ }
14268
+ const key = Object.keys(servers).find((candidate) => candidate.toLowerCase() === provider2);
14269
+ return key ? servers[key] : void 0;
14270
+ }
14271
+ function findProviderMcpConfig(provider2, configPaths) {
14272
+ const paths = configPaths ?? resolveConfigPaths();
14273
+ for (const path of paths) {
14274
+ if (!(0, import_node_fs12.existsSync)(path)) {
14275
+ continue;
14276
+ }
14277
+ try {
14278
+ const raw = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
14279
+ const servers = parseMcpServers(raw);
14280
+ if (!servers) {
14281
+ continue;
14512
14282
  }
14513
- )
14514
- );
14515
- console.log(LAUNCH_ACTION_END);
14283
+ const entry = findServerEntry(servers, provider2);
14284
+ if (!entry || typeof entry !== "object") {
14285
+ continue;
14286
+ }
14287
+ const server = entry;
14288
+ return {
14289
+ command: typeof server.command === "string" ? server.command : void 0,
14290
+ args: Array.isArray(server.args) ? server.args.filter((arg) => typeof arg === "string") : void 0,
14291
+ url: typeof server.url === "string" ? server.url : void 0,
14292
+ source: path
14293
+ };
14294
+ } catch {
14295
+ continue;
14296
+ }
14297
+ }
14298
+ return void 0;
14299
+ }
14300
+ async function verifyProviderGap(options) {
14301
+ if (options.plan !== "pro") {
14302
+ return {
14303
+ verified: false,
14304
+ reason: "pro-required",
14305
+ upgradeUrl: UPGRADE_URL4
14306
+ };
14307
+ }
14308
+ const provider2 = options.provider.toLowerCase().trim();
14309
+ if (!SUPPORTED_PROVIDERS.has(provider2)) {
14310
+ return {
14311
+ verified: false,
14312
+ reason: "unsupported-provider"
14313
+ };
14314
+ }
14315
+ const mcpConfig = findProviderMcpConfig(provider2);
14316
+ if (!mcpConfig) {
14317
+ return {
14318
+ verified: false,
14319
+ mcpUnavailable: true,
14320
+ fallbackCommand: FALLBACK_COMMAND
14321
+ };
14322
+ }
14323
+ return {
14324
+ verified: false,
14325
+ mcpUnavailable: true,
14326
+ fallbackCommand: FALLBACK_COMMAND
14327
+ };
14516
14328
  }
14517
-
14518
- // src/launch/types.ts
14519
- var LAUNCH_PERMISSION_MODES = ["manual", "ask", "safe", "full"];
14520
14329
 
14521
14330
  // src/cli.ts
14522
14331
  function printHelp() {
@@ -14546,7 +14355,6 @@ Usage:
14546
14355
 
14547
14356
  viberaven --agent-mode [--json|--jsonl] [path]
14548
14357
  Agent-first scan; writes tasklist, gate-result, context-map, and per-gap JSON
14549
- Optional: --launch-mode manual|ask|safe|full (default: ask)
14550
14358
 
14551
14359
  viberaven --strict[=warning] [path]
14552
14360
  Fail when production gate is not clear; warning mode also fails on warnings
@@ -14683,13 +14491,6 @@ function shouldConsumeLeadingHyphenValue(command, key, value) {
14683
14491
  function hasFlag(flags, key) {
14684
14492
  return flags[key] === true || typeof flags[key] === "string";
14685
14493
  }
14686
- function resolveLaunchPermissionMode(flags) {
14687
- const value = flags["launch-mode"];
14688
- if (typeof value !== "string") {
14689
- return "ask";
14690
- }
14691
- return LAUNCH_PERMISSION_MODES.includes(value) ? value : "ask";
14692
- }
14693
14494
  async function guardEarlyVerifyScan(input) {
14694
14495
  if (input.flags["force-scan"] === true) {
14695
14496
  return void 0;
@@ -14698,7 +14499,7 @@ async function guardEarlyVerifyScan(input) {
14698
14499
  if (!verifyLike) {
14699
14500
  return void 0;
14700
14501
  }
14701
- const workspacePath = input.positional[0] ? (0, import_node_path25.join)(process.cwd(), input.positional[0]) : await resolveWorkspaceRoot(process.cwd());
14502
+ const workspacePath = input.positional[0] ? (0, import_node_path26.join)(process.cwd(), input.positional[0]) : await resolveWorkspaceRoot(process.cwd());
14702
14503
  const loopState = await loadLoopState(workspacePath);
14703
14504
  if (loopState.batchApplied <= 0) {
14704
14505
  return void 0;
@@ -14774,7 +14575,7 @@ async function cmdStatus(flags, positional) {
14774
14575
  console.log("Not signed in. Run: viberaven login");
14775
14576
  return 1;
14776
14577
  }
14777
- const startDir = positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd();
14578
+ const startDir = positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd();
14778
14579
  let artifact;
14779
14580
  try {
14780
14581
  artifact = await loadLastArtifact(startDir);
@@ -14928,7 +14729,7 @@ async function cmdWatch(flags) {
14928
14729
  }
14929
14730
  }
14930
14731
  async function runScanCommand(flags, positional, options) {
14931
- const workspacePath = positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : await resolveWorkspaceRoot(process.cwd());
14732
+ const workspacePath = positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : await resolveWorkspaceRoot(process.cwd());
14932
14733
  const apiBaseUrl = resolveApiBaseUrl(typeof flags["api-url"] === "string" ? flags["api-url"] : void 0);
14933
14734
  let accessToken;
14934
14735
  try {
@@ -14974,17 +14775,17 @@ async function runScanCommand(flags, positional, options) {
14974
14775
  return { exitCode: 1 };
14975
14776
  }
14976
14777
  const artifact = await enrichArtifactWithAccount(result.artifact, apiBaseUrl, accessToken);
14977
- const paths = await writeScanArtifacts({
14978
- artifact,
14979
- cwd: workspacePath,
14980
- launchPermissionMode: resolveLaunchPermissionMode(flags)
14981
- });
14778
+ const paths = await writeScanArtifacts({ artifact, cwd: workspacePath });
14982
14779
  if (flags.json && !options?.deferMachineOutput) {
14983
14780
  console.log(formatScanJsonStdout(artifact));
14984
14781
  return { exitCode: 0, artifacts: paths };
14985
14782
  }
14986
14783
  if (!options?.deferMachineOutput) {
14987
14784
  printScanSummary(artifact, paths);
14785
+ if (flags["agent-mode"]) {
14786
+ const prp = JSON.parse(await (0, import_promises19.readFile)(paths.prpPath, "utf8"));
14787
+ console.log(renderProductionProtocolSummary(prp));
14788
+ }
14988
14789
  }
14989
14790
  if (artifact.usage && !options?.deferMachineOutput) {
14990
14791
  console.log(formatUsageLine(artifact.usage));
@@ -14993,14 +14794,11 @@ async function runScanCommand(flags, positional, options) {
14993
14794
  const loopState = await loadLoopState(workspacePath);
14994
14795
  const openGapCount = artifact.gaps.length;
14995
14796
  const updatedState = resetBatch(loopState, openGapCount);
14996
- const tasks = paths.tasks;
14797
+ const tasks = buildTaskList(artifact);
14997
14798
  const plan = artifact.plan ?? "free";
14998
14799
  const block = buildNextActionBlock(tasks, updatedState, plan);
14999
14800
  printNextActionBlock(block);
15000
14801
  printProviderActionBlock(tasks);
15001
- const launchPlan = paths.launchPlan;
15002
- console.log(renderLaunchSummary(launchPlan));
15003
- printLaunchActionBlock(launchPlan);
15004
14802
  await saveLoopState(workspacePath, updatedState);
15005
14803
  }
15006
14804
  if (flags.open) {
@@ -15013,7 +14811,7 @@ async function runScanCommand(flags, positional, options) {
15013
14811
  return { exitCode: 0, artifacts: paths };
15014
14812
  }
15015
14813
  async function cmdReport(flags, positional) {
15016
- const startDir = positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd();
14814
+ const startDir = positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd();
15017
14815
  try {
15018
14816
  const paths = await refreshReportFromDisk(startDir);
15019
14817
  console.log(`Report refreshed: ${paths.reportPath}`);
@@ -15035,7 +14833,7 @@ async function cmdReport(flags, positional) {
15035
14833
  }
15036
14834
  }
15037
14835
  async function cmdPrompt(flags, positional) {
15038
- const startDir = positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd();
14836
+ const startDir = positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd();
15039
14837
  let artifact;
15040
14838
  try {
15041
14839
  artifact = await loadLastArtifact(startDir);
@@ -15133,7 +14931,7 @@ async function main() {
15133
14931
  const wantsJsonl = hasFlag(flags, "jsonl");
15134
14932
  const wantsStrict = hasFlag(flags, "strict");
15135
14933
  if (flags.condense) {
15136
- const cwd = positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd();
14934
+ const cwd = positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd();
15137
14935
  const result = await runCondenseCommand({ cwd });
15138
14936
  console.log(`VibeRaven context map refreshed: ${result.contextMapPath}`);
15139
14937
  return 0;
@@ -15197,7 +14995,7 @@ async function main() {
15197
14995
  case "next":
15198
14996
  return runNextCommand({
15199
14997
  json: Boolean(flags.json),
15200
- cwd: positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd()
14998
+ cwd: positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd()
15201
14999
  });
15202
15000
  case "guide": {
15203
15001
  const provider2 = positional[0];
@@ -15235,7 +15033,7 @@ async function main() {
15235
15033
  case "provider-verify":
15236
15034
  return cmdProviderVerify(flags, positional);
15237
15035
  case "init": {
15238
- const cwd = positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd();
15036
+ const cwd = positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd();
15239
15037
  const agents = typeof flags.agents === "string" ? flags.agents : void 0;
15240
15038
  return runInitCommand({
15241
15039
  cwd,
@@ -15249,7 +15047,7 @@ async function main() {
15249
15047
  return 1;
15250
15048
  }
15251
15049
  return runDoctorAgentsCommand({
15252
- cwd: positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd()
15050
+ cwd: positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd()
15253
15051
  });
15254
15052
  case "validate-npm-package":
15255
15053
  return runValidateNpmPackageCommand({
@@ -15262,7 +15060,7 @@ async function main() {
15262
15060
  return 1;
15263
15061
  }
15264
15062
  return runAuditCommand({
15265
- cwd: positional[0] ? (0, import_node_path25.join)(process.cwd(), positional[0]) : process.cwd(),
15063
+ cwd: positional[0] ? (0, import_node_path26.join)(process.cwd(), positional[0]) : process.cwd(),
15266
15064
  json: Boolean(flags.json)
15267
15065
  });
15268
15066
  default:
@@ -15288,7 +15086,6 @@ if (require.main === module) {
15288
15086
  parseArgs,
15289
15087
  printHelp,
15290
15088
  resolveDefaultEntrypointMode,
15291
- resolveLaunchPermissionMode,
15292
15089
  runScanCommand
15293
15090
  });
15294
15091
  //# sourceMappingURL=cli.js.map