@viberaven/cli 1.2.0 → 1.2.1

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
@@ -394,8 +394,6 @@ var init_backendClient = __esm({
394
394
  this.status = status;
395
395
  this.upgradeUrl = upgradeUrl;
396
396
  }
397
- status;
398
- upgradeUrl;
399
397
  };
400
398
  }
401
399
  });
@@ -2222,20 +2220,20 @@ function mapEvidenceSourceToLegacyEvidenceClass(source, status) {
2222
2220
  }
2223
2221
  return "mcp-verifier";
2224
2222
  }
2225
- function isProviderLayerCheck(check2) {
2226
- return check2.evidenceSource === "provider" || check2.evidenceSource === "mcp";
2223
+ function isProviderLayerCheck(check) {
2224
+ return check.evidenceSource === "provider" || check.evidenceSource === "mcp";
2227
2225
  }
2228
- function isRepoLayerCheck(check2) {
2229
- return check2.evidenceSource === "repo";
2226
+ function isRepoLayerCheck(check) {
2227
+ return check.evidenceSource === "repo";
2230
2228
  }
2231
2229
  function computeLayerReadinessPercent(checks, layer) {
2232
2230
  const filtered = checks.filter(
2233
- (check2) => layer === "repo" ? isRepoLayerCheck(check2) : isProviderLayerCheck(check2)
2231
+ (check) => layer === "repo" ? isRepoLayerCheck(check) : isProviderLayerCheck(check)
2234
2232
  );
2235
2233
  if (filtered.length === 0) {
2236
2234
  return 100;
2237
2235
  }
2238
- const verified = filtered.filter((check2) => check2.status === "verified").length;
2236
+ const verified = filtered.filter((check) => check.status === "verified").length;
2239
2237
  return Math.round(verified / filtered.length * 100);
2240
2238
  }
2241
2239
  function aggregateReadinessPercents(providerResults) {
@@ -2274,7 +2272,7 @@ function mergeVerificationIntoMissionGraph(graph, layer) {
2274
2272
  if (!mission) {
2275
2273
  continue;
2276
2274
  }
2277
- if (mission.checks.some((check2) => check2.verificationCheckId === layerCheck.id || check2.id === missionRowId(layerCheck.id))) {
2275
+ if (mission.checks.some((check) => check.verificationCheckId === layerCheck.id || check.id === missionRowId(layerCheck.id))) {
2278
2276
  continue;
2279
2277
  }
2280
2278
  mission.checks.push(verificationCheckToMissionCheck(layerCheck, mission));
@@ -2365,7 +2363,7 @@ function readinessPercentForRepoChecks(checks) {
2365
2363
  if (repoChecks.length === 0) {
2366
2364
  return 100;
2367
2365
  }
2368
- const verified = repoChecks.filter((check2) => isVerifiedMissionCheck(check2)).length;
2366
+ const verified = repoChecks.filter((check) => isVerifiedMissionCheck(check)).length;
2369
2367
  return Math.round(verified / repoChecks.length * 100);
2370
2368
  }
2371
2369
  function readinessPercentForProviderChecks(checks) {
@@ -2373,29 +2371,29 @@ function readinessPercentForProviderChecks(checks) {
2373
2371
  if (providerChecks.length === 0) {
2374
2372
  return 100;
2375
2373
  }
2376
- const verified = providerChecks.filter((check2) => isVerifiedMissionCheck(check2)).length;
2374
+ const verified = providerChecks.filter((check) => isVerifiedMissionCheck(check)).length;
2377
2375
  return Math.round(verified / providerChecks.length * 100);
2378
2376
  }
2379
- function isRepoLayerMissionCheck(check2) {
2380
- if (check2.evidenceSource === "provider" || check2.evidenceSource === "mcp" || check2.evidenceSource === "manual") {
2377
+ function isRepoLayerMissionCheck(check) {
2378
+ if (check.evidenceSource === "provider" || check.evidenceSource === "mcp" || check.evidenceSource === "manual") {
2381
2379
  return false;
2382
2380
  }
2383
- if (check2.evidenceSource === "repo") {
2381
+ if (check.evidenceSource === "repo") {
2384
2382
  return true;
2385
2383
  }
2386
- return check2.evidenceClass === "repo-verified" || check2.evidenceClass === "missing-repo-fix";
2384
+ return check.evidenceClass === "repo-verified" || check.evidenceClass === "missing-repo-fix";
2387
2385
  }
2388
- function isProviderLayerMissionCheck(check2) {
2389
- if (check2.evidenceSource === "provider" || check2.evidenceSource === "mcp") {
2386
+ function isProviderLayerMissionCheck(check) {
2387
+ if (check.evidenceSource === "provider" || check.evidenceSource === "mcp") {
2390
2388
  return true;
2391
2389
  }
2392
- return check2.evidenceClass === "mcp-verifier";
2390
+ return check.evidenceClass === "mcp-verifier";
2393
2391
  }
2394
- function isVerifiedMissionCheck(check2) {
2395
- if (check2.verificationStatus) {
2396
- return check2.verificationStatus === "verified";
2392
+ function isVerifiedMissionCheck(check) {
2393
+ if (check.verificationStatus) {
2394
+ return check.verificationStatus === "verified";
2397
2395
  }
2398
- return check2.status === "passed" || check2.status === "user-confirmed";
2396
+ return check.status === "passed" || check.status === "user-confirmed";
2399
2397
  }
2400
2398
  function rebuildAreas(providerMissions) {
2401
2399
  const byArea = /* @__PURE__ */ new Map();
@@ -2424,7 +2422,7 @@ function rebuildAreas(providerMissions) {
2424
2422
  const repoReadinessPercent = percentVerified(repoChecks);
2425
2423
  const providerReadinessPercent = percentVerified(providerChecks);
2426
2424
  const criticalCount = missions.flatMap((m2) => m2.checks).filter(
2427
- (check2) => isProviderLayerMissionCheck(check2) && (check2.verificationStatus === "missing" || check2.status === "missing" || check2.status === "failed")
2425
+ (check) => isProviderLayerMissionCheck(check) && (check.verificationStatus === "missing" || check.status === "missing" || check.status === "failed")
2428
2426
  ).length;
2429
2427
  return {
2430
2428
  key,
@@ -2441,7 +2439,7 @@ function percentVerified(checks) {
2441
2439
  if (checks.length === 0) {
2442
2440
  return 100;
2443
2441
  }
2444
- const verified = checks.filter((check2) => isVerifiedMissionCheck(check2)).length;
2442
+ const verified = checks.filter((check) => isVerifiedMissionCheck(check)).length;
2445
2443
  return Math.round(verified / checks.length * 100);
2446
2444
  }
2447
2445
  var PROVIDER_WIRING_KEY;
@@ -2504,7 +2502,7 @@ function toProviderMission(summary) {
2504
2502
  promptSubject: summary.promptSubject,
2505
2503
  readinessPercent: summary.readinessPercent,
2506
2504
  repoReadinessPercent: summary.readinessPercent,
2507
- providerReadinessPercent: checks.some((check2) => check2.evidenceClass === "mcp-verifier") ? 0 : 100,
2505
+ providerReadinessPercent: checks.some((check) => check.evidenceClass === "mcp-verifier") ? 0 : 100,
2508
2506
  checks
2509
2507
  };
2510
2508
  }
@@ -2549,7 +2547,7 @@ function overlaySifgLeaks(providerMissions, graph) {
2549
2547
  const providerCheckIds = new Map(
2550
2548
  providerMissions.map((mission) => [
2551
2549
  mission.key,
2552
- new Set(mission.checks.map((check2) => check2.id))
2550
+ new Set(mission.checks.map((check) => check.id))
2553
2551
  ])
2554
2552
  );
2555
2553
  for (const leak of graph.leaks) {
@@ -2568,9 +2566,9 @@ function overlaySifgLeaks(providerMissions, graph) {
2568
2566
  continue;
2569
2567
  }
2570
2568
  const usedCheckIds = providerCheckIds.get(mission.key) ?? /* @__PURE__ */ new Set();
2571
- const check2 = toSifgMissionCheck(mission, pipeline, pipelineId, leaks, usedCheckIds);
2572
- mission.checks.push(check2);
2573
- usedCheckIds.add(check2.id);
2569
+ const check = toSifgMissionCheck(mission, pipeline, pipelineId, leaks, usedCheckIds);
2570
+ mission.checks.push(check);
2571
+ usedCheckIds.add(check.id);
2574
2572
  providerCheckIds.set(mission.key, usedCheckIds);
2575
2573
  }
2576
2574
  for (const mission of providerMissions) {
@@ -2621,11 +2619,11 @@ function stableSifgSuffix(id) {
2621
2619
  }
2622
2620
  function readinessPercentForChecks(checks) {
2623
2621
  const actionableChecks = checks.filter(isActionableCheck);
2624
- const passed = actionableChecks.filter((check2) => check2.status === "passed").length;
2622
+ const passed = actionableChecks.filter((check) => check.status === "passed").length;
2625
2623
  return Math.round(passed / Math.max(actionableChecks.length, 1) * 100);
2626
2624
  }
2627
- function isActionableCheck(check2) {
2628
- return check2.evidenceClass !== "manual-dashboard" && check2.evidenceClass !== "mcp-verifier";
2625
+ function isActionableCheck(check) {
2626
+ return check.evidenceClass !== "manual-dashboard" && check.evidenceClass !== "mcp-verifier";
2629
2627
  }
2630
2628
  function buildAreas(providerMissions) {
2631
2629
  const byArea = /* @__PURE__ */ new Map();
@@ -2636,15 +2634,15 @@ function buildAreas(providerMissions) {
2636
2634
  }
2637
2635
  return [...byArea.entries()].map(([key, missions]) => {
2638
2636
  const actionableChecks = missions.flatMap((mission) => mission.checks).filter(isActionableCheck);
2639
- const passed = actionableChecks.filter((check2) => check2.status === "passed").length;
2640
- const missing = actionableChecks.filter((check2) => check2.status === "missing" || check2.status === "failed").length;
2637
+ const passed = actionableChecks.filter((check) => check.status === "passed").length;
2638
+ const missing = actionableChecks.filter((check) => check.status === "missing" || check.status === "failed").length;
2641
2639
  return {
2642
2640
  key,
2643
2641
  label: AREA_LABELS[key],
2644
2642
  readinessPercent: Math.round(passed / Math.max(actionableChecks.length, 1) * 100),
2645
2643
  repoReadinessPercent: Math.round(passed / Math.max(actionableChecks.length, 1) * 100),
2646
2644
  providerReadinessPercent: missions.some(
2647
- (mission) => mission.checks.some((check2) => check2.evidenceClass === "mcp-verifier")
2645
+ (mission) => mission.checks.some((check) => check.evidenceClass === "mcp-verifier")
2648
2646
  ) ? 0 : 100,
2649
2647
  criticalCount: missing,
2650
2648
  providerMissions: missions
@@ -7784,9 +7782,9 @@ function runVerifier(verifier, ctx) {
7784
7782
  }
7785
7783
  const connectionState = verifier.connectStatus(ctx);
7786
7784
  const rawChecks = verifier.runChecks(ctx);
7787
- const checks = rawChecks.map((check2) => ({
7788
- ...check2,
7789
- status: coerceProviderVerificationStatus(check2.status, connectionState)
7785
+ const checks = rawChecks.map((check) => ({
7786
+ ...check,
7787
+ status: coerceProviderVerificationStatus(check.status, connectionState)
7790
7788
  }));
7791
7789
  const diffs = verifier.buildDiffs(ctx);
7792
7790
  return {
@@ -8639,24 +8637,24 @@ var init_planLimits = __esm({
8639
8637
  });
8640
8638
 
8641
8639
  // src/playbooks/checkMap.ts
8642
- function mapCheckToPlaybook(check2) {
8643
- if (CHECK_TO_PLAYBOOK[check2.id]) {
8644
- return CHECK_TO_PLAYBOOK[check2.id];
8640
+ function mapCheckToPlaybook(check) {
8641
+ if (CHECK_TO_PLAYBOOK[check.id]) {
8642
+ return CHECK_TO_PLAYBOOK[check.id];
8645
8643
  }
8646
- const providerKey = check2.providerKey.toLowerCase();
8647
- if (providerKey.includes("vercel") || check2.area === "deployment") {
8644
+ const providerKey = check.providerKey.toLowerCase();
8645
+ if (providerKey.includes("vercel") || check.area === "deployment") {
8648
8646
  return "vercel";
8649
8647
  }
8650
- if (providerKey.includes("stripe") || check2.area === "payments") {
8648
+ if (providerKey.includes("stripe") || check.area === "payments") {
8651
8649
  return "stripe";
8652
8650
  }
8653
- if (providerKey.includes("supabase") && check2.area === "auth") {
8651
+ if (providerKey.includes("supabase") && check.area === "auth") {
8654
8652
  return "auth-supabase";
8655
8653
  }
8656
- if (providerKey.includes("supabase") || check2.area === "database") {
8654
+ if (providerKey.includes("supabase") || check.area === "database") {
8657
8655
  return "supabase";
8658
8656
  }
8659
- if (check2.area === "auth") {
8657
+ if (check.area === "auth") {
8660
8658
  return "auth-supabase";
8661
8659
  }
8662
8660
  return "vercel";
@@ -8836,21 +8834,21 @@ var init_loadPlaybook = __esm({
8836
8834
  });
8837
8835
 
8838
8836
  // src/playbooks/manualChecks.ts
8839
- function isManualProviderCheck(check2) {
8840
- return check2.evidenceClass === "manual-dashboard" || check2.evidenceClass === "mcp-verifier" || check2.evidenceSource === "provider" || check2.evidenceSource === "mcp" || check2.status === "needs-connection" || check2.status === "unknown";
8837
+ function isManualProviderCheck(check) {
8838
+ return check.evidenceClass === "manual-dashboard" || check.evidenceClass === "mcp-verifier" || check.evidenceSource === "provider" || check.evidenceSource === "mcp" || check.status === "needs-connection" || check.status === "unknown";
8841
8839
  }
8842
8840
  function collectManualChecks(artifact) {
8843
8841
  const refs = [];
8844
8842
  for (const area of artifact.missionGraph.areas ?? []) {
8845
8843
  for (const mission of area.providerMissions) {
8846
- for (const check2 of mission.checks) {
8847
- if (!isManualProviderCheck(check2)) {
8844
+ for (const check of mission.checks) {
8845
+ if (!isManualProviderCheck(check)) {
8848
8846
  continue;
8849
8847
  }
8850
8848
  refs.push({
8851
8849
  areaLabel: area.label,
8852
8850
  providerLabel: mission.providerLabel,
8853
- check: check2,
8851
+ check,
8854
8852
  mapCategory: area.key
8855
8853
  });
8856
8854
  }
@@ -9125,8 +9123,8 @@ function generateAgentSummary(artifact) {
9125
9123
  const manualChecks = (artifact.missionGraph.areas ?? []).flatMap(
9126
9124
  (area) => area.providerMissions.flatMap(
9127
9125
  (mission) => mission.checks.filter(
9128
- (check2) => check2.evidenceClass === "manual-dashboard" || check2.evidenceClass === "mcp-verifier" || check2.evidenceSource === "provider" || check2.evidenceSource === "mcp" || check2.status === "needs-connection" || check2.status === "unknown"
9129
- ).map((check2) => ({ area: area.label, provider: mission.providerLabel, check: check2 }))
9126
+ (check) => check.evidenceClass === "manual-dashboard" || check.evidenceClass === "mcp-verifier" || check.evidenceSource === "provider" || check.evidenceSource === "mcp" || check.status === "needs-connection" || check.status === "unknown"
9127
+ ).map((check) => ({ area: area.label, provider: mission.providerLabel, check }))
9130
9128
  )
9131
9129
  );
9132
9130
  lines.push("");
@@ -10469,9 +10467,9 @@ var init_clipboard = __esm({
10469
10467
  }
10470
10468
  });
10471
10469
 
10472
- // ../../node_modules/picocolors/picocolors.js
10470
+ // node_modules/picocolors/picocolors.js
10473
10471
  var require_picocolors = __commonJS({
10474
- "../../node_modules/picocolors/picocolors.js"(exports2, module2) {
10472
+ "node_modules/picocolors/picocolors.js"(exports2, module2) {
10475
10473
  var p2 = process || {};
10476
10474
  var argv = p2.argv || [];
10477
10475
  var env = p2.env || {};
@@ -10550,9 +10548,9 @@ function missionMatchesProvider(mission, provider2) {
10550
10548
  return normalizeProviderToken2(mission.provider || mission.providerLabel || mission.key) === current || normalizeProviderToken2(mission.providerLabel || mission.provider || mission.key) === current;
10551
10549
  }
10552
10550
  function missionEvidenceScore(mission) {
10553
- const repoVerified = mission.checks.filter((check2) => check2.evidenceClass === "repo-verified" || check2.status === "passed").length;
10551
+ const repoVerified = mission.checks.filter((check) => check.evidenceClass === "repo-verified" || check.status === "passed").length;
10554
10552
  const missing = mission.checks.filter(
10555
- (check2) => check2.evidenceClass === "missing-repo-fix" || check2.status === "missing" || check2.status === "failed"
10553
+ (check) => check.evidenceClass === "missing-repo-fix" || check.status === "missing" || check.status === "failed"
10556
10554
  ).length;
10557
10555
  return repoVerified * 100 + (mission.readinessPercent ?? 0) - missing;
10558
10556
  }
@@ -10572,7 +10570,7 @@ function openChecksForMission(mission) {
10572
10570
  return 0;
10573
10571
  }
10574
10572
  return mission.checks.filter(
10575
- (check2) => check2.status === "missing" || check2.status === "failed" || check2.status === "needs-connection"
10573
+ (check) => check.status === "missing" || check.status === "failed" || check.status === "needs-connection"
10576
10574
  ).length;
10577
10575
  }
10578
10576
  var init_missionSelection = __esm({
@@ -10609,7 +10607,7 @@ function manualActionCheckCount(artifact) {
10609
10607
  return (artifact.missionGraph.areas ?? []).reduce((areaTotal, area) => {
10610
10608
  return areaTotal + area.providerMissions.reduce((missionTotal, mission) => {
10611
10609
  return missionTotal + mission.checks.filter(
10612
- (check2) => check2.evidenceClass === "manual-dashboard" || check2.evidenceClass === "mcp-verifier" || check2.evidenceSource === "provider" || check2.evidenceSource === "mcp" || check2.status === "needs-connection" || check2.status === "unknown"
10610
+ (check) => check.evidenceClass === "manual-dashboard" || check.evidenceClass === "mcp-verifier" || check.evidenceSource === "provider" || check.evidenceSource === "mcp" || check.status === "needs-connection" || check.status === "unknown"
10613
10611
  ).length;
10614
10612
  }, 0);
10615
10613
  }, 0);
@@ -11647,9 +11645,9 @@ var init_runnerConnect = __esm({
11647
11645
  }
11648
11646
  });
11649
11647
 
11650
- // ../../node_modules/sisteransi/src/index.js
11648
+ // node_modules/sisteransi/src/index.js
11651
11649
  var require_src = __commonJS({
11652
- "../../node_modules/sisteransi/src/index.js"(exports2, module2) {
11650
+ "node_modules/sisteransi/src/index.js"(exports2, module2) {
11653
11651
  "use strict";
11654
11652
  var ESC = "\x1B";
11655
11653
  var CSI = `${ESC}[`;
@@ -11703,7 +11701,7 @@ var require_src = __commonJS({
11703
11701
  }
11704
11702
  });
11705
11703
 
11706
- // ../../node_modules/@clack/core/dist/index.mjs
11704
+ // node_modules/@clack/core/dist/index.mjs
11707
11705
  function DD({ onlyFirst: e2 = false } = {}) {
11708
11706
  const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
11709
11707
  return new RegExp(t, e2 ? void 0 : "g");
@@ -11815,7 +11813,7 @@ function fD({ input: e2 = import_node_process.stdin, output: u2 = import_node_pr
11815
11813
  }
11816
11814
  var import_sisteransi, import_node_process, g, import_node_readline, import_node_stream, uD, W, tD, eD, FD, sD, w, N, I, R, C, iD, rD, ED, d, oD, y, V, nD, G, _, z, K, aD, k, hD, lD, xD, B, AD, S, gD, vD, h, x, A, OD, PD, J, LD;
11817
11815
  var init_dist = __esm({
11818
- "../../node_modules/@clack/core/dist/index.mjs"() {
11816
+ "node_modules/@clack/core/dist/index.mjs"() {
11819
11817
  import_sisteransi = __toESM(require_src(), 1);
11820
11818
  import_node_process = require("node:process");
11821
11819
  g = __toESM(require("node:readline"), 1);
@@ -11941,7 +11939,7 @@ var init_dist = __esm({
11941
11939
  xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
11942
11940
  B = { actions: new Set(xD), aliases: /* @__PURE__ */ new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["", "cancel"], ["escape", "cancel"]]) };
11943
11941
  AD = globalThis.process.platform.startsWith("win");
11944
- S = /* @__PURE__ */ Symbol("clack:cancel");
11942
+ S = Symbol("clack:cancel");
11945
11943
  gD = Object.defineProperty;
11946
11944
  vD = (e2, u2, t) => u2 in e2 ? gD(e2, u2, { enumerable: true, configurable: true, writable: true, value: t }) : e2[u2] = t;
11947
11945
  h = (e2, u2, t) => (vD(e2, typeof u2 != "symbol" ? u2 + "" : u2, t), t);
@@ -12065,13 +12063,13 @@ var init_dist = __esm({
12065
12063
  }
12066
12064
  });
12067
12065
 
12068
- // ../../node_modules/@clack/prompts/dist/index.mjs
12066
+ // node_modules/@clack/prompts/dist/index.mjs
12069
12067
  function ce() {
12070
12068
  return import_node_process2.default.platform !== "win32" ? import_node_process2.default.env.TERM !== "linux" : !!import_node_process2.default.env.CI || !!import_node_process2.default.env.WT_SESSION || !!import_node_process2.default.env.TERMINUS_SUBLIME || import_node_process2.default.env.ConEmuTask === "{cmd::Cmder}" || import_node_process2.default.env.TERM_PROGRAM === "Terminus-Sublime" || import_node_process2.default.env.TERM_PROGRAM === "vscode" || import_node_process2.default.env.TERM === "xterm-256color" || import_node_process2.default.env.TERM === "alacritty" || import_node_process2.default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
12071
12069
  }
12072
12070
  var import_node_process2, import_picocolors2, import_sisteransi2, V2, u, le, L2, W2, C2, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2, G2, ve, xe, Ie, Se, M2, J2, Y2;
12073
12071
  var init_dist2 = __esm({
12074
- "../../node_modules/@clack/prompts/dist/index.mjs"() {
12072
+ "node_modules/@clack/prompts/dist/index.mjs"() {
12075
12073
  init_dist();
12076
12074
  init_dist();
12077
12075
  import_node_process2 = __toESM(require("node:process"), 1);
@@ -12306,7 +12304,7 @@ var VERSION;
12306
12304
  var init_version = __esm({
12307
12305
  "src/version.ts"() {
12308
12306
  "use strict";
12309
- VERSION = "1.2.0";
12307
+ VERSION = "1.2.1";
12310
12308
  }
12311
12309
  });
12312
12310
 
@@ -12631,7 +12629,7 @@ function buildVercelSupabaseAudit(input) {
12631
12629
  buildPoolerCheck(input.files),
12632
12630
  buildServiceRoleCheck(input.files)
12633
12631
  ];
12634
- const status = checks.every((check2) => check2.status === "pass") ? "pass" : "needs_work";
12632
+ const status = checks.every((check) => check.status === "pass") ? "pass" : "needs_work";
12635
12633
  return {
12636
12634
  status,
12637
12635
  summary: status === "pass" ? "Repo evidence passes the local Vercel/Supabase audit checks." : "Repo evidence needs work before claiming Vercel/Supabase production readiness.",
@@ -12718,13 +12716,13 @@ function renderVercelSupabaseAudit(result) {
12718
12716
  "Boundary: this audit uses local repo evidence only. Provider dashboard settings still need manual verification or read-only provider MCP confirmation.",
12719
12717
  ""
12720
12718
  ];
12721
- for (const check2 of result.checks) {
12722
- lines.push(`${check2.status === "pass" ? "PASS" : "NEEDS_WORK"} ${check2.id}`);
12723
- lines.push(` ${check2.summary}`);
12724
- for (const evidence of check2.evidence.slice(0, 5)) {
12719
+ for (const check of result.checks) {
12720
+ lines.push(`${check.status === "pass" ? "PASS" : "NEEDS_WORK"} ${check.id}`);
12721
+ lines.push(` ${check.summary}`);
12722
+ for (const evidence of check.evidence.slice(0, 5)) {
12725
12723
  lines.push(` - ${evidence}`);
12726
12724
  }
12727
- if (check2.evidence.length === 0) {
12725
+ if (check.evidence.length === 0) {
12728
12726
  lines.push(" - No local evidence found.");
12729
12727
  }
12730
12728
  lines.push("");
@@ -15167,15 +15165,15 @@ async function checkAgentInjection(cwd) {
15167
15165
  }
15168
15166
  }
15169
15167
  return {
15170
- ok: checks.every((check2) => check2.status === "pass"),
15168
+ ok: checks.every((check) => check.status === "pass"),
15171
15169
  checks
15172
15170
  };
15173
15171
  }
15174
15172
  function formatDoctorAgentsReport(report) {
15175
15173
  const lines = ["VibeRaven agent injection doctor", ""];
15176
- for (const check2 of report.checks) {
15177
- const icon = check2.status === "pass" ? "\u2713" : "\u2717";
15178
- lines.push(`${icon} ${check2.message}`);
15174
+ for (const check of report.checks) {
15175
+ const icon = check.status === "pass" ? "\u2713" : "\u2717";
15176
+ lines.push(`${icon} ${check.message}`);
15179
15177
  }
15180
15178
  lines.push("");
15181
15179
  lines.push(report.ok ? "All agent injection checks passed." : "Agent injection checks failed.");
@@ -15641,288 +15639,106 @@ var init_verifyAction = __esm({
15641
15639
  }
15642
15640
  });
15643
15641
 
15644
- // src/output/nextActionBlock.ts
15645
- function buildNextActionBlock(tasks, loopState, plan) {
15646
- const batchSize = plan === "pro" ? 10 : 3;
15647
- const batchApplied = loopState.batchApplied;
15648
- const remainingInBatch = batchSize - batchApplied;
15649
- const scanNow = batchApplied >= batchSize;
15650
- const stalled = loopState.stalledScans >= 2;
15651
- const stalledScans = loopState.stalledScans;
15652
- const base = { batchSize, batchApplied, remainingInBatch, scanNow, stalled, stalledScans };
15653
- if (stalled) {
15654
- const stallReason = resolveStallReason(tasks);
15655
- return {
15656
- ...base,
15657
- type: "stalled",
15658
- title: "Loop stalled - no gap reduction after 2+ consecutive scans",
15659
- agentInstruction: "Stop the scan loop. Explain the blocker plainly, then either guide the provider/user action or report that no safe repo-code recipe is available.",
15660
- executionPlan: [
15661
- { kind: "stop", note: "Do not keep spending scans while the loop is stalled." }
15662
- ],
15663
- requiresUserAction: true,
15664
- stallReason
15665
- };
15666
- }
15667
- if (scanNow) {
15668
- return {
15669
- ...base,
15670
- type: "verify",
15671
- title: "Batch complete - run verify to rescan before next batch",
15672
- agentInstruction: "Run verify now, read the refreshed VibeRaven artifacts, then continue with the next safe repo fix or provider step. Do not stop at a summary.",
15673
- executionPlan: [
15674
- { kind: "verify", command: "viberaven_verify" },
15675
- { kind: "continue-loop", note: "After verify, continue until the gate is clear or a provider/user blocker remains." }
15676
- ],
15677
- mcpTool: "viberaven_verify",
15678
- mcpArgs: {},
15679
- requiresUserAction: false
15680
- };
15681
- }
15682
- const repoCodeTask = tasks.find((task) => task.fixType === "repo-code" && !task.requiresUserAction);
15683
- if (repoCodeTask) {
15684
- const fallbackCommand = repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0;
15685
- return {
15686
- ...base,
15687
- type: "repo-code",
15688
- gapId: repoCodeTask.gapId,
15689
- title: repoCodeTask.title,
15690
- agentInstruction: "Apply this repo-code fix now using the MCP tool or fallback command, then continue the local VibeRaven loop. Do not stop at a summary.",
15691
- executionPlan: [
15692
- {
15693
- kind: "apply-repo-fix",
15694
- command: repoCodeTask.mcpTool ?? fallbackCommand,
15695
- note: "Patch only this gap and preserve unrelated user changes."
15696
- },
15697
- { kind: "continue-loop", note: "Apply remaining safe repo fixes until the batch is full, then verify once." }
15698
- ],
15699
- mcpTool: repoCodeTask.mcpTool,
15700
- mcpArgs: repoCodeTask.mcpArgs,
15701
- fallbackCommand,
15702
- requiresUserAction: false
15703
- };
15704
- }
15705
- const providerTask = tasks.find((task) => task.fixType === "provider-action");
15706
- if (providerTask) {
15707
- return {
15708
- ...base,
15709
- type: "provider-action",
15710
- gapId: providerTask.gapId,
15711
- title: providerTask.title,
15712
- agentInstruction: "Open or present the provider step now. If browser/tool access is available, open the dashboard link for the user; otherwise show the exact step and copy values. Do not keep telling the user to verify until the provider step is done.",
15713
- executionPlan: [
15714
- { kind: "open-provider-step", note: "Use VIBERAVEN_PROVIDER_ACTION for the exact dashboard step and URL." },
15715
- { kind: "wait-for-user", note: "Wait for confirmation or read-only MCP evidence before verifying." }
15716
- ],
15717
- requiresUserAction: true
15718
- };
15719
- }
15720
- const upgradeTask = tasks.find((task) => task.fixType === "upgrade-required");
15721
- if (upgradeTask) {
15722
- return {
15723
- ...base,
15724
- type: "upgrade-required",
15725
- gapId: upgradeTask.gapId,
15726
- title: upgradeTask.title,
15727
- agentInstruction: "Explain that this production lane needs an upgrade or connected provider evidence. Continue with any remaining unlocked repo-code fixes if present; otherwise stop cleanly.",
15728
- executionPlan: [
15729
- { kind: "upgrade", command: "https://viberaven.dev/pricing" },
15730
- { kind: "stop", note: "Do not pretend locked lanes or provider state were fixed locally." }
15731
- ],
15732
- requiresUserAction: true,
15733
- upgradeUrl: "https://viberaven.dev/pricing"
15734
- };
15735
- }
15736
- return {
15737
- ...base,
15738
- type: "done",
15739
- title: "All gaps resolved - production gate is clear",
15740
- agentInstruction: "The repo-code gate is clear. Run strict before deploy and still verify provider dashboard state through MCP or the provider dashboard.",
15741
- executionPlan: [
15742
- { kind: "verify", command: "npx -y viberaven --strict" },
15743
- { kind: "stop", note: "Do not deploy until provider dashboard state is verified where applicable." }
15744
- ],
15745
- requiresUserAction: false
15746
- };
15747
- }
15748
- function resolveStallReason(tasks) {
15749
- if (tasks.length === 0) return "no-recipes";
15750
- const allUpgradeOrEmpty = tasks.every((task) => task.fixType === "upgrade-required");
15751
- if (allUpgradeOrEmpty) return "no-recipes";
15752
- const allProviderAction = tasks.every((task) => task.fixType === "provider-action");
15753
- if (allProviderAction) return "provider-action-required";
15754
- return "unknown";
15755
- }
15756
- function buildProviderActionBlock(task) {
15757
- if (task.fixType !== "provider-action" || !task.providerAction) {
15758
- return void 0;
15759
- }
15760
- const pa = task.providerAction;
15761
- return {
15762
- VIBERAVEN_PROVIDER_ACTION: {
15763
- gap: task.gapId,
15764
- provider: pa.provider,
15765
- dashboardUrl: pa.dashboardUrl,
15766
- exactStep: pa.exactStep,
15767
- envKeyName: pa.envKeyName ?? null,
15768
- envKeyExample: pa.envKeyExample ?? null,
15769
- doneSignal: pa.doneSignal,
15770
- verifyCommand: task.verifyCommand,
15771
- mcpAlternative: task.mcpTool ?? pa.mcpAlternative ?? null
15772
- }
15773
- };
15774
- }
15775
- function printProviderActionBlock(tasks) {
15776
- const task = tasks.find(
15777
- (entry) => entry.fixType === "provider-action" && entry.requiresUserAction === true
15778
- );
15779
- if (!task) return;
15780
- const block = buildProviderActionBlock(task);
15781
- if (!block) return;
15782
- console.log(PROVIDER_ACTION_START);
15783
- console.log(JSON.stringify(block, null, 2));
15784
- console.log(PROVIDER_ACTION_END);
15785
- }
15786
- function printNextActionBlock(block) {
15787
- console.log(NEXT_ACTION_START);
15788
- console.log(JSON.stringify(block, null, 2));
15789
- console.log(NEXT_ACTION_END);
15790
- }
15791
- var NEXT_ACTION_START, NEXT_ACTION_END, PROVIDER_ACTION_START, PROVIDER_ACTION_END;
15792
- var init_nextActionBlock = __esm({
15793
- "src/output/nextActionBlock.ts"() {
15794
- "use strict";
15795
- NEXT_ACTION_START = "VIBERAVEN_NEXT_ACTION_START";
15796
- NEXT_ACTION_END = "VIBERAVEN_NEXT_ACTION_END";
15797
- PROVIDER_ACTION_START = "VIBERAVEN_PROVIDER_ACTION_START";
15798
- PROVIDER_ACTION_END = "VIBERAVEN_PROVIDER_ACTION_END";
15799
- }
15800
- });
15801
-
15802
15642
  // src/commands/preview.ts
15803
- function previewArtifact(cwd) {
15643
+ function buildPreviewManifest() {
15804
15644
  return {
15805
15645
  version: 1,
15806
- scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
15807
- workspacePath: cwd,
15808
- score: 42,
15809
- scoreLabel: "Blocked",
15810
- summary: "Vercel, Supabase, and Stripe are detected, but launch-critical provider setup is not proven yet.",
15811
- archetype: "ai-built-saas",
15812
- plan: "free",
15813
- productionCorePercent: 40,
15814
- usage: {
15815
- plan: "free",
15816
- remainingPrompts: 0,
15817
- used: 0,
15818
- limit: 0,
15819
- period: "lifetime",
15820
- unlockedMapCategoryKeys: ["appFlow", "frontend", "backend", "auth", "database", "payments"]
15821
- },
15822
- gaps: [
15646
+ generatedAt: "2026-06-16T00:00:00.000Z",
15647
+ workspaceRoot: ".",
15648
+ gateStatus: "not_clear",
15649
+ actions: [
15823
15650
  {
15824
- id: "auth_secret_missing",
15825
- category: "SECURITY & AUTH",
15651
+ id: "VR-A1",
15652
+ actionKey: "provider-action:stripe:stripe-webhook:/api/stripe/webhook:checkout.session.completed,customer.subscription.deleted,customer.subscription.updated",
15653
+ revision: 1,
15654
+ kind: "provider-action",
15655
+ provider: "stripe",
15656
+ title: "Connect Stripe Webhook",
15657
+ status: "waiting-on-provider",
15826
15658
  severity: "critical",
15827
- title: "Create production auth secret",
15828
- detail: "The app needs a production session secret before real users sign in.",
15829
- copyPrompt: "Generate and document NEXTAUTH_SECRET or the equivalent auth secret for this stack.",
15830
- toolSuggestions: [],
15831
- mcpSuggestion: null,
15832
- primaryMapCategory: "auth",
15833
- affectedMapCategories: []
15659
+ gapId: "stripe_webhook_secret_missing",
15660
+ readiness: ["Webhook endpoint path detected", "Required events prepared"],
15661
+ target: {
15662
+ type: "provider",
15663
+ provider: "stripe",
15664
+ label: "Create Stripe webhook endpoint for /api/stripe/webhook."
15665
+ },
15666
+ copyPayloads: [
15667
+ {
15668
+ label: "Required webhook events",
15669
+ format: "text",
15670
+ value: [
15671
+ "checkout.session.completed",
15672
+ "customer.subscription.updated",
15673
+ "customer.subscription.deleted"
15674
+ ]
15675
+ }
15676
+ ],
15677
+ verifyCommand: `${PUBLIC_COMMAND} verify --action VR-A1`,
15678
+ resumeInstruction: "Stripe webhook is configured. Continue VibeRaven from VR-A1."
15834
15679
  },
15835
15680
  {
15836
- id: "rls_disabled",
15837
- category: "DATABASE & DATA",
15681
+ id: "VR-A2",
15682
+ actionKey: "repo-code:supabase:rls:supabase/migrations/20260615_rls.sql:user-owned-tables",
15683
+ revision: 1,
15684
+ kind: "repo-code",
15685
+ provider: "supabase",
15686
+ title: "Apply Supabase RLS",
15687
+ status: "waiting-on-database-proof",
15838
15688
  severity: "critical",
15839
- title: "Verify Supabase RLS before launch",
15840
- detail: "Database access must be protected by Row Level Security or equivalent server-side controls.",
15841
- copyPrompt: "Open Supabase and verify RLS policies for user-owned tables.",
15842
- toolSuggestions: [],
15843
- mcpSuggestion: null,
15844
- primaryMapCategory: "database",
15845
- affectedMapCategories: []
15689
+ gapId: "supabase_rls_policy_proof",
15690
+ readiness: ["Affected tables detected", "Migration file target prepared"],
15691
+ target: {
15692
+ type: "file",
15693
+ label: "RLS migration",
15694
+ path: "supabase/migrations/20260615_rls.sql"
15695
+ },
15696
+ copyPayloads: [
15697
+ {
15698
+ label: "Tiny SQL shape",
15699
+ format: "sql",
15700
+ value: 'alter table public.example enable row level security;\ncreate policy "Users manage own rows" on public.example for all using (auth.uid() = user_id);'
15701
+ }
15702
+ ],
15703
+ verifyCommand: `${PUBLIC_COMMAND} verify --action VR-A2`,
15704
+ resumeInstruction: "Supabase RLS is applied. Continue VibeRaven from VR-A2."
15846
15705
  },
15847
15706
  {
15848
- id: "stripe_webhook_secret_missing",
15849
- category: "PAYMENTS",
15850
- severity: "critical",
15851
- title: "Connect Stripe webhook secret",
15852
- detail: "Stripe webhook signature verification needs STRIPE_WEBHOOK_SECRET before live payments.",
15853
- copyPrompt: "Create a Stripe webhook endpoint and add STRIPE_WEBHOOK_SECRET to the deployment environment.",
15854
- toolSuggestions: [],
15855
- mcpSuggestion: null,
15856
- primaryMapCategory: "payments",
15857
- affectedMapCategories: []
15707
+ id: "VR-A3",
15708
+ actionKey: "verify:gate:final:npx-y-viberaven-strict",
15709
+ revision: 1,
15710
+ kind: "verify",
15711
+ title: "Run Final Verification",
15712
+ status: "blocked",
15713
+ severity: "warning",
15714
+ readiness: ["Run after repo-code and provider actions are complete"],
15715
+ target: {
15716
+ type: "command",
15717
+ label: "Strict gate",
15718
+ command: `${PUBLIC_COMMAND} --strict`
15719
+ },
15720
+ resumeInstruction: "Final verification finished. Continue VibeRaven from VR-A3."
15858
15721
  }
15859
- ],
15860
- missionGraph: {
15861
- areas: [],
15862
- byArea: {},
15863
- byProvider: {},
15864
- repositoryEvidence: { env: [], security: [] }
15865
- },
15866
- stackWiring: { items: [], byKey: {} },
15867
- providerRegistry: {
15868
- version: 1,
15869
- source: "bundled",
15870
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
15871
- status: "fresh",
15872
- staleAfterDays: 14,
15873
- providers: []
15874
- }
15722
+ ]
15875
15723
  };
15876
15724
  }
15877
- function check(done, text) {
15878
- const mark = done ? import_picocolors5.default.green("[x]") : import_picocolors5.default.yellow("[ ]");
15879
- return ` ${mark} ${text}`;
15880
- }
15881
15725
  async function runPreviewCommand(options) {
15882
- const artifact = previewArtifact(options.cwd);
15883
- const tasks = buildTaskList(artifact);
15884
- const next = buildNextActionBlock(tasks, {
15885
- batchApplied: 1,
15886
- appliedGapIdsSinceScan: ["auth_secret_missing"],
15887
- lastGapCount: artifact.gaps.length,
15888
- stalledScans: 0
15889
- }, "free");
15726
+ const manifest = buildPreviewManifest();
15890
15727
  if (options.json) {
15891
- console.log(JSON.stringify({ artifact, tasks, next }, null, 2));
15728
+ console.log(JSON.stringify({ manifest }, null, 2));
15892
15729
  return 0;
15893
15730
  }
15894
15731
  console.log(import_picocolors5.default.dim(`VibeRaven ${VERSION} preview - local rehearsal, no login or API spend.`));
15895
- console.log(import_picocolors5.default.bold("VibeRaven"));
15896
- console.log("Taking this app from demo to production.");
15897
- console.log("");
15898
- console.log(`${import_picocolors5.default.bold("Status:")} ${import_picocolors5.default.red("BLOCKED")} | vercel + supabase + stripe | 3 launch gaps`);
15732
+ console.log(import_picocolors5.default.dim("This is sample renderer data, not a production verdict for this repository."));
15899
15733
  console.log("");
15900
- console.log(import_picocolors5.default.bold("Progress"));
15901
- console.log(check(true, "Understand the stack and launch gaps"));
15902
- console.log(check(true, "Patch the first repo-owned secret gap"));
15903
- console.log(check(false, "Open Supabase and verify RLS policies"));
15904
- console.log(check(false, "Connect Stripe webhook signing secret"));
15905
- console.log(check(false, "Verify again before launch"));
15906
- console.log("");
15907
- console.log(import_picocolors5.default.bold("I can do now"));
15908
- console.log(" 1. Add missing env names and agent rules.");
15909
- console.log(" 2. Prepare focused repo fixes the coding agent can apply.");
15910
- console.log(" 3. Keep the launch loop moving until provider proof is needed.");
15911
- console.log("");
15912
- console.log(import_picocolors5.default.bold("I need you for"));
15913
- console.log(" 1. Supabase: open the project and confirm RLS policies.");
15914
- console.log(" 2. Stripe: create or open the webhook endpoint.");
15915
- console.log(" 3. Deployment: paste provider secrets into Vercel or your host.");
15916
- console.log("");
15917
- console.log(import_picocolors5.default.bold("Open"));
15918
- console.log(` supabase: ${import_picocolors5.default.cyan("https://supabase.com/dashboard")}`);
15919
- console.log(` stripe: ${import_picocolors5.default.cyan("https://dashboard.stripe.com/")}`);
15920
- console.log("");
15921
- console.log(`${import_picocolors5.default.bold("Copy env names:")} NEXTAUTH_SECRET, STRIPE_WEBHOOK_SECRET`);
15922
- console.log(`${import_picocolors5.default.bold("Next:")} I will guide the blocked provider setup, then verify when you confirm it is done.`);
15734
+ console.log(renderActionSurface(manifest, { limit: 3 }).trimEnd());
15923
15735
  if (options.agentMode) {
15924
15736
  console.log("");
15925
- console.log(import_picocolors5.default.dim("Agent note: render the checklist above as the live timeline; update [ ] to [x] as work completes."));
15737
+ console.log(
15738
+ import_picocolors5.default.dim(
15739
+ "Agent note: treat each visible action as the next production action surface. Do not mark provider actions resolved until provider proof exists."
15740
+ )
15741
+ );
15926
15742
  }
15927
15743
  return 0;
15928
15744
  }
@@ -15931,8 +15747,8 @@ var init_preview = __esm({
15931
15747
  "src/commands/preview.ts"() {
15932
15748
  "use strict";
15933
15749
  import_picocolors5 = __toESM(require_picocolors());
15934
- init_buildTaskList();
15935
- init_nextActionBlock();
15750
+ init_commands();
15751
+ init_render();
15936
15752
  init_version();
15937
15753
  }
15938
15754
  });
@@ -17148,6 +16964,7 @@ const demo = {
17148
16964
  activeModal: null,
17149
16965
  activeStudioTab: 'chat',
17150
16966
  selectedCliId: 'codex',
16967
+ agentPermissionMode: 'ask',
17151
16968
  cliConnected: false,
17152
16969
  cliSetupComplete: false,
17153
16970
  cliConnectTargetId: null,
@@ -17184,6 +17001,23 @@ const demo = {
17184
17001
  releaseChangelog: { entries: [], from: '', to: '', fromLabel: '', toLabel: '', loading: false, error: '' },
17185
17002
  };
17186
17003
 
17004
+ function readPermissionMode() {
17005
+ try {
17006
+ const raw = localStorage.getItem('viberaven:agentChatPermissionMode');
17007
+ return raw === 'full-access' ? 'full-access' : 'ask';
17008
+ } catch {
17009
+ return 'ask';
17010
+ }
17011
+ }
17012
+
17013
+ function savePermissionMode(mode) {
17014
+ try {
17015
+ localStorage.setItem('viberaven:agentChatPermissionMode', mode);
17016
+ } catch {
17017
+ // Ignore storage failures in preview shells.
17018
+ }
17019
+ }
17020
+
17187
17021
  function readCliSessionReady() {
17188
17022
  try {
17189
17023
  let raw = localStorage.getItem('viberaven-cli-ready');
@@ -17206,6 +17040,7 @@ function writeCliSessionReady(value) {
17206
17040
  }
17207
17041
 
17208
17042
  demo.cliSessionReady = readCliSessionReady();
17043
+ demo.agentPermissionMode = readPermissionMode();
17209
17044
 
17210
17045
  function cliAgentInstalled(agent) {
17211
17046
  if (!agent) return false;
@@ -18563,6 +18398,7 @@ function runChatTask(kind, promptOverride) {
18563
18398
  prompt,
18564
18399
  displayPrompt: label,
18565
18400
  taskKind: kind,
18401
+ permissionMode: demo.agentPermissionMode,
18566
18402
  provider: { area: provider.area, name: provider.name },
18567
18403
  release: release ? { label: release.label } : undefined
18568
18404
  })
@@ -19523,6 +19359,7 @@ function ModelPicker(index) {
19523
19359
  '<button type="button" data-action="toggle-reasoning" data-chat-index="' + String(index) + '"><span>Reasoning</span><strong>' + escapeHtml(chat.reasoning) + '</strong><i></i></button>' +
19524
19360
  '<button type="button" data-action="toggle-models" data-chat-index="' + String(index) + '"><span>Model</span><strong>' + escapeHtml(selectedModel) + '</strong><i></i></button>' +
19525
19361
  '<button type="button" data-action="toggle-context" data-chat-index="' + String(index) + '"><span>Context</span><strong>' + escapeHtml(chat.context) + '</strong><i></i></button>' +
19362
+ PermissionModeToggle(index) +
19526
19363
  (scoped && demo.reasoningMenuOpen ? '<div class="vr-model-menu is-reasoning" role="menu"><p>Reasoning</p>' + reasoningLevels.map((level) =>
19527
19364
  '<button type="button" data-reasoning="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.reasoning === level ? '<b></b>' : '') + '</button>'
19528
19365
  ).join('') + '</div>' : '') +
@@ -19535,6 +19372,14 @@ function ModelPicker(index) {
19535
19372
  '</div>';
19536
19373
  }
19537
19374
 
19375
+ function PermissionModeToggle(index) {
19376
+ const isFullAccess = demo.agentPermissionMode === 'full-access';
19377
+ return '<div class="vr-permission-toggle" role="group" aria-label="Agent permission mode">' +
19378
+ '<button type="button" class="vr-permission-btn' + (!isFullAccess ? ' is-active' : '') + '" data-permission-mode="ask" data-chat-index="' + String(index) + '" aria-pressed="' + String(!isFullAccess) + '" title="Ask for approval before each risky action">Ask each change</button>' +
19379
+ '<button type="button" class="vr-permission-btn is-danger' + (isFullAccess ? ' is-active' : '') + '" data-permission-mode="full-access" data-chat-index="' + String(index) + '" aria-pressed="' + String(isFullAccess) + '" title="Run without per-action approval prompts \u2014 use with care">Full access</button>' +
19380
+ '</div>';
19381
+ }
19382
+
19538
19383
  function ChatBlockersSummary(cards) {
19539
19384
  const blockers = Array.isArray(cards.blockers) ? cards.blockers : [];
19540
19385
  const count = typeof cards.blockerCount === 'number' ? cards.blockerCount : blockers.length;
@@ -20561,6 +20406,24 @@ app.addEventListener('click', async (event) => {
20561
20406
  return;
20562
20407
  }
20563
20408
 
20409
+ const permissionButton = event.target.closest('[data-permission-mode]');
20410
+ if (permissionButton) {
20411
+ event.preventDefault();
20412
+ const mode = permissionButton.getAttribute('data-permission-mode');
20413
+ demo.agentPermissionMode = mode === 'full-access' ? 'full-access' : 'ask';
20414
+ savePermissionMode(demo.agentPermissionMode);
20415
+ const chatIndex = Number(permissionButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
20416
+ demo.pickerChatIndex = chatIndex;
20417
+ demo.modelMenuOpen = false;
20418
+ demo.reasoningMenuOpen = false;
20419
+ demo.contextMenuOpen = false;
20420
+ demo.notice = demo.agentPermissionMode === 'full-access'
20421
+ ? 'Full access mode: agent runs without per-action approval prompts.'
20422
+ : 'Ask mode: agent will request approval before each risky action.';
20423
+ render();
20424
+ return;
20425
+ }
20426
+
20564
20427
  const stageButton = event.target.closest('[data-stage-step]');
20565
20428
  if (stageButton) {
20566
20429
  const stage = stageButton.getAttribute('data-stage-step');
@@ -28190,6 +28053,46 @@ body:has(.vr-app.is-dragging) {
28190
28053
  display: none;
28191
28054
  }
28192
28055
  }
28056
+ .vr-permission-toggle {
28057
+ display: inline-flex;
28058
+ align-items: center;
28059
+ gap: 0;
28060
+ border: 1px solid rgba(148, 163, 184, 0.18);
28061
+ border-radius: 8px;
28062
+ overflow: hidden;
28063
+ background: rgba(39, 40, 44, 0.92);
28064
+ }
28065
+ .vr-permission-btn {
28066
+ min-height: 28px;
28067
+ padding: 0 10px;
28068
+ font-size: 11px;
28069
+ font-weight: 640;
28070
+ color: #94a3b8;
28071
+ background: transparent;
28072
+ border: none;
28073
+ border-radius: 0;
28074
+ cursor: pointer;
28075
+ transition: background 0.12s, color 0.12s;
28076
+ white-space: nowrap;
28077
+ }
28078
+ .vr-permission-btn + .vr-permission-btn {
28079
+ border-left: 1px solid rgba(148, 163, 184, 0.14);
28080
+ }
28081
+ .vr-permission-btn.is-active {
28082
+ background: rgba(100, 116, 139, 0.28);
28083
+ color: #f1f5f9;
28084
+ }
28085
+ .vr-permission-btn.is-danger {
28086
+ color: #f59e0b;
28087
+ }
28088
+ .vr-permission-btn.is-danger.is-active {
28089
+ background: rgba(245, 158, 11, 0.18);
28090
+ color: #fbbf24;
28091
+ }
28092
+ .vr-permission-btn:hover:not(.is-active) {
28093
+ background: rgba(148, 163, 184, 0.1);
28094
+ color: #e2e8f0;
28095
+ }
28193
28096
  `;
28194
28097
  }
28195
28098
  });
@@ -28801,6 +28704,8 @@ function parseAgentChatRequest(value) {
28801
28704
  if (!prompt) return { error: "Agent chat prompt is required" };
28802
28705
  const provider2 = isRecord7(value.provider) ? { area: stringField(value.provider.area, 120), name: stringField(value.provider.name, 120) } : void 0;
28803
28706
  const release = isRecord7(value.release) ? { label: stringField(value.release.label, 120) } : void 0;
28707
+ const rawPermMode = stringField(value.permissionMode, 20);
28708
+ const permissionMode = rawPermMode === "full-access" ? "full-access" : "ask";
28804
28709
  return {
28805
28710
  cliId: rawCliId,
28806
28711
  modelId: stringField(value.modelId, 120),
@@ -28809,6 +28714,7 @@ function parseAgentChatRequest(value) {
28809
28714
  prompt,
28810
28715
  displayPrompt: stringField(value.displayPrompt, 240),
28811
28716
  taskKind: stringField(value.taskKind, 40),
28717
+ permissionMode,
28812
28718
  provider: provider2,
28813
28719
  release
28814
28720
  };
@@ -28900,13 +28806,24 @@ function insertCodexExecOptions(codexArgs, pairs) {
28900
28806
  const insertAt = execIndex >= 0 ? execIndex + 1 : codexArgs.length;
28901
28807
  codexArgs.splice(insertAt, 0, ...pairs);
28902
28808
  }
28903
- function commandForAgentChat(request, prompt, cwd, outputPath) {
28904
- const command = process.platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
28809
+ function resolveCodexSandboxArgs(permissionMode, platform) {
28810
+ if (permissionMode === "full-access") {
28811
+ return ["--sandbox", "danger-full-access", "--ask-for-approval", "never"];
28812
+ }
28813
+ if (platform === "win32") {
28814
+ return ["--sandbox", "danger-full-access", "--ask-for-approval", "on-request"];
28815
+ }
28816
+ return ["--sandbox", "workspace-write", "--ask-for-approval", "on-request"];
28817
+ }
28818
+ function commandForAgentChat(request, prompt, cwd, outputPath, platform = process.platform) {
28819
+ const command = platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
28905
28820
  const promptArg = prompt.replace(/\s*\r?\n\s*/g, " ");
28906
28821
  const model = normalizeCliModelId(request.modelId);
28907
28822
  const effort = resolveCliReasoningEffort(request.cliId, request.reasoning);
28823
+ const permissionMode = request.permissionMode ?? "ask";
28908
28824
  if (request.cliId === "gemini") {
28909
- const geminiArgs = ["-p", promptArg, "--output-format", "text", "--skip-trust"];
28825
+ const geminiArgs = ["-p", promptArg, "--output-format", "text"];
28826
+ if (permissionMode === "full-access") geminiArgs.push("--skip-trust");
28910
28827
  if (model) geminiArgs.splice(0, 0, "-m", model);
28911
28828
  return { command, args: geminiArgs };
28912
28829
  }
@@ -28914,12 +28831,13 @@ function commandForAgentChat(request, prompt, cwd, outputPath) {
28914
28831
  const claudeArgs = ["-p", promptArg];
28915
28832
  if (model) claudeArgs.unshift("--model", model);
28916
28833
  if (effort) claudeArgs.unshift("--effort", effort);
28917
- if (request.taskKind === "fix" || request.taskKind === "plan" || request.taskKind === "provider") {
28834
+ if (permissionMode === "full-access") {
28918
28835
  claudeArgs.push("--dangerously-skip-permissions");
28919
28836
  }
28920
28837
  return { command, args: claudeArgs };
28921
28838
  }
28922
- const codexArgs = ["--cd", cwd, "--sandbox", "workspace-write", "--ask-for-approval", "never", "exec", "--color", "never"];
28839
+ const sandboxArgs = resolveCodexSandboxArgs(permissionMode, platform);
28840
+ const codexArgs = ["--cd", cwd, ...sandboxArgs, "exec", "--color", "never"];
28923
28841
  const codexExecOptions = [];
28924
28842
  if (model) codexExecOptions.push("-m", model);
28925
28843
  if (effort) codexExecOptions.push("-c", `model_reasoning_effort="${effort}"`);
@@ -29709,6 +29627,164 @@ var init_server = __esm({
29709
29627
  }
29710
29628
  });
29711
29629
 
29630
+ // src/output/nextActionBlock.ts
29631
+ function buildNextActionBlock(tasks, loopState, plan) {
29632
+ const batchSize = plan === "pro" ? 10 : 3;
29633
+ const batchApplied = loopState.batchApplied;
29634
+ const remainingInBatch = batchSize - batchApplied;
29635
+ const scanNow = batchApplied >= batchSize;
29636
+ const stalled = loopState.stalledScans >= 2;
29637
+ const stalledScans = loopState.stalledScans;
29638
+ const base = { batchSize, batchApplied, remainingInBatch, scanNow, stalled, stalledScans };
29639
+ if (stalled) {
29640
+ const stallReason = resolveStallReason(tasks);
29641
+ return {
29642
+ ...base,
29643
+ type: "stalled",
29644
+ title: "Loop stalled - no gap reduction after 2+ consecutive scans",
29645
+ agentInstruction: "Stop the scan loop. Explain the blocker plainly, then either guide the provider/user action or report that no safe repo-code recipe is available.",
29646
+ executionPlan: [
29647
+ { kind: "stop", note: "Do not keep spending scans while the loop is stalled." }
29648
+ ],
29649
+ requiresUserAction: true,
29650
+ stallReason
29651
+ };
29652
+ }
29653
+ if (scanNow) {
29654
+ return {
29655
+ ...base,
29656
+ type: "verify",
29657
+ title: "Batch complete - run verify to rescan before next batch",
29658
+ agentInstruction: "Run verify now, read the refreshed VibeRaven artifacts, then continue with the next safe repo fix or provider step. Do not stop at a summary.",
29659
+ executionPlan: [
29660
+ { kind: "verify", command: "viberaven_verify" },
29661
+ { kind: "continue-loop", note: "After verify, continue until the gate is clear or a provider/user blocker remains." }
29662
+ ],
29663
+ mcpTool: "viberaven_verify",
29664
+ mcpArgs: {},
29665
+ requiresUserAction: false
29666
+ };
29667
+ }
29668
+ const repoCodeTask = tasks.find((task) => task.fixType === "repo-code" && !task.requiresUserAction);
29669
+ if (repoCodeTask) {
29670
+ const fallbackCommand = repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0;
29671
+ return {
29672
+ ...base,
29673
+ type: "repo-code",
29674
+ gapId: repoCodeTask.gapId,
29675
+ title: repoCodeTask.title,
29676
+ agentInstruction: "Apply this repo-code fix now using the MCP tool or fallback command, then continue the local VibeRaven loop. Do not stop at a summary.",
29677
+ executionPlan: [
29678
+ {
29679
+ kind: "apply-repo-fix",
29680
+ command: repoCodeTask.mcpTool ?? fallbackCommand,
29681
+ note: "Patch only this gap and preserve unrelated user changes."
29682
+ },
29683
+ { kind: "continue-loop", note: "Apply remaining safe repo fixes until the batch is full, then verify once." }
29684
+ ],
29685
+ mcpTool: repoCodeTask.mcpTool,
29686
+ mcpArgs: repoCodeTask.mcpArgs,
29687
+ fallbackCommand,
29688
+ requiresUserAction: false
29689
+ };
29690
+ }
29691
+ const providerTask = tasks.find((task) => task.fixType === "provider-action");
29692
+ if (providerTask) {
29693
+ return {
29694
+ ...base,
29695
+ type: "provider-action",
29696
+ gapId: providerTask.gapId,
29697
+ title: providerTask.title,
29698
+ agentInstruction: "Open or present the provider step now. If browser/tool access is available, open the dashboard link for the user; otherwise show the exact step and copy values. Do not keep telling the user to verify until the provider step is done.",
29699
+ executionPlan: [
29700
+ { kind: "open-provider-step", note: "Use VIBERAVEN_PROVIDER_ACTION for the exact dashboard step and URL." },
29701
+ { kind: "wait-for-user", note: "Wait for confirmation or read-only MCP evidence before verifying." }
29702
+ ],
29703
+ requiresUserAction: true
29704
+ };
29705
+ }
29706
+ const upgradeTask = tasks.find((task) => task.fixType === "upgrade-required");
29707
+ if (upgradeTask) {
29708
+ return {
29709
+ ...base,
29710
+ type: "upgrade-required",
29711
+ gapId: upgradeTask.gapId,
29712
+ title: upgradeTask.title,
29713
+ agentInstruction: "Explain that this production lane needs an upgrade or connected provider evidence. Continue with any remaining unlocked repo-code fixes if present; otherwise stop cleanly.",
29714
+ executionPlan: [
29715
+ { kind: "upgrade", command: "https://viberaven.dev/pricing" },
29716
+ { kind: "stop", note: "Do not pretend locked lanes or provider state were fixed locally." }
29717
+ ],
29718
+ requiresUserAction: true,
29719
+ upgradeUrl: "https://viberaven.dev/pricing"
29720
+ };
29721
+ }
29722
+ return {
29723
+ ...base,
29724
+ type: "done",
29725
+ title: "All gaps resolved - production gate is clear",
29726
+ agentInstruction: "The repo-code gate is clear. Run strict before deploy and still verify provider dashboard state through MCP or the provider dashboard.",
29727
+ executionPlan: [
29728
+ { kind: "verify", command: "npx -y viberaven --strict" },
29729
+ { kind: "stop", note: "Do not deploy until provider dashboard state is verified where applicable." }
29730
+ ],
29731
+ requiresUserAction: false
29732
+ };
29733
+ }
29734
+ function resolveStallReason(tasks) {
29735
+ if (tasks.length === 0) return "no-recipes";
29736
+ const allUpgradeOrEmpty = tasks.every((task) => task.fixType === "upgrade-required");
29737
+ if (allUpgradeOrEmpty) return "no-recipes";
29738
+ const allProviderAction = tasks.every((task) => task.fixType === "provider-action");
29739
+ if (allProviderAction) return "provider-action-required";
29740
+ return "unknown";
29741
+ }
29742
+ function buildProviderActionBlock(task) {
29743
+ if (task.fixType !== "provider-action" || !task.providerAction) {
29744
+ return void 0;
29745
+ }
29746
+ const pa = task.providerAction;
29747
+ return {
29748
+ VIBERAVEN_PROVIDER_ACTION: {
29749
+ gap: task.gapId,
29750
+ provider: pa.provider,
29751
+ dashboardUrl: pa.dashboardUrl,
29752
+ exactStep: pa.exactStep,
29753
+ envKeyName: pa.envKeyName ?? null,
29754
+ envKeyExample: pa.envKeyExample ?? null,
29755
+ doneSignal: pa.doneSignal,
29756
+ verifyCommand: task.verifyCommand,
29757
+ mcpAlternative: task.mcpTool ?? pa.mcpAlternative ?? null
29758
+ }
29759
+ };
29760
+ }
29761
+ function printProviderActionBlock(tasks) {
29762
+ const task = tasks.find(
29763
+ (entry) => entry.fixType === "provider-action" && entry.requiresUserAction === true
29764
+ );
29765
+ if (!task) return;
29766
+ const block = buildProviderActionBlock(task);
29767
+ if (!block) return;
29768
+ console.log(PROVIDER_ACTION_START);
29769
+ console.log(JSON.stringify(block, null, 2));
29770
+ console.log(PROVIDER_ACTION_END);
29771
+ }
29772
+ function printNextActionBlock(block) {
29773
+ console.log(NEXT_ACTION_START);
29774
+ console.log(JSON.stringify(block, null, 2));
29775
+ console.log(NEXT_ACTION_END);
29776
+ }
29777
+ var NEXT_ACTION_START, NEXT_ACTION_END, PROVIDER_ACTION_START, PROVIDER_ACTION_END;
29778
+ var init_nextActionBlock = __esm({
29779
+ "src/output/nextActionBlock.ts"() {
29780
+ "use strict";
29781
+ NEXT_ACTION_START = "VIBERAVEN_NEXT_ACTION_START";
29782
+ NEXT_ACTION_END = "VIBERAVEN_NEXT_ACTION_END";
29783
+ PROVIDER_ACTION_START = "VIBERAVEN_PROVIDER_ACTION_START";
29784
+ PROVIDER_ACTION_END = "VIBERAVEN_PROVIDER_ACTION_END";
29785
+ }
29786
+ });
29787
+
29712
29788
  // src/providerMcpBridge.ts
29713
29789
  function defaultMcpConfigPaths() {
29714
29790
  const home = (0, import_node_os2.homedir)();
@@ -30055,8 +30131,8 @@ async function cmdLogout() {
30055
30131
  }
30056
30132
  async function cmdProviderVerify(flags, positional) {
30057
30133
  const provider2 = typeof flags.provider === "string" ? flags.provider : positional[0];
30058
- const check2 = typeof flags.check === "string" ? flags.check : positional[1];
30059
- if (!provider2 || !check2) {
30134
+ const check = typeof flags.check === "string" ? flags.check : positional[1];
30135
+ if (!provider2 || !check) {
30060
30136
  console.error("Usage: viberaven provider-verify --provider <supabase|vercel> --check <id> [--plan free|pro]");
30061
30137
  return 1;
30062
30138
  }
@@ -30069,7 +30145,7 @@ async function cmdProviderVerify(flags, positional) {
30069
30145
  }
30070
30146
  const result = await verifyProviderGap({
30071
30147
  provider: provider2,
30072
- check: check2,
30148
+ check,
30073
30149
  cwd: process.cwd(),
30074
30150
  plan
30075
30151
  });