@viberaven/cli 1.2.3 → 1.3.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/AGENTS.md +42 -157
- package/README.md +73 -33
- package/SECURITY.md +52 -53
- package/assets/report/assets/provider-authjs.svg +5 -5
- package/assets/report/assets/provider-aws.svg +5 -5
- package/assets/report/assets/provider-logrocket.svg +4 -4
- package/assets/report/assets/viberaven-favicon.png +0 -0
- package/assets/report/station.js +2 -2
- package/dist/cli.js +744 -639
- package/dist/cli.js.map +4 -4
- package/dist/report/assets/provider-authjs.svg +5 -5
- package/dist/report/assets/provider-aws.svg +5 -5
- package/dist/report/assets/provider-logrocket.svg +4 -4
- package/dist/report/assets/viberaven-favicon.png +0 -0
- package/dist/report/station.js +2 -2
- package/package.json +73 -75
- package/templates/AGENTS.snippet.md +45 -52
- package/templates/CLAUDE.snippet.md +19 -17
- package/templates/CURSOR.snippet.md +29 -17
- package/assets/report/assets/provider-auth.png +0 -0
- package/assets/report/assets/provider-authjs.png +0 -0
- package/assets/report/assets/provider-clerk-mark.svg +0 -1
- package/assets/report/assets/provider-clerk.png +0 -0
- package/assets/report/assets/provider-database.png +0 -0
- package/assets/report/assets/provider-env.png +0 -0
- package/assets/report/assets/provider-github-mark.svg +0 -1
- package/assets/report/assets/provider-github.png +0 -0
- package/assets/report/assets/provider-posthog-mark.svg +0 -1
- package/assets/report/assets/provider-posthog.png +0 -0
- package/assets/report/assets/provider-resend-mark.svg +0 -1
- package/assets/report/assets/provider-resend.png +0 -0
- package/assets/report/assets/provider-sentry-mark.svg +0 -1
- package/assets/report/assets/provider-sentry.png +0 -0
- package/assets/report/assets/provider-stripe-mark.svg +0 -1
- package/assets/report/assets/provider-stripe.png +0 -0
- package/assets/report/assets/provider-supabase-mark.svg +0 -1
- package/assets/report/assets/provider-supabase.png +0 -0
- package/assets/report/assets/provider-upstash-mark.svg +0 -1
- package/assets/report/assets/provider-upstash.png +0 -0
- package/assets/report/assets/provider-vercel-mark.svg +0 -1
- package/assets/report/assets/provider-vercel.png +0 -0
- package/assets/report/assets/viberaven-agent-icon.png +0 -0
- package/assets/report/assets/viberaven-mascot-alert.png +0 -0
- package/assets/report/assets/viberaven-mascot-fixing.png +0 -0
- package/assets/report/assets/viberaven-mascot-verified.png +0 -0
- package/dist/report/assets/provider-auth.png +0 -0
- package/dist/report/assets/provider-authjs.png +0 -0
- package/dist/report/assets/provider-clerk-mark.svg +0 -1
- package/dist/report/assets/provider-clerk.png +0 -0
- package/dist/report/assets/provider-database.png +0 -0
- package/dist/report/assets/provider-env.png +0 -0
- package/dist/report/assets/provider-github-mark.svg +0 -1
- package/dist/report/assets/provider-github.png +0 -0
- package/dist/report/assets/provider-posthog-mark.svg +0 -1
- package/dist/report/assets/provider-posthog.png +0 -0
- package/dist/report/assets/provider-resend-mark.svg +0 -1
- package/dist/report/assets/provider-resend.png +0 -0
- package/dist/report/assets/provider-sentry-mark.svg +0 -1
- package/dist/report/assets/provider-sentry.png +0 -0
- package/dist/report/assets/provider-stripe-mark.svg +0 -1
- package/dist/report/assets/provider-stripe.png +0 -0
- package/dist/report/assets/provider-supabase-mark.svg +0 -1
- package/dist/report/assets/provider-supabase.png +0 -0
- package/dist/report/assets/provider-upstash-mark.svg +0 -1
- package/dist/report/assets/provider-upstash.png +0 -0
- package/dist/report/assets/provider-vercel-mark.svg +0 -1
- package/dist/report/assets/provider-vercel.png +0 -0
- package/dist/report/assets/viberaven-agent-icon.png +0 -0
- package/dist/report/assets/viberaven-mascot-alert.png +0 -0
- package/dist/report/assets/viberaven-mascot-fixing.png +0 -0
- package/dist/report/assets/viberaven-mascot-verified.png +0 -0
- /package/assets/report/assets/{viberaven-mascot-idle.png → viberaven-mascot.png} +0 -0
- /package/dist/report/assets/{viberaven-mascot-idle.png → viberaven-mascot.png} +0 -0
package/dist/cli.js
CHANGED
|
@@ -394,6 +394,8 @@ var init_backendClient = __esm({
|
|
|
394
394
|
this.status = status;
|
|
395
395
|
this.upgradeUrl = upgradeUrl;
|
|
396
396
|
}
|
|
397
|
+
status;
|
|
398
|
+
upgradeUrl;
|
|
397
399
|
};
|
|
398
400
|
}
|
|
399
401
|
});
|
|
@@ -543,12 +545,12 @@ function createAppWindowOpenCommands(target, platform = process.platform, env =
|
|
|
543
545
|
}
|
|
544
546
|
async function openWithSystemDefault(target) {
|
|
545
547
|
const { command, args, shell } = createOpenCommand(target);
|
|
546
|
-
await new Promise((
|
|
548
|
+
await new Promise((resolve6, reject) => {
|
|
547
549
|
const child = (0, import_node_child_process.spawn)(command, args, { stdio: "ignore", shell });
|
|
548
550
|
child.on("error", reject);
|
|
549
551
|
child.on("exit", (code) => {
|
|
550
552
|
if (code === 0) {
|
|
551
|
-
|
|
553
|
+
resolve6();
|
|
552
554
|
} else {
|
|
553
555
|
reject(new Error(`Could not open browser (exit ${code ?? "unknown"}). Open manually: ${target}`));
|
|
554
556
|
}
|
|
@@ -559,7 +561,7 @@ async function spawnDetached(command) {
|
|
|
559
561
|
if (/^[A-Za-z]:[\\/]/.test(command.command) && !(0, import_node_fs2.existsSync)(command.command)) {
|
|
560
562
|
throw new Error(`Browser not found: ${command.command}`);
|
|
561
563
|
}
|
|
562
|
-
await new Promise((
|
|
564
|
+
await new Promise((resolve6, reject) => {
|
|
563
565
|
const child = (0, import_node_child_process.spawn)(command.command, command.args, {
|
|
564
566
|
detached: true,
|
|
565
567
|
stdio: "ignore",
|
|
@@ -567,7 +569,7 @@ async function spawnDetached(command) {
|
|
|
567
569
|
});
|
|
568
570
|
child.once("spawn", () => {
|
|
569
571
|
child.unref();
|
|
570
|
-
|
|
572
|
+
resolve6();
|
|
571
573
|
});
|
|
572
574
|
child.once("error", reject);
|
|
573
575
|
});
|
|
@@ -636,7 +638,7 @@ var init_commands = __esm({
|
|
|
636
638
|
|
|
637
639
|
// src/auth.ts
|
|
638
640
|
function sleep(ms) {
|
|
639
|
-
return new Promise((
|
|
641
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
640
642
|
}
|
|
641
643
|
async function runDeviceLogin(apiBaseUrl) {
|
|
642
644
|
const signIn = await startManagedSignIn(apiBaseUrl);
|
|
@@ -9143,7 +9145,7 @@ function generateAgentSummary(artifact) {
|
|
|
9143
9145
|
lines.push("Do not claim human-provider actions as repo-code fixes.");
|
|
9144
9146
|
lines.push("");
|
|
9145
9147
|
lines.push("## Agent workflow");
|
|
9146
|
-
lines.push("1. Read `.viberaven/agent-tasklist.md` first for the
|
|
9148
|
+
lines.push("1. Read `.viberaven/agent-tasklist.md` first for the what-changed map.");
|
|
9147
9149
|
lines.push("2. Read `.viberaven/launch-playbook.md` for the full checklist.");
|
|
9148
9150
|
lines.push("3. Run `viberaven next --json` - one action at a time.");
|
|
9149
9151
|
lines.push("4. Repo fix: `viberaven prompt --gap <id>` then implement.");
|
|
@@ -9417,7 +9419,7 @@ function generateLaunchPlaybook(artifact) {
|
|
|
9417
9419
|
}
|
|
9418
9420
|
}
|
|
9419
9421
|
lines.push("## Agent loop", "");
|
|
9420
|
-
lines.push("1. Read `.viberaven/agent-tasklist.md` for the current
|
|
9422
|
+
lines.push("1. Read `.viberaven/agent-tasklist.md` for the current what-changed map.");
|
|
9421
9423
|
lines.push("2. `viberaven next --json`");
|
|
9422
9424
|
lines.push("3. Fix repo or run `viberaven guide <provider>`");
|
|
9423
9425
|
lines.push(`4. Run \`${PUBLIC_VERIFY_COMMAND}\` to refresh the gate and \`.viberaven/agent-tasklist.md\`.`);
|
|
@@ -9790,36 +9792,11 @@ var init_reportAssets = __esm({
|
|
|
9790
9792
|
"station.js",
|
|
9791
9793
|
"report-cli.css",
|
|
9792
9794
|
"assets/viberaven-logo.png",
|
|
9793
|
-
"assets/viberaven-
|
|
9794
|
-
"assets/viberaven-mascot
|
|
9795
|
-
"assets/viberaven-mascot-fixing.png",
|
|
9796
|
-
"assets/viberaven-mascot-verified.png",
|
|
9797
|
-
"assets/viberaven-mascot-alert.png",
|
|
9795
|
+
"assets/viberaven-favicon.png",
|
|
9796
|
+
"assets/viberaven-mascot.png",
|
|
9798
9797
|
"assets/provider-authjs.svg",
|
|
9799
9798
|
"assets/provider-aws.svg",
|
|
9800
|
-
"assets/provider-logrocket.svg"
|
|
9801
|
-
"assets/provider-auth.png",
|
|
9802
|
-
"assets/provider-authjs.png",
|
|
9803
|
-
"assets/provider-clerk.png",
|
|
9804
|
-
"assets/provider-clerk-mark.svg",
|
|
9805
|
-
"assets/provider-database.png",
|
|
9806
|
-
"assets/provider-env.png",
|
|
9807
|
-
"assets/provider-github.png",
|
|
9808
|
-
"assets/provider-github-mark.svg",
|
|
9809
|
-
"assets/provider-posthog.png",
|
|
9810
|
-
"assets/provider-posthog-mark.svg",
|
|
9811
|
-
"assets/provider-resend.png",
|
|
9812
|
-
"assets/provider-resend-mark.svg",
|
|
9813
|
-
"assets/provider-sentry.png",
|
|
9814
|
-
"assets/provider-sentry-mark.svg",
|
|
9815
|
-
"assets/provider-stripe.png",
|
|
9816
|
-
"assets/provider-stripe-mark.svg",
|
|
9817
|
-
"assets/provider-supabase.png",
|
|
9818
|
-
"assets/provider-supabase-mark.svg",
|
|
9819
|
-
"assets/provider-upstash.png",
|
|
9820
|
-
"assets/provider-upstash-mark.svg",
|
|
9821
|
-
"assets/provider-vercel.png",
|
|
9822
|
-
"assets/provider-vercel-mark.svg"
|
|
9799
|
+
"assets/provider-logrocket.svg"
|
|
9823
9800
|
];
|
|
9824
9801
|
}
|
|
9825
9802
|
});
|
|
@@ -10440,12 +10417,12 @@ async function copyToClipboard(text) {
|
|
|
10440
10417
|
}
|
|
10441
10418
|
}
|
|
10442
10419
|
function pipeToCommand(command, text, extraArgs = []) {
|
|
10443
|
-
return new Promise((
|
|
10420
|
+
return new Promise((resolve6, reject) => {
|
|
10444
10421
|
const child = (0, import_node_child_process2.spawn)(command, extraArgs, { stdio: ["pipe", "ignore", "ignore"] });
|
|
10445
10422
|
child.on("error", reject);
|
|
10446
10423
|
child.on("close", (code) => {
|
|
10447
10424
|
if (code === 0) {
|
|
10448
|
-
|
|
10425
|
+
resolve6();
|
|
10449
10426
|
} else {
|
|
10450
10427
|
reject(new Error(`${command} exited with code ${code ?? "unknown"}`));
|
|
10451
10428
|
}
|
|
@@ -10467,9 +10444,9 @@ var init_clipboard = __esm({
|
|
|
10467
10444
|
}
|
|
10468
10445
|
});
|
|
10469
10446
|
|
|
10470
|
-
// node_modules/picocolors/picocolors.js
|
|
10447
|
+
// ../../node_modules/picocolors/picocolors.js
|
|
10471
10448
|
var require_picocolors = __commonJS({
|
|
10472
|
-
"node_modules/picocolors/picocolors.js"(exports2, module2) {
|
|
10449
|
+
"../../node_modules/picocolors/picocolors.js"(exports2, module2) {
|
|
10473
10450
|
var p2 = process || {};
|
|
10474
10451
|
var argv = p2.argv || [];
|
|
10475
10452
|
var env = p2.env || {};
|
|
@@ -10659,7 +10636,7 @@ function printScanSummary(artifact, paths) {
|
|
|
10659
10636
|
if (next.upgradeUrl) {
|
|
10660
10637
|
console.log(`Upgrade: ${next.upgradeUrl}`);
|
|
10661
10638
|
}
|
|
10662
|
-
console.log(formatAgentStatus(AGENT_ACTION, "
|
|
10639
|
+
console.log(formatAgentStatus(AGENT_ACTION, "Read .viberaven/agent-tasklist.md, run the next command above, then rescan."));
|
|
10663
10640
|
console.log("");
|
|
10664
10641
|
if (artifact.usage) {
|
|
10665
10642
|
const lanes = artifact.usage.unlockedMapCategoryKeys.length;
|
|
@@ -10923,10 +10900,10 @@ function sleepForRunnerPoll(ms, signal) {
|
|
|
10923
10900
|
if (signal?.aborted) {
|
|
10924
10901
|
return Promise.reject(createRunnerWatchAbortError());
|
|
10925
10902
|
}
|
|
10926
|
-
return new Promise((
|
|
10903
|
+
return new Promise((resolve6, reject) => {
|
|
10927
10904
|
const timer = setTimeout(() => {
|
|
10928
10905
|
cleanup();
|
|
10929
|
-
|
|
10906
|
+
resolve6();
|
|
10930
10907
|
}, ms);
|
|
10931
10908
|
const onAbort = () => {
|
|
10932
10909
|
cleanup();
|
|
@@ -11498,9 +11475,9 @@ function formatRepoMatch(repoMatch) {
|
|
|
11498
11475
|
}
|
|
11499
11476
|
}
|
|
11500
11477
|
async function runCommand(command, args, cwd) {
|
|
11501
|
-
return new Promise((
|
|
11478
|
+
return new Promise((resolve6) => {
|
|
11502
11479
|
(0, import_node_child_process3.execFile)(command, args, { cwd, windowsHide: true }, (error, stdout, stderr) => {
|
|
11503
|
-
|
|
11480
|
+
resolve6({
|
|
11504
11481
|
ok: !error,
|
|
11505
11482
|
stdout: String(stdout ?? ""),
|
|
11506
11483
|
stderr: String(stderr ?? "")
|
|
@@ -11645,9 +11622,9 @@ var init_runnerConnect = __esm({
|
|
|
11645
11622
|
}
|
|
11646
11623
|
});
|
|
11647
11624
|
|
|
11648
|
-
// node_modules/sisteransi/src/index.js
|
|
11625
|
+
// ../../node_modules/sisteransi/src/index.js
|
|
11649
11626
|
var require_src = __commonJS({
|
|
11650
|
-
"node_modules/sisteransi/src/index.js"(exports2, module2) {
|
|
11627
|
+
"../../node_modules/sisteransi/src/index.js"(exports2, module2) {
|
|
11651
11628
|
"use strict";
|
|
11652
11629
|
var ESC = "\x1B";
|
|
11653
11630
|
var CSI = `${ESC}[`;
|
|
@@ -11701,7 +11678,7 @@ var require_src = __commonJS({
|
|
|
11701
11678
|
}
|
|
11702
11679
|
});
|
|
11703
11680
|
|
|
11704
|
-
// node_modules/@clack/core/dist/index.mjs
|
|
11681
|
+
// ../../node_modules/@clack/core/dist/index.mjs
|
|
11705
11682
|
function DD({ onlyFirst: e2 = false } = {}) {
|
|
11706
11683
|
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("|");
|
|
11707
11684
|
return new RegExp(t, e2 ? void 0 : "g");
|
|
@@ -11813,7 +11790,7 @@ function fD({ input: e2 = import_node_process.stdin, output: u2 = import_node_pr
|
|
|
11813
11790
|
}
|
|
11814
11791
|
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;
|
|
11815
11792
|
var init_dist = __esm({
|
|
11816
|
-
"node_modules/@clack/core/dist/index.mjs"() {
|
|
11793
|
+
"../../node_modules/@clack/core/dist/index.mjs"() {
|
|
11817
11794
|
import_sisteransi = __toESM(require_src(), 1);
|
|
11818
11795
|
import_node_process = require("node:process");
|
|
11819
11796
|
g = __toESM(require("node:readline"), 1);
|
|
@@ -11939,7 +11916,7 @@ var init_dist = __esm({
|
|
|
11939
11916
|
xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
11940
11917
|
B = { actions: new Set(xD), aliases: /* @__PURE__ */ new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["", "cancel"], ["escape", "cancel"]]) };
|
|
11941
11918
|
AD = globalThis.process.platform.startsWith("win");
|
|
11942
|
-
S = Symbol("clack:cancel");
|
|
11919
|
+
S = /* @__PURE__ */ Symbol("clack:cancel");
|
|
11943
11920
|
gD = Object.defineProperty;
|
|
11944
11921
|
vD = (e2, u2, t) => u2 in e2 ? gD(e2, u2, { enumerable: true, configurable: true, writable: true, value: t }) : e2[u2] = t;
|
|
11945
11922
|
h = (e2, u2, t) => (vD(e2, typeof u2 != "symbol" ? u2 + "" : u2, t), t);
|
|
@@ -12063,13 +12040,13 @@ var init_dist = __esm({
|
|
|
12063
12040
|
}
|
|
12064
12041
|
});
|
|
12065
12042
|
|
|
12066
|
-
// node_modules/@clack/prompts/dist/index.mjs
|
|
12043
|
+
// ../../node_modules/@clack/prompts/dist/index.mjs
|
|
12067
12044
|
function ce() {
|
|
12068
12045
|
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";
|
|
12069
12046
|
}
|
|
12070
12047
|
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;
|
|
12071
12048
|
var init_dist2 = __esm({
|
|
12072
|
-
"node_modules/@clack/prompts/dist/index.mjs"() {
|
|
12049
|
+
"../../node_modules/@clack/prompts/dist/index.mjs"() {
|
|
12073
12050
|
init_dist();
|
|
12074
12051
|
init_dist();
|
|
12075
12052
|
import_node_process2 = __toESM(require("node:process"), 1);
|
|
@@ -12253,16 +12230,16 @@ function originalHint(gap) {
|
|
|
12253
12230
|
function buildAgentFixPrompt(artifact, gap) {
|
|
12254
12231
|
const affected = [gap.primaryMapCategory, ...gap.affectedMapCategories ?? []].filter(Boolean).filter((value, index, all) => all.indexOf(value) === index).join(", ");
|
|
12255
12232
|
return [
|
|
12256
|
-
"You are an AI coding agent using VibeRaven as the
|
|
12233
|
+
"You are an AI coding agent using VibeRaven as the what-changed layer for a real app.",
|
|
12257
12234
|
"",
|
|
12258
|
-
"Goal:
|
|
12235
|
+
"Goal: understand what changed, which provider context matters, and fix one repo-code gap at a time.",
|
|
12259
12236
|
"",
|
|
12260
12237
|
`Project: ${artifact.workspacePath}`,
|
|
12261
|
-
`Current VibeRaven state:
|
|
12238
|
+
`Current VibeRaven state: context core ${artifact.productionCorePercent}% | score ${artifact.score} (${artifact.scoreLabel})`,
|
|
12262
12239
|
`Gap: ${gap.title}`,
|
|
12263
12240
|
`Gap id: ${gap.id}`,
|
|
12264
12241
|
`Severity: ${gap.severity}`,
|
|
12265
|
-
`
|
|
12242
|
+
`Context area: ${gap.primaryMapCategory}${affected ? ` | affected: ${affected}` : ""}`,
|
|
12266
12243
|
`Scanner detail: ${compact(gap.detail)}`,
|
|
12267
12244
|
"",
|
|
12268
12245
|
"Required workflow:",
|
|
@@ -12272,7 +12249,7 @@ function buildAgentFixPrompt(artifact, gap) {
|
|
|
12272
12249
|
"4. Inspect the real implementation files. Do not assume framework/provider wiring from package names alone.",
|
|
12273
12250
|
"5. Make the smallest durable repo-code change that addresses this specific gap.",
|
|
12274
12251
|
"6. Keep provider dashboard work separate. Open provider dashboards only when VibeRaven asks for a provider/manual action, and explain why you opened them.",
|
|
12275
|
-
`7. For Vercel + Supabase apps, run \`${PUBLIC_AUDIT_COMMAND}\` before claiming
|
|
12252
|
+
`7. For Vercel + Supabase apps, run \`${PUBLIC_AUDIT_COMMAND}\` before claiming the fix is grounded.`,
|
|
12276
12253
|
"8. Treat that audit as local repo evidence only; do not claim provider dashboard settings are fixed unless the user verifies them or read-only provider MCP confirms them.",
|
|
12277
12254
|
"9. Do not claim provider dashboard or read-only MCP checks as repo-code fixes.",
|
|
12278
12255
|
`10. VibeRaven cleanup is non-destructive. You may run \`${PUBLIC_CLEAN_PLAN_COMMAND}\` only to create a reviewable context cleanup plan, not to delete code.`,
|
|
@@ -12304,7 +12281,7 @@ var VERSION;
|
|
|
12304
12281
|
var init_version = __esm({
|
|
12305
12282
|
"src/version.ts"() {
|
|
12306
12283
|
"use strict";
|
|
12307
|
-
VERSION = "1.
|
|
12284
|
+
VERSION = "1.3.0";
|
|
12308
12285
|
}
|
|
12309
12286
|
});
|
|
12310
12287
|
|
|
@@ -12400,186 +12377,20 @@ function redactEvidenceLine(line) {
|
|
|
12400
12377
|
function lineEvidence(file, pattern) {
|
|
12401
12378
|
return file.content.split(/\r?\n/).map((line, index) => ({ line: line.trim(), lineNumber: index + 1 })).filter(({ line }) => pattern.test(line)).map(({ line, lineNumber }) => `${file.path}:${lineNumber}: ${redactEvidenceLine(line)}`);
|
|
12402
12379
|
}
|
|
12403
|
-
function lineNumberAt(content, index) {
|
|
12404
|
-
return content.slice(0, index).split(/\r?\n/).length;
|
|
12405
|
-
}
|
|
12406
|
-
function statementEvidence(file, pattern) {
|
|
12407
|
-
const evidence = [];
|
|
12408
|
-
for (const match of file.content.matchAll(pattern)) {
|
|
12409
|
-
evidence.push(
|
|
12410
|
-
`${file.path}:${lineNumberAt(file.content, match.index ?? 0)}: ${redactEvidenceLine(
|
|
12411
|
-
String(match[0]).replace(/\s+/g, " ").trim()
|
|
12412
|
-
)}`
|
|
12413
|
-
);
|
|
12414
|
-
}
|
|
12415
|
-
return evidence;
|
|
12416
|
-
}
|
|
12417
|
-
function normalizeIdent(value) {
|
|
12418
|
-
return (value ?? "").replace(/^"|"$/g, "").toLowerCase();
|
|
12419
|
-
}
|
|
12420
|
-
function canonicalPublicTable(schema, table) {
|
|
12421
|
-
const normalizedSchema = normalizeIdent(schema);
|
|
12422
|
-
if (normalizedSchema && normalizedSchema !== "public") {
|
|
12423
|
-
return void 0;
|
|
12424
|
-
}
|
|
12425
|
-
return `public.${normalizeIdent(table)}`;
|
|
12426
|
-
}
|
|
12427
|
-
function parseRelationRef(ref) {
|
|
12428
|
-
const parts = ref.split(".").map((part) => normalizeIdent(part.trim()));
|
|
12429
|
-
if (parts.length === 1) {
|
|
12430
|
-
return `public.${parts[0]}`;
|
|
12431
|
-
}
|
|
12432
|
-
if (parts.length === 2 && parts[0] === "public") {
|
|
12433
|
-
return `public.${parts[1]}`;
|
|
12434
|
-
}
|
|
12435
|
-
return void 0;
|
|
12436
|
-
}
|
|
12437
|
-
function relationEvidence(files, pattern, relationGroup = "relation") {
|
|
12438
|
-
const evidence = [];
|
|
12439
|
-
for (const file of files) {
|
|
12440
|
-
for (const match of file.content.matchAll(pattern)) {
|
|
12441
|
-
const groups = match.groups ?? {};
|
|
12442
|
-
const relation = parseRelationRef(String(groups[relationGroup] ?? ""));
|
|
12443
|
-
if (!relation) {
|
|
12444
|
-
continue;
|
|
12445
|
-
}
|
|
12446
|
-
evidence.push({
|
|
12447
|
-
relation,
|
|
12448
|
-
evidence: `${file.path}:${lineNumberAt(file.content, match.index ?? 0)}: ${redactEvidenceLine(
|
|
12449
|
-
String(match[0]).replace(/\s+/g, " ").trim()
|
|
12450
|
-
)}`
|
|
12451
|
-
});
|
|
12452
|
-
}
|
|
12453
|
-
}
|
|
12454
|
-
return evidence;
|
|
12455
|
-
}
|
|
12456
12380
|
function sqlFiles(files) {
|
|
12457
12381
|
return files.filter((file) => file.path.toLowerCase().endsWith(".sql"));
|
|
12458
12382
|
}
|
|
12459
12383
|
function buildRlsCheck(files) {
|
|
12460
12384
|
const sql = sqlFiles(files);
|
|
12461
|
-
const createdTables = [];
|
|
12462
|
-
for (const file of sql) {
|
|
12463
|
-
const pattern = /\bcreate\s+table\s+(?:if\s+not\s+exists\s+)?(?:(?<schema>"?[A-Za-z_][\w$]*"?)\.)?(?<table>"?[A-Za-z_][\w$]*"?)/gi;
|
|
12464
|
-
for (const match of file.content.matchAll(pattern)) {
|
|
12465
|
-
const relation = canonicalPublicTable(match.groups?.schema, String(match.groups?.table ?? ""));
|
|
12466
|
-
if (!relation) {
|
|
12467
|
-
continue;
|
|
12468
|
-
}
|
|
12469
|
-
createdTables.push({
|
|
12470
|
-
relation,
|
|
12471
|
-
evidence: `${file.path}:${lineNumberAt(file.content, match.index ?? 0)}: ${redactEvidenceLine(
|
|
12472
|
-
String(match[0]).replace(/\s+/g, " ").trim()
|
|
12473
|
-
)}`
|
|
12474
|
-
});
|
|
12475
|
-
}
|
|
12476
|
-
}
|
|
12477
|
-
const enabledTables = new Set(
|
|
12478
|
-
relationEvidence(
|
|
12479
|
-
sql,
|
|
12480
|
-
/\balter\s+table\s+(?:if\s+exists\s+)?(?:only\s+)?(?<relation>(?:"?[A-Za-z_][\w$]*"?\.)?"?[A-Za-z_][\w$]*"?)\s+enable\s+row\s+level\s+security\b/gi
|
|
12481
|
-
).map((item4) => item4.relation)
|
|
12482
|
-
);
|
|
12483
|
-
const policyTables = new Set(
|
|
12484
|
-
relationEvidence(
|
|
12485
|
-
sql,
|
|
12486
|
-
/\bcreate\s+policy\b[\s\S]*?\bon\s+(?<relation>(?:"?[A-Za-z_][\w$]*"?\.)?"?[A-Za-z_][\w$]*"?)[\s\S]*?;/gi
|
|
12487
|
-
).map((item4) => item4.relation)
|
|
12488
|
-
);
|
|
12489
12385
|
const rlsEvidence2 = sql.flatMap((file) => lineEvidence(file, /\benable\s+row\s+level\s+security\b/i));
|
|
12490
12386
|
const policyEvidence = sql.flatMap((file) => lineEvidence(file, /\bcreate\s+policy\b/i));
|
|
12491
|
-
const
|
|
12492
|
-
const status = createdTables.length > 0 ? missingTableEvidence.length === 0 ? "pass" : "needs_work" : rlsEvidence2.length > 0 && policyEvidence.length > 0 ? "pass" : "needs_work";
|
|
12387
|
+
const status = rlsEvidence2.length > 0 && policyEvidence.length > 0 ? "pass" : "needs_work";
|
|
12493
12388
|
return {
|
|
12494
12389
|
id: "supabase-rls-policy-proof",
|
|
12495
12390
|
title: "Supabase RLS policy proof",
|
|
12496
12391
|
status,
|
|
12497
|
-
summary: status === "pass" ?
|
|
12498
|
-
evidence: [...
|
|
12499
|
-
};
|
|
12500
|
-
}
|
|
12501
|
-
function buildRlsPolicyQualityCheck(files) {
|
|
12502
|
-
const sql = sqlFiles(files);
|
|
12503
|
-
const evidence = sql.flatMap(
|
|
12504
|
-
(file) => statementEvidence(file, /\bcreate\s+policy\b[\s\S]*?\b(?:using|with\s+check)\s*\(\s*true\s*\)[\s\S]*?;/gi)
|
|
12505
|
-
);
|
|
12506
|
-
const status = evidence.length === 0 ? "pass" : "needs_work";
|
|
12507
|
-
return {
|
|
12508
|
-
id: "supabase-rls-policy-quality",
|
|
12509
|
-
title: "Supabase RLS policy quality",
|
|
12510
|
-
status,
|
|
12511
|
-
summary: status === "pass" ? "No permissive `using (true)` or `with check (true)` policy evidence found." : "Found RLS policies that allow every row. Public access may be intentional, but it must be reviewed before production.",
|
|
12512
|
-
evidence: evidence.slice(0, 5)
|
|
12513
|
-
};
|
|
12514
|
-
}
|
|
12515
|
-
function buildViewSecurityInvokerCheck(files) {
|
|
12516
|
-
const sql = sqlFiles(files);
|
|
12517
|
-
const secureViews = /* @__PURE__ */ new Set();
|
|
12518
|
-
const insecureEvidence = [];
|
|
12519
|
-
for (const file of sql) {
|
|
12520
|
-
for (const match of file.content.matchAll(
|
|
12521
|
-
/\bcreate\s+(?:or\s+replace\s+)?view\s+(?<relation>(?:"?[A-Za-z_][\w$]*"?\.)?"?[A-Za-z_][\w$]*"?)[\s\S]*?;/gi
|
|
12522
|
-
)) {
|
|
12523
|
-
const relation = parseRelationRef(String(match.groups?.relation ?? ""));
|
|
12524
|
-
if (!relation) {
|
|
12525
|
-
continue;
|
|
12526
|
-
}
|
|
12527
|
-
const statement = String(match[0]);
|
|
12528
|
-
if (/\bsecurity_invoker\b/i.test(statement)) {
|
|
12529
|
-
secureViews.add(relation);
|
|
12530
|
-
continue;
|
|
12531
|
-
}
|
|
12532
|
-
insecureEvidence.push({
|
|
12533
|
-
relation,
|
|
12534
|
-
evidence: `${file.path}:${lineNumberAt(file.content, match.index ?? 0)}: ${redactEvidenceLine(
|
|
12535
|
-
statement.replace(/\s+/g, " ").trim()
|
|
12536
|
-
)}`
|
|
12537
|
-
});
|
|
12538
|
-
}
|
|
12539
|
-
for (const match of file.content.matchAll(
|
|
12540
|
-
/\balter\s+view\s+(?<relation>(?:"?[A-Za-z_][\w$]*"?\.)?"?[A-Za-z_][\w$]*"?)[\s\S]*?\bsecurity_invoker\s*=\s*true\b[\s\S]*?;/gi
|
|
12541
|
-
)) {
|
|
12542
|
-
const relation = parseRelationRef(String(match.groups?.relation ?? ""));
|
|
12543
|
-
if (relation) {
|
|
12544
|
-
secureViews.add(relation);
|
|
12545
|
-
}
|
|
12546
|
-
}
|
|
12547
|
-
}
|
|
12548
|
-
const evidence = insecureEvidence.filter(({ relation }) => !secureViews.has(relation)).map(({ evidence: evidence2 }) => evidence2);
|
|
12549
|
-
const status = evidence.length === 0 ? "pass" : "needs_work";
|
|
12550
|
-
return {
|
|
12551
|
-
id: "supabase-view-security-invoker",
|
|
12552
|
-
title: "Supabase view security invoker",
|
|
12553
|
-
status,
|
|
12554
|
-
summary: status === "pass" ? "No public view evidence without `security_invoker` found." : "Found public Supabase views without `security_invoker` evidence. Views can bypass underlying RLS by default.",
|
|
12555
|
-
evidence: evidence.slice(0, 5)
|
|
12556
|
-
};
|
|
12557
|
-
}
|
|
12558
|
-
function buildSecurityDefinerBoundaryCheck(files) {
|
|
12559
|
-
const sql = sqlFiles(files);
|
|
12560
|
-
const evidence = [];
|
|
12561
|
-
for (const file of sql) {
|
|
12562
|
-
for (const match of file.content.matchAll(
|
|
12563
|
-
/\bcreate\s+(?:or\s+replace\s+)?function\s+(?<relation>(?:"?[A-Za-z_][\w$]*"?\.)?"?[A-Za-z_][\w$]*"?)[\s\S]*?\bsecurity\s+definer\b[\s\S]*?;/gi
|
|
12564
|
-
)) {
|
|
12565
|
-
const relation = parseRelationRef(String(match.groups?.relation ?? ""));
|
|
12566
|
-
if (!relation) {
|
|
12567
|
-
continue;
|
|
12568
|
-
}
|
|
12569
|
-
evidence.push(
|
|
12570
|
-
`${file.path}:${lineNumberAt(file.content, match.index ?? 0)}: ${redactEvidenceLine(
|
|
12571
|
-
String(match[0]).replace(/\s+/g, " ").trim()
|
|
12572
|
-
)}`
|
|
12573
|
-
);
|
|
12574
|
-
}
|
|
12575
|
-
}
|
|
12576
|
-
const status = evidence.length === 0 ? "pass" : "needs_work";
|
|
12577
|
-
return {
|
|
12578
|
-
id: "supabase-security-definer-boundary",
|
|
12579
|
-
title: "Supabase security definer boundary",
|
|
12580
|
-
status,
|
|
12581
|
-
summary: status === "pass" ? "No `security definer` functions in the public schema were found." : "Found `security definer` functions in the public schema. Keep privileged functions in a private, unexposed schema.",
|
|
12582
|
-
evidence: evidence.slice(0, 5)
|
|
12392
|
+
summary: status === "pass" ? "Found SQL evidence for row level security and at least one policy." : "Missing SQL evidence for both `enable row level security` and `create policy`.",
|
|
12393
|
+
evidence: [...rlsEvidence2.slice(0, 5), ...policyEvidence.slice(0, 5)]
|
|
12583
12394
|
};
|
|
12584
12395
|
}
|
|
12585
12396
|
function buildPoolerCheck(files) {
|
|
@@ -12623,9 +12434,6 @@ function buildServiceRoleCheck(files) {
|
|
|
12623
12434
|
function buildVercelSupabaseAudit(input) {
|
|
12624
12435
|
const checks = [
|
|
12625
12436
|
buildRlsCheck(input.files),
|
|
12626
|
-
buildRlsPolicyQualityCheck(input.files),
|
|
12627
|
-
buildViewSecurityInvokerCheck(input.files),
|
|
12628
|
-
buildSecurityDefinerBoundaryCheck(input.files),
|
|
12629
12437
|
buildPoolerCheck(input.files),
|
|
12630
12438
|
buildServiceRoleCheck(input.files)
|
|
12631
12439
|
];
|
|
@@ -12874,7 +12682,7 @@ function normalizeLineEndings(value) {
|
|
|
12874
12682
|
function escapeRegExp3(value) {
|
|
12875
12683
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12876
12684
|
}
|
|
12877
|
-
var VIBERAVEN_BLOCK_START, VIBERAVEN_BLOCK_END, VIBERAVEN_LEGACY_BLOCK_START, VIBERAVEN_LEGACY_BLOCK_END, HEAL_PLAN_GAP_COMMAND, PROMPT_GAP_COMMAND, HEAL_APPLY_GAP_COMMAND, AGENT_RULES_PREAMBLE, STACK_FRAMING,
|
|
12685
|
+
var VIBERAVEN_BLOCK_START, VIBERAVEN_BLOCK_END, VIBERAVEN_LEGACY_BLOCK_START, VIBERAVEN_LEGACY_BLOCK_END, HEAL_PLAN_GAP_COMMAND, PROMPT_GAP_COMMAND, HEAL_APPLY_GAP_COMMAND, AGENT_RULES_PREAMBLE, STACK_FRAMING, ARCHITECTURE_ORIENTATION, AGENT_NEGATIVE_CONSTRAINTS, ANCHOR_FOOTER, AGENT_RULES_BODY, AGENT_CONTEXT_BODY, MISSION_MAP_BODY, BLOCK_MARKER_PAIRS;
|
|
12878
12686
|
var init_agentRulesBlock = __esm({
|
|
12879
12687
|
"src/commands/agentRulesBlock.ts"() {
|
|
12880
12688
|
"use strict";
|
|
@@ -12886,65 +12694,88 @@ var init_agentRulesBlock = __esm({
|
|
|
12886
12694
|
HEAL_PLAN_GAP_COMMAND = healPlanGapCommand("<id>");
|
|
12887
12695
|
PROMPT_GAP_COMMAND = promptGapCommand("<id>");
|
|
12888
12696
|
HEAL_APPLY_GAP_COMMAND = `${PUBLIC_COMMAND} --heal --apply --gap <id> --yes`;
|
|
12889
|
-
AGENT_RULES_PREAMBLE = `
|
|
12697
|
+
AGENT_RULES_PREAMBLE = `AI agents can code. They still need senior-engineer context before they change real apps.
|
|
12890
12698
|
|
|
12891
|
-
Canonical command: \`${
|
|
12699
|
+
Canonical Studio command: \`${PUBLIC_COMMAND}\`
|
|
12892
12700
|
|
|
12893
|
-
|
|
12701
|
+
Non-interactive artifact loop: \`${PUBLIC_AGENT_MODE_COMMAND}\`
|
|
12894
12702
|
|
|
12895
|
-
|
|
12703
|
+
Use VibeRaven at the start of production-sensitive coding work, feature work, provider work, release/version debugging, or launch work, including when the agent needs to know which version broke or what provider context matters.
|
|
12896
12704
|
|
|
12897
|
-
|
|
12705
|
+
Default loop: orient the architecture, ask only the missing questions needed for a safe plan, inspect release/provider context, choose the right VibeRaven skill, fix one evidenced change, then verify.
|
|
12706
|
+
|
|
12707
|
+
Maps repo evidence, release drift, architecture boundaries, and provider boundaries into agent-readable context.`;
|
|
12898
12708
|
STACK_FRAMING = `Stack context for this repo: Next.js, Supabase, Vercel, VibeRaven.
|
|
12899
|
-
Do NOT deploy to Vercel or ship to production users without
|
|
12900
|
-
Do NOT rely on manual
|
|
12901
|
-
|
|
12709
|
+
Do NOT deploy to Vercel or ship to production users without VibeRaven architecture/release/provider context.
|
|
12710
|
+
Do NOT rely on manual checklists when VibeRaven artifacts exist in \`.viberaven/\`.`;
|
|
12711
|
+
ARCHITECTURE_ORIENTATION = `## VibeRaven Architecture Orientation
|
|
12712
|
+
|
|
12713
|
+
At the start of a real app task, before writing a plan or editing code:
|
|
12714
|
+
|
|
12715
|
+
1. Identify the product surface, user path, and desired outcome.
|
|
12716
|
+
2. Map the architecture boundary involved: UI/API, auth/session, data/schema/RLS, provider dashboard, deploy/env, background job/webhook, billing, storage, or release/version drift.
|
|
12717
|
+
3. Check existing VibeRaven context: \`.viberaven/production-context.md\`, \`.viberaven/agent-context.md\`, \`.viberaven/mission-map.md\`, and recent git history when present.
|
|
12718
|
+
4. Ask concise questions only when the missing answer changes the plan, such as last working version, provider involved, production symptom, deploy target, or whether dashboard proof exists.
|
|
12719
|
+
5. Build the plan around the architecture boundary first, then the code change. Do not start from the nearest file.
|
|
12720
|
+
6. Route to the suited VibeRaven skill:
|
|
12721
|
+
- \`what-broke\` for regressions, version drift, or "worked yesterday" bugs.
|
|
12722
|
+
- \`production-context\` for release notes, architecture memory, provider boundaries, migrations, incidents, and rollback notes.
|
|
12723
|
+
- \`viberaven\` for Studio, MCP context, provider cards, connected agents, access modes, and release/version context.
|
|
12724
|
+
- \`go-live\` for push, deploy, live URL proof, and provider/human launch boundaries.
|
|
12902
12725
|
|
|
12903
|
-
|
|
12726
|
+
Output shape before implementation:
|
|
12904
12727
|
|
|
12905
|
-
|
|
12906
|
-
|
|
12907
|
-
|
|
12908
|
-
4. Fix \`nextActions\` in order.
|
|
12909
|
-
5. Re-run \`${PUBLIC_AGENT_MODE_COMMAND}\`.`;
|
|
12910
|
-
AGENT_NEGATIVE_CONSTRAINTS = `## Event-Triggered Production Verification
|
|
12728
|
+
\`\`\`text
|
|
12729
|
+
Architecture boundary:
|
|
12730
|
+
- ...
|
|
12911
12731
|
|
|
12912
|
-
|
|
12732
|
+
Questions/blockers:
|
|
12733
|
+
- ... or none
|
|
12913
12734
|
|
|
12914
|
-
|
|
12735
|
+
Plan:
|
|
12736
|
+
- ...
|
|
12737
|
+
|
|
12738
|
+
VibeRaven skill/context:
|
|
12739
|
+
- ...
|
|
12740
|
+
\`\`\``;
|
|
12741
|
+
AGENT_NEGATIVE_CONSTRAINTS = `## Event-Triggered Context Check
|
|
12742
|
+
|
|
12743
|
+
Trigger: modifications to \`package.json\`, \`vercel.json\`, \`supabase/migrations/**/*\`, \`.env.example\`, provider-sensitive paths, or deploy workflow files.
|
|
12744
|
+
|
|
12745
|
+
1. Do NOT claim the app is ready to ship until \`decision.status\` is not \`blocked\` and \`gate.status === "clear"\` in \`.viberaven/gate-result.json\`.
|
|
12915
12746
|
2. Do NOT run verify after every file patch. Batch heals, then \`${PUBLIC_VERIFY_COMMAND}\` once per loop.
|
|
12916
|
-
3. Do NOT \`git push\` or deploy after
|
|
12747
|
+
3. Do NOT \`git push\` or deploy after provider-sensitive changes without VibeRaven architecture/release/provider context.
|
|
12917
12748
|
4. If anomalies appear, read \`.viberaven/agent-tasklist.md\` fully before writing new repo logic.
|
|
12918
|
-
5. Do NOT mark
|
|
12749
|
+
5. Do NOT mark the app ready because the local dev server starts successfully; INSTEAD open Studio or run the artifact loop and read \`.viberaven/gate-result.json\`.
|
|
12919
12750
|
6. Do NOT treat the Supabase dashboard UI as proof of RLS; INSTEAD fix repo evidence gaps from \`.viberaven/agent-tasklist.md\`.
|
|
12920
|
-
7. Do NOT add or change npm dependencies without calling \`viberaven_validate_npm_package\` (MCP) or verifying the package exists on the public npm registry; INSTEAD
|
|
12751
|
+
7. Do NOT add or change npm dependencies without calling \`viberaven_validate_npm_package\` (MCP) or verifying the package exists on the public npm registry; INSTEAD refresh architecture/release/provider context after dependency changes.
|
|
12921
12752
|
8. Do NOT refactor or edit files unrelated to the current TASK-001 gap; INSTEAD make minimal, targeted changes.
|
|
12922
12753
|
9. Do NOT install new dependencies unless TASK-001 or the user explicitly requires them.
|
|
12923
|
-
10. Do NOT claim provider
|
|
12754
|
+
10. Do NOT claim live provider state is complete from repo edits alone; INSTEAD name the provider proof or dashboard action still needed.
|
|
12924
12755
|
|
|
12925
|
-
Prefer \`viberaven_check_readiness\` when MCP is configured; otherwise \`${PUBLIC_AGENT_MODE_COMMAND}
|
|
12756
|
+
Prefer \`viberaven_check_readiness\` when MCP is configured; otherwise \`${PUBLIC_COMMAND}\` for Studio or \`${PUBLIC_AGENT_MODE_COMMAND}\` for artifacts.`;
|
|
12926
12757
|
ANCHOR_FOOTER = `## Anchor (mandatory)
|
|
12927
12758
|
|
|
12928
|
-
Before ending any deploy,
|
|
12929
|
-
\`${
|
|
12930
|
-
|
|
12759
|
+
Before ending any deploy, provider-sensitive, database-policy, or dependency task, open Studio or run the artifact loop:
|
|
12760
|
+
\`${PUBLIC_COMMAND}\`
|
|
12761
|
+
Context is not clear until \`gate.status === "clear"\` in \`.viberaven/gate-result.json\`.`;
|
|
12931
12762
|
AGENT_RULES_BODY = `${AGENT_RULES_PREAMBLE}
|
|
12932
12763
|
|
|
12933
12764
|
${STACK_FRAMING}
|
|
12934
12765
|
|
|
12935
|
-
${
|
|
12766
|
+
${ARCHITECTURE_ORIENTATION}
|
|
12936
12767
|
|
|
12937
12768
|
${AGENT_NEGATIVE_CONSTRAINTS}
|
|
12938
12769
|
|
|
12939
|
-
## VibeRaven
|
|
12770
|
+
## VibeRaven What-Changed Layer
|
|
12940
12771
|
|
|
12941
|
-
- Before running build, compile, cleanup, deployment, vercel, or supabase commands,
|
|
12942
|
-
- Treat VibeRaven as
|
|
12943
|
-
- Read \`.viberaven/agent-tasklist.md\` first. If it says CRITICAL GAPS DETECTED or
|
|
12772
|
+
- Before running build, compile, cleanup, deployment, vercel, or supabase commands, open Studio with \`${PUBLIC_COMMAND}\` or run the artifact loop when non-interactive context is needed.
|
|
12773
|
+
- Treat VibeRaven as senior-engineer architecture, release drift, and provider context for AI-built apps: identify the boundary, what changed, which version broke, and what provider state matters before editing.
|
|
12774
|
+
- Read \`.viberaven/agent-tasklist.md\` first. If it says CRITICAL GAPS DETECTED or the decision is not clear, fix one listed repo-code gap before deploying.
|
|
12944
12775
|
- Read \`.viberaven/gate-result.json\` for the machine verdict.
|
|
12945
12776
|
- Read \`.viberaven/context-map.json\` for compact agent context.
|
|
12946
12777
|
- Read \`.viberaven/agent-summary.md\` second for scan context.
|
|
12947
|
-
- Read \`.viberaven/launch-playbook.md\` third for the full
|
|
12778
|
+
- Read \`.viberaven/launch-playbook.md\` third for the full context map.
|
|
12948
12779
|
- Use \`${PUBLIC_NEXT_JSON_COMMAND}\` or \`${PROMPT_GAP_COMMAND}\` for one focused repo-code fix at a time.
|
|
12949
12780
|
- For Vercel + Supabase launch checks, run \`${PUBLIC_AUDIT_COMMAND}\`.
|
|
12950
12781
|
- Run \`${PUBLIC_VERIFY_COMMAND}\` after one fix.
|
|
@@ -12953,11 +12784,11 @@ ${AGENT_NEGATIVE_CONSTRAINTS}
|
|
|
12953
12784
|
- Only use \`${HEAL_APPLY_GAP_COMMAND}\` for supported low-risk repo-code recipes.
|
|
12954
12785
|
- Preview local rule installation with \`${PUBLIC_INIT_ALL_COMMAND} --dry-run\`.
|
|
12955
12786
|
- Cleanup is non-destructive: only run \`${PUBLIC_CLEAN_PLAN_COMMAND}\` to create a reviewable cleanup plan.
|
|
12956
|
-
- Provider dashboard checks are not cleared by repo-code edits.
|
|
12787
|
+
- Provider dashboard checks are not cleared by repo-code edits. Database rules, storage behavior, deployment/runtime behavior, quotas, dashboard toggles, and live provider proof must be completed or verified in the provider dashboard or through read-only provider MCP evidence.
|
|
12957
12788
|
- Do not claim provider dashboard work is fixed by repo-code edits.
|
|
12958
12789
|
- If VibeRaven prints \`LOGIN_URL_READY\`, open that URL for the user using the available browser tool or system browser. Tell the user: "I opened VibeRaven sign-in so you can approve access; I will continue after approval." Do not ask for passwords, tokens, cookies, or secrets. Keep the terminal process alive while the user approves.
|
|
12959
12790
|
|
|
12960
|
-
## VibeRaven
|
|
12791
|
+
## VibeRaven What-Changed Loop
|
|
12961
12792
|
|
|
12962
12793
|
After every scan, read \`.viberaven/agent-tasklist.md\` for the prioritized task list.
|
|
12963
12794
|
|
|
@@ -12978,23 +12809,24 @@ The loop is:
|
|
|
12978
12809
|
- Wait for user confirmation, then verify.
|
|
12979
12810
|
9. If \`fixType === 'upgrade-required'\`, provide upgradeUrl and move on.
|
|
12980
12811
|
|
|
12981
|
-
Do not stop at "scan complete." The loop is not done until \`gate.status === 'clear'
|
|
12812
|
+
Do not stop at "scan complete." The loop is not done until the agent knows what changed, \`gate.status === 'clear'\`, and the next fix is grounded in evidence.`;
|
|
12982
12813
|
AGENT_CONTEXT_BODY = `${AGENT_RULES_PREAMBLE}
|
|
12983
12814
|
|
|
12984
12815
|
After \`--agent-mode\`, read these artifacts in order:
|
|
12985
12816
|
|
|
12986
|
-
1. \`.viberaven/
|
|
12987
|
-
2. \`.viberaven/
|
|
12988
|
-
3. \`.viberaven/
|
|
12989
|
-
4. \`.viberaven/
|
|
12990
|
-
|
|
12817
|
+
1. \`.viberaven/mission-map.md\`
|
|
12818
|
+
2. \`.viberaven/agent-tasklist.md\`
|
|
12819
|
+
3. \`.viberaven/gate-result.json\`
|
|
12820
|
+
4. \`.viberaven/context-map.json\`
|
|
12821
|
+
|
|
12822
|
+
Before editing, summarize the architecture boundary and missing questions from those artifacts.`;
|
|
12991
12823
|
MISSION_MAP_BODY = `${AGENT_RULES_PREAMBLE}
|
|
12992
12824
|
|
|
12993
12825
|
## Mission Map loop
|
|
12994
12826
|
|
|
12995
12827
|
1. Run \`${PUBLIC_AGENT_MODE_COMMAND}\` from the project root.
|
|
12996
12828
|
2. Read \`.viberaven/agent-tasklist.md\` and \`.viberaven/gate-result.json\`.
|
|
12997
|
-
3. Fix one
|
|
12829
|
+
3. Fix one evidenced change with architecture/release/provider context.
|
|
12998
12830
|
4. Re-run VibeRaven until \`gate.status === 'clear'\`.`;
|
|
12999
12831
|
BLOCK_MARKER_PAIRS = [
|
|
13000
12832
|
[VIBERAVEN_BLOCK_START, VIBERAVEN_BLOCK_END],
|
|
@@ -13010,20 +12842,24 @@ function buildCursorRulesPack() {
|
|
|
13010
12842
|
filename: "viberaven-core.mdc",
|
|
13011
12843
|
content: [
|
|
13012
12844
|
"---",
|
|
13013
|
-
"description: VibeRaven
|
|
12845
|
+
"description: VibeRaven what-changed layer for architecture, release, and provider context",
|
|
13014
12846
|
"alwaysApply: true",
|
|
13015
12847
|
"---",
|
|
13016
12848
|
"",
|
|
13017
|
-
|
|
12849
|
+
"At the start of real app work, map the architecture boundary before editing: UI/API, auth/session, data/schema/RLS, provider dashboard, deploy/env, background job/webhook, billing, storage, or release/version drift.",
|
|
12850
|
+
"",
|
|
12851
|
+
"Ask concise questions only when the answer changes the plan: last working version, production symptom, provider involved, deploy target, or provider/dashboard proof.",
|
|
12852
|
+
"",
|
|
12853
|
+
`Open Studio with \`npx -y viberaven\` for context. Run \`${PUBLIC_AGENT_MODE_COMMAND}\` before deploy, provider-sensitive, database-policy, or dependency changes when artifact context is needed.`,
|
|
13018
12854
|
"",
|
|
13019
12855
|
"Read `.viberaven/agent-tasklist.md` first, then `.viberaven/gate-result.json` and `.viberaven/mission-map.md`.",
|
|
13020
|
-
`Fix one gap, then \`${PUBLIC_VERIFY_COMMAND}\`. Before CI or production promote: \`${PUBLIC_STRICT_COMMAND}\`.`,
|
|
12856
|
+
`Fix one scoped gap, then \`${PUBLIC_VERIFY_COMMAND}\`. Before CI or production promote: \`${PUBLIC_STRICT_COMMAND}\`.`,
|
|
13021
12857
|
"",
|
|
13022
|
-
'
|
|
12858
|
+
'Context is not clear until the architecture boundary, release/version context, and provider proof boundary are understood. For launch gates, `gate.status === "clear"` is required.',
|
|
13023
12859
|
"",
|
|
13024
12860
|
DOMAIN_PATH_POINTER,
|
|
13025
12861
|
"",
|
|
13026
|
-
"Full
|
|
12862
|
+
"Full VibeRaven rules: `AGENTS.md` / `CLAUDE.md` (installed by `npx -y viberaven init --agents all`)."
|
|
13027
12863
|
].join("\n")
|
|
13028
12864
|
},
|
|
13029
12865
|
{
|
|
@@ -13130,7 +12966,7 @@ var init_cursorRulesPack = __esm({
|
|
|
13130
12966
|
init_commands();
|
|
13131
12967
|
CURSOR_RULES_DIR = ".cursor/rules";
|
|
13132
12968
|
LEGACY_CURSOR_RULE_FILE = `${CURSOR_RULES_DIR}/viberaven.mdc`;
|
|
13133
|
-
DOMAIN_PATH_POINTER = "Before editing these files, read `.viberaven/agent-context.md` and `.viberaven/mission-map.md
|
|
12969
|
+
DOMAIN_PATH_POINTER = "Before editing these files, read `.viberaven/agent-context.md` and `.viberaven/mission-map.md` for what changed, which architecture boundary is affected, and which provider context matters.";
|
|
13134
12970
|
}
|
|
13135
12971
|
});
|
|
13136
12972
|
|
|
@@ -13683,7 +13519,7 @@ async function handleOpenDashboard(cwd) {
|
|
|
13683
13519
|
function buildMenuOptions(isSignedIn) {
|
|
13684
13520
|
return [
|
|
13685
13521
|
{ value: "next", label: "What's next?", hint: "One action from last scan" },
|
|
13686
|
-
{ value: "scan", label: "Scan project", hint: "Map
|
|
13522
|
+
{ value: "scan", label: "Scan project", hint: "Map what changed" },
|
|
13687
13523
|
{ value: "open-report", label: "Open report in browser", hint: "Rebuilds UI from last scan" },
|
|
13688
13524
|
{ value: "guide", label: "Provider guide", hint: "Vercel, Supabase, Stripe steps" },
|
|
13689
13525
|
{ value: "open-dashboard", label: "Open dashboard", hint: "Browser link for next step" },
|
|
@@ -15623,7 +15459,7 @@ async function runVerifyActionCommand(input) {
|
|
|
15623
15459
|
}
|
|
15624
15460
|
process.stdout.write(
|
|
15625
15461
|
`Verifying ${entry.id} (${entry.title ?? "untitled action"}).
|
|
15626
|
-
Run \`npx -y viberaven --verify\` to refresh
|
|
15462
|
+
Run \`npx -y viberaven --verify\` to refresh VibeRaven context for this action.
|
|
15627
15463
|
`
|
|
15628
15464
|
);
|
|
15629
15465
|
return 0;
|
|
@@ -15959,10 +15795,6 @@ function providerLogoHtml(providerOrLabel, labelFallback, ...moreCandidates) {
|
|
|
15959
15795
|
}
|
|
15960
15796
|
function providerRailLogoHtml(providerOrLabel, labelFallback, ...moreCandidates) {
|
|
15961
15797
|
const key = resolveProviderLogoKey(providerOrLabel, labelFallback, ...moreCandidates) || normalizeProviderKey2(providerOrLabel);
|
|
15962
|
-
const assetUrl = key ? providerAssetUrl(key) : void 0;
|
|
15963
|
-
if (assetUrl) {
|
|
15964
|
-
return providerIconImgHtml(assetUrl, key);
|
|
15965
|
-
}
|
|
15966
15798
|
const iconUrl = key && LOCAL_UI_BRAND_ICON_KEYS.has(key) ? PROVIDER_ICON_URLS[key] : void 0;
|
|
15967
15799
|
if (iconUrl) {
|
|
15968
15800
|
return providerIconImgHtml(iconUrl, key);
|
|
@@ -16098,18 +15930,6 @@ var init_providerLogos = __esm({
|
|
|
16098
15930
|
"svelte"
|
|
16099
15931
|
]);
|
|
16100
15932
|
PROVIDER_ASSET_FILES = {
|
|
16101
|
-
auth: "provider-auth.png",
|
|
16102
|
-
clerk: "provider-clerk.png",
|
|
16103
|
-
database: "provider-database.png",
|
|
16104
|
-
env: "provider-env.png",
|
|
16105
|
-
github: "provider-github.png",
|
|
16106
|
-
posthog: "provider-posthog.png",
|
|
16107
|
-
resend: "provider-resend.png",
|
|
16108
|
-
sentry: "provider-sentry.png",
|
|
16109
|
-
stripe: "provider-stripe.png",
|
|
16110
|
-
supabase: "provider-supabase.png",
|
|
16111
|
-
upstash: "provider-upstash.png",
|
|
16112
|
-
vercel: "provider-vercel.png",
|
|
16113
15933
|
authjs: "provider-authjs.svg",
|
|
16114
15934
|
logrocket: "provider-logrocket.svg",
|
|
16115
15935
|
aws: "provider-aws.svg"
|
|
@@ -16127,16 +15947,16 @@ var init_providerLogos = __esm({
|
|
|
16127
15947
|
turso: "https://cdn.simpleicons.org/turso/4FF8D2",
|
|
16128
15948
|
"lemon-squeezy": "https://cdn.simpleicons.org/lemonsqueezy/FFC233",
|
|
16129
15949
|
stripe: "https://cdn.simpleicons.org/stripe/635BFF",
|
|
16130
|
-
github: "https://cdn.simpleicons.org/github/
|
|
15950
|
+
github: "https://cdn.simpleicons.org/github/FFFFFF",
|
|
16131
15951
|
gitlab: "https://cdn.simpleicons.org/gitlab/FC6D26",
|
|
16132
|
-
vercel: "https://cdn.simpleicons.org/vercel/
|
|
15952
|
+
vercel: "https://cdn.simpleicons.org/vercel/FFFFFF",
|
|
16133
15953
|
netlify: "https://cdn.simpleicons.org/netlify/00C7B7",
|
|
16134
15954
|
render: "https://cdn.simpleicons.org/render/46E3B7",
|
|
16135
15955
|
railway: "https://cdn.simpleicons.org/railway/0B0D0E",
|
|
16136
15956
|
cloudflare: "https://cdn.simpleicons.org/cloudflare/F38020",
|
|
16137
|
-
sentry: "https://cdn.simpleicons.org/sentry/
|
|
15957
|
+
sentry: "https://cdn.simpleicons.org/sentry/8B5CF6",
|
|
16138
15958
|
posthog: "https://cdn.simpleicons.org/posthog/F54E00",
|
|
16139
|
-
resend: "https://cdn.simpleicons.org/resend/
|
|
15959
|
+
resend: "https://cdn.simpleicons.org/resend/FFFFFF",
|
|
16140
15960
|
upstash: "https://cdn.simpleicons.org/upstash/00E9A3",
|
|
16141
15961
|
playwright: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/playwright/playwright-original.svg",
|
|
16142
15962
|
figma: "https://cdn.simpleicons.org/figma/F24E1E",
|
|
@@ -16170,7 +15990,7 @@ var init_providerLogos = __esm({
|
|
|
16170
15990
|
// src/local-ui/prompts.ts
|
|
16171
15991
|
function buildLocalUiPrompt(input) {
|
|
16172
15992
|
const lines = [
|
|
16173
|
-
"You are fixing one VibeRaven
|
|
15993
|
+
"You are fixing one VibeRaven what-changed gap.",
|
|
16174
15994
|
"",
|
|
16175
15995
|
`Project: ${input.projectName}`,
|
|
16176
15996
|
`Provider: ${input.providerName}`,
|
|
@@ -16184,7 +16004,7 @@ function buildLocalUiPrompt(input) {
|
|
|
16184
16004
|
"- .viberaven/gate-result.json",
|
|
16185
16005
|
"",
|
|
16186
16006
|
"Fix only this repo-code gap.",
|
|
16187
|
-
"Do not claim
|
|
16007
|
+
"Do not claim the app is ready until VibeRaven verify is clear.",
|
|
16188
16008
|
"Provider dashboard setup remains manual unless VibeRaven has live provider evidence.",
|
|
16189
16009
|
"After the fix, run:",
|
|
16190
16010
|
"npx -y viberaven --verify"
|
|
@@ -16506,7 +16326,7 @@ function buildMissionCards(artifact, providers) {
|
|
|
16506
16326
|
const connectProviders = buildConnectProviders(providers);
|
|
16507
16327
|
const blockerCount = blockers.length;
|
|
16508
16328
|
const hasScan = Boolean(artifact.scannedAt);
|
|
16509
|
-
const summary = !hasScan ? "
|
|
16329
|
+
const summary = !hasScan ? "Open VibeRaven Studio to inspect what changed and surface missing release or provider context." : blockerCount === 0 ? "No context blockers detected in the latest evidence." : `I analyzed the release evidence and found ${blockerCount} context blocker${blockerCount === 1 ? "" : "s"} to resolve before the next fix.`;
|
|
16510
16330
|
return {
|
|
16511
16331
|
summary,
|
|
16512
16332
|
blockerCount,
|
|
@@ -16964,7 +16784,6 @@ const demo = {
|
|
|
16964
16784
|
activeModal: null,
|
|
16965
16785
|
activeStudioTab: 'chat',
|
|
16966
16786
|
selectedCliId: 'codex',
|
|
16967
|
-
agentPermissionMode: 'ask',
|
|
16968
16787
|
cliConnected: false,
|
|
16969
16788
|
cliSetupComplete: false,
|
|
16970
16789
|
cliConnectTargetId: null,
|
|
@@ -16983,11 +16802,13 @@ const demo = {
|
|
|
16983
16802
|
selectedModelId: 'gpt-5.5',
|
|
16984
16803
|
selectedReasoning: 'High',
|
|
16985
16804
|
selectedContext: 'Production',
|
|
16805
|
+
selectedAccessMode: 'approve',
|
|
16986
16806
|
modelMenuOpen: false,
|
|
16987
16807
|
reasoningMenuOpen: false,
|
|
16988
16808
|
contextMenuOpen: false,
|
|
16809
|
+
accessMenuOpen: false,
|
|
16989
16810
|
pickerChatIndex: 0,
|
|
16990
|
-
chatContexts: [{ providerId: null, releaseId: null, cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production', messages: [], activeTask: null }],
|
|
16811
|
+
chatContexts: [{ providerId: null, releaseId: null, cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production', accessMode: 'approve', messages: [], activeTask: null }],
|
|
16991
16812
|
activeRecentChatId: null,
|
|
16992
16813
|
droppedProviderId: null,
|
|
16993
16814
|
dragKind: null,
|
|
@@ -17001,23 +16822,6 @@ const demo = {
|
|
|
17001
16822
|
releaseChangelog: { entries: [], from: '', to: '', fromLabel: '', toLabel: '', loading: false, error: '' },
|
|
17002
16823
|
};
|
|
17003
16824
|
|
|
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
|
-
|
|
17021
16825
|
function readCliSessionReady() {
|
|
17022
16826
|
try {
|
|
17023
16827
|
let raw = localStorage.getItem('viberaven-cli-ready');
|
|
@@ -17040,7 +16844,6 @@ function writeCliSessionReady(value) {
|
|
|
17040
16844
|
}
|
|
17041
16845
|
|
|
17042
16846
|
demo.cliSessionReady = readCliSessionReady();
|
|
17043
|
-
demo.agentPermissionMode = readPermissionMode();
|
|
17044
16847
|
|
|
17045
16848
|
function cliAgentInstalled(agent) {
|
|
17046
16849
|
if (!agent) return false;
|
|
@@ -17123,17 +16926,17 @@ const providerMarkAssets = {
|
|
|
17123
16926
|
};
|
|
17124
16927
|
|
|
17125
16928
|
const mascotAssets = {
|
|
17126
|
-
idle: '/report/assets/viberaven-mascot
|
|
17127
|
-
fixing: '/report/assets/viberaven-mascot
|
|
17128
|
-
verified: '/report/assets/viberaven-mascot
|
|
17129
|
-
alert: '/report/assets/viberaven-mascot
|
|
16929
|
+
idle: '/report/assets/viberaven-mascot.png',
|
|
16930
|
+
fixing: '/report/assets/viberaven-mascot.png',
|
|
16931
|
+
verified: '/report/assets/viberaven-mascot.png',
|
|
16932
|
+
alert: '/report/assets/viberaven-mascot.png',
|
|
17130
16933
|
};
|
|
17131
16934
|
|
|
17132
16935
|
const providerDashboardUrls = {
|
|
17133
16936
|
supabase: 'https://supabase.com/dashboard/projects',
|
|
17134
16937
|
vercel: 'https://vercel.com/dashboard',
|
|
17135
16938
|
stripe: 'https://dashboard.stripe.com',
|
|
17136
|
-
github: 'https://github.com/
|
|
16939
|
+
github: 'https://github.com/new',
|
|
17137
16940
|
sentry: 'https://sentry.io',
|
|
17138
16941
|
posthog: 'https://app.posthog.com',
|
|
17139
16942
|
clerk: 'https://dashboard.clerk.com',
|
|
@@ -17146,6 +16949,14 @@ const publicGithubUrl = 'https://github.com/ohad6k/VibeRaven';
|
|
|
17146
16949
|
const publicGithubApiUrl = 'https://api.github.com/repos/ohad6k/VibeRaven';
|
|
17147
16950
|
const docsUrl = 'https://viberaven.dev';
|
|
17148
16951
|
const communityUrl = 'https://github.com/ohad6k/VibeRaven/discussions/7';
|
|
16952
|
+
const goLiveUrls = {
|
|
16953
|
+
githubLogin: 'https://github.com/login',
|
|
16954
|
+
githubNew: 'https://github.com/new',
|
|
16955
|
+
githubCliAuth: 'https://cli.github.com/manual/gh_auth_login',
|
|
16956
|
+
vercelLogin: 'https://vercel.com/login',
|
|
16957
|
+
vercelNew: 'https://vercel.com/new',
|
|
16958
|
+
vercelDashboard: 'https://vercel.com/dashboard',
|
|
16959
|
+
};
|
|
17149
16960
|
|
|
17150
16961
|
const githubStats = {
|
|
17151
16962
|
loading: false,
|
|
@@ -17335,6 +17146,52 @@ function providerHealthIcon(health) {
|
|
|
17335
17146
|
return Icon('refresh');
|
|
17336
17147
|
}
|
|
17337
17148
|
|
|
17149
|
+
function providerMcp(provider) {
|
|
17150
|
+
return provider && provider.mcp ? provider.mcp : {
|
|
17151
|
+
status: 'disconnected',
|
|
17152
|
+
label: 'Connect MCP',
|
|
17153
|
+
connectCommand: 'Add this provider to your local MCP config, then drag it into chat.',
|
|
17154
|
+
capabilities: [],
|
|
17155
|
+
};
|
|
17156
|
+
}
|
|
17157
|
+
|
|
17158
|
+
function providerMcpChip(provider) {
|
|
17159
|
+
const mcp = providerMcp(provider);
|
|
17160
|
+
const connected = mcp.status === 'connected';
|
|
17161
|
+
const label = connected ? 'MCP connected' : 'MCP not connected';
|
|
17162
|
+
return '<span class="vr-provider-mcp-chip ' + (connected ? 'is-connected' : 'is-disconnected') + '" title="' + escapeHtml(label) + '" aria-label="' + escapeHtml(label) + '">' +
|
|
17163
|
+
'<i></i><span>' + escapeHtml(label) + '</span>' +
|
|
17164
|
+
'</span>';
|
|
17165
|
+
}
|
|
17166
|
+
|
|
17167
|
+
function providerAssetSrc(provider) {
|
|
17168
|
+
if (!provider) return providerAssets.supabase;
|
|
17169
|
+
return providerMarkAssets[provider.id] || providerAssets[provider.id] || providerAssets.supabase;
|
|
17170
|
+
}
|
|
17171
|
+
|
|
17172
|
+
function ProviderToken(provider, extraClass) {
|
|
17173
|
+
const className = 'vr-provider-token' + (extraClass ? ' ' + extraClass : '');
|
|
17174
|
+
const iconHtml = provider && provider.iconHtml ? String(provider.iconHtml) : '';
|
|
17175
|
+
return '<span class="' + className + '">' + (iconHtml.trim() ? iconHtml : '<img src="' + providerAssetSrc(provider) + '" alt="" />') + '</span>';
|
|
17176
|
+
}
|
|
17177
|
+
|
|
17178
|
+
function ProviderLogo(provider, className) {
|
|
17179
|
+
const iconHtml = provider && provider.iconHtml ? String(provider.iconHtml) : '';
|
|
17180
|
+
return iconHtml.trim()
|
|
17181
|
+
? '<span class="' + className + ' is-logo-html">' + iconHtml + '</span>'
|
|
17182
|
+
: '<img class="' + className + '" src="' + providerAssetSrc(provider) + '" alt="" />';
|
|
17183
|
+
}
|
|
17184
|
+
|
|
17185
|
+
function ProviderMcpPanel(provider) {
|
|
17186
|
+
const mcp = providerMcp(provider);
|
|
17187
|
+
const connected = mcp.status === 'connected';
|
|
17188
|
+
const capabilities = Array.isArray(mcp.capabilities) && mcp.capabilities.length ? mcp.capabilities : ['provider context', 'repo-aware chat'];
|
|
17189
|
+
return '<section class="vr-provider-mcp-panel ' + (connected ? 'is-connected' : 'is-disconnected') + '">' +
|
|
17190
|
+
'<header><span>' + Icon('agent') + '</span><div><strong>' + escapeHtml(connected ? 'MCP connected' : 'Connect MCP') + '</strong><em>' + escapeHtml(connected ? (mcp.source || 'local MCP config') : (mcp.connectCommand || 'Add this provider MCP server in your local MCP config.')) + '</em></div></header>' +
|
|
17191
|
+
'<div>' + capabilities.map((item) => '<small>' + escapeHtml(item) + '</small>').join('') + '</div>' +
|
|
17192
|
+
'</section>';
|
|
17193
|
+
}
|
|
17194
|
+
|
|
17338
17195
|
function normalizeProvider(provider) {
|
|
17339
17196
|
const missing = provider.state === 'not_detected';
|
|
17340
17197
|
return {
|
|
@@ -17348,6 +17205,8 @@ function normalizeProvider(provider) {
|
|
|
17348
17205
|
lastSync: currentState.project && currentState.project.scannedAt ? 'scan artifact' : 'startup',
|
|
17349
17206
|
checks: providerChecks(provider),
|
|
17350
17207
|
state: provider.state || 'not_detected',
|
|
17208
|
+
mcp: provider.mcp || null,
|
|
17209
|
+
iconHtml: provider.iconHtml || '',
|
|
17351
17210
|
};
|
|
17352
17211
|
}
|
|
17353
17212
|
|
|
@@ -17552,6 +17411,11 @@ let cliModels = {
|
|
|
17552
17411
|
|
|
17553
17412
|
const reasoningLevels = ['Low', 'Medium', 'High', 'Extra High'];
|
|
17554
17413
|
const contextLevels = ['Production', 'Provider', 'Release', 'Security'];
|
|
17414
|
+
const accessModes = [
|
|
17415
|
+
{ id: 'ask', label: 'Ask approval', description: 'Confirm edits and external access' },
|
|
17416
|
+
{ id: 'approve', label: 'Approve for me', description: 'Run safe repo actions automatically' },
|
|
17417
|
+
{ id: 'full', label: 'Full access', description: 'Unrestricted local project access' },
|
|
17418
|
+
];
|
|
17555
17419
|
const topStages = [
|
|
17556
17420
|
{ id: 'provider', number: '1', label: 'Provider Proof', state: 'Waiting' },
|
|
17557
17421
|
{ id: 'agent', number: '2', label: 'Agent Fix', state: 'Ready' },
|
|
@@ -17653,6 +17517,7 @@ function buildRecentChatEntry(prompt, provider, release, chat, existing) {
|
|
|
17653
17517
|
modelId: lane.modelId || base.modelId || demo.selectedModelId || 'gpt-5.5',
|
|
17654
17518
|
reasoning: lane.reasoning || base.reasoning || demo.selectedReasoning || 'High',
|
|
17655
17519
|
context: lane.context || base.context || demo.selectedContext || 'Production',
|
|
17520
|
+
accessMode: lane.accessMode || base.accessMode || demo.selectedAccessMode || 'approve',
|
|
17656
17521
|
messages: serializeChatMessages(lane.messages),
|
|
17657
17522
|
};
|
|
17658
17523
|
}
|
|
@@ -17680,6 +17545,7 @@ function syncDemoFromChatContext(context) {
|
|
|
17680
17545
|
demo.selectedModelId = context.modelId;
|
|
17681
17546
|
demo.selectedReasoning = context.reasoning;
|
|
17682
17547
|
demo.selectedContext = context.context;
|
|
17548
|
+
demo.selectedAccessMode = context.accessMode || 'approve';
|
|
17683
17549
|
if (context.providerId) demo.selectedProviderId = context.providerId;
|
|
17684
17550
|
if (context.releaseId) demo.selectedReleaseId = context.releaseId;
|
|
17685
17551
|
syncPrimaryContext();
|
|
@@ -17694,6 +17560,7 @@ function restoreRecentChat(recent) {
|
|
|
17694
17560
|
modelId: recent.modelId,
|
|
17695
17561
|
reasoning: recent.reasoning,
|
|
17696
17562
|
context: recent.context,
|
|
17563
|
+
accessMode: recent.accessMode,
|
|
17697
17564
|
messages: recent.messages || [],
|
|
17698
17565
|
draft: '',
|
|
17699
17566
|
activeTask: null,
|
|
@@ -17802,14 +17669,14 @@ function GitHubStats() {
|
|
|
17802
17669
|
function agentPromptText() {
|
|
17803
17670
|
const provider = providers.find((item) => item.id === demo.selectedProviderId) || providers[0];
|
|
17804
17671
|
return [
|
|
17805
|
-
'You are fixing one VibeRaven
|
|
17672
|
+
'You are fixing one VibeRaven what-changed gap.',
|
|
17806
17673
|
'',
|
|
17807
17674
|
'Project: ' + projectName(),
|
|
17808
17675
|
'Focus: ' + provider.name + ' ' + provider.area,
|
|
17809
17676
|
'Stage: ' + (demo.activeStepId || 'agent'),
|
|
17810
17677
|
'',
|
|
17811
17678
|
'Goal:',
|
|
17812
|
-
'- Find the smallest repo-side fix
|
|
17679
|
+
'- Find the smallest repo-side fix grounded in what changed.',
|
|
17813
17680
|
'- Do not claim provider dashboard work from code alone.',
|
|
17814
17681
|
'- Keep the change scoped and verify through the VibeRaven UI action.',
|
|
17815
17682
|
'',
|
|
@@ -17913,6 +17780,9 @@ function contextIconChip(iconName, size) {
|
|
|
17913
17780
|
}
|
|
17914
17781
|
|
|
17915
17782
|
function BrandMark(id) {
|
|
17783
|
+
if (id === 'github') {
|
|
17784
|
+
return '<span class="vr-inline-brand-mark is-github"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 2C6.48 2 2 6.58 2 12.26c0 4.52 2.87 8.35 6.86 9.71.5.1.69-.22.69-.49 0-.24-.01-.87-.01-1.7-2.78.62-3.37-1.36-3.37-1.36-.45-1.17-1.11-1.48-1.11-1.48-.91-.64.07-.63.07-.63 1 .07 1.53 1.05 1.53 1.05.9 1.56 2.36 1.11 2.94.85.09-.67.35-1.11.63-1.37-2.22-.26-4.56-1.14-4.56-5.07 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.7 0 0 .84-.28 2.75 1.05A9.2 9.2 0 0 1 12 6.84c.85 0 1.71.12 2.51.34 1.91-1.33 2.75-1.05 2.75-1.05.55 1.4.2 2.44.1 2.7.64.72 1.03 1.63 1.03 2.75 0 3.94-2.34 4.8-4.57 5.06.36.32.68.94.68 1.9 0 1.37-.01 2.47-.01 2.8 0 .27.18.6.7.49A10.03 10.03 0 0 0 22 12.26C22 6.58 17.52 2 12 2Z"/></svg></span>';
|
|
17785
|
+
}
|
|
17916
17786
|
return '<span class="vr-inline-brand-mark"><img src="' + escapeHtml(providerMarkAssets[id] || providerAssets[id]) + '" alt="" /></span>';
|
|
17917
17787
|
}
|
|
17918
17788
|
|
|
@@ -17938,6 +17808,7 @@ function defaultChatContext(seed) {
|
|
|
17938
17808
|
modelId: source.modelId || demo.selectedModelId || normalizeModelId(models[0]),
|
|
17939
17809
|
reasoning: source.reasoning || demo.selectedReasoning || 'High',
|
|
17940
17810
|
context: source.context || demo.selectedContext || 'Production',
|
|
17811
|
+
accessMode: source.accessMode || demo.selectedAccessMode || 'approve',
|
|
17941
17812
|
draft: source.draft || '',
|
|
17942
17813
|
messages: Array.isArray(source.messages) ? source.messages.slice() : [],
|
|
17943
17814
|
activeTask: source.activeTask || null,
|
|
@@ -18053,7 +17924,7 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18053
17924
|
const topBlocker = blockers[0];
|
|
18054
17925
|
const gateClear = gate.status === 'clear';
|
|
18055
17926
|
const gateLabel = gate.label || 'Waiting for project evidence';
|
|
18056
|
-
const mainBlocker = mc.mainBlocker || topBlocker?.title || '
|
|
17927
|
+
const mainBlocker = mc.mainBlocker || topBlocker?.title || 'Open context to find what changed';
|
|
18057
17928
|
const blockerText = formatBlockerLines(blockers, 6);
|
|
18058
17929
|
const planText = formatPlanLines(planSteps, 8);
|
|
18059
17930
|
const connectText = connectProviders.slice(0, 5).map((item) => '- ' + item.name + ' (' + item.status + ')').join('\\n');
|
|
@@ -18062,12 +17933,12 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18062
17933
|
|
|
18063
17934
|
const missions = {
|
|
18064
17935
|
analyze: {
|
|
18065
|
-
title: 'Analyzing
|
|
18066
|
-
label: blockers.length ? 'Analyze ' + blockers.length + ' blocker' + (blockers.length === 1 ? '' : 's') : 'Analyze
|
|
17936
|
+
title: 'Analyzing what changed',
|
|
17937
|
+
label: blockers.length ? 'Analyze ' + blockers.length + ' blocker' + (blockers.length === 1 ? '' : 's') : 'Analyze what changed',
|
|
18067
17938
|
prompt: [
|
|
18068
|
-
'Analyze
|
|
17939
|
+
'Analyze what changed in this project folder.',
|
|
18069
17940
|
'',
|
|
18070
|
-
'
|
|
17941
|
+
'Project status: ' + gateLabel + ' (' + (gate.status || 'unknown') + ')',
|
|
18071
17942
|
'Main blocker: ' + mainBlocker,
|
|
18072
17943
|
blockers.length ? 'Known blockers from the latest scan:\\n' + blockerText : 'No blockers loaded yet \u2014 inspect .viberaven/gate-result.json and agent-tasklist.md if present.',
|
|
18073
17944
|
connectText ? '\\nProviders needing connect:\\n' + connectText : '',
|
|
@@ -18079,15 +17950,15 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18079
17950
|
].filter(Boolean).join('\\n'),
|
|
18080
17951
|
line: 'Reading repo evidence, provider proof, and release context.',
|
|
18081
17952
|
steps: ['Scan evidence', 'Rank risks', 'Prepare fix plan'],
|
|
18082
|
-
notice: blockers.length ? 'Analyzing ' + blockers.length + '
|
|
17953
|
+
notice: blockers.length ? 'Analyzing ' + blockers.length + ' blocker' + (blockers.length === 1 ? '' : 's') + '.' : 'Analyzing what changed.',
|
|
18083
17954
|
},
|
|
18084
17955
|
plan: {
|
|
18085
17956
|
title: 'Building fix plan',
|
|
18086
|
-
label: planSteps.length ? '
|
|
17957
|
+
label: planSteps.length ? 'Fix plan \xB7 ' + planSteps.length + ' action' + (planSteps.length === 1 ? '' : 's') : 'Build fix plan',
|
|
18087
17958
|
prompt: [
|
|
18088
|
-
'Build a safe, ordered
|
|
17959
|
+
'Build a safe, ordered fix plan from the current what-changed context.',
|
|
18089
17960
|
'',
|
|
18090
|
-
'
|
|
17961
|
+
'Project status: ' + gateLabel,
|
|
18091
17962
|
'Main blocker: ' + mainBlocker,
|
|
18092
17963
|
blockers.length ? 'Blockers (' + blockers.length + '):\\n' + blockerText : 'No scan blockers loaded \u2014 inspect .viberaven artifacts first.',
|
|
18093
17964
|
planSteps.length ? '\\nSuggested steps from scan:\\n' + planText : '',
|
|
@@ -18106,7 +17977,7 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18106
17977
|
title: 'Applying scoped fix',
|
|
18107
17978
|
label: topBlocker ? 'Agent fix \xB7 ' + truncateMissionLabel(topBlocker.title, 34) : 'Apply next repo fix',
|
|
18108
17979
|
prompt: [
|
|
18109
|
-
'Apply ONE scoped repo fix for the highest-priority
|
|
17980
|
+
'Apply ONE scoped repo fix for the highest-priority what-changed blocker.',
|
|
18110
17981
|
'',
|
|
18111
17982
|
topBlocker ? 'Target blocker: ' + topBlocker.title : 'Target: ' + mainBlocker,
|
|
18112
17983
|
topBlocker?.detail ? 'Detail: ' + topBlocker.detail : '',
|
|
@@ -18121,17 +17992,17 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18121
17992
|
'- Do not claim provider dashboard setup is complete from repo edits alone.',
|
|
18122
17993
|
'- After edits, list files touched and recommend verify.',
|
|
18123
17994
|
].filter(Boolean).join('\\n'),
|
|
18124
|
-
line: 'Patching only the selected
|
|
17995
|
+
line: 'Patching only the selected what-changed gap, then preparing verification.',
|
|
18125
17996
|
steps: ['Patch code', 'Update proof', 'Prepare verify'],
|
|
18126
17997
|
notice: topBlocker ? 'Agent fix started for: ' + truncateMissionLabel(topBlocker.title, 48) + '.' : 'Agent fix mission started.',
|
|
18127
17998
|
},
|
|
18128
17999
|
verify: {
|
|
18129
18000
|
title: 'Running verification',
|
|
18130
|
-
label: gateClear ? 'Re-verify
|
|
18001
|
+
label: gateClear ? 'Re-verify context' : 'Verify context',
|
|
18131
18002
|
prompt: [
|
|
18132
|
-
'Verify
|
|
18003
|
+
'Verify the current what-changed context for this project.',
|
|
18133
18004
|
'',
|
|
18134
|
-
'
|
|
18005
|
+
'Project status: ' + gateLabel + ' (' + (gate.status || 'unknown') + ')',
|
|
18135
18006
|
'Main blocker: ' + mainBlocker,
|
|
18136
18007
|
blockers.length ? 'Open blockers:\\n' + blockerText : '',
|
|
18137
18008
|
'',
|
|
@@ -18142,15 +18013,15 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18142
18013
|
].filter(Boolean).join('\\n'),
|
|
18143
18014
|
line: 'Checking evidence, provider state, and release readiness.',
|
|
18144
18015
|
steps: ['Run checks', 'Read proof', 'Mark status'],
|
|
18145
|
-
notice: gateClear ? 'Re-
|
|
18016
|
+
notice: gateClear ? 'Re-checking release proof.' : 'Checking evidence, provider state, and release context.',
|
|
18146
18017
|
},
|
|
18147
18018
|
diff: {
|
|
18148
18019
|
title: 'Reviewing diff',
|
|
18149
|
-
label: 'Review
|
|
18020
|
+
label: 'Review release diff',
|
|
18150
18021
|
prompt: [
|
|
18151
|
-
'Review the current
|
|
18022
|
+
'Review the current release diff for this project.',
|
|
18152
18023
|
'',
|
|
18153
|
-
'
|
|
18024
|
+
'Project status: ' + gateLabel,
|
|
18154
18025
|
topBlocker ? 'Top blocker context: ' + topBlocker.title : '',
|
|
18155
18026
|
'',
|
|
18156
18027
|
'Show grouped changes, flag risky edits, and say what still needs verify before release.',
|
|
@@ -18163,9 +18034,9 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18163
18034
|
title: 'Explaining changes',
|
|
18164
18035
|
label: 'Explain changes & next steps',
|
|
18165
18036
|
prompt: [
|
|
18166
|
-
'Explain
|
|
18037
|
+
'Explain what changed and what to verify next.',
|
|
18167
18038
|
'',
|
|
18168
|
-
'
|
|
18039
|
+
'Project status: ' + gateLabel,
|
|
18169
18040
|
mainBlocker ? 'Main blocker: ' + mainBlocker : '',
|
|
18170
18041
|
blockers.length ? 'Active blockers:\\n' + blockerText : '',
|
|
18171
18042
|
'',
|
|
@@ -18206,6 +18077,38 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18206
18077
|
steps: missingProvider ? ['Check repo', 'List env', 'Dashboard steps'] : ['Read provider', 'Check proof', 'Attach context'],
|
|
18207
18078
|
notice: missingProvider ? provider.name + ' connect mission started.' : provider.name + ' proof check started.',
|
|
18208
18079
|
},
|
|
18080
|
+
'go-live': {
|
|
18081
|
+
title: 'Preparing GitHub and Vercel launch',
|
|
18082
|
+
label: 'Go live on GitHub + Vercel',
|
|
18083
|
+
prompt: [
|
|
18084
|
+
'Take this local project live through GitHub and Vercel with explicit proof.',
|
|
18085
|
+
'',
|
|
18086
|
+
'Project status: ' + gateLabel + ' (' + (gate.status || 'unknown') + ')',
|
|
18087
|
+
'Main blocker: ' + mainBlocker,
|
|
18088
|
+
blockers.length ? 'Known blockers from the latest scan:\\n' + blockerText : 'No scan blockers loaded yet - inspect the repo and .viberaven artifacts if present.',
|
|
18089
|
+
connectText ? '\\nProviders needing connect:\\n' + connectText : '',
|
|
18090
|
+
'',
|
|
18091
|
+
'Launch path:',
|
|
18092
|
+
'1. Inspect git status, branch, remotes, package scripts, Vercel config, and deploy notes before changing anything.',
|
|
18093
|
+
'2. Detect GitHub/Vercel tools with gh --version, gh auth status, vercel --version or npx vercel --version, and vercel whoami or npx vercel whoami.',
|
|
18094
|
+
'3. Run the narrowest local build/typecheck/test command that proves the app can ship.',
|
|
18095
|
+
'4. If no GitHub remote exists and gh is authenticated, create the repo and push after repo name/visibility are clear. If auth/manual setup is needed, open ' + goLiveUrls.githubLogin + ' or ' + goLiveUrls.githubNew + '.',
|
|
18096
|
+
'5. Connect or verify Vercel project linkage, framework/build settings, env var names, and production deploy command. If auth/manual setup is needed, open ' + goLiveUrls.vercelLogin + ', ' + goLiveUrls.vercelNew + ', or ' + goLiveUrls.vercelDashboard + '.',
|
|
18097
|
+
'6. Deploy when auth and intent are clear for the selected access mode. Capture deployment URL and verify it if possible.',
|
|
18098
|
+
'',
|
|
18099
|
+
'Rules:',
|
|
18100
|
+
'- Do every safe step directly. Do not stop at a checklist if commands or official pages can move the launch forward.',
|
|
18101
|
+
'- Do not include .env files, secrets, build output, or unrelated dirty work in commits.',
|
|
18102
|
+
'- Do not ask for passwords, cookies, tokens, API keys, or secret values.',
|
|
18103
|
+
'- Do not claim GitHub or Vercel dashboard state is complete without CLI, MCP, dashboard, or live URL proof.',
|
|
18104
|
+
'- Avoid destructive git operations and force pushes unless the user explicitly asks and the risk is explained.',
|
|
18105
|
+
'',
|
|
18106
|
+
'Return a launch receipt with GitHub repo/branch/SHA, Vercel project/deployment URL, local proof command, live proof result, links opened, and remaining dashboard actions.',
|
|
18107
|
+
].filter(Boolean).join('\\n'),
|
|
18108
|
+
line: 'Connecting repo evidence to GitHub, Vercel, and live deployment proof.',
|
|
18109
|
+
steps: ['Check repo', 'Push GitHub', 'Deploy Vercel', 'Verify live'],
|
|
18110
|
+
notice: 'Go Live mission started for GitHub and Vercel.',
|
|
18111
|
+
},
|
|
18209
18112
|
};
|
|
18210
18113
|
|
|
18211
18114
|
const mission = missions[kind] || missions.analyze;
|
|
@@ -18269,7 +18172,7 @@ function quickActionButtonSpec(index) {
|
|
|
18269
18172
|
action: 'plan',
|
|
18270
18173
|
icon: 'report',
|
|
18271
18174
|
label: planSteps.length ? 'Plan \xB7 ' + planSteps.length : 'Plan',
|
|
18272
|
-
hint: planSteps.length ? 'Build
|
|
18175
|
+
hint: planSteps.length ? 'Build fix plan \xB7 ' + planSteps.length + ' actions' : 'Build fix plan',
|
|
18273
18176
|
primary: true,
|
|
18274
18177
|
},
|
|
18275
18178
|
{
|
|
@@ -18284,7 +18187,14 @@ function quickActionButtonSpec(index) {
|
|
|
18284
18187
|
action: 'verify-now',
|
|
18285
18188
|
icon: 'shield',
|
|
18286
18189
|
label: gateClear ? 'Re-verify' : 'Verify',
|
|
18287
|
-
hint: gateClear ? 'Re-verify
|
|
18190
|
+
hint: gateClear ? 'Re-verify readiness' : 'Verify readiness',
|
|
18191
|
+
primary: true,
|
|
18192
|
+
},
|
|
18193
|
+
{
|
|
18194
|
+
action: 'go-live',
|
|
18195
|
+
icon: 'cloud',
|
|
18196
|
+
label: 'Go live',
|
|
18197
|
+
hint: 'Push GitHub + deploy Vercel',
|
|
18288
18198
|
primary: true,
|
|
18289
18199
|
},
|
|
18290
18200
|
{
|
|
@@ -18348,7 +18258,7 @@ function runChatTask(kind, promptOverride) {
|
|
|
18348
18258
|
const responseText = isError
|
|
18349
18259
|
? (message || 'The connected CLI did not return a usable response.')
|
|
18350
18260
|
: (message || 'Ready for the next safe action.');
|
|
18351
|
-
const attachKinds = ['analyze', 'plan', 'provider', 'verify'];
|
|
18261
|
+
const attachKinds = ['analyze', 'plan', 'provider', 'verify', 'go-live'];
|
|
18352
18262
|
const cards = attachKinds.includes(kind)
|
|
18353
18263
|
? (cardsPayload || missionCards)
|
|
18354
18264
|
: (cardsPayload && ['diff', 'explain'].includes(kind) ? cardsPayload : null);
|
|
@@ -18373,7 +18283,7 @@ function runChatTask(kind, promptOverride) {
|
|
|
18373
18283
|
demo.notice = 'Verification finished in chat. Launch proof is green.';
|
|
18374
18284
|
} else if (kind === 'fix') {
|
|
18375
18285
|
demo.activeStepId = 'verify';
|
|
18376
|
-
demo.notice = 'Fix prepared in chat. Run Verify to
|
|
18286
|
+
demo.notice = 'Fix prepared in chat. Run Verify to update release proof.';
|
|
18377
18287
|
} else {
|
|
18378
18288
|
demo.notice = taskMeta(kind).title + ' finished in chat.';
|
|
18379
18289
|
}
|
|
@@ -18395,12 +18305,12 @@ function runChatTask(kind, promptOverride) {
|
|
|
18395
18305
|
modelId: selectedModelLabel(chatIndex),
|
|
18396
18306
|
reasoning: chat.reasoning,
|
|
18397
18307
|
context: chat.context,
|
|
18308
|
+
accessMode: chat.accessMode || 'approve',
|
|
18398
18309
|
prompt,
|
|
18399
18310
|
displayPrompt: label,
|
|
18400
18311
|
taskKind: kind,
|
|
18401
|
-
|
|
18402
|
-
|
|
18403
|
-
release: release ? { label: release.label } : undefined
|
|
18312
|
+
provider: { id: provider.id, area: provider.area, name: provider.name },
|
|
18313
|
+
release: release ? { id: release.id, label: release.label } : undefined
|
|
18404
18314
|
})
|
|
18405
18315
|
})
|
|
18406
18316
|
.then(async (response) => {
|
|
@@ -18429,7 +18339,7 @@ function sendChatInput(chatIndex) {
|
|
|
18429
18339
|
}
|
|
18430
18340
|
chat.draft = '';
|
|
18431
18341
|
if (input && 'value' in input) input.value = '';
|
|
18432
|
-
runChatTask(chat.providerId ? 'provider' : 'analyze', value);
|
|
18342
|
+
runChatTask(chat.releaseId ? 'diff' : chat.providerId ? 'provider' : 'analyze', value);
|
|
18433
18343
|
}
|
|
18434
18344
|
|
|
18435
18345
|
function resetLaunchPreview() {
|
|
@@ -18449,11 +18359,13 @@ function resetLaunchPreview() {
|
|
|
18449
18359
|
demo.selectedModelId = 'gpt-5.5';
|
|
18450
18360
|
demo.selectedReasoning = 'High';
|
|
18451
18361
|
demo.selectedContext = 'Production';
|
|
18362
|
+
demo.selectedAccessMode = 'approve';
|
|
18452
18363
|
demo.modelMenuOpen = false;
|
|
18453
18364
|
demo.reasoningMenuOpen = false;
|
|
18454
18365
|
demo.contextMenuOpen = false;
|
|
18366
|
+
demo.accessMenuOpen = false;
|
|
18455
18367
|
demo.pickerChatIndex = 0;
|
|
18456
|
-
demo.chatContexts = [defaultChatContext({ cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production' })];
|
|
18368
|
+
demo.chatContexts = [defaultChatContext({ cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production', accessMode: 'approve' })];
|
|
18457
18369
|
demo.droppedProviderId = null;
|
|
18458
18370
|
demo.droppedReleaseId = null;
|
|
18459
18371
|
clearChatTaskTimer();
|
|
@@ -18523,10 +18435,10 @@ function RecentChatRail() {
|
|
|
18523
18435
|
|
|
18524
18436
|
function ProviderCard(provider) {
|
|
18525
18437
|
const slot = stackSlots[provider.id] || provider.area;
|
|
18526
|
-
return '<button class="vr-provider-card ' + (provider.id === demo.selectedProviderId ? 'is-selected' : '') + '" type="button" draggable="true" data-provider="' + escapeHtml(provider.id) + '" aria-label="Open ' + escapeHtml(provider.name) + ' stack slot">' +
|
|
18527
|
-
|
|
18528
|
-
'<span class="vr-provider-light"></span>' +
|
|
18438
|
+
return '<button class="vr-provider-card ' + (provider.id === demo.selectedProviderId ? 'is-selected' : '') + '" type="button" draggable="true" data-provider="' + escapeHtml(provider.id) + '" data-provider-tone="' + escapeHtml(provider.tone || 'neutral') + '" aria-label="Open ' + escapeHtml(provider.name) + ' stack slot">' +
|
|
18439
|
+
ProviderToken(provider) +
|
|
18529
18440
|
'<div><small>' + escapeHtml(slot) + '</small><strong>' + escapeHtml(provider.name) + '</strong><em>' + escapeHtml(provider.status) + '</em></div>' +
|
|
18441
|
+
providerMcpChip(provider) +
|
|
18530
18442
|
'<span class="vr-provider-proof-chip"><span>Open</span>' + Icon('chevronRight') + '</span>' +
|
|
18531
18443
|
'</button>';
|
|
18532
18444
|
}
|
|
@@ -18534,9 +18446,10 @@ function ProviderCard(provider) {
|
|
|
18534
18446
|
function ProviderDetailPanel() {
|
|
18535
18447
|
const provider = providers.find((item) => item.id === demo.selectedProviderId) || providers[0];
|
|
18536
18448
|
return '<aside class="vr-provider-detail-panel">' +
|
|
18537
|
-
'<div class="vr-detail-head"
|
|
18449
|
+
'<div class="vr-detail-head">' + ProviderToken(provider, 'is-large') + '<div><span>' + escapeHtml(provider.area) + '</span><strong>' + escapeHtml(provider.name) + '</strong></div>' + StatusBadge(provider.status, provider.tone) + '</div>' +
|
|
18538
18450
|
'<p>' + escapeHtml(provider.detail) + '</p>' +
|
|
18539
18451
|
'<div class="vr-provider-stats"><span><b>Checks</b><em>' + escapeHtml(provider.checks) + '</em></span><span><b>Region</b><em>' + escapeHtml(provider.region) + '</em></span><span><b>Last sync</b><em>' + escapeHtml(provider.lastSync) + '</em></span></div>' +
|
|
18452
|
+
ProviderMcpPanel(provider) +
|
|
18540
18453
|
'<a class="vr-provider-dashboard" href="' + escapeHtml(providerDashboardUrls[provider.id] || docsUrl) + '" target="_blank" rel="noreferrer">Open dashboard ' + Icon('external') + '</a>' +
|
|
18541
18454
|
'</aside>';
|
|
18542
18455
|
}
|
|
@@ -18557,7 +18470,7 @@ function ProviderPicker() {
|
|
|
18557
18470
|
return '<div class="vr-provider-picker" aria-label="Provider picker">' +
|
|
18558
18471
|
'<div><strong>Connector picker</strong><span>Select one provider. VibeRaven opens its proof panel and next action.</span></div>' +
|
|
18559
18472
|
'<div class="vr-provider-picker-list">' + boardProviders.map((provider) =>
|
|
18560
|
-
'<button type="button" data-provider="' + escapeHtml(provider.id) + '"
|
|
18473
|
+
'<button type="button" data-provider="' + escapeHtml(provider.id) + '">' + ProviderToken(provider, 'is-picker') + '<span>' + escapeHtml(provider.name) + '</span></button>'
|
|
18561
18474
|
).join('') + '</div>' +
|
|
18562
18475
|
'</div>';
|
|
18563
18476
|
}
|
|
@@ -18613,11 +18526,12 @@ function ProviderModal() {
|
|
|
18613
18526
|
const checkRows = providerModalCheckRows(raw);
|
|
18614
18527
|
return ModalShell('provider',
|
|
18615
18528
|
'<header class="vr-modal-provider-head">' +
|
|
18616
|
-
'
|
|
18529
|
+
ProviderLogo(provider, 'vr-modal-provider-logo') +
|
|
18617
18530
|
'<div><h2>' + escapeHtml(provider.name) + '</h2>' + StatusBadge(provider.status, provider.tone) + '<p>' + escapeHtml(provider.area) + ' provider</p></div>' +
|
|
18618
18531
|
'<img class="vr-modal-mascot" src="' + providerModalMascot(health) + '" alt="" />' +
|
|
18619
18532
|
'</header>' +
|
|
18620
18533
|
'<section class="vr-modal-health is-' + escapeHtml(health.tone) + '"><span>' + providerHealthIcon(health) + '</span><div><strong>' + escapeHtml(health.label) + '</strong><em>' + escapeHtml(health.summary) + '</em></div><b>' + escapeHtml(health.meta) + '</b></section>' +
|
|
18534
|
+
ProviderMcpPanel(provider) +
|
|
18621
18535
|
'<div class="vr-modal-action-grid">' +
|
|
18622
18536
|
GlowButton('Open slot', { action: 'guide', tone: 'purple' }) +
|
|
18623
18537
|
'<button type="button" data-action="recheck">' + Icon('refresh') + 'Re-check</button>' +
|
|
@@ -18644,7 +18558,7 @@ function AddProviderModal() {
|
|
|
18644
18558
|
'</header>' +
|
|
18645
18559
|
'<section class="vr-modal-provider-options">' + featured.map((item) => {
|
|
18646
18560
|
const provider = providers.find((candidate) => candidate.id === item.icon) || providers[0];
|
|
18647
|
-
return '<button type="button" data-provider="' + escapeHtml(provider.id) + '"
|
|
18561
|
+
return '<button type="button" data-provider="' + escapeHtml(provider.id) + '">' + ProviderToken(provider, 'is-large') + '<div><small>' + escapeHtml(item.slot) + '</small><strong>' + escapeHtml(item.provider) + '</strong><em>' + escapeHtml(item.caption) + '</em></div><b>Connect</b></button>';
|
|
18648
18562
|
}).join('') + '</section>' +
|
|
18649
18563
|
'<section class="vr-modal-connect-note">' + Icon('lock') + '<span>VibeRaven only opens setup guidance here. Real credentials stay in your local runner or provider dashboard.</span></section>'
|
|
18650
18564
|
);
|
|
@@ -18674,16 +18588,16 @@ function AgentModal() {
|
|
|
18674
18588
|
return ModalShell('agent',
|
|
18675
18589
|
'<header class="vr-modal-agent-head">' +
|
|
18676
18590
|
'<img class="vr-modal-agent-avatar" src="' + mascotUrl() + '" alt="" />' +
|
|
18677
|
-
'<div><p>Agent Action</p><h2>VibeRaven</h2><em>' + (verified ? 'Everything is verified in preview mode.' : fixing ? 'I am fixing the
|
|
18591
|
+
'<div><p>Agent Action</p><h2>VibeRaven</h2><em>' + (verified ? 'Everything is verified in preview mode.' : fixing ? 'I am fixing the evidenced change now.' : 'I will fix the issue with release and provider context.') + '</em></div>' +
|
|
18678
18592
|
'<aside>' + Icon('clock') + '<span>' + (verified ? 'Status' : 'Estimated time') + '</span><strong>' + (verified ? 'Complete' : fixing ? 'Running' : '2 - 4 min') + '</strong></aside>' +
|
|
18679
18593
|
'</header>' +
|
|
18680
18594
|
'<section class="vr-modal-tasklist"><h3>Task checklist</h3><ul>' +
|
|
18681
|
-
ModalCheck('Diagnose issue', 'Find the highest-impact
|
|
18682
|
-
ModalCheck('Apply focused fix', 'Patch only the
|
|
18595
|
+
ModalCheck('Diagnose issue', 'Find the highest-impact context gap.', fixing || verified ? 'done' : 'active', fixing || verified ? 'OK' : 'Ready') +
|
|
18596
|
+
ModalCheck('Apply focused fix', 'Patch only the evidenced change.', verified ? 'done' : fixing ? 'running' : 'pending', verified ? 'OK' : fixing ? 'Running' : 'Pending') +
|
|
18683
18597
|
ModalCheck('Run verification tests', 'Confirm the flow is safe after the fix.', verified ? 'done' : fixing ? 'active' : 'pending', verified ? 'OK' : fixing ? 'Queued' : 'Pending') +
|
|
18684
18598
|
ModalCheck('Confirm systems operational', 'Move the launch flow to clear.', verified ? 'done' : 'pending') +
|
|
18685
18599
|
'</ul></section>' +
|
|
18686
|
-
'<section class="vr-modal-progress ' + (!verified && !fixing ? 'is-ready' : '') + '">' + Icon('shield') + '<div><strong>' + (verified ? 'Verification complete' : fixing ? 'Fix in progress' : 'Ready for focused fix') + '</strong><p>' + (verified ? 'The launch flow is green in preview mode.' : fixing ? 'Running checks to
|
|
18600
|
+
'<section class="vr-modal-progress ' + (!verified && !fixing ? 'is-ready' : '') + '">' + Icon('shield') + '<div><strong>' + (verified ? 'Verification complete' : fixing ? 'Fix in progress' : 'Ready for focused fix') + '</strong><p>' + (verified ? 'The launch flow is green in preview mode.' : fixing ? 'Running checks to keep the fix grounded.' : 'Start the agent when you are ready to patch the evidenced change.') + '</p></div>' + Icon('spark') + '</section>' +
|
|
18687
18601
|
'<div class="vr-modal-button-row">' +
|
|
18688
18602
|
GlowButton(fixing ? 'Fixing...' : verified ? 'Complete' : 'Start Agent Fix', { action: 'start-agent-fix', tone: verified ? 'green' : 'purple' }) +
|
|
18689
18603
|
'<button type="button" data-action="verify-now">Verify Now</button>' +
|
|
@@ -18702,7 +18616,7 @@ function GuideModal() {
|
|
|
18702
18616
|
'</header>' +
|
|
18703
18617
|
'<section class="vr-modal-flow-list">' +
|
|
18704
18618
|
'<button type="button" data-provider="' + escapeHtml(provider.id) + '"><span>1</span><div><strong>Review provider proof</strong><em>Open ' + escapeHtml(provider.name) + ' status and dashboard action.</em></div>' + Icon('external') + '</button>' +
|
|
18705
|
-
'<button type="button" data-action="prompt"><span>2</span><div><strong>Open agent mission</strong><em>Give the connected CLI one
|
|
18619
|
+
'<button type="button" data-action="prompt"><span>2</span><div><strong>Open agent mission</strong><em>Give the connected CLI one evidenced change, not the whole app.</em></div>' + Icon('prompt') + '</button>' +
|
|
18706
18620
|
'<button type="button" data-action="verify-now"><span>3</span><div><strong>Verify the flow</strong><em>Turn the launch path green after the focused fix.</em></div>' + Icon('check') + '</button>' +
|
|
18707
18621
|
'</section>'
|
|
18708
18622
|
);
|
|
@@ -18729,13 +18643,13 @@ function PlanModal() {
|
|
|
18729
18643
|
return ModalShell('plan',
|
|
18730
18644
|
'<header class="vr-modal-guide-head">' +
|
|
18731
18645
|
'<img class="vr-modal-agent-avatar" src="' + mascotAssets.idle + '" alt="" />' +
|
|
18732
|
-
'<div><p>
|
|
18646
|
+
'<div><p>Release Plan</p><h2>Safe fix path</h2><em>One scoped mission: understand what changed, fix it, then prepare release proof.</em></div>' +
|
|
18733
18647
|
'<aside>' + Icon('shield') + '<span>Context</span><strong>' + escapeHtml(provider.name) + '</strong></aside>' +
|
|
18734
18648
|
'</header>' +
|
|
18735
18649
|
'<section class="vr-modal-flow-list">' +
|
|
18736
18650
|
'<button type="button" data-action="add-context"><span>1</span><div><strong>Add launch context</strong><em>Drag a provider or version into chat so the agent has the exact proof target.</em></div>' + Icon('plus') + '</button>' +
|
|
18737
|
-
'<button type="button" data-action="prompt"><span>2</span><div><strong>Open scoped mission</strong><em>Use a
|
|
18738
|
-
'<button type="button" data-action="start-agent-fix"><span>3</span><div><strong>Apply one fix</strong><em>Send the connected model to patch the
|
|
18651
|
+
'<button type="button" data-action="prompt"><span>2</span><div><strong>Open scoped mission</strong><em>Use a context-aware prompt tied to ' + escapeHtml(provider.area) + ' evidence.</em></div>' + Icon('prompt') + '</button>' +
|
|
18652
|
+
'<button type="button" data-action="start-agent-fix"><span>3</span><div><strong>Apply one fix</strong><em>Send the connected model to patch the evidenced change only.</em></div>' + Icon('agent') + '</button>' +
|
|
18739
18653
|
'<button type="button" data-action="show-diff"><span>4</span><div><strong>Review diff</strong><em>Inspect repo changes before accepting verification.</em></div>' + Icon('code') + '</button>' +
|
|
18740
18654
|
'<button type="button" data-action="verify-now"><span>5</span><div><strong>Run verify</strong><em>Move the mission into a green verified state after review.</em></div>' + Icon('check') + '</button>' +
|
|
18741
18655
|
'</section>' +
|
|
@@ -18846,21 +18760,18 @@ function connectCliAgent(agentId, chatIndex, options) {
|
|
|
18846
18760
|
}
|
|
18847
18761
|
|
|
18848
18762
|
function cliSetupProbeLabel() {
|
|
18849
|
-
return demo.cliProbeStatus === 'probing' ? 'Testing
|
|
18763
|
+
return demo.cliProbeStatus === 'probing' ? 'Testing...' : demo.cliProbeStatus === 'success' ? 'Connected' : demo.cliProbeStatus === 'failed' ? 'Try again' : 'Test connection';
|
|
18850
18764
|
}
|
|
18851
18765
|
|
|
18852
18766
|
function CliSetupActions(targetId, index) {
|
|
18853
18767
|
const setup = cliSetupFor(targetId);
|
|
18854
18768
|
const probeLabel = cliSetupProbeLabel();
|
|
18855
|
-
|
|
18856
|
-
const ctaClass = 'vr-cli-action-button is-primary' + (ctaPending ? ' is-pending' : '');
|
|
18857
|
-
return '<p class="vr-cli-setup-cta-hint">After sign-in, click <strong>Test connection</strong> \u2014 chat only works once verified.</p>' +
|
|
18858
|
-
'<div class="vr-cli-connect-expand-actions">' +
|
|
18769
|
+
return '<div class="vr-cli-connect-expand-actions">' +
|
|
18859
18770
|
'<button class="vr-cli-action-button" type="button" data-action="run-cli-install" data-cli-agent="' + escapeHtml(targetId) + '" data-chat-index="' + String(index) + '">' + Icon('shell') + 'Run install</button>' +
|
|
18860
18771
|
'<button class="vr-cli-action-button" type="button" data-action="run-cli-signin" data-cli-agent="' + escapeHtml(targetId) + '" data-chat-index="' + String(index) + '">' + Icon('shell') + 'Run sign in</button>' +
|
|
18861
|
-
'<button class="
|
|
18772
|
+
'<button class="vr-cli-action-button is-primary" type="button" data-action="test-cli-connection" data-cli-agent="' + escapeHtml(targetId) + '" data-chat-index="' + String(index) + '">' + Icon('refresh') + escapeHtml(probeLabel) + '</button>' +
|
|
18862
18773
|
'</div>' +
|
|
18863
|
-
'<p class="vr-cli-setup-hint">
|
|
18774
|
+
'<p class="vr-cli-setup-hint">Run install and sign in, then use <strong>Test connection</strong> to unlock chat control. Commands: <code>' + escapeHtml(setup.installCommand) + '</code> then <code>' + escapeHtml(setup.signInCommand) + '</code></p>';
|
|
18864
18775
|
}
|
|
18865
18776
|
|
|
18866
18777
|
function appendTerminalLines(lines) {
|
|
@@ -18924,7 +18835,7 @@ function selectTerminalCli(agentId) {
|
|
|
18924
18835
|
if (!demo.cliTerminalLines.length) {
|
|
18925
18836
|
demo.cliTerminalLines = [
|
|
18926
18837
|
'VibeRaven Studio shell',
|
|
18927
|
-
'Run install, run sign in, then
|
|
18838
|
+
'Run install, run sign in, then use Test connection to continue.',
|
|
18928
18839
|
''
|
|
18929
18840
|
];
|
|
18930
18841
|
} else {
|
|
@@ -18956,8 +18867,8 @@ function StudioTerminalView() {
|
|
|
18956
18867
|
const lines = demo.cliTerminalLines.length
|
|
18957
18868
|
? demo.cliTerminalLines
|
|
18958
18869
|
: [
|
|
18959
|
-
|
|
18960
|
-
'Type commands at the $ prompt. Use
|
|
18870
|
+
'VibeRaven Studio shell',
|
|
18871
|
+
'Type commands at the $ prompt. Use Test connection after sign-in.',
|
|
18961
18872
|
''
|
|
18962
18873
|
];
|
|
18963
18874
|
const title = terminalConnectTitle(agent);
|
|
@@ -19011,7 +18922,7 @@ function ChatFirstTimeConnect(index) {
|
|
|
19011
18922
|
: '<p class="vr-chat-first-connect-note">Click Connect to open the Terminal tab \u2014 install, sign in, then test connection.</p>';
|
|
19012
18923
|
return '<section class="vr-chat-empty-state vr-chat-first-connect" data-chat-index="' + String(index) + '">' +
|
|
19013
18924
|
'<strong>First time</strong>' +
|
|
19014
|
-
'<span>Connect
|
|
18925
|
+
'<span>Connect your repo agent through VibeRaven Studio.</span>' +
|
|
19015
18926
|
'<div class="vr-cli-strip is-inline">' + codingAgents.map((agent) => CliAgentButton(agent, index)).join('') + '</div>' +
|
|
19016
18927
|
hintLine +
|
|
19017
18928
|
'</section>';
|
|
@@ -19300,7 +19211,7 @@ async function runCliSignInInStudio(agentId, chatIndex) {
|
|
|
19300
19211
|
String(payload?.output || payload?.message || 'Sign-in command finished.'),
|
|
19301
19212
|
payload?.interactiveNote ? String(payload.interactiveNote) : '',
|
|
19302
19213
|
'',
|
|
19303
|
-
'Complete any browser login, then click Test connection
|
|
19214
|
+
'Complete any browser login, then click Test connection.'
|
|
19304
19215
|
]);
|
|
19305
19216
|
demo.cliTerminalDraft = setupCommandFallback(agentId, 'sign-in');
|
|
19306
19217
|
demo.notice = 'Sign-in ran in Studio terminal. Finish login if prompted, then test the connection.';
|
|
@@ -19332,7 +19243,7 @@ async function openCliOsTerminal(agentId, chatIndex) {
|
|
|
19332
19243
|
'',
|
|
19333
19244
|
String(payload?.message || 'Complete sign-in in the OS terminal window that opened.'),
|
|
19334
19245
|
'',
|
|
19335
|
-
'When login finishes, return here and click Test connection
|
|
19246
|
+
'When login finishes, return here and click Test connection.'
|
|
19336
19247
|
]);
|
|
19337
19248
|
demo.notice = payload?.ok ? 'OS terminal opened for sign-in fallback.' : 'Could not open an OS terminal window.';
|
|
19338
19249
|
} catch {
|
|
@@ -19347,11 +19258,12 @@ function ModelPicker(index) {
|
|
|
19347
19258
|
const models = allModelOptions(index);
|
|
19348
19259
|
const selectedModel = selectedModelLabel(index);
|
|
19349
19260
|
const scoped = demo.pickerChatIndex === index;
|
|
19261
|
+
const access = accessModes.find((mode) => mode.id === chat.accessMode) || accessModes[1];
|
|
19350
19262
|
return '<div class="vr-model-picker">' +
|
|
19351
19263
|
'<button type="button" data-action="toggle-reasoning" data-chat-index="' + String(index) + '"><span>Reasoning</span><strong>' + escapeHtml(chat.reasoning) + '</strong><i></i></button>' +
|
|
19352
19264
|
'<button type="button" data-action="toggle-models" data-chat-index="' + String(index) + '"><span>Model</span><strong>' + escapeHtml(selectedModel) + '</strong><i></i></button>' +
|
|
19353
19265
|
'<button type="button" data-action="toggle-context" data-chat-index="' + String(index) + '"><span>Context</span><strong>' + escapeHtml(chat.context) + '</strong><i></i></button>' +
|
|
19354
|
-
|
|
19266
|
+
'<button type="button" data-action="toggle-access" data-chat-index="' + String(index) + '"><span>Access</span><strong>' + escapeHtml(access.label) + '</strong><i></i></button>' +
|
|
19355
19267
|
(scoped && demo.reasoningMenuOpen ? '<div class="vr-model-menu is-reasoning" role="menu"><p>Reasoning</p>' + reasoningLevels.map((level) =>
|
|
19356
19268
|
'<button type="button" data-reasoning="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.reasoning === level ? '<b></b>' : '') + '</button>'
|
|
19357
19269
|
).join('') + '</div>' : '') +
|
|
@@ -19361,14 +19273,9 @@ function ModelPicker(index) {
|
|
|
19361
19273
|
(scoped && demo.contextMenuOpen ? '<div class="vr-model-menu is-context" role="menu"><p>Context</p>' + contextLevels.map((level) =>
|
|
19362
19274
|
'<button type="button" data-context="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.context === level ? '<b></b>' : '') + '</button>'
|
|
19363
19275
|
).join('') + '</div>' : '') +
|
|
19364
|
-
'
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
function PermissionModeToggle(index) {
|
|
19368
|
-
const isFullAccess = demo.agentPermissionMode === 'full-access';
|
|
19369
|
-
return '<div class="vr-permission-toggle" role="group" aria-label="Agent permission mode">' +
|
|
19370
|
-
'<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>' +
|
|
19371
|
-
'<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>' +
|
|
19276
|
+
(scoped && demo.accessMenuOpen ? '<div class="vr-model-menu is-access" role="menu"><p>Access</p>' + accessModes.map((mode) =>
|
|
19277
|
+
'<button type="button" data-access-mode="' + escapeHtml(mode.id) + '" data-chat-index="' + String(index) + '"><span><strong>' + escapeHtml(mode.label) + '</strong><em>' + escapeHtml(mode.description) + '</em></span>' + (chat.accessMode === mode.id ? '<b></b>' : '') + '</button>'
|
|
19278
|
+
).join('') + '</div>' : '') +
|
|
19372
19279
|
'</div>';
|
|
19373
19280
|
}
|
|
19374
19281
|
|
|
@@ -19388,10 +19295,10 @@ function ChatBlockersSummary(cards) {
|
|
|
19388
19295
|
function ChatPlanCard(steps, chatIndex) {
|
|
19389
19296
|
const rows = Array.isArray(steps) ? steps : [];
|
|
19390
19297
|
if (!rows.length) return '';
|
|
19391
|
-
return '<section class="vr-chat-card vr-chat-plan-card"><header><strong>
|
|
19298
|
+
return '<section class="vr-chat-card vr-chat-plan-card"><header><strong>Fix plan</strong><b>' + String(rows.length) + ' actions</b></header><ol class="vr-chat-plan-list">' +
|
|
19392
19299
|
rows.map((step, index) =>
|
|
19393
19300
|
'<li><button class="vr-plan-step" type="button" data-action="mission-step" data-step-id="' + escapeHtml(step.id || ('step-' + String(index))) + '" data-chat-index="' + String(chatIndex) + '">' +
|
|
19394
|
-
'<span class="vr-plan-step-num"
|
|
19301
|
+
'<span class="vr-plan-step-num"></span>' +
|
|
19395
19302
|
'<span class="vr-plan-step-body">' +
|
|
19396
19303
|
'<span class="vr-plan-step-title">' + escapeHtml(step.title || 'Fix step') + '</span>' +
|
|
19397
19304
|
'<span class="vr-plan-step-tag">' + escapeHtml(step.category || 'Quality') + '</span>' +
|
|
@@ -19428,7 +19335,7 @@ function ChatMissionCards(cards, chatIndex, options) {
|
|
|
19428
19335
|
if (showPlan && planSteps.length) html += ChatPlanCard(planSteps, chatIndex);
|
|
19429
19336
|
if (connectProviders.length) html += ChatProviderConnectCard(connectProviders, chatIndex);
|
|
19430
19337
|
if (planSteps.length && !showPlan) {
|
|
19431
|
-
html += '<button class="vr-chat-plan-row" type="button" data-action="view-fix-plan" data-chat-index="' + String(chatIndex) + '">' + Icon('report') + '<strong>View
|
|
19338
|
+
html += '<button class="vr-chat-plan-row" type="button" data-action="view-fix-plan" data-chat-index="' + String(chatIndex) + '">' + Icon('report') + '<strong>View fix plan</strong><em>' + String(planSteps.length) + ' actions</em><b></b></button>';
|
|
19432
19339
|
}
|
|
19433
19340
|
html += '</div>';
|
|
19434
19341
|
return html;
|
|
@@ -19497,7 +19404,9 @@ function linkLabelForUrl(url) {
|
|
|
19497
19404
|
if (lower.includes('sentry.io')) return 'Open Sentry';
|
|
19498
19405
|
if (lower.includes('supabase.com')) return 'Open Supabase';
|
|
19499
19406
|
if (lower.includes('vercel.com')) return 'Open Vercel';
|
|
19407
|
+
if (lower.includes('github.com')) return 'Open GitHub';
|
|
19500
19408
|
if (lower.includes('stripe.com')) return 'Open Stripe';
|
|
19409
|
+
if (lower.includes('cli.github.com')) return 'Open GitHub CLI docs';
|
|
19501
19410
|
if (lower.includes('dashboard')) return 'Open dashboard';
|
|
19502
19411
|
return 'Open link';
|
|
19503
19412
|
}
|
|
@@ -19555,9 +19464,9 @@ function renderAgentListItems(items, chatIndex) {
|
|
|
19555
19464
|
|
|
19556
19465
|
function normalizeAgentSectionKey(raw) {
|
|
19557
19466
|
const key = String(raw || '').trim().toLowerCase().replace(/\\s*\\(\\d+\\)\\s*$/, '').trim();
|
|
19558
|
-
if (/^(gate|
|
|
19559
|
-
if (/^(blockers?|
|
|
19560
|
-
if (/^(suggested steps?|fix plan
|
|
19467
|
+
if (/^(gate|production gate)$/.test(key)) return null;
|
|
19468
|
+
if (/^(blockers?|context gaps?)$/.test(key)) return 'Context gaps';
|
|
19469
|
+
if (/^(suggested steps?|fix plan)$/.test(key)) return 'Suggested steps';
|
|
19561
19470
|
if (/^(summary|tl;dr|tldr)$/.test(key)) return 'Summary';
|
|
19562
19471
|
if (key === 'findings') return 'Findings';
|
|
19563
19472
|
if (key === 'changes made') return 'Changes made';
|
|
@@ -19590,15 +19499,7 @@ function dedupeAgentMarkdownBody(text, cards) {
|
|
|
19590
19499
|
}
|
|
19591
19500
|
|
|
19592
19501
|
function AgentGateStrip(gateText, gateState) {
|
|
19593
|
-
|
|
19594
|
-
const parsed = String(gateText || '').trim();
|
|
19595
|
-
const status = gate.status || 'unknown';
|
|
19596
|
-
const label = parsed || gate.label || 'Waiting for project evidence';
|
|
19597
|
-
const tone = status === 'clear' ? 'clear' : (status === 'blocked' || status === 'not_clear' ? 'blocked' : 'unknown');
|
|
19598
|
-
return '<div class="vr-agent-gate-strip" data-tone="' + escapeHtml(tone) + '">' +
|
|
19599
|
-
Icon('shield') +
|
|
19600
|
-
'<span><strong>Launch gate</strong><em>' + escapeHtml(label) + '</em></span>' +
|
|
19601
|
-
'</div>';
|
|
19502
|
+
return '';
|
|
19602
19503
|
}
|
|
19603
19504
|
|
|
19604
19505
|
function parseAgentSections(text, options) {
|
|
@@ -19645,8 +19546,7 @@ function renderAgentSectionCard(section, chatIndex) {
|
|
|
19645
19546
|
const name = section.name;
|
|
19646
19547
|
const lower = name.toLowerCase();
|
|
19647
19548
|
if (lower === 'gate') {
|
|
19648
|
-
|
|
19649
|
-
return AgentGateStrip(gateText, currentState.gate || null);
|
|
19549
|
+
return '';
|
|
19650
19550
|
}
|
|
19651
19551
|
const isNext = lower === 'next step';
|
|
19652
19552
|
const isBlockers = lower === 'blockers';
|
|
@@ -19664,6 +19564,7 @@ function renderAgentSectionCard(section, chatIndex) {
|
|
|
19664
19564
|
const blob = section.items.concat(section.paragraphs).join(' ').toLowerCase();
|
|
19665
19565
|
const actions = [];
|
|
19666
19566
|
if (/fix|wire|implement|add|configure|apply|sentry|monitor/.test(blob)) actions.push(agentApplyFixButton(chatIndex));
|
|
19567
|
+
if (blob.includes('github')) actions.push(agentLinkButton('Open GitHub', providerDashboardUrls.github || goLiveUrls.githubNew));
|
|
19667
19568
|
if (blob.includes('sentry')) actions.push(agentLinkButton('Open Sentry', providerDashboardUrls.sentry || 'https://sentry.io'));
|
|
19668
19569
|
if (blob.includes('supabase')) actions.push(agentLinkButton('Open Supabase', providerDashboardUrls.supabase || 'https://supabase.com/dashboard/projects'));
|
|
19669
19570
|
if (blob.includes('vercel')) actions.push(agentLinkButton('Open Vercel', providerDashboardUrls.vercel || 'https://vercel.com/dashboard'));
|
|
@@ -19835,7 +19736,7 @@ function readOnlyContextChipsHtml(providerId, releaseId) {
|
|
|
19835
19736
|
kind: 'provider',
|
|
19836
19737
|
index: 0,
|
|
19837
19738
|
id: provider.id,
|
|
19838
|
-
iconHtml: '<img src="' + (
|
|
19739
|
+
iconHtml: provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />',
|
|
19839
19740
|
mutedLabel: provider.area,
|
|
19840
19741
|
label: provider.name,
|
|
19841
19742
|
readOnly: true,
|
|
@@ -19926,7 +19827,7 @@ function ContextDropZone(index, showAttached) {
|
|
|
19926
19827
|
kind: 'provider',
|
|
19927
19828
|
index,
|
|
19928
19829
|
id: provider.id,
|
|
19929
|
-
iconHtml: '<img src="' + (
|
|
19830
|
+
iconHtml: provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />',
|
|
19930
19831
|
mutedLabel: provider.area,
|
|
19931
19832
|
label: provider.name,
|
|
19932
19833
|
}) : '') +
|
|
@@ -20038,12 +19939,13 @@ function AgentActionPanel() {
|
|
|
20038
19939
|
return '<aside class="vr-agent-panel" aria-label="VibeRaven AI Agent panel">' +
|
|
20039
19940
|
'<div class="vr-agent-control">' +
|
|
20040
19941
|
'<section class="vr-agent-hero ' + (fixing ? 'is-fixing' : '') + (verified ? ' is-verified' : '') + '">' +
|
|
20041
|
-
'<div><p>VibeRaven Agent</p><h2>' + (verified ? 'Ready
|
|
19942
|
+
'<div><p>VibeRaven Agent</p><h2>' + (verified ? 'Ready with proof' : fixing ? 'Fixing what changed' : 'Ready') + '</h2><em>' + (verified ? 'High confidence. Safe to proceed.' : fixing ? 'Patching proof now.' : 'High confidence. Safe to proceed.') + '</em></div>' +
|
|
20042
19943
|
'<img src="' + mascotUrl() + '" alt="" />' +
|
|
20043
19944
|
'</section>' +
|
|
20044
19945
|
'<section class="vr-quick-actions"><h3>Quick Actions</h3>' +
|
|
20045
19946
|
[
|
|
20046
|
-
{ id: '
|
|
19947
|
+
{ id: 'go-live', icon: 'cloud', title: 'Go Live', caption: 'GitHub + Vercel' },
|
|
19948
|
+
{ id: 'guide', icon: 'guide', title: 'Analyze Issues', caption: 'Find what changed' },
|
|
20047
19949
|
{ id: 'show-diff', icon: 'code', title: 'View Diff', caption: 'Review changes' },
|
|
20048
19950
|
{ id: 'recheck', icon: 'refresh', title: 'Run Verify', caption: 'Run checks again' },
|
|
20049
19951
|
{ id: 'explain-changes', icon: 'prompt', title: 'Explain Changes', caption: 'Summarize the fix' },
|
|
@@ -20204,7 +20106,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20204
20106
|
if (demo.activeStudioTab === 'terminal' && !demo.cliTerminalLines.length) {
|
|
20205
20107
|
demo.cliTerminalLines = [
|
|
20206
20108
|
'VibeRaven Studio shell',
|
|
20207
|
-
'Type commands at the $ prompt. Use
|
|
20109
|
+
'Type commands at the $ prompt. Use Test connection after sign-in.',
|
|
20208
20110
|
''
|
|
20209
20111
|
];
|
|
20210
20112
|
}
|
|
@@ -20302,6 +20204,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20302
20204
|
demo.modelMenuOpen = false;
|
|
20303
20205
|
demo.reasoningMenuOpen = false;
|
|
20304
20206
|
demo.contextMenuOpen = false;
|
|
20207
|
+
demo.accessMenuOpen = false;
|
|
20305
20208
|
demo.cliProbeStatus = 'idle';
|
|
20306
20209
|
demo.cliProbeMessage = '';
|
|
20307
20210
|
demo.pickerChatIndex = chatIndex;
|
|
@@ -20329,6 +20232,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20329
20232
|
demo.modelMenuOpen = false;
|
|
20330
20233
|
demo.reasoningMenuOpen = false;
|
|
20331
20234
|
demo.contextMenuOpen = false;
|
|
20235
|
+
demo.accessMenuOpen = false;
|
|
20332
20236
|
demo.notice = (cliAgents.find((item) => item.id === chat.cliId)?.label || chat.cliId) + ' selected for this chat.';
|
|
20333
20237
|
render();
|
|
20334
20238
|
return;
|
|
@@ -20346,6 +20250,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20346
20250
|
demo.modelMenuOpen = false;
|
|
20347
20251
|
demo.reasoningMenuOpen = false;
|
|
20348
20252
|
demo.contextMenuOpen = false;
|
|
20253
|
+
demo.accessMenuOpen = false;
|
|
20349
20254
|
demo.activeStudioTab = 'chat';
|
|
20350
20255
|
demo.pickerChatIndex = chatIndex;
|
|
20351
20256
|
demo.notice = selectedModelLabel(chatIndex) + ' selected for this chat.';
|
|
@@ -20364,6 +20269,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20364
20269
|
demo.reasoningMenuOpen = false;
|
|
20365
20270
|
demo.modelMenuOpen = false;
|
|
20366
20271
|
demo.contextMenuOpen = false;
|
|
20272
|
+
demo.accessMenuOpen = false;
|
|
20367
20273
|
demo.activeStudioTab = 'chat';
|
|
20368
20274
|
demo.pickerChatIndex = chatIndex;
|
|
20369
20275
|
demo.notice = chat.reasoning + ' reasoning selected for this chat.';
|
|
@@ -20382,6 +20288,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20382
20288
|
demo.contextMenuOpen = false;
|
|
20383
20289
|
demo.modelMenuOpen = false;
|
|
20384
20290
|
demo.reasoningMenuOpen = false;
|
|
20291
|
+
demo.accessMenuOpen = false;
|
|
20385
20292
|
demo.activeStudioTab = 'chat';
|
|
20386
20293
|
demo.pickerChatIndex = chatIndex;
|
|
20387
20294
|
demo.notice = chat.context + ' context selected for this chat.';
|
|
@@ -20390,21 +20297,23 @@ app.addEventListener('click', async (event) => {
|
|
|
20390
20297
|
return;
|
|
20391
20298
|
}
|
|
20392
20299
|
|
|
20393
|
-
const
|
|
20394
|
-
if (
|
|
20300
|
+
const accessButton = event.target.closest('[data-access-mode]');
|
|
20301
|
+
if (accessButton) {
|
|
20395
20302
|
event.preventDefault();
|
|
20396
|
-
const
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
|
|
20400
|
-
demo.
|
|
20303
|
+
const chatIndex = Number(accessButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
|
|
20304
|
+
const chat = chatContext(chatIndex);
|
|
20305
|
+
const selected = accessModes.find((mode) => mode.id === accessButton.getAttribute('data-access-mode')) || accessModes[1];
|
|
20306
|
+
chat.accessMode = selected.id;
|
|
20307
|
+
demo.selectedAccessMode = selected.id;
|
|
20308
|
+
demo.accessMenuOpen = false;
|
|
20309
|
+
demo.contextMenuOpen = false;
|
|
20401
20310
|
demo.modelMenuOpen = false;
|
|
20402
20311
|
demo.reasoningMenuOpen = false;
|
|
20403
|
-
demo.
|
|
20404
|
-
demo.
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20312
|
+
demo.activeStudioTab = 'chat';
|
|
20313
|
+
demo.pickerChatIndex = chatIndex;
|
|
20314
|
+
demo.notice = selected.label + ' selected for this chat.';
|
|
20315
|
+
refreshPickerMenus();
|
|
20316
|
+
refreshBottomTip();
|
|
20408
20317
|
return;
|
|
20409
20318
|
}
|
|
20410
20319
|
|
|
@@ -20415,6 +20324,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20415
20324
|
demo.modelMenuOpen = false;
|
|
20416
20325
|
demo.reasoningMenuOpen = false;
|
|
20417
20326
|
demo.contextMenuOpen = false;
|
|
20327
|
+
demo.accessMenuOpen = false;
|
|
20418
20328
|
if (stage === 'provider') {
|
|
20419
20329
|
demo.activeStudioTab = 'chat';
|
|
20420
20330
|
demo.providerPickerOpen = true;
|
|
@@ -20588,7 +20498,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20588
20498
|
}
|
|
20589
20499
|
if (action === 'copy-prompt') {
|
|
20590
20500
|
const copied = await copyText(agentPromptText());
|
|
20591
|
-
demo.notice = copied ? 'Agent mission ready. Keep the connected CLI scoped to
|
|
20501
|
+
demo.notice = copied ? 'Agent mission ready. Keep the connected CLI scoped to the evidenced change.' : 'Mission is still visible; clipboard permission was not available.';
|
|
20592
20502
|
render();
|
|
20593
20503
|
return;
|
|
20594
20504
|
}
|
|
@@ -20601,6 +20511,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20601
20511
|
demo.modelMenuOpen = !samePicker;
|
|
20602
20512
|
demo.reasoningMenuOpen = false;
|
|
20603
20513
|
demo.contextMenuOpen = false;
|
|
20514
|
+
demo.accessMenuOpen = false;
|
|
20604
20515
|
refreshPickerMenus();
|
|
20605
20516
|
return;
|
|
20606
20517
|
}
|
|
@@ -20613,6 +20524,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20613
20524
|
demo.reasoningMenuOpen = !samePicker;
|
|
20614
20525
|
demo.modelMenuOpen = false;
|
|
20615
20526
|
demo.contextMenuOpen = false;
|
|
20527
|
+
demo.accessMenuOpen = false;
|
|
20616
20528
|
refreshPickerMenus();
|
|
20617
20529
|
return;
|
|
20618
20530
|
}
|
|
@@ -20625,6 +20537,20 @@ app.addEventListener('click', async (event) => {
|
|
|
20625
20537
|
demo.contextMenuOpen = !samePicker;
|
|
20626
20538
|
demo.modelMenuOpen = false;
|
|
20627
20539
|
demo.reasoningMenuOpen = false;
|
|
20540
|
+
demo.accessMenuOpen = false;
|
|
20541
|
+
refreshPickerMenus();
|
|
20542
|
+
return;
|
|
20543
|
+
}
|
|
20544
|
+
if (action === 'toggle-access') {
|
|
20545
|
+
event.preventDefault();
|
|
20546
|
+
const chatIndex = Number(actionButton.getAttribute('data-chat-index') || '0');
|
|
20547
|
+
const samePicker = demo.pickerChatIndex === chatIndex && demo.accessMenuOpen;
|
|
20548
|
+
demo.activeStudioTab = 'chat';
|
|
20549
|
+
demo.pickerChatIndex = chatIndex;
|
|
20550
|
+
demo.accessMenuOpen = !samePicker;
|
|
20551
|
+
demo.modelMenuOpen = false;
|
|
20552
|
+
demo.reasoningMenuOpen = false;
|
|
20553
|
+
demo.contextMenuOpen = false;
|
|
20628
20554
|
refreshPickerMenus();
|
|
20629
20555
|
return;
|
|
20630
20556
|
}
|
|
@@ -20728,6 +20654,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20728
20654
|
demo.modelMenuOpen = false;
|
|
20729
20655
|
demo.reasoningMenuOpen = false;
|
|
20730
20656
|
demo.contextMenuOpen = false;
|
|
20657
|
+
demo.accessMenuOpen = false;
|
|
20731
20658
|
demo.notice = 'New chat opened.';
|
|
20732
20659
|
render();
|
|
20733
20660
|
return;
|
|
@@ -20801,12 +20728,17 @@ app.addEventListener('click', async (event) => {
|
|
|
20801
20728
|
runChatTask('analyze');
|
|
20802
20729
|
return;
|
|
20803
20730
|
}
|
|
20731
|
+
if (action === 'go-live') {
|
|
20732
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
20733
|
+
runChatTask('go-live');
|
|
20734
|
+
return;
|
|
20735
|
+
}
|
|
20804
20736
|
if (action === 'prompt') {
|
|
20805
20737
|
demo.activeNavId = 'agents';
|
|
20806
20738
|
demo.activeStepId = 'agent';
|
|
20807
20739
|
demo.providerPickerOpen = false;
|
|
20808
20740
|
demo.activeModal = 'prompt';
|
|
20809
|
-
demo.notice = 'Agent mission is ready. Keep the fix scoped to the
|
|
20741
|
+
demo.notice = 'Agent mission is ready. Keep the fix scoped to the evidenced change.';
|
|
20810
20742
|
render();
|
|
20811
20743
|
return;
|
|
20812
20744
|
}
|
|
@@ -20833,7 +20765,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20833
20765
|
const chatIndex = Number(actionButton.getAttribute('data-chat-index') || String(actionChatIndex));
|
|
20834
20766
|
demo.fixPlanExpandedChatIndex = demo.fixPlanExpandedChatIndex === chatIndex ? null : chatIndex;
|
|
20835
20767
|
demo.pickerChatIndex = chatIndex;
|
|
20836
|
-
demo.notice = demo.fixPlanExpandedChatIndex === chatIndex ? '
|
|
20768
|
+
demo.notice = demo.fixPlanExpandedChatIndex === chatIndex ? 'Fix plan expanded in chat.' : 'Fix plan collapsed.';
|
|
20837
20769
|
render();
|
|
20838
20770
|
return;
|
|
20839
20771
|
}
|
|
@@ -20890,7 +20822,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20890
20822
|
environment: 'Environment selector is scoped to the local Studio preview.',
|
|
20891
20823
|
account: 'VibeRaven agent opened from the header mascot.',
|
|
20892
20824
|
'all-releases': 'Release history view opens next; this preview keeps the timeline focused.',
|
|
20893
|
-
'explain-changes': 'Change summary opened
|
|
20825
|
+
'explain-changes': 'Change summary opened with release-context wording.',
|
|
20894
20826
|
};
|
|
20895
20827
|
if (actionMessages[action]) {
|
|
20896
20828
|
if (action === 'all-releases') {
|
|
@@ -20973,7 +20905,7 @@ app.addEventListener('dragstart', (event) => {
|
|
|
20973
20905
|
event,
|
|
20974
20906
|
provider ? provider.name : 'Provider',
|
|
20975
20907
|
provider ? provider.area : 'Drop into VibeRaven chat',
|
|
20976
|
-
provider ? '<img src="' +
|
|
20908
|
+
provider ? (provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />') : ''
|
|
20977
20909
|
);
|
|
20978
20910
|
providerButton.classList.add('is-being-dragged');
|
|
20979
20911
|
demo.notice = 'Dragging provider context. Drop it into a chat composer or Split chat.';
|
|
@@ -21063,7 +20995,7 @@ app.addEventListener('drop', (event) => {
|
|
|
21063
20995
|
if (newChatTarget) demo.activeRecentChatId = null;
|
|
21064
20996
|
if (chatIndex === 0) syncPrimaryContext();
|
|
21065
20997
|
if (provider && provider.state === 'not_detected') {
|
|
21066
|
-
context.draft = 'Help me connect ' + provider.name + '
|
|
20998
|
+
context.draft = 'Help me connect ' + provider.name + ' with context. What provider state, runtime behavior, or dashboard proof does this repo need?';
|
|
21067
20999
|
demo.notice = provider.name + ' is missing \u2014 connect steps prefilled. Send when ready.';
|
|
21068
21000
|
} else {
|
|
21069
21001
|
demo.notice = provider ? provider.name + ' context attached to chat ' + String(chatIndex + 1) + '. Suggested actions updated for ' + (stackSlots[provider.id] || provider.area) + '.' : 'Provider context attached.';
|
|
@@ -23768,21 +23700,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
23768
23700
|
background: rgba(124, 58, 237, 0.92);
|
|
23769
23701
|
color: #fff;
|
|
23770
23702
|
}
|
|
23771
|
-
.vr-cli-setup-cta-hint {
|
|
23772
|
-
margin: 0 0 6px;
|
|
23773
|
-
color: #94a3b8;
|
|
23774
|
-
font-size: 11px;
|
|
23775
|
-
font-weight: 500;
|
|
23776
|
-
line-height: 1.35;
|
|
23777
|
-
}
|
|
23778
|
-
.vr-cli-setup-cta-hint strong {
|
|
23779
|
-
color: #c4b5fd;
|
|
23780
|
-
font-weight: 650;
|
|
23781
|
-
}
|
|
23782
|
-
.vr-cli-action-button.is-primary.is-pending {
|
|
23783
|
-
border-color: rgba(168, 85, 247, 0.55);
|
|
23784
|
-
box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.25);
|
|
23785
|
-
}
|
|
23786
23703
|
.vr-cli-strip button.is-connect-target {
|
|
23787
23704
|
border-color: rgba(248, 250, 252, 0.34);
|
|
23788
23705
|
box-shadow: inset 0 0 0 1px rgba(248, 250, 252, 0.08);
|
|
@@ -24507,16 +24424,15 @@ body:has(.vr-app.is-dragging) {
|
|
|
24507
24424
|
border-color: rgba(168, 85, 247, 0.38);
|
|
24508
24425
|
}
|
|
24509
24426
|
.vr-plan-step-num {
|
|
24510
|
-
width:
|
|
24511
|
-
height:
|
|
24427
|
+
width: 10px;
|
|
24428
|
+
height: 10px;
|
|
24512
24429
|
flex: 0 0 auto;
|
|
24513
24430
|
display: grid;
|
|
24514
24431
|
place-items: center;
|
|
24515
|
-
border: 1px solid rgba(168, 85, 247, 0.
|
|
24432
|
+
border: 1px solid rgba(168, 85, 247, 0.5);
|
|
24516
24433
|
border-radius: 999px;
|
|
24517
|
-
|
|
24518
|
-
|
|
24519
|
-
font-weight: 700;
|
|
24434
|
+
background: rgba(168, 85, 247, 0.28);
|
|
24435
|
+
box-shadow: 0 0 10px rgba(168, 85, 247, 0.22);
|
|
24520
24436
|
}
|
|
24521
24437
|
.vr-plan-step-body {
|
|
24522
24438
|
flex: 1 1 0;
|
|
@@ -25128,6 +25044,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
25128
25044
|
.vr-model-menu.is-context {
|
|
25129
25045
|
right: 0;
|
|
25130
25046
|
}
|
|
25047
|
+
.vr-model-menu.is-access {
|
|
25048
|
+
right: 0;
|
|
25049
|
+
min-width: 270px;
|
|
25050
|
+
}
|
|
25131
25051
|
.vr-studio-chat.is-split .vr-model-menu {
|
|
25132
25052
|
bottom: calc(100% + 10px);
|
|
25133
25053
|
min-width: min(245px, calc(100vw - 32px));
|
|
@@ -25144,6 +25064,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
25144
25064
|
left: auto;
|
|
25145
25065
|
right: 0;
|
|
25146
25066
|
}
|
|
25067
|
+
.vr-studio-chat.is-split .vr-model-menu.is-access {
|
|
25068
|
+
left: auto;
|
|
25069
|
+
right: 0;
|
|
25070
|
+
}
|
|
25147
25071
|
.vr-model-menu p {
|
|
25148
25072
|
margin: 2px 4px 6px;
|
|
25149
25073
|
color: #a8a29e;
|
|
@@ -25288,7 +25212,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25288
25212
|
}
|
|
25289
25213
|
.vr-bottom-inventory .vr-provider-card {
|
|
25290
25214
|
min-height: 48px;
|
|
25291
|
-
grid-template-columns: 34px minmax(0, 1fr)
|
|
25215
|
+
grid-template-columns: 34px minmax(0, 1fr) 18px 22px;
|
|
25292
25216
|
grid-template-rows: 1fr;
|
|
25293
25217
|
align-items: center;
|
|
25294
25218
|
gap: 8px;
|
|
@@ -25345,14 +25269,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
25345
25269
|
fill: none !important;
|
|
25346
25270
|
stroke: currentColor !important;
|
|
25347
25271
|
}
|
|
25348
|
-
.vr-bottom-inventory .vr-provider-light {
|
|
25349
|
-
right: 36px;
|
|
25350
|
-
top: 50%;
|
|
25351
|
-
width: 7px;
|
|
25352
|
-
height: 7px;
|
|
25353
|
-
transform: translateY(-50%);
|
|
25354
|
-
box-shadow: 0 0 9px rgba(34, 197, 94, 0.42);
|
|
25355
|
-
}
|
|
25356
25272
|
.vr-bottom-inventory .vr-provider-card .vr-status-badge {
|
|
25357
25273
|
grid-column: 3;
|
|
25358
25274
|
min-height: 18px;
|
|
@@ -25639,8 +25555,35 @@ body:has(.vr-app.is-dragging) {
|
|
|
25639
25555
|
filter: saturate(1.04) contrast(1.02);
|
|
25640
25556
|
transition: transform 180ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
25641
25557
|
}
|
|
25558
|
+
.vr-provider-token .provider-logo__img {
|
|
25559
|
+
filter: saturate(1.22) contrast(1.14);
|
|
25560
|
+
}
|
|
25561
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="github"],
|
|
25562
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="vercel"],
|
|
25563
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="resend"] {
|
|
25564
|
+
filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.18));
|
|
25565
|
+
}
|
|
25566
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="sentry"] {
|
|
25567
|
+
filter: saturate(1.34) contrast(1.16) drop-shadow(0 0 9px rgba(139, 92, 246, 0.26));
|
|
25568
|
+
}
|
|
25569
|
+
.vr-provider-token svg {
|
|
25570
|
+
position: relative;
|
|
25571
|
+
z-index: 1;
|
|
25572
|
+
width: 26px;
|
|
25573
|
+
height: 26px;
|
|
25574
|
+
display: block;
|
|
25575
|
+
}
|
|
25576
|
+
.vr-provider-token .vr-provider-logo,
|
|
25577
|
+
.vr-provider-token .vr-provider-logo img {
|
|
25578
|
+
width: 26px;
|
|
25579
|
+
height: 26px;
|
|
25580
|
+
display: block;
|
|
25581
|
+
object-fit: contain;
|
|
25582
|
+
}
|
|
25642
25583
|
.vr-provider-card:hover .vr-provider-token img,
|
|
25643
|
-
.vr-provider-card.is-selected .vr-provider-token img
|
|
25584
|
+
.vr-provider-card.is-selected .vr-provider-token img,
|
|
25585
|
+
.vr-provider-card:hover .vr-provider-token svg,
|
|
25586
|
+
.vr-provider-card.is-selected .vr-provider-token svg {
|
|
25644
25587
|
transform: scale(1.08);
|
|
25645
25588
|
}
|
|
25646
25589
|
.vr-provider-token.is-picker {
|
|
@@ -25661,15 +25604,11 @@ body:has(.vr-app.is-dragging) {
|
|
|
25661
25604
|
width: 34px;
|
|
25662
25605
|
height: 34px;
|
|
25663
25606
|
}
|
|
25664
|
-
.vr-provider-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
25669
|
-
height: 8px;
|
|
25670
|
-
border-radius: 999px;
|
|
25671
|
-
background: var(--vr-green);
|
|
25672
|
-
box-shadow: 0 0 8px rgba(34, 197, 94, 0.36);
|
|
25607
|
+
.vr-provider-token.is-large svg,
|
|
25608
|
+
.vr-provider-token.is-large .vr-provider-logo,
|
|
25609
|
+
.vr-provider-token.is-large .vr-provider-logo img {
|
|
25610
|
+
width: 34px;
|
|
25611
|
+
height: 34px;
|
|
25673
25612
|
}
|
|
25674
25613
|
.vr-provider-card small,
|
|
25675
25614
|
.vr-provider-card strong,
|
|
@@ -25699,6 +25638,15 @@ body:has(.vr-app.is-dragging) {
|
|
|
25699
25638
|
font-size: 11px;
|
|
25700
25639
|
font-weight: 520;
|
|
25701
25640
|
}
|
|
25641
|
+
.vr-provider-card[data-provider-tone="orange"] em {
|
|
25642
|
+
color: #fbbf24;
|
|
25643
|
+
}
|
|
25644
|
+
.vr-provider-card[data-provider-tone="red"] em {
|
|
25645
|
+
color: #fb7185;
|
|
25646
|
+
}
|
|
25647
|
+
.vr-provider-card[data-provider-tone="neutral"] em {
|
|
25648
|
+
color: #aeb7c6;
|
|
25649
|
+
}
|
|
25702
25650
|
.vr-provider-proof-chip {
|
|
25703
25651
|
grid-column: 1 / -1;
|
|
25704
25652
|
display: inline-flex;
|
|
@@ -25730,6 +25678,130 @@ body:has(.vr-app.is-dragging) {
|
|
|
25730
25678
|
height: 13px;
|
|
25731
25679
|
stroke: currentColor;
|
|
25732
25680
|
}
|
|
25681
|
+
.vr-provider-mcp-chip {
|
|
25682
|
+
grid-column: 2;
|
|
25683
|
+
grid-row: 2;
|
|
25684
|
+
justify-self: end;
|
|
25685
|
+
min-width: 0;
|
|
25686
|
+
width: 8px;
|
|
25687
|
+
height: 8px;
|
|
25688
|
+
display: inline-flex;
|
|
25689
|
+
align-items: center;
|
|
25690
|
+
justify-content: center;
|
|
25691
|
+
gap: 0;
|
|
25692
|
+
border: 0;
|
|
25693
|
+
border-radius: 999px;
|
|
25694
|
+
padding: 0;
|
|
25695
|
+
color: #fbbf24;
|
|
25696
|
+
font-size: 10px;
|
|
25697
|
+
font-weight: 720;
|
|
25698
|
+
line-height: 1;
|
|
25699
|
+
background: transparent;
|
|
25700
|
+
}
|
|
25701
|
+
.vr-provider-mcp-chip i {
|
|
25702
|
+
width: 8px;
|
|
25703
|
+
height: 8px;
|
|
25704
|
+
flex: 0 0 auto;
|
|
25705
|
+
border-radius: 999px;
|
|
25706
|
+
background: #f59e0b;
|
|
25707
|
+
box-shadow: 0 0 8px rgba(245, 158, 11, 0.36);
|
|
25708
|
+
animation: vrStatusPulse 2.7s ease-in-out infinite;
|
|
25709
|
+
}
|
|
25710
|
+
.vr-provider-mcp-chip span {
|
|
25711
|
+
position: absolute;
|
|
25712
|
+
width: 1px;
|
|
25713
|
+
height: 1px;
|
|
25714
|
+
overflow: hidden;
|
|
25715
|
+
clip: rect(0 0 0 0);
|
|
25716
|
+
}
|
|
25717
|
+
.vr-provider-mcp-chip.is-connected {
|
|
25718
|
+
border-color: transparent;
|
|
25719
|
+
background: transparent;
|
|
25720
|
+
color: #bbf7d0;
|
|
25721
|
+
}
|
|
25722
|
+
.vr-provider-mcp-chip.is-connected i {
|
|
25723
|
+
background: #22c55e;
|
|
25724
|
+
box-shadow: 0 0 8px rgba(34, 197, 94, 0.42);
|
|
25725
|
+
}
|
|
25726
|
+
@keyframes vrStatusPulse {
|
|
25727
|
+
0%, 100% {
|
|
25728
|
+
opacity: 0.72;
|
|
25729
|
+
transform: scale(0.92);
|
|
25730
|
+
}
|
|
25731
|
+
50% {
|
|
25732
|
+
opacity: 1;
|
|
25733
|
+
transform: scale(1.08);
|
|
25734
|
+
}
|
|
25735
|
+
}
|
|
25736
|
+
.vr-provider-mcp-panel {
|
|
25737
|
+
display: grid;
|
|
25738
|
+
gap: 10px;
|
|
25739
|
+
border: 1px solid rgba(148, 163, 184, 0.13);
|
|
25740
|
+
border-radius: 10px;
|
|
25741
|
+
padding: 10px;
|
|
25742
|
+
background: rgba(255, 255, 255, 0.035);
|
|
25743
|
+
}
|
|
25744
|
+
.vr-provider-mcp-panel header {
|
|
25745
|
+
display: grid;
|
|
25746
|
+
grid-template-columns: 30px minmax(0, 1fr);
|
|
25747
|
+
gap: 10px;
|
|
25748
|
+
align-items: center;
|
|
25749
|
+
}
|
|
25750
|
+
.vr-provider-mcp-panel header > span {
|
|
25751
|
+
width: 30px;
|
|
25752
|
+
height: 30px;
|
|
25753
|
+
display: inline-grid;
|
|
25754
|
+
place-items: center;
|
|
25755
|
+
border-radius: 8px;
|
|
25756
|
+
background: rgba(245, 158, 11, 0.11);
|
|
25757
|
+
color: #fbbf24;
|
|
25758
|
+
}
|
|
25759
|
+
.vr-provider-mcp-panel strong,
|
|
25760
|
+
.vr-provider-mcp-panel em {
|
|
25761
|
+
display: block;
|
|
25762
|
+
min-width: 0;
|
|
25763
|
+
}
|
|
25764
|
+
.vr-provider-mcp-panel strong {
|
|
25765
|
+
color: #f8fafc;
|
|
25766
|
+
font-size: 13px;
|
|
25767
|
+
}
|
|
25768
|
+
.vr-provider-mcp-panel em {
|
|
25769
|
+
margin-top: 2px;
|
|
25770
|
+
color: #98a2b3;
|
|
25771
|
+
font-size: 11px;
|
|
25772
|
+
font-style: normal;
|
|
25773
|
+
}
|
|
25774
|
+
.vr-provider-mcp-panel > div {
|
|
25775
|
+
display: flex;
|
|
25776
|
+
flex-wrap: wrap;
|
|
25777
|
+
gap: 6px;
|
|
25778
|
+
}
|
|
25779
|
+
.vr-provider-mcp-panel small {
|
|
25780
|
+
border-radius: 999px;
|
|
25781
|
+
border: 1px solid rgba(148, 163, 184, 0.13);
|
|
25782
|
+
padding: 4px 7px;
|
|
25783
|
+
color: #b9c2cf;
|
|
25784
|
+
font-size: 10px;
|
|
25785
|
+
font-weight: 680;
|
|
25786
|
+
}
|
|
25787
|
+
.vr-provider-mcp-panel.is-connected {
|
|
25788
|
+
border-color: rgba(34, 197, 94, 0.24);
|
|
25789
|
+
background: rgba(34, 197, 94, 0.055);
|
|
25790
|
+
}
|
|
25791
|
+
.vr-provider-mcp-panel.is-connected header > span {
|
|
25792
|
+
background: rgba(34, 197, 94, 0.12);
|
|
25793
|
+
color: #86efac;
|
|
25794
|
+
}
|
|
25795
|
+
.vr-bottom-inventory .vr-provider-mcp-chip {
|
|
25796
|
+
grid-column: 3;
|
|
25797
|
+
grid-row: 1;
|
|
25798
|
+
justify-self: end;
|
|
25799
|
+
min-width: 0;
|
|
25800
|
+
width: 8px;
|
|
25801
|
+
height: 8px;
|
|
25802
|
+
padding: 0;
|
|
25803
|
+
font-size: 0;
|
|
25804
|
+
}
|
|
25733
25805
|
.vr-bottom-inventory .vr-provider-proof-chip {
|
|
25734
25806
|
grid-column: 4;
|
|
25735
25807
|
justify-self: end;
|
|
@@ -25751,13 +25823,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
25751
25823
|
height: 15px;
|
|
25752
25824
|
stroke-width: 2.35;
|
|
25753
25825
|
}
|
|
25754
|
-
.vr-bottom-inventory .vr-provider-light {
|
|
25755
|
-
right: 36px;
|
|
25756
|
-
top: 50%;
|
|
25757
|
-
width: 7px;
|
|
25758
|
-
height: 7px;
|
|
25759
|
-
transform: translateY(-50%);
|
|
25760
|
-
}
|
|
25761
25826
|
.vr-bottom-inventory .vr-provider-card:hover .vr-provider-proof-chip,
|
|
25762
25827
|
.vr-bottom-inventory .vr-provider-card.is-selected .vr-provider-proof-chip {
|
|
25763
25828
|
background: transparent;
|
|
@@ -26352,33 +26417,48 @@ body:has(.vr-app.is-dragging) {
|
|
|
26352
26417
|
width: 18px;
|
|
26353
26418
|
height: 18px;
|
|
26354
26419
|
}
|
|
26420
|
+
.vr-bottom-tip-bar .vr-inline-brand-mark.is-github {
|
|
26421
|
+
display: inline-grid;
|
|
26422
|
+
place-items: center;
|
|
26423
|
+
color: #f8fafc;
|
|
26424
|
+
}
|
|
26425
|
+
.vr-bottom-tip-bar .vr-inline-brand-mark.is-github svg {
|
|
26426
|
+
width: 17px;
|
|
26427
|
+
height: 17px;
|
|
26428
|
+
display: block;
|
|
26429
|
+
fill: currentColor;
|
|
26430
|
+
}
|
|
26355
26431
|
.vr-tip-mascot {
|
|
26432
|
+
width: 34px;
|
|
26433
|
+
height: 34px;
|
|
26356
26434
|
align-self: stretch;
|
|
26357
26435
|
position: relative;
|
|
26358
26436
|
display: grid;
|
|
26359
26437
|
place-items: end center;
|
|
26360
26438
|
overflow: hidden;
|
|
26439
|
+
border-right: 1px solid rgba(148, 163, 184, 0.16);
|
|
26361
26440
|
}
|
|
26362
26441
|
.vr-tip-mascot::before {
|
|
26363
26442
|
content: "";
|
|
26364
26443
|
position: absolute;
|
|
26365
|
-
left:
|
|
26366
|
-
right:
|
|
26367
|
-
bottom:
|
|
26368
|
-
height:
|
|
26444
|
+
left: 8px;
|
|
26445
|
+
right: 8px;
|
|
26446
|
+
bottom: 2px;
|
|
26447
|
+
height: 10px;
|
|
26369
26448
|
border-radius: 999px;
|
|
26370
|
-
background: rgba(124, 58, 237, 0.
|
|
26371
|
-
filter: blur(
|
|
26449
|
+
background: rgba(124, 58, 237, 0.24);
|
|
26450
|
+
filter: blur(8px);
|
|
26372
26451
|
}
|
|
26373
26452
|
.vr-tip-mascot img {
|
|
26374
26453
|
position: relative;
|
|
26454
|
+
z-index: 1;
|
|
26375
26455
|
align-self: end;
|
|
26376
|
-
width:
|
|
26377
|
-
height:
|
|
26456
|
+
width: 32px;
|
|
26457
|
+
height: 32px;
|
|
26378
26458
|
object-fit: contain;
|
|
26379
26459
|
object-position: bottom;
|
|
26380
|
-
transform: translateY(
|
|
26381
|
-
filter: saturate(1.
|
|
26460
|
+
transform: translateY(3px);
|
|
26461
|
+
filter: saturate(1.16) drop-shadow(0 0 12px rgba(168, 85, 247, 0.46));
|
|
26382
26462
|
}
|
|
26383
26463
|
.vr-bottom-tip-bar span {
|
|
26384
26464
|
color: #cbd5e1;
|
|
@@ -26701,6 +26781,18 @@ body:has(.vr-app.is-dragging) {
|
|
|
26701
26781
|
box-shadow: var(--vr-glow-purple);
|
|
26702
26782
|
transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1), box-shadow 200ms ease;
|
|
26703
26783
|
}
|
|
26784
|
+
.vr-modal-provider-logo.is-logo-html {
|
|
26785
|
+
display: grid;
|
|
26786
|
+
place-items: center;
|
|
26787
|
+
}
|
|
26788
|
+
.vr-modal-provider-logo.is-logo-html img,
|
|
26789
|
+
.vr-modal-provider-logo.is-logo-html svg,
|
|
26790
|
+
.vr-modal-provider-logo.is-logo-html .vr-provider-logo {
|
|
26791
|
+
width: 74px;
|
|
26792
|
+
height: 74px;
|
|
26793
|
+
display: block;
|
|
26794
|
+
object-fit: contain;
|
|
26795
|
+
}
|
|
26704
26796
|
|
|
26705
26797
|
.vr-modal-provider-logo:hover {
|
|
26706
26798
|
transform: translateY(-3px) rotate(-2deg);
|
|
@@ -28046,46 +28138,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
28046
28138
|
display: none;
|
|
28047
28139
|
}
|
|
28048
28140
|
}
|
|
28049
|
-
.vr-permission-toggle {
|
|
28050
|
-
display: inline-flex;
|
|
28051
|
-
align-items: center;
|
|
28052
|
-
gap: 0;
|
|
28053
|
-
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
28054
|
-
border-radius: 8px;
|
|
28055
|
-
overflow: hidden;
|
|
28056
|
-
background: rgba(39, 40, 44, 0.92);
|
|
28057
|
-
}
|
|
28058
|
-
.vr-permission-btn {
|
|
28059
|
-
min-height: 28px;
|
|
28060
|
-
padding: 0 10px;
|
|
28061
|
-
font-size: 11px;
|
|
28062
|
-
font-weight: 640;
|
|
28063
|
-
color: #94a3b8;
|
|
28064
|
-
background: transparent;
|
|
28065
|
-
border: none;
|
|
28066
|
-
border-radius: 0;
|
|
28067
|
-
cursor: pointer;
|
|
28068
|
-
transition: background 0.12s, color 0.12s;
|
|
28069
|
-
white-space: nowrap;
|
|
28070
|
-
}
|
|
28071
|
-
.vr-permission-btn + .vr-permission-btn {
|
|
28072
|
-
border-left: 1px solid rgba(148, 163, 184, 0.14);
|
|
28073
|
-
}
|
|
28074
|
-
.vr-permission-btn.is-active {
|
|
28075
|
-
background: rgba(100, 116, 139, 0.28);
|
|
28076
|
-
color: #f1f5f9;
|
|
28077
|
-
}
|
|
28078
|
-
.vr-permission-btn.is-danger {
|
|
28079
|
-
color: #f59e0b;
|
|
28080
|
-
}
|
|
28081
|
-
.vr-permission-btn.is-danger.is-active {
|
|
28082
|
-
background: rgba(245, 158, 11, 0.18);
|
|
28083
|
-
color: #fbbf24;
|
|
28084
|
-
}
|
|
28085
|
-
.vr-permission-btn:hover:not(.is-active) {
|
|
28086
|
-
background: rgba(148, 163, 184, 0.1);
|
|
28087
|
-
color: #e2e8f0;
|
|
28088
|
-
}
|
|
28089
28141
|
`;
|
|
28090
28142
|
}
|
|
28091
28143
|
});
|
|
@@ -28102,8 +28154,9 @@ function renderLocalUiHtml(state) {
|
|
|
28102
28154
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
28103
28155
|
<meta name="theme-color" content="#050816" />
|
|
28104
28156
|
<title>VibeRaven</title>
|
|
28105
|
-
<link rel="icon" type="image/png" href="/report/assets/viberaven-
|
|
28106
|
-
<link rel="
|
|
28157
|
+
<link rel="icon" type="image/png" sizes="64x64" href="/report/assets/viberaven-favicon.png" />
|
|
28158
|
+
<link rel="shortcut icon" type="image/png" href="/report/assets/viberaven-favicon.png" />
|
|
28159
|
+
<link rel="apple-touch-icon" href="/report/assets/viberaven-mascot.png" />
|
|
28107
28160
|
<style>${localUiCss}</style>
|
|
28108
28161
|
</head>
|
|
28109
28162
|
<body>
|
|
@@ -28366,6 +28419,19 @@ async function releaseChangelogBetween(cwd, fromRef, toRef) {
|
|
|
28366
28419
|
});
|
|
28367
28420
|
return { from: fromRef, to: toRef, fromLabel: fromRef, toLabel: toRef, entries };
|
|
28368
28421
|
}
|
|
28422
|
+
async function releaseDiffContextBlock(cwd, releaseId) {
|
|
28423
|
+
const ref = safeGitRef(releaseId);
|
|
28424
|
+
if (!ref || ref === "workspace") return void 0;
|
|
28425
|
+
if (!await gitRefExists(cwd, ref)) return void 0;
|
|
28426
|
+
const comparison = await compareReleaseRefs(cwd, ref, "HEAD");
|
|
28427
|
+
const stats = comparison.stats;
|
|
28428
|
+
const diffPreview = comparison.diff.length > 6e3 ? comparison.diff.slice(0, 6e3) + "\n[diff truncated]" : comparison.diff;
|
|
28429
|
+
return [
|
|
28430
|
+
`Attached release diff (${comparison.fromLabel} -> ${comparison.toLabel}):`,
|
|
28431
|
+
`Files changed: ${stats.files}; insertions: ${stats.insertions}; deletions: ${stats.deletions}`,
|
|
28432
|
+
diffPreview
|
|
28433
|
+
].join("\n");
|
|
28434
|
+
}
|
|
28369
28435
|
async function rollbackReleaseRef(cwd, targetRef) {
|
|
28370
28436
|
if (!await gitRefExists(cwd, targetRef)) {
|
|
28371
28437
|
return { ok: false, message: `Release ref "${targetRef}" was not found in this repo.`, checkedOut: "" };
|
|
@@ -28558,7 +28624,7 @@ async function detectLocalCliAgents(cwd, options = {}) {
|
|
|
28558
28624
|
return {
|
|
28559
28625
|
...agent,
|
|
28560
28626
|
installed,
|
|
28561
|
-
connected:
|
|
28627
|
+
connected: agent.id === "terminal",
|
|
28562
28628
|
source: simulateDisconnected ? "simulated" : installed ? "detected" : "fallback",
|
|
28563
28629
|
models: cliModelDefaults(agent.id),
|
|
28564
28630
|
setup: CLI_AGENT_SETUP[agent.id]
|
|
@@ -28576,6 +28642,60 @@ function isPlaceholderProjectName(value) {
|
|
|
28576
28642
|
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
28577
28643
|
return normalized === "" || normalized === "project" || normalized === "npx-open-source-check" || normalized.startsWith("viberaven-local-ui");
|
|
28578
28644
|
}
|
|
28645
|
+
async function readMcpEvidence(cwd) {
|
|
28646
|
+
const candidates = MCP_CONFIG_PATHS.map((relativePath) => ({
|
|
28647
|
+
source: relativePath.replace(/\\/g, "/"),
|
|
28648
|
+
path: (0, import_node_path31.resolve)(cwd, relativePath)
|
|
28649
|
+
}));
|
|
28650
|
+
const home = process.env.USERPROFILE || process.env.HOME;
|
|
28651
|
+
if (home) {
|
|
28652
|
+
candidates.push({
|
|
28653
|
+
source: "~/.codex/config.toml",
|
|
28654
|
+
path: (0, import_node_path31.resolve)(home, ".codex", "config.toml")
|
|
28655
|
+
});
|
|
28656
|
+
}
|
|
28657
|
+
const evidence = [];
|
|
28658
|
+
for (const candidate of candidates) {
|
|
28659
|
+
try {
|
|
28660
|
+
const text = await (0, import_promises24.readFile)(candidate.path, "utf8");
|
|
28661
|
+
if (/mcp/i.test(text)) evidence.push({ source: candidate.source, text });
|
|
28662
|
+
} catch {
|
|
28663
|
+
}
|
|
28664
|
+
}
|
|
28665
|
+
return evidence;
|
|
28666
|
+
}
|
|
28667
|
+
function mcpForProvider(provider2, evidence) {
|
|
28668
|
+
const needles = MCP_PROVIDER_NEEDLES[provider2.id] ?? [provider2.id];
|
|
28669
|
+
const match = evidence.find((item4) => {
|
|
28670
|
+
const lower = item4.text.toLowerCase();
|
|
28671
|
+
return needles.some((needle) => lower.includes(needle.toLowerCase()));
|
|
28672
|
+
});
|
|
28673
|
+
if (match) {
|
|
28674
|
+
return {
|
|
28675
|
+
status: "connected",
|
|
28676
|
+
label: "MCP connected",
|
|
28677
|
+
source: match.source,
|
|
28678
|
+
connectCommand: MCP_CONNECT_COMMANDS[provider2.id],
|
|
28679
|
+
capabilities: ["repo context", provider2.area, "provider-aware chat"]
|
|
28680
|
+
};
|
|
28681
|
+
}
|
|
28682
|
+
return {
|
|
28683
|
+
status: "disconnected",
|
|
28684
|
+
label: "Connect MCP",
|
|
28685
|
+
connectCommand: MCP_CONNECT_COMMANDS[provider2.id] ?? `Add a ${provider2.name} MCP server entry, then drag ${provider2.name} into chat.`,
|
|
28686
|
+
capabilities: []
|
|
28687
|
+
};
|
|
28688
|
+
}
|
|
28689
|
+
async function applyMcpDetection(state, cwd) {
|
|
28690
|
+
const evidence = await readMcpEvidence(cwd);
|
|
28691
|
+
return {
|
|
28692
|
+
...state,
|
|
28693
|
+
providers: state.providers.map((provider2) => ({
|
|
28694
|
+
...provider2,
|
|
28695
|
+
mcp: mcpForProvider(provider2, evidence)
|
|
28696
|
+
}))
|
|
28697
|
+
};
|
|
28698
|
+
}
|
|
28579
28699
|
async function enrichProjectMetadata(state, cwd) {
|
|
28580
28700
|
const packageJson = await readPackageJson2(cwd);
|
|
28581
28701
|
const metadata = {
|
|
@@ -28584,7 +28704,7 @@ async function enrichProjectMetadata(state, cwd) {
|
|
|
28584
28704
|
};
|
|
28585
28705
|
const files = await listProjectFiles(cwd);
|
|
28586
28706
|
const deps = dependencyNames(packageJson);
|
|
28587
|
-
const detectedState = state.empty ? applyProviderDetection(state, deps, files) : state;
|
|
28707
|
+
const detectedState = await applyMcpDetection(state.empty ? applyProviderDetection(state, deps, files) : state, cwd);
|
|
28588
28708
|
const releases = await detectReleases(cwd, metadata.version);
|
|
28589
28709
|
const missionCards = state.empty ? buildMissionCards(
|
|
28590
28710
|
{
|
|
@@ -28695,19 +28815,19 @@ function parseAgentChatRequest(value) {
|
|
|
28695
28815
|
if (rawCliId !== "codex" && rawCliId !== "claude" && rawCliId !== "gemini") return { error: "Unsupported coding CLI" };
|
|
28696
28816
|
const prompt = stringField(value.prompt, 12e3);
|
|
28697
28817
|
if (!prompt) return { error: "Agent chat prompt is required" };
|
|
28698
|
-
const provider2 = isRecord7(value.provider) ? { area: stringField(value.provider.area, 120), name: stringField(value.provider.name, 120) } : void 0;
|
|
28699
|
-
const release = isRecord7(value.release) ? { label: stringField(value.release.label, 120) } : void 0;
|
|
28700
|
-
const
|
|
28701
|
-
const
|
|
28818
|
+
const provider2 = isRecord7(value.provider) ? { id: stringField(value.provider.id, 80), area: stringField(value.provider.area, 120), name: stringField(value.provider.name, 120) } : void 0;
|
|
28819
|
+
const release = isRecord7(value.release) ? { id: stringField(value.release.id, 200), label: stringField(value.release.label, 120) } : void 0;
|
|
28820
|
+
const requestedAccessMode = stringField(value.accessMode, 40);
|
|
28821
|
+
const accessMode = requestedAccessMode === "ask" || requestedAccessMode === "approve" || requestedAccessMode === "full" ? requestedAccessMode : "approve";
|
|
28702
28822
|
return {
|
|
28703
28823
|
cliId: rawCliId,
|
|
28704
28824
|
modelId: stringField(value.modelId, 120),
|
|
28705
28825
|
reasoning: stringField(value.reasoning, 80),
|
|
28706
28826
|
context: stringField(value.context, 80),
|
|
28827
|
+
accessMode,
|
|
28707
28828
|
prompt,
|
|
28708
28829
|
displayPrompt: stringField(value.displayPrompt, 240),
|
|
28709
28830
|
taskKind: stringField(value.taskKind, 40),
|
|
28710
|
-
permissionMode,
|
|
28711
28831
|
provider: provider2,
|
|
28712
28832
|
release
|
|
28713
28833
|
};
|
|
@@ -28715,17 +28835,17 @@ function parseAgentChatRequest(value) {
|
|
|
28715
28835
|
function taskKindExecutionBlock(taskKind) {
|
|
28716
28836
|
switch (taskKind) {
|
|
28717
28837
|
case "analyze":
|
|
28718
|
-
return "Execution mode: analyze
|
|
28838
|
+
return "Execution mode: analyze what changed. Read repo files and .viberaven artifacts; return concise findings with paths. Do not dump CLI install manuals or numbered manual runbooks.";
|
|
28719
28839
|
case "plan":
|
|
28720
28840
|
return "Execution mode: build an ordered fix plan from repo evidence. If the top blocker is repo-code, apply that fix in the project before answering. Do not reply with only manual instructions when code edits are possible.";
|
|
28721
28841
|
case "fix":
|
|
28722
28842
|
return "Execution mode: apply one minimal scoped repo fix IN CODE NOW. Read existing files, edit the project, save changes, then summarize. Forbidden: telling the user what to do manually when you can patch the repo yourself.";
|
|
28723
28843
|
case "verify":
|
|
28724
|
-
return "Execution mode: verify
|
|
28844
|
+
return "Execution mode: verify the what-changed context. Prefer `npx -y viberaven --verify` or read .viberaven/gate-result.json and agent-tasklist.md.";
|
|
28725
28845
|
case "provider":
|
|
28726
28846
|
return "Execution mode: provider proof or connect mission. Edit repo wiring when missing; separate dashboard-only steps from code changes; never claim live connection without proof.";
|
|
28727
28847
|
case "diff":
|
|
28728
|
-
return "Execution mode: review
|
|
28848
|
+
return "Execution mode: review the release diff and flag risky changes.";
|
|
28729
28849
|
case "explain":
|
|
28730
28850
|
return "Execution mode: explain recent changes and next verification steps.";
|
|
28731
28851
|
default:
|
|
@@ -28750,24 +28870,30 @@ async function buildAgentChatPrompt(request, cwd) {
|
|
|
28750
28870
|
const state = await readState(cwd);
|
|
28751
28871
|
const executionBlock = taskKindExecutionBlock(request.taskKind);
|
|
28752
28872
|
const cardsBlock = missionCardsContextBlock(state);
|
|
28873
|
+
const providerState2 = request.provider?.id ? state.providers.find((provider2) => provider2.id === request.provider?.id) : state.providers.find((provider2) => provider2.name === request.provider?.name);
|
|
28874
|
+
const mcp = providerState2?.mcp;
|
|
28875
|
+
const releaseDiffBlock = await releaseDiffContextBlock(cwd, request.release?.id);
|
|
28753
28876
|
const lines = [
|
|
28754
|
-
"You are VibeRaven Studio, a
|
|
28877
|
+
"You are VibeRaven Studio, a what-changed coding agent for an open-source local runner.",
|
|
28755
28878
|
`Project folder: ${cwd}`,
|
|
28756
28879
|
request.modelId ? `Selected model label: ${request.modelId}` : void 0,
|
|
28757
28880
|
request.reasoning ? `Reasoning: ${request.reasoning}` : void 0,
|
|
28758
28881
|
request.context ? `Context: ${request.context}` : void 0,
|
|
28882
|
+
`Access mode: ${request.accessMode ?? "approve"}`,
|
|
28759
28883
|
request.provider?.name ? `Provider context: ${request.provider.area ?? "Provider"} / ${request.provider.name}` : void 0,
|
|
28884
|
+
mcp ? `Provider MCP: ${mcp.label}${mcp.source ? ` (${mcp.source})` : ""}` : void 0,
|
|
28760
28885
|
request.release?.label ? `Release context: ${request.release.label}` : void 0,
|
|
28761
|
-
|
|
28886
|
+
releaseDiffBlock,
|
|
28887
|
+
state.gate?.label ? `Project status: ${state.gate.label} (${state.gate.status ?? "unknown"})` : void 0,
|
|
28762
28888
|
state.missionControl?.mainBlocker ? `Main blocker: ${state.missionControl.mainBlocker}` : void 0,
|
|
28763
28889
|
executionBlock,
|
|
28764
28890
|
cardsBlock,
|
|
28765
28891
|
"",
|
|
28766
28892
|
"Safety rules:",
|
|
28767
28893
|
"- Stay scoped to this project folder.",
|
|
28768
|
-
"-
|
|
28894
|
+
(request.accessMode ?? "approve") === "ask" ? "- Ask before editing files, using the internet, running destructive commands, or changing provider settings." : (request.accessMode ?? "approve") === "full" ? "- Full access is enabled for this local project; still explain destructive changes before running them." : "- Edit project files when needed, but explain risky or destructive changes before making them.",
|
|
28769
28895
|
"- Do not claim provider dashboard setup is complete from repo edits alone.",
|
|
28770
|
-
"- Keep the answer focused on
|
|
28896
|
+
"- Keep the answer focused on what changed, provider context, and the next grounded action.",
|
|
28771
28897
|
"- Return only the final user-facing answer. Do not echo this prompt, session metadata, logs, or command transcripts.",
|
|
28772
28898
|
"- For fix/plan/provider repo gaps: edit files in this project before answering. Manual dashboard steps are only for gaps that cannot be solved in repo code.",
|
|
28773
28899
|
"- Never paste long VibeRaven operator manuals, heal loops, or PowerShell command blocks unless the user explicitly asked how to run verify.",
|
|
@@ -28799,24 +28925,19 @@ function insertCodexExecOptions(codexArgs, pairs) {
|
|
|
28799
28925
|
const insertAt = execIndex >= 0 ? execIndex + 1 : codexArgs.length;
|
|
28800
28926
|
codexArgs.splice(insertAt, 0, ...pairs);
|
|
28801
28927
|
}
|
|
28802
|
-
function
|
|
28803
|
-
if (
|
|
28804
|
-
|
|
28805
|
-
|
|
28806
|
-
if (platform === "win32") {
|
|
28807
|
-
return ["--sandbox", "danger-full-access", "--ask-for-approval", "on-request"];
|
|
28808
|
-
}
|
|
28809
|
-
return ["--sandbox", "workspace-write", "--ask-for-approval", "on-request"];
|
|
28928
|
+
function codexAccessFlags(accessMode) {
|
|
28929
|
+
if (accessMode === "ask") return ["--sandbox", "workspace-write", "--ask-for-approval", "on-request"];
|
|
28930
|
+
if (accessMode === "full") return ["--sandbox", "danger-full-access", "--ask-for-approval", "never"];
|
|
28931
|
+
return ["--sandbox", "workspace-write", "--ask-for-approval", "on-failure"];
|
|
28810
28932
|
}
|
|
28811
|
-
function commandForAgentChat(request, prompt, cwd, outputPath
|
|
28812
|
-
const command = platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
|
|
28933
|
+
function commandForAgentChat(request, prompt, cwd, outputPath) {
|
|
28934
|
+
const command = process.platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
|
|
28813
28935
|
const promptArg = prompt.replace(/\s*\r?\n\s*/g, " ");
|
|
28814
28936
|
const model = normalizeCliModelId(request.modelId);
|
|
28815
28937
|
const effort = resolveCliReasoningEffort(request.cliId, request.reasoning);
|
|
28816
|
-
const permissionMode = request.permissionMode ?? "ask";
|
|
28817
28938
|
if (request.cliId === "gemini") {
|
|
28818
28939
|
const geminiArgs = ["-p", promptArg, "--output-format", "text"];
|
|
28819
|
-
if (
|
|
28940
|
+
if (request.accessMode !== "ask") geminiArgs.push("--skip-trust");
|
|
28820
28941
|
if (model) geminiArgs.splice(0, 0, "-m", model);
|
|
28821
28942
|
return { command, args: geminiArgs };
|
|
28822
28943
|
}
|
|
@@ -28824,13 +28945,12 @@ function commandForAgentChat(request, prompt, cwd, outputPath, platform = proces
|
|
|
28824
28945
|
const claudeArgs = ["-p", promptArg];
|
|
28825
28946
|
if (model) claudeArgs.unshift("--model", model);
|
|
28826
28947
|
if (effort) claudeArgs.unshift("--effort", effort);
|
|
28827
|
-
if (
|
|
28948
|
+
if (request.accessMode === "full") {
|
|
28828
28949
|
claudeArgs.push("--dangerously-skip-permissions");
|
|
28829
28950
|
}
|
|
28830
28951
|
return { command, args: claudeArgs };
|
|
28831
28952
|
}
|
|
28832
|
-
const
|
|
28833
|
-
const codexArgs = ["--cd", cwd, ...sandboxArgs, "exec", "--color", "never"];
|
|
28953
|
+
const codexArgs = ["--cd", cwd, ...codexAccessFlags(request.accessMode), "exec", "--color", "never"];
|
|
28834
28954
|
const codexExecOptions = [];
|
|
28835
28955
|
if (model) codexExecOptions.push("-m", model);
|
|
28836
28956
|
if (effort) codexExecOptions.push("-c", `model_reasoning_effort="${effort}"`);
|
|
@@ -28971,7 +29091,7 @@ async function runLocalAction(cwd, intent) {
|
|
|
28971
29091
|
"# VibeRaven preview rehearsal",
|
|
28972
29092
|
"",
|
|
28973
29093
|
`Project: ${projectName}`,
|
|
28974
|
-
`
|
|
29094
|
+
`Project status: ${gateLabel}`,
|
|
28975
29095
|
`Blocker: ${blocker}`,
|
|
28976
29096
|
"",
|
|
28977
29097
|
"## Recording flow",
|
|
@@ -29171,7 +29291,7 @@ async function sendReportArtifact(cwd, response) {
|
|
|
29171
29291
|
</div>
|
|
29172
29292
|
<section class="steps" aria-label="Report next steps">
|
|
29173
29293
|
<div class="step"><b>1. Manage providers</b><span>Use the Provider Control Board to review each slot and open the right dashboard.</span></div>
|
|
29174
|
-
<div class="step"><b>2. Start agent fix</b><span>Preview the handoff flow and keep the fix scoped to one
|
|
29294
|
+
<div class="step"><b>2. Start agent fix</b><span>Preview the handoff flow and keep the fix scoped to one evidenced change.</span></div>
|
|
29175
29295
|
<div class="step"><b>3. Verify</b><span>Use Verify Now in the launch screen when you are ready to check the flow.</span></div>
|
|
29176
29296
|
</section>
|
|
29177
29297
|
<div class="actions">
|
|
@@ -29571,7 +29691,7 @@ async function waitForServerShutdown() {
|
|
|
29571
29691
|
process.once("SIGTERM", done);
|
|
29572
29692
|
});
|
|
29573
29693
|
}
|
|
29574
|
-
var import_node_http, import_node_child_process4, import_promises24, import_node_path31, CLI_AGENT_SETUP, CLI_AUTH_PROBE;
|
|
29694
|
+
var import_node_http, import_node_child_process4, import_promises24, import_node_path31, CLI_AGENT_SETUP, MCP_CONFIG_PATHS, MCP_PROVIDER_NEEDLES, MCP_CONNECT_COMMANDS, CLI_AUTH_PROBE;
|
|
29575
29695
|
var init_server = __esm({
|
|
29576
29696
|
"src/local-ui/server.ts"() {
|
|
29577
29697
|
"use strict";
|
|
@@ -29612,6 +29732,30 @@ var init_server = __esm({
|
|
|
29612
29732
|
docsUrl: "https://viberaven.dev"
|
|
29613
29733
|
}
|
|
29614
29734
|
};
|
|
29735
|
+
MCP_CONFIG_PATHS = [
|
|
29736
|
+
".mcp.json",
|
|
29737
|
+
"mcp.json",
|
|
29738
|
+
(0, import_node_path31.join)(".cursor", "mcp.json"),
|
|
29739
|
+
(0, import_node_path31.join)(".vscode", "mcp.json")
|
|
29740
|
+
];
|
|
29741
|
+
MCP_PROVIDER_NEEDLES = {
|
|
29742
|
+
supabase: ["supabase", "@supabase/mcp", "mcp-server-supabase"],
|
|
29743
|
+
vercel: ["vercel"],
|
|
29744
|
+
stripe: ["stripe"],
|
|
29745
|
+
github: ["github"],
|
|
29746
|
+
sentry: ["sentry"],
|
|
29747
|
+
posthog: ["posthog"],
|
|
29748
|
+
clerk: ["clerk"],
|
|
29749
|
+
authjs: ["authjs", "next-auth", "nextauth"],
|
|
29750
|
+
resend: ["resend"],
|
|
29751
|
+
upstash: ["upstash"]
|
|
29752
|
+
};
|
|
29753
|
+
MCP_CONNECT_COMMANDS = {
|
|
29754
|
+
supabase: "Add the Supabase MCP server to your local MCP config, then drag Supabase into chat.",
|
|
29755
|
+
vercel: "Add a Vercel MCP server entry to your local MCP config, then drag Vercel into chat.",
|
|
29756
|
+
stripe: "Add a Stripe MCP server entry to your local MCP config, then drag Stripe into chat.",
|
|
29757
|
+
github: "Add the GitHub MCP server to your local MCP config, then drag GitHub into chat."
|
|
29758
|
+
};
|
|
29615
29759
|
CLI_AUTH_PROBE = {
|
|
29616
29760
|
codex: "codex login status",
|
|
29617
29761
|
claude: "claude auth status",
|
|
@@ -29634,11 +29778,7 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29634
29778
|
return {
|
|
29635
29779
|
...base,
|
|
29636
29780
|
type: "stalled",
|
|
29637
|
-
title: "Loop stalled
|
|
29638
|
-
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.",
|
|
29639
|
-
executionPlan: [
|
|
29640
|
-
{ kind: "stop", note: "Do not keep spending scans while the loop is stalled." }
|
|
29641
|
-
],
|
|
29781
|
+
title: "Loop stalled \xE2\u20AC\u201D no gap reduction after 2+ consecutive scans",
|
|
29642
29782
|
requiresUserAction: true,
|
|
29643
29783
|
stallReason
|
|
29644
29784
|
};
|
|
@@ -29647,67 +29787,42 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29647
29787
|
return {
|
|
29648
29788
|
...base,
|
|
29649
29789
|
type: "verify",
|
|
29650
|
-
title: "Batch complete
|
|
29651
|
-
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.",
|
|
29652
|
-
executionPlan: [
|
|
29653
|
-
{ kind: "verify", command: "viberaven_verify" },
|
|
29654
|
-
{ kind: "continue-loop", note: "After verify, continue until the gate is clear or a provider/user blocker remains." }
|
|
29655
|
-
],
|
|
29790
|
+
title: "Batch complete \xE2\u20AC\u201D run verify to rescan before next batch",
|
|
29656
29791
|
mcpTool: "viberaven_verify",
|
|
29657
29792
|
mcpArgs: {},
|
|
29658
29793
|
requiresUserAction: false
|
|
29659
29794
|
};
|
|
29660
29795
|
}
|
|
29661
|
-
const repoCodeTask = tasks.find((
|
|
29796
|
+
const repoCodeTask = tasks.find((t) => t.fixType === "repo-code" && !t.requiresUserAction);
|
|
29662
29797
|
if (repoCodeTask) {
|
|
29663
|
-
const fallbackCommand = repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0;
|
|
29664
29798
|
return {
|
|
29665
29799
|
...base,
|
|
29666
29800
|
type: "repo-code",
|
|
29667
29801
|
gapId: repoCodeTask.gapId,
|
|
29668
29802
|
title: repoCodeTask.title,
|
|
29669
|
-
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.",
|
|
29670
|
-
executionPlan: [
|
|
29671
|
-
{
|
|
29672
|
-
kind: "apply-repo-fix",
|
|
29673
|
-
command: repoCodeTask.mcpTool ?? fallbackCommand,
|
|
29674
|
-
note: "Patch only this gap and preserve unrelated user changes."
|
|
29675
|
-
},
|
|
29676
|
-
{ kind: "continue-loop", note: "Apply remaining safe repo fixes until the batch is full, then verify once." }
|
|
29677
|
-
],
|
|
29678
29803
|
mcpTool: repoCodeTask.mcpTool,
|
|
29679
29804
|
mcpArgs: repoCodeTask.mcpArgs,
|
|
29680
|
-
fallbackCommand,
|
|
29805
|
+
fallbackCommand: repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0,
|
|
29681
29806
|
requiresUserAction: false
|
|
29682
29807
|
};
|
|
29683
29808
|
}
|
|
29684
|
-
const providerTask = tasks.find((
|
|
29809
|
+
const providerTask = tasks.find((t) => t.fixType === "provider-action");
|
|
29685
29810
|
if (providerTask) {
|
|
29686
29811
|
return {
|
|
29687
29812
|
...base,
|
|
29688
29813
|
type: "provider-action",
|
|
29689
29814
|
gapId: providerTask.gapId,
|
|
29690
29815
|
title: providerTask.title,
|
|
29691
|
-
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.",
|
|
29692
|
-
executionPlan: [
|
|
29693
|
-
{ kind: "open-provider-step", note: "Use VIBERAVEN_PROVIDER_ACTION for the exact dashboard step and URL." },
|
|
29694
|
-
{ kind: "wait-for-user", note: "Wait for confirmation or read-only MCP evidence before verifying." }
|
|
29695
|
-
],
|
|
29696
29816
|
requiresUserAction: true
|
|
29697
29817
|
};
|
|
29698
29818
|
}
|
|
29699
|
-
const upgradeTask = tasks.find((
|
|
29819
|
+
const upgradeTask = tasks.find((t) => t.fixType === "upgrade-required");
|
|
29700
29820
|
if (upgradeTask) {
|
|
29701
29821
|
return {
|
|
29702
29822
|
...base,
|
|
29703
29823
|
type: "upgrade-required",
|
|
29704
29824
|
gapId: upgradeTask.gapId,
|
|
29705
29825
|
title: upgradeTask.title,
|
|
29706
|
-
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.",
|
|
29707
|
-
executionPlan: [
|
|
29708
|
-
{ kind: "upgrade", command: "https://viberaven.dev/pricing" },
|
|
29709
|
-
{ kind: "stop", note: "Do not pretend locked lanes or provider state were fixed locally." }
|
|
29710
|
-
],
|
|
29711
29826
|
requiresUserAction: true,
|
|
29712
29827
|
upgradeUrl: "https://viberaven.dev/pricing"
|
|
29713
29828
|
};
|
|
@@ -29715,20 +29830,15 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29715
29830
|
return {
|
|
29716
29831
|
...base,
|
|
29717
29832
|
type: "done",
|
|
29718
|
-
title: "All gaps resolved -
|
|
29719
|
-
agentInstruction: "The repo-code gate is clear. Run strict before deploy and still verify provider dashboard state through MCP or the provider dashboard.",
|
|
29720
|
-
executionPlan: [
|
|
29721
|
-
{ kind: "verify", command: "npx -y viberaven --strict" },
|
|
29722
|
-
{ kind: "stop", note: "Do not deploy until provider dashboard state is verified where applicable." }
|
|
29723
|
-
],
|
|
29833
|
+
title: "All gaps resolved - what-changed context is clear",
|
|
29724
29834
|
requiresUserAction: false
|
|
29725
29835
|
};
|
|
29726
29836
|
}
|
|
29727
29837
|
function resolveStallReason(tasks) {
|
|
29728
29838
|
if (tasks.length === 0) return "no-recipes";
|
|
29729
|
-
const allUpgradeOrEmpty = tasks.every((
|
|
29839
|
+
const allUpgradeOrEmpty = tasks.every((t) => t.fixType === "upgrade-required");
|
|
29730
29840
|
if (allUpgradeOrEmpty) return "no-recipes";
|
|
29731
|
-
const allProviderAction = tasks.every((
|
|
29841
|
+
const allProviderAction = tasks.every((t) => t.fixType === "provider-action");
|
|
29732
29842
|
if (allProviderAction) return "provider-action-required";
|
|
29733
29843
|
return "unknown";
|
|
29734
29844
|
}
|
|
@@ -29753,7 +29863,7 @@ function buildProviderActionBlock(task) {
|
|
|
29753
29863
|
}
|
|
29754
29864
|
function printProviderActionBlock(tasks) {
|
|
29755
29865
|
const task = tasks.find(
|
|
29756
|
-
(
|
|
29866
|
+
(t) => t.fixType === "provider-action" && t.requiresUserAction === true
|
|
29757
29867
|
);
|
|
29758
29868
|
if (!task) return;
|
|
29759
29869
|
const block = buildProviderActionBlock(task);
|
|
@@ -29893,15 +30003,16 @@ __export(cli_exports, {
|
|
|
29893
30003
|
});
|
|
29894
30004
|
module.exports = __toCommonJS(cli_exports);
|
|
29895
30005
|
function printHelp() {
|
|
29896
|
-
console.log(`viberaven ${VERSION}
|
|
30006
|
+
console.log(`viberaven ${VERSION} - what changed for AI-built apps
|
|
29897
30007
|
|
|
29898
30008
|
|
|
29899
30009
|
|
|
29900
30010
|
Usage:
|
|
29901
30011
|
|
|
29902
|
-
viberaven Open the local
|
|
30012
|
+
viberaven Open the local Studio for human TTY use
|
|
30013
|
+
|
|
30014
|
+
viberaven ui [path] Open the local Studio
|
|
29903
30015
|
|
|
29904
|
-
viberaven ui [path] Open the local launch console
|
|
29905
30016
|
viberaven tui Same interactive menu
|
|
29906
30017
|
|
|
29907
30018
|
viberaven login [--api-url <url>]
|
|
@@ -29911,7 +30022,7 @@ Usage:
|
|
|
29911
30022
|
viberaven status
|
|
29912
30023
|
|
|
29913
30024
|
viberaven actions [--json] [path]
|
|
29914
|
-
Print current chat-native
|
|
30025
|
+
Print current chat-native action surface
|
|
29915
30026
|
|
|
29916
30027
|
viberaven preview [--agent-mode] [--json]
|
|
29917
30028
|
Local production rehearsal for videos and onboarding; no login or API spend
|
|
@@ -29928,7 +30039,7 @@ Usage:
|
|
|
29928
30039
|
Agent-first scan; writes tasklist, gate-result, context-map, and per-gap JSON
|
|
29929
30040
|
|
|
29930
30041
|
viberaven --strict[=warning] [path]
|
|
29931
|
-
Fail when
|
|
30042
|
+
Fail when what-changed context is not clear; warning mode also fails on warnings
|
|
29932
30043
|
|
|
29933
30044
|
viberaven --condense [path]
|
|
29934
30045
|
Refresh .viberaven/context-map.json from the last scan
|
|
@@ -29973,7 +30084,7 @@ Agent workflow (Claude Code / Codex):
|
|
|
29973
30084
|
|
|
29974
30085
|
Read .viberaven/agent-tasklist.md first, .viberaven/gate-result.json for the machine verdict, then .viberaven/context-map.json
|
|
29975
30086
|
|
|
29976
|
-
viberaven next --json \
|
|
30087
|
+
viberaven next --json \xE2\u2020\u2019 guide/open \xE2\u2020\u2019 scan again
|
|
29977
30088
|
|
|
29978
30089
|
|
|
29979
30090
|
|
|
@@ -29989,7 +30100,7 @@ Environment:
|
|
|
29989
30100
|
|
|
29990
30101
|
Security:
|
|
29991
30102
|
|
|
29992
|
-
CLI scans use VibeRaven login \
|
|
30103
|
+
CLI scans use VibeRaven login \xE2\u20AC\u201D not OPENAI_API_KEY. See packages/cli/SECURITY.md.
|
|
29993
30104
|
|
|
29994
30105
|
`);
|
|
29995
30106
|
}
|
|
@@ -30010,9 +30121,6 @@ function parseArgs(argv) {
|
|
|
30010
30121
|
if (arg.startsWith("--")) {
|
|
30011
30122
|
const equalsIndex = arg.indexOf("=");
|
|
30012
30123
|
const key = equalsIndex === -1 ? arg.slice(2) : arg.slice(2, equalsIndex);
|
|
30013
|
-
if (key === "pet") {
|
|
30014
|
-
continue;
|
|
30015
|
-
}
|
|
30016
30124
|
if (equalsIndex !== -1) {
|
|
30017
30125
|
flags[key] = arg.slice(equalsIndex + 1);
|
|
30018
30126
|
continue;
|
|
@@ -30108,9 +30216,6 @@ function resolveDefaultEntrypointMode(options) {
|
|
|
30108
30216
|
if (options.env.VIBERAVEN_AGENT === "1") return "agent-scan";
|
|
30109
30217
|
return "local-ui";
|
|
30110
30218
|
}
|
|
30111
|
-
function resolvePositionalCwd(positional) {
|
|
30112
|
-
return positional[0] ? (0, import_node_path33.resolve)(process.cwd(), positional[0]) : process.cwd();
|
|
30113
|
-
}
|
|
30114
30219
|
function formatScanJsonStdout(artifact) {
|
|
30115
30220
|
return JSON.stringify(sanitizeArtifactForDisk(artifact), null, 2);
|
|
30116
30221
|
}
|
|
@@ -30151,7 +30256,7 @@ async function cmdStatus(flags, positional) {
|
|
|
30151
30256
|
console.log("Not signed in. Run: viberaven login");
|
|
30152
30257
|
return 1;
|
|
30153
30258
|
}
|
|
30154
|
-
const startDir =
|
|
30259
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30155
30260
|
let artifact;
|
|
30156
30261
|
try {
|
|
30157
30262
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -30188,7 +30293,7 @@ async function cmdStatus(flags, positional) {
|
|
|
30188
30293
|
console.log(`Plan: ${synced.plan ?? "unknown"}`);
|
|
30189
30294
|
console.log(formatUsageLine(usage));
|
|
30190
30295
|
if (artifact) {
|
|
30191
|
-
console.log(`Production core: ${artifact.productionCorePercent}% \xB7 Score ${artifact.score}`);
|
|
30296
|
+
console.log(`Production core: ${artifact.productionCorePercent}% \xC2\xB7 Score ${artifact.score}`);
|
|
30192
30297
|
console.log(
|
|
30193
30298
|
`Lanes: ${usage.unlockedMapCategoryKeys.length}/${PRODUCTION_MAP_CATEGORY_KEYS_ALL.length} unlocked`
|
|
30194
30299
|
);
|
|
@@ -30305,7 +30410,7 @@ async function cmdWatch(flags) {
|
|
|
30305
30410
|
}
|
|
30306
30411
|
}
|
|
30307
30412
|
async function runScanCommand(flags, positional, options) {
|
|
30308
|
-
const workspacePath = positional[0] ?
|
|
30413
|
+
const workspacePath = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : await resolveWorkspaceRoot(process.cwd());
|
|
30309
30414
|
const apiBaseUrl = resolveApiBaseUrl(typeof flags["api-url"] === "string" ? flags["api-url"] : void 0);
|
|
30310
30415
|
let accessToken;
|
|
30311
30416
|
try {
|
|
@@ -30329,7 +30434,7 @@ async function runScanCommand(flags, positional, options) {
|
|
|
30329
30434
|
}
|
|
30330
30435
|
}
|
|
30331
30436
|
if (!options?.deferMachineOutput) {
|
|
30332
|
-
console.log(`Scanning ${workspacePath}\
|
|
30437
|
+
console.log(`Scanning ${workspacePath}\xE2\u20AC\xA6`);
|
|
30333
30438
|
}
|
|
30334
30439
|
const result = await runProjectScan({ workspacePath, accessToken, apiBaseUrl });
|
|
30335
30440
|
if (!result.ok) {
|
|
@@ -30389,7 +30494,7 @@ async function runScanCommand(flags, positional, options) {
|
|
|
30389
30494
|
return { exitCode: 0, artifacts: paths };
|
|
30390
30495
|
}
|
|
30391
30496
|
async function cmdReport(flags, positional) {
|
|
30392
|
-
const startDir =
|
|
30497
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30393
30498
|
try {
|
|
30394
30499
|
const paths = await refreshReportFromDisk(startDir);
|
|
30395
30500
|
console.log(`Report refreshed: ${paths.reportPath}`);
|
|
@@ -30411,7 +30516,7 @@ async function cmdReport(flags, positional) {
|
|
|
30411
30516
|
}
|
|
30412
30517
|
}
|
|
30413
30518
|
async function cmdPrompt(flags, positional) {
|
|
30414
|
-
const startDir =
|
|
30519
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30415
30520
|
let artifact;
|
|
30416
30521
|
try {
|
|
30417
30522
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -30475,7 +30580,7 @@ async function cmdStack(positional) {
|
|
|
30475
30580
|
const file = await loadStackChoicesFile(cwd);
|
|
30476
30581
|
file.choices[area] = { provider: provider2, selectedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
30477
30582
|
await saveStackChoicesFile(cwd, file);
|
|
30478
|
-
console.log(`Set ${area} \
|
|
30583
|
+
console.log(`Set ${area} \xE2\u2020\u2019 ${provider2}. Run \`viberaven scan\` to re-map.`);
|
|
30479
30584
|
return 0;
|
|
30480
30585
|
}
|
|
30481
30586
|
if (sub === "clear") {
|
|
@@ -30508,7 +30613,7 @@ async function main() {
|
|
|
30508
30613
|
const wantsJsonl = hasFlag(flags, "jsonl");
|
|
30509
30614
|
const wantsStrict = hasFlag(flags, "strict");
|
|
30510
30615
|
if (flags.condense) {
|
|
30511
|
-
const cwd =
|
|
30616
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30512
30617
|
const result = await runCondenseCommand({ cwd });
|
|
30513
30618
|
console.log(`VibeRaven context map refreshed: ${result.contextMapPath}`);
|
|
30514
30619
|
return 0;
|
|
@@ -30528,7 +30633,7 @@ async function main() {
|
|
|
30528
30633
|
}
|
|
30529
30634
|
if (!command && flags.verify === true && typeof flags.action === "string") {
|
|
30530
30635
|
return runVerifyActionCommand({
|
|
30531
|
-
cwd:
|
|
30636
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30532
30637
|
actionId: flags.action
|
|
30533
30638
|
});
|
|
30534
30639
|
}
|
|
@@ -30565,7 +30670,7 @@ async function main() {
|
|
|
30565
30670
|
env: process.env
|
|
30566
30671
|
});
|
|
30567
30672
|
if (mode === "local-ui") {
|
|
30568
|
-
const cwd =
|
|
30673
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30569
30674
|
const handle = await startLocalUiServer({ cwd });
|
|
30570
30675
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
30571
30676
|
await waitForServerShutdown();
|
|
@@ -30585,7 +30690,7 @@ async function main() {
|
|
|
30585
30690
|
await runInteractiveSession();
|
|
30586
30691
|
return 0;
|
|
30587
30692
|
case "ui": {
|
|
30588
|
-
const cwd =
|
|
30693
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30589
30694
|
const handle = await startLocalUiServer({ cwd });
|
|
30590
30695
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
30591
30696
|
await waitForServerShutdown();
|
|
@@ -30602,19 +30707,19 @@ async function main() {
|
|
|
30602
30707
|
return cmdStatus(flags, positional);
|
|
30603
30708
|
case "actions":
|
|
30604
30709
|
return runActionsCommand({
|
|
30605
|
-
cwd:
|
|
30710
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30606
30711
|
json: Boolean(flags.json)
|
|
30607
30712
|
});
|
|
30608
30713
|
case "preview":
|
|
30609
30714
|
return runPreviewCommand({
|
|
30610
|
-
cwd:
|
|
30715
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30611
30716
|
agentMode: flags["agent-mode"] === true,
|
|
30612
30717
|
json: Boolean(flags.json)
|
|
30613
30718
|
});
|
|
30614
30719
|
case "next":
|
|
30615
30720
|
return runNextCommand({
|
|
30616
30721
|
json: Boolean(flags.json),
|
|
30617
|
-
cwd:
|
|
30722
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd()
|
|
30618
30723
|
});
|
|
30619
30724
|
case "guide": {
|
|
30620
30725
|
const provider2 = positional[0];
|
|
@@ -30652,7 +30757,7 @@ async function main() {
|
|
|
30652
30757
|
case "provider-verify":
|
|
30653
30758
|
return cmdProviderVerify(flags, positional);
|
|
30654
30759
|
case "init": {
|
|
30655
|
-
const cwd =
|
|
30760
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30656
30761
|
const agents = typeof flags.agents === "string" ? flags.agents : void 0;
|
|
30657
30762
|
return runInitCommand({
|
|
30658
30763
|
cwd,
|
|
@@ -30666,7 +30771,7 @@ async function main() {
|
|
|
30666
30771
|
return 1;
|
|
30667
30772
|
}
|
|
30668
30773
|
return runDoctorAgentsCommand({
|
|
30669
|
-
cwd:
|
|
30774
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd()
|
|
30670
30775
|
});
|
|
30671
30776
|
case "validate-npm-package":
|
|
30672
30777
|
return runValidateNpmPackageCommand({
|
|
@@ -30679,7 +30784,7 @@ async function main() {
|
|
|
30679
30784
|
return 1;
|
|
30680
30785
|
}
|
|
30681
30786
|
return runAuditCommand({
|
|
30682
|
-
cwd:
|
|
30787
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30683
30788
|
json: Boolean(flags.json)
|
|
30684
30789
|
});
|
|
30685
30790
|
default:
|