@viberaven/cli 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/SECURITY.md +53 -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 +558 -561
- 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 +75 -75
- 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);
|
|
@@ -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);
|
|
@@ -12304,7 +12281,7 @@ var VERSION;
|
|
|
12304
12281
|
var init_version = __esm({
|
|
12305
12282
|
"src/version.ts"() {
|
|
12306
12283
|
"use strict";
|
|
12307
|
-
VERSION = "1.2.
|
|
12284
|
+
VERSION = "1.2.4";
|
|
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, 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";
|
|
@@ -12898,15 +12706,6 @@ Maps repo evidence to OWASP LLM Top 10 launch risks. Supports SAFECode-style dep
|
|
|
12898
12706
|
STACK_FRAMING = `Stack context for this repo: Next.js, Supabase, Vercel, VibeRaven.
|
|
12899
12707
|
Do NOT deploy to Vercel or ship to production users without running \`${PUBLIC_AGENT_MODE_COMMAND}\`.
|
|
12900
12708
|
Do NOT rely on manual production checklists when VibeRaven gate artifacts exist in \`.viberaven/\`.`;
|
|
12901
|
-
PRODUCTION_PROTOCOL = `## VibeRaven Production Protocol
|
|
12902
|
-
|
|
12903
|
-
Before making deploy, auth, database, payment, API, or scaling changes:
|
|
12904
|
-
|
|
12905
|
-
1. Read \`.viberaven/prp.json\`.
|
|
12906
|
-
2. Follow \`.viberaven/mission-map.md\`.
|
|
12907
|
-
3. Do not deploy if \`decision.status\` is \`blocked\`.
|
|
12908
|
-
4. Fix \`nextActions\` in order.
|
|
12909
|
-
5. Re-run \`${PUBLIC_AGENT_MODE_COMMAND}\`.`;
|
|
12910
12709
|
AGENT_NEGATIVE_CONSTRAINTS = `## Event-Triggered Production Verification
|
|
12911
12710
|
|
|
12912
12711
|
Trigger: modifications to \`package.json\`, \`vercel.json\`, \`supabase/migrations/**/*\`, \`.env.example\`, auth/billing/webhook paths, or deploy workflow files.
|
|
@@ -12932,8 +12731,6 @@ Gate is not clear until \`gate.status === "clear"\` in \`.viberaven/gate-result.
|
|
|
12932
12731
|
|
|
12933
12732
|
${STACK_FRAMING}
|
|
12934
12733
|
|
|
12935
|
-
${PRODUCTION_PROTOCOL}
|
|
12936
|
-
|
|
12937
12734
|
${AGENT_NEGATIVE_CONSTRAINTS}
|
|
12938
12735
|
|
|
12939
12736
|
## VibeRaven Production-Readiness Gate
|
|
@@ -12983,11 +12780,10 @@ Do not stop at "scan complete." The loop is not done until \`gate.status === 'cl
|
|
|
12983
12780
|
|
|
12984
12781
|
After \`--agent-mode\`, read these artifacts in order:
|
|
12985
12782
|
|
|
12986
|
-
1. \`.viberaven/
|
|
12987
|
-
2. \`.viberaven/
|
|
12988
|
-
3. \`.viberaven/
|
|
12989
|
-
4. \`.viberaven/
|
|
12990
|
-
5. \`.viberaven/context-map.json\``;
|
|
12783
|
+
1. \`.viberaven/mission-map.md\`
|
|
12784
|
+
2. \`.viberaven/agent-tasklist.md\`
|
|
12785
|
+
3. \`.viberaven/gate-result.json\`
|
|
12786
|
+
4. \`.viberaven/context-map.json\``;
|
|
12991
12787
|
MISSION_MAP_BODY = `${AGENT_RULES_PREAMBLE}
|
|
12992
12788
|
|
|
12993
12789
|
## Mission Map loop
|
|
@@ -15959,10 +15755,6 @@ function providerLogoHtml(providerOrLabel, labelFallback, ...moreCandidates) {
|
|
|
15959
15755
|
}
|
|
15960
15756
|
function providerRailLogoHtml(providerOrLabel, labelFallback, ...moreCandidates) {
|
|
15961
15757
|
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
15758
|
const iconUrl = key && LOCAL_UI_BRAND_ICON_KEYS.has(key) ? PROVIDER_ICON_URLS[key] : void 0;
|
|
15967
15759
|
if (iconUrl) {
|
|
15968
15760
|
return providerIconImgHtml(iconUrl, key);
|
|
@@ -16098,18 +15890,6 @@ var init_providerLogos = __esm({
|
|
|
16098
15890
|
"svelte"
|
|
16099
15891
|
]);
|
|
16100
15892
|
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
15893
|
authjs: "provider-authjs.svg",
|
|
16114
15894
|
logrocket: "provider-logrocket.svg",
|
|
16115
15895
|
aws: "provider-aws.svg"
|
|
@@ -16127,16 +15907,16 @@ var init_providerLogos = __esm({
|
|
|
16127
15907
|
turso: "https://cdn.simpleicons.org/turso/4FF8D2",
|
|
16128
15908
|
"lemon-squeezy": "https://cdn.simpleicons.org/lemonsqueezy/FFC233",
|
|
16129
15909
|
stripe: "https://cdn.simpleicons.org/stripe/635BFF",
|
|
16130
|
-
github: "https://cdn.simpleicons.org/github/
|
|
15910
|
+
github: "https://cdn.simpleicons.org/github/FFFFFF",
|
|
16131
15911
|
gitlab: "https://cdn.simpleicons.org/gitlab/FC6D26",
|
|
16132
|
-
vercel: "https://cdn.simpleicons.org/vercel/
|
|
15912
|
+
vercel: "https://cdn.simpleicons.org/vercel/FFFFFF",
|
|
16133
15913
|
netlify: "https://cdn.simpleicons.org/netlify/00C7B7",
|
|
16134
15914
|
render: "https://cdn.simpleicons.org/render/46E3B7",
|
|
16135
15915
|
railway: "https://cdn.simpleicons.org/railway/0B0D0E",
|
|
16136
15916
|
cloudflare: "https://cdn.simpleicons.org/cloudflare/F38020",
|
|
16137
|
-
sentry: "https://cdn.simpleicons.org/sentry/
|
|
15917
|
+
sentry: "https://cdn.simpleicons.org/sentry/8B5CF6",
|
|
16138
15918
|
posthog: "https://cdn.simpleicons.org/posthog/F54E00",
|
|
16139
|
-
resend: "https://cdn.simpleicons.org/resend/
|
|
15919
|
+
resend: "https://cdn.simpleicons.org/resend/FFFFFF",
|
|
16140
15920
|
upstash: "https://cdn.simpleicons.org/upstash/00E9A3",
|
|
16141
15921
|
playwright: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/playwright/playwright-original.svg",
|
|
16142
15922
|
figma: "https://cdn.simpleicons.org/figma/F24E1E",
|
|
@@ -16964,7 +16744,6 @@ const demo = {
|
|
|
16964
16744
|
activeModal: null,
|
|
16965
16745
|
activeStudioTab: 'chat',
|
|
16966
16746
|
selectedCliId: 'codex',
|
|
16967
|
-
agentPermissionMode: 'ask',
|
|
16968
16747
|
cliConnected: false,
|
|
16969
16748
|
cliSetupComplete: false,
|
|
16970
16749
|
cliConnectTargetId: null,
|
|
@@ -16983,11 +16762,13 @@ const demo = {
|
|
|
16983
16762
|
selectedModelId: 'gpt-5.5',
|
|
16984
16763
|
selectedReasoning: 'High',
|
|
16985
16764
|
selectedContext: 'Production',
|
|
16765
|
+
selectedAccessMode: 'approve',
|
|
16986
16766
|
modelMenuOpen: false,
|
|
16987
16767
|
reasoningMenuOpen: false,
|
|
16988
16768
|
contextMenuOpen: false,
|
|
16769
|
+
accessMenuOpen: false,
|
|
16989
16770
|
pickerChatIndex: 0,
|
|
16990
|
-
chatContexts: [{ providerId: null, releaseId: null, cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production', messages: [], activeTask: null }],
|
|
16771
|
+
chatContexts: [{ providerId: null, releaseId: null, cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production', accessMode: 'approve', messages: [], activeTask: null }],
|
|
16991
16772
|
activeRecentChatId: null,
|
|
16992
16773
|
droppedProviderId: null,
|
|
16993
16774
|
dragKind: null,
|
|
@@ -17001,23 +16782,6 @@ const demo = {
|
|
|
17001
16782
|
releaseChangelog: { entries: [], from: '', to: '', fromLabel: '', toLabel: '', loading: false, error: '' },
|
|
17002
16783
|
};
|
|
17003
16784
|
|
|
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
16785
|
function readCliSessionReady() {
|
|
17022
16786
|
try {
|
|
17023
16787
|
let raw = localStorage.getItem('viberaven-cli-ready');
|
|
@@ -17040,7 +16804,6 @@ function writeCliSessionReady(value) {
|
|
|
17040
16804
|
}
|
|
17041
16805
|
|
|
17042
16806
|
demo.cliSessionReady = readCliSessionReady();
|
|
17043
|
-
demo.agentPermissionMode = readPermissionMode();
|
|
17044
16807
|
|
|
17045
16808
|
function cliAgentInstalled(agent) {
|
|
17046
16809
|
if (!agent) return false;
|
|
@@ -17123,10 +16886,10 @@ const providerMarkAssets = {
|
|
|
17123
16886
|
};
|
|
17124
16887
|
|
|
17125
16888
|
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
|
|
16889
|
+
idle: '/report/assets/viberaven-mascot.png',
|
|
16890
|
+
fixing: '/report/assets/viberaven-mascot.png',
|
|
16891
|
+
verified: '/report/assets/viberaven-mascot.png',
|
|
16892
|
+
alert: '/report/assets/viberaven-mascot.png',
|
|
17130
16893
|
};
|
|
17131
16894
|
|
|
17132
16895
|
const providerDashboardUrls = {
|
|
@@ -17335,6 +17098,52 @@ function providerHealthIcon(health) {
|
|
|
17335
17098
|
return Icon('refresh');
|
|
17336
17099
|
}
|
|
17337
17100
|
|
|
17101
|
+
function providerMcp(provider) {
|
|
17102
|
+
return provider && provider.mcp ? provider.mcp : {
|
|
17103
|
+
status: 'disconnected',
|
|
17104
|
+
label: 'Connect MCP',
|
|
17105
|
+
connectCommand: 'Add this provider to your local MCP config, then drag it into chat.',
|
|
17106
|
+
capabilities: [],
|
|
17107
|
+
};
|
|
17108
|
+
}
|
|
17109
|
+
|
|
17110
|
+
function providerMcpChip(provider) {
|
|
17111
|
+
const mcp = providerMcp(provider);
|
|
17112
|
+
const connected = mcp.status === 'connected';
|
|
17113
|
+
const label = connected ? 'MCP connected' : 'MCP not connected';
|
|
17114
|
+
return '<span class="vr-provider-mcp-chip ' + (connected ? 'is-connected' : 'is-disconnected') + '" title="' + escapeHtml(label) + '" aria-label="' + escapeHtml(label) + '">' +
|
|
17115
|
+
'<i></i><span>' + escapeHtml(label) + '</span>' +
|
|
17116
|
+
'</span>';
|
|
17117
|
+
}
|
|
17118
|
+
|
|
17119
|
+
function providerAssetSrc(provider) {
|
|
17120
|
+
if (!provider) return providerAssets.supabase;
|
|
17121
|
+
return providerMarkAssets[provider.id] || providerAssets[provider.id] || providerAssets.supabase;
|
|
17122
|
+
}
|
|
17123
|
+
|
|
17124
|
+
function ProviderToken(provider, extraClass) {
|
|
17125
|
+
const className = 'vr-provider-token' + (extraClass ? ' ' + extraClass : '');
|
|
17126
|
+
const iconHtml = provider && provider.iconHtml ? String(provider.iconHtml) : '';
|
|
17127
|
+
return '<span class="' + className + '">' + (iconHtml.trim() ? iconHtml : '<img src="' + providerAssetSrc(provider) + '" alt="" />') + '</span>';
|
|
17128
|
+
}
|
|
17129
|
+
|
|
17130
|
+
function ProviderLogo(provider, className) {
|
|
17131
|
+
const iconHtml = provider && provider.iconHtml ? String(provider.iconHtml) : '';
|
|
17132
|
+
return iconHtml.trim()
|
|
17133
|
+
? '<span class="' + className + ' is-logo-html">' + iconHtml + '</span>'
|
|
17134
|
+
: '<img class="' + className + '" src="' + providerAssetSrc(provider) + '" alt="" />';
|
|
17135
|
+
}
|
|
17136
|
+
|
|
17137
|
+
function ProviderMcpPanel(provider) {
|
|
17138
|
+
const mcp = providerMcp(provider);
|
|
17139
|
+
const connected = mcp.status === 'connected';
|
|
17140
|
+
const capabilities = Array.isArray(mcp.capabilities) && mcp.capabilities.length ? mcp.capabilities : ['provider context', 'repo-aware chat'];
|
|
17141
|
+
return '<section class="vr-provider-mcp-panel ' + (connected ? 'is-connected' : 'is-disconnected') + '">' +
|
|
17142
|
+
'<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>' +
|
|
17143
|
+
'<div>' + capabilities.map((item) => '<small>' + escapeHtml(item) + '</small>').join('') + '</div>' +
|
|
17144
|
+
'</section>';
|
|
17145
|
+
}
|
|
17146
|
+
|
|
17338
17147
|
function normalizeProvider(provider) {
|
|
17339
17148
|
const missing = provider.state === 'not_detected';
|
|
17340
17149
|
return {
|
|
@@ -17348,6 +17157,8 @@ function normalizeProvider(provider) {
|
|
|
17348
17157
|
lastSync: currentState.project && currentState.project.scannedAt ? 'scan artifact' : 'startup',
|
|
17349
17158
|
checks: providerChecks(provider),
|
|
17350
17159
|
state: provider.state || 'not_detected',
|
|
17160
|
+
mcp: provider.mcp || null,
|
|
17161
|
+
iconHtml: provider.iconHtml || '',
|
|
17351
17162
|
};
|
|
17352
17163
|
}
|
|
17353
17164
|
|
|
@@ -17552,6 +17363,11 @@ let cliModels = {
|
|
|
17552
17363
|
|
|
17553
17364
|
const reasoningLevels = ['Low', 'Medium', 'High', 'Extra High'];
|
|
17554
17365
|
const contextLevels = ['Production', 'Provider', 'Release', 'Security'];
|
|
17366
|
+
const accessModes = [
|
|
17367
|
+
{ id: 'ask', label: 'Ask approval', description: 'Confirm edits and external access' },
|
|
17368
|
+
{ id: 'approve', label: 'Approve for me', description: 'Run safe repo actions automatically' },
|
|
17369
|
+
{ id: 'full', label: 'Full access', description: 'Unrestricted local project access' },
|
|
17370
|
+
];
|
|
17555
17371
|
const topStages = [
|
|
17556
17372
|
{ id: 'provider', number: '1', label: 'Provider Proof', state: 'Waiting' },
|
|
17557
17373
|
{ id: 'agent', number: '2', label: 'Agent Fix', state: 'Ready' },
|
|
@@ -17653,6 +17469,7 @@ function buildRecentChatEntry(prompt, provider, release, chat, existing) {
|
|
|
17653
17469
|
modelId: lane.modelId || base.modelId || demo.selectedModelId || 'gpt-5.5',
|
|
17654
17470
|
reasoning: lane.reasoning || base.reasoning || demo.selectedReasoning || 'High',
|
|
17655
17471
|
context: lane.context || base.context || demo.selectedContext || 'Production',
|
|
17472
|
+
accessMode: lane.accessMode || base.accessMode || demo.selectedAccessMode || 'approve',
|
|
17656
17473
|
messages: serializeChatMessages(lane.messages),
|
|
17657
17474
|
};
|
|
17658
17475
|
}
|
|
@@ -17680,6 +17497,7 @@ function syncDemoFromChatContext(context) {
|
|
|
17680
17497
|
demo.selectedModelId = context.modelId;
|
|
17681
17498
|
demo.selectedReasoning = context.reasoning;
|
|
17682
17499
|
demo.selectedContext = context.context;
|
|
17500
|
+
demo.selectedAccessMode = context.accessMode || 'approve';
|
|
17683
17501
|
if (context.providerId) demo.selectedProviderId = context.providerId;
|
|
17684
17502
|
if (context.releaseId) demo.selectedReleaseId = context.releaseId;
|
|
17685
17503
|
syncPrimaryContext();
|
|
@@ -17694,6 +17512,7 @@ function restoreRecentChat(recent) {
|
|
|
17694
17512
|
modelId: recent.modelId,
|
|
17695
17513
|
reasoning: recent.reasoning,
|
|
17696
17514
|
context: recent.context,
|
|
17515
|
+
accessMode: recent.accessMode,
|
|
17697
17516
|
messages: recent.messages || [],
|
|
17698
17517
|
draft: '',
|
|
17699
17518
|
activeTask: null,
|
|
@@ -17913,6 +17732,9 @@ function contextIconChip(iconName, size) {
|
|
|
17913
17732
|
}
|
|
17914
17733
|
|
|
17915
17734
|
function BrandMark(id) {
|
|
17735
|
+
if (id === 'github') {
|
|
17736
|
+
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>';
|
|
17737
|
+
}
|
|
17916
17738
|
return '<span class="vr-inline-brand-mark"><img src="' + escapeHtml(providerMarkAssets[id] || providerAssets[id]) + '" alt="" /></span>';
|
|
17917
17739
|
}
|
|
17918
17740
|
|
|
@@ -17938,6 +17760,7 @@ function defaultChatContext(seed) {
|
|
|
17938
17760
|
modelId: source.modelId || demo.selectedModelId || normalizeModelId(models[0]),
|
|
17939
17761
|
reasoning: source.reasoning || demo.selectedReasoning || 'High',
|
|
17940
17762
|
context: source.context || demo.selectedContext || 'Production',
|
|
17763
|
+
accessMode: source.accessMode || demo.selectedAccessMode || 'approve',
|
|
17941
17764
|
draft: source.draft || '',
|
|
17942
17765
|
messages: Array.isArray(source.messages) ? source.messages.slice() : [],
|
|
17943
17766
|
activeTask: source.activeTask || null,
|
|
@@ -18067,7 +17890,7 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18067
17890
|
prompt: [
|
|
18068
17891
|
'Analyze production launch readiness in this project folder.',
|
|
18069
17892
|
'',
|
|
18070
|
-
'
|
|
17893
|
+
'Project status: ' + gateLabel + ' (' + (gate.status || 'unknown') + ')',
|
|
18071
17894
|
'Main blocker: ' + mainBlocker,
|
|
18072
17895
|
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
17896
|
connectText ? '\\nProviders needing connect:\\n' + connectText : '',
|
|
@@ -18083,11 +17906,11 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18083
17906
|
},
|
|
18084
17907
|
plan: {
|
|
18085
17908
|
title: 'Building fix plan',
|
|
18086
|
-
label: planSteps.length ? '
|
|
17909
|
+
label: planSteps.length ? 'Fix plan \xB7 ' + planSteps.length + ' action' + (planSteps.length === 1 ? '' : 's') : 'Build fix plan',
|
|
18087
17910
|
prompt: [
|
|
18088
|
-
'Build a safe, ordered
|
|
17911
|
+
'Build a safe, ordered fix plan for this launch.',
|
|
18089
17912
|
'',
|
|
18090
|
-
'
|
|
17913
|
+
'Project status: ' + gateLabel,
|
|
18091
17914
|
'Main blocker: ' + mainBlocker,
|
|
18092
17915
|
blockers.length ? 'Blockers (' + blockers.length + '):\\n' + blockerText : 'No scan blockers loaded \u2014 inspect .viberaven artifacts first.',
|
|
18093
17916
|
planSteps.length ? '\\nSuggested steps from scan:\\n' + planText : '',
|
|
@@ -18127,11 +17950,11 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18127
17950
|
},
|
|
18128
17951
|
verify: {
|
|
18129
17952
|
title: 'Running verification',
|
|
18130
|
-
label: gateClear ? 'Re-verify
|
|
17953
|
+
label: gateClear ? 'Re-verify readiness' : 'Verify readiness',
|
|
18131
17954
|
prompt: [
|
|
18132
17955
|
'Verify production launch readiness for this project.',
|
|
18133
17956
|
'',
|
|
18134
|
-
'
|
|
17957
|
+
'Project status: ' + gateLabel + ' (' + (gate.status || 'unknown') + ')',
|
|
18135
17958
|
'Main blocker: ' + mainBlocker,
|
|
18136
17959
|
blockers.length ? 'Open blockers:\\n' + blockerText : '',
|
|
18137
17960
|
'',
|
|
@@ -18142,7 +17965,7 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18142
17965
|
].filter(Boolean).join('\\n'),
|
|
18143
17966
|
line: 'Checking evidence, provider state, and release readiness.',
|
|
18144
17967
|
steps: ['Run checks', 'Read proof', 'Mark status'],
|
|
18145
|
-
notice: gateClear ? 'Re-verifying launch proof.' : 'Running
|
|
17968
|
+
notice: gateClear ? 'Re-verifying launch proof.' : 'Running production readiness verification.',
|
|
18146
17969
|
},
|
|
18147
17970
|
diff: {
|
|
18148
17971
|
title: 'Reviewing diff',
|
|
@@ -18150,7 +17973,7 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18150
17973
|
prompt: [
|
|
18151
17974
|
'Review the current production diff for this project.',
|
|
18152
17975
|
'',
|
|
18153
|
-
'
|
|
17976
|
+
'Project status: ' + gateLabel,
|
|
18154
17977
|
topBlocker ? 'Top blocker context: ' + topBlocker.title : '',
|
|
18155
17978
|
'',
|
|
18156
17979
|
'Show grouped changes, flag risky edits, and say what still needs verify before release.',
|
|
@@ -18165,7 +17988,7 @@ function resolveQuickActionMission(kind, chatIndex, promptOverride) {
|
|
|
18165
17988
|
prompt: [
|
|
18166
17989
|
'Explain recent production changes and what to verify next.',
|
|
18167
17990
|
'',
|
|
18168
|
-
'
|
|
17991
|
+
'Project status: ' + gateLabel,
|
|
18169
17992
|
mainBlocker ? 'Main blocker: ' + mainBlocker : '',
|
|
18170
17993
|
blockers.length ? 'Active blockers:\\n' + blockerText : '',
|
|
18171
17994
|
'',
|
|
@@ -18269,7 +18092,7 @@ function quickActionButtonSpec(index) {
|
|
|
18269
18092
|
action: 'plan',
|
|
18270
18093
|
icon: 'report',
|
|
18271
18094
|
label: planSteps.length ? 'Plan \xB7 ' + planSteps.length : 'Plan',
|
|
18272
|
-
hint: planSteps.length ? 'Build
|
|
18095
|
+
hint: planSteps.length ? 'Build fix plan \xB7 ' + planSteps.length + ' actions' : 'Build fix plan',
|
|
18273
18096
|
primary: true,
|
|
18274
18097
|
},
|
|
18275
18098
|
{
|
|
@@ -18284,7 +18107,7 @@ function quickActionButtonSpec(index) {
|
|
|
18284
18107
|
action: 'verify-now',
|
|
18285
18108
|
icon: 'shield',
|
|
18286
18109
|
label: gateClear ? 'Re-verify' : 'Verify',
|
|
18287
|
-
hint: gateClear ? 'Re-verify
|
|
18110
|
+
hint: gateClear ? 'Re-verify readiness' : 'Verify readiness',
|
|
18288
18111
|
primary: true,
|
|
18289
18112
|
},
|
|
18290
18113
|
{
|
|
@@ -18373,7 +18196,7 @@ function runChatTask(kind, promptOverride) {
|
|
|
18373
18196
|
demo.notice = 'Verification finished in chat. Launch proof is green.';
|
|
18374
18197
|
} else if (kind === 'fix') {
|
|
18375
18198
|
demo.activeStepId = 'verify';
|
|
18376
|
-
demo.notice = 'Fix prepared in chat. Run Verify to
|
|
18199
|
+
demo.notice = 'Fix prepared in chat. Run Verify to update production readiness.';
|
|
18377
18200
|
} else {
|
|
18378
18201
|
demo.notice = taskMeta(kind).title + ' finished in chat.';
|
|
18379
18202
|
}
|
|
@@ -18395,12 +18218,12 @@ function runChatTask(kind, promptOverride) {
|
|
|
18395
18218
|
modelId: selectedModelLabel(chatIndex),
|
|
18396
18219
|
reasoning: chat.reasoning,
|
|
18397
18220
|
context: chat.context,
|
|
18221
|
+
accessMode: chat.accessMode || 'approve',
|
|
18398
18222
|
prompt,
|
|
18399
18223
|
displayPrompt: label,
|
|
18400
18224
|
taskKind: kind,
|
|
18401
|
-
|
|
18402
|
-
|
|
18403
|
-
release: release ? { label: release.label } : undefined
|
|
18225
|
+
provider: { id: provider.id, area: provider.area, name: provider.name },
|
|
18226
|
+
release: release ? { id: release.id, label: release.label } : undefined
|
|
18404
18227
|
})
|
|
18405
18228
|
})
|
|
18406
18229
|
.then(async (response) => {
|
|
@@ -18429,7 +18252,7 @@ function sendChatInput(chatIndex) {
|
|
|
18429
18252
|
}
|
|
18430
18253
|
chat.draft = '';
|
|
18431
18254
|
if (input && 'value' in input) input.value = '';
|
|
18432
|
-
runChatTask(chat.providerId ? 'provider' : 'analyze', value);
|
|
18255
|
+
runChatTask(chat.releaseId ? 'diff' : chat.providerId ? 'provider' : 'analyze', value);
|
|
18433
18256
|
}
|
|
18434
18257
|
|
|
18435
18258
|
function resetLaunchPreview() {
|
|
@@ -18449,11 +18272,13 @@ function resetLaunchPreview() {
|
|
|
18449
18272
|
demo.selectedModelId = 'gpt-5.5';
|
|
18450
18273
|
demo.selectedReasoning = 'High';
|
|
18451
18274
|
demo.selectedContext = 'Production';
|
|
18275
|
+
demo.selectedAccessMode = 'approve';
|
|
18452
18276
|
demo.modelMenuOpen = false;
|
|
18453
18277
|
demo.reasoningMenuOpen = false;
|
|
18454
18278
|
demo.contextMenuOpen = false;
|
|
18279
|
+
demo.accessMenuOpen = false;
|
|
18455
18280
|
demo.pickerChatIndex = 0;
|
|
18456
|
-
demo.chatContexts = [defaultChatContext({ cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production' })];
|
|
18281
|
+
demo.chatContexts = [defaultChatContext({ cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production', accessMode: 'approve' })];
|
|
18457
18282
|
demo.droppedProviderId = null;
|
|
18458
18283
|
demo.droppedReleaseId = null;
|
|
18459
18284
|
clearChatTaskTimer();
|
|
@@ -18523,10 +18348,10 @@ function RecentChatRail() {
|
|
|
18523
18348
|
|
|
18524
18349
|
function ProviderCard(provider) {
|
|
18525
18350
|
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>' +
|
|
18351
|
+
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">' +
|
|
18352
|
+
ProviderToken(provider) +
|
|
18529
18353
|
'<div><small>' + escapeHtml(slot) + '</small><strong>' + escapeHtml(provider.name) + '</strong><em>' + escapeHtml(provider.status) + '</em></div>' +
|
|
18354
|
+
providerMcpChip(provider) +
|
|
18530
18355
|
'<span class="vr-provider-proof-chip"><span>Open</span>' + Icon('chevronRight') + '</span>' +
|
|
18531
18356
|
'</button>';
|
|
18532
18357
|
}
|
|
@@ -18534,9 +18359,10 @@ function ProviderCard(provider) {
|
|
|
18534
18359
|
function ProviderDetailPanel() {
|
|
18535
18360
|
const provider = providers.find((item) => item.id === demo.selectedProviderId) || providers[0];
|
|
18536
18361
|
return '<aside class="vr-provider-detail-panel">' +
|
|
18537
|
-
'<div class="vr-detail-head"
|
|
18362
|
+
'<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
18363
|
'<p>' + escapeHtml(provider.detail) + '</p>' +
|
|
18539
18364
|
'<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>' +
|
|
18365
|
+
ProviderMcpPanel(provider) +
|
|
18540
18366
|
'<a class="vr-provider-dashboard" href="' + escapeHtml(providerDashboardUrls[provider.id] || docsUrl) + '" target="_blank" rel="noreferrer">Open dashboard ' + Icon('external') + '</a>' +
|
|
18541
18367
|
'</aside>';
|
|
18542
18368
|
}
|
|
@@ -18557,7 +18383,7 @@ function ProviderPicker() {
|
|
|
18557
18383
|
return '<div class="vr-provider-picker" aria-label="Provider picker">' +
|
|
18558
18384
|
'<div><strong>Connector picker</strong><span>Select one provider. VibeRaven opens its proof panel and next action.</span></div>' +
|
|
18559
18385
|
'<div class="vr-provider-picker-list">' + boardProviders.map((provider) =>
|
|
18560
|
-
'<button type="button" data-provider="' + escapeHtml(provider.id) + '"
|
|
18386
|
+
'<button type="button" data-provider="' + escapeHtml(provider.id) + '">' + ProviderToken(provider, 'is-picker') + '<span>' + escapeHtml(provider.name) + '</span></button>'
|
|
18561
18387
|
).join('') + '</div>' +
|
|
18562
18388
|
'</div>';
|
|
18563
18389
|
}
|
|
@@ -18613,11 +18439,12 @@ function ProviderModal() {
|
|
|
18613
18439
|
const checkRows = providerModalCheckRows(raw);
|
|
18614
18440
|
return ModalShell('provider',
|
|
18615
18441
|
'<header class="vr-modal-provider-head">' +
|
|
18616
|
-
'
|
|
18442
|
+
ProviderLogo(provider, 'vr-modal-provider-logo') +
|
|
18617
18443
|
'<div><h2>' + escapeHtml(provider.name) + '</h2>' + StatusBadge(provider.status, provider.tone) + '<p>' + escapeHtml(provider.area) + ' provider</p></div>' +
|
|
18618
18444
|
'<img class="vr-modal-mascot" src="' + providerModalMascot(health) + '" alt="" />' +
|
|
18619
18445
|
'</header>' +
|
|
18620
18446
|
'<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>' +
|
|
18447
|
+
ProviderMcpPanel(provider) +
|
|
18621
18448
|
'<div class="vr-modal-action-grid">' +
|
|
18622
18449
|
GlowButton('Open slot', { action: 'guide', tone: 'purple' }) +
|
|
18623
18450
|
'<button type="button" data-action="recheck">' + Icon('refresh') + 'Re-check</button>' +
|
|
@@ -18644,7 +18471,7 @@ function AddProviderModal() {
|
|
|
18644
18471
|
'</header>' +
|
|
18645
18472
|
'<section class="vr-modal-provider-options">' + featured.map((item) => {
|
|
18646
18473
|
const provider = providers.find((candidate) => candidate.id === item.icon) || providers[0];
|
|
18647
|
-
return '<button type="button" data-provider="' + escapeHtml(provider.id) + '"
|
|
18474
|
+
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
18475
|
}).join('') + '</section>' +
|
|
18649
18476
|
'<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
18477
|
);
|
|
@@ -18846,21 +18673,18 @@ function connectCliAgent(agentId, chatIndex, options) {
|
|
|
18846
18673
|
}
|
|
18847
18674
|
|
|
18848
18675
|
function cliSetupProbeLabel() {
|
|
18849
|
-
return demo.cliProbeStatus === 'probing' ? 'Testing
|
|
18676
|
+
return demo.cliProbeStatus === 'probing' ? 'Testing...' : demo.cliProbeStatus === 'success' ? 'Connected' : demo.cliProbeStatus === 'failed' ? 'Try again' : 'Test connection';
|
|
18850
18677
|
}
|
|
18851
18678
|
|
|
18852
18679
|
function CliSetupActions(targetId, index) {
|
|
18853
18680
|
const setup = cliSetupFor(targetId);
|
|
18854
18681
|
const probeLabel = cliSetupProbeLabel();
|
|
18855
|
-
const ctaPending = demo.cliProbeStatus !== 'success' && demo.cliProbeStatus !== 'probing';
|
|
18856
|
-
const ctaClass = 'vr-cli-action-button is-primary is-cta' + (ctaPending ? ' is-pending' : '');
|
|
18857
18682
|
return '<div class="vr-cli-connect-expand-actions">' +
|
|
18858
18683
|
'<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>' +
|
|
18859
18684
|
'<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>' +
|
|
18685
|
+
'<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>' +
|
|
18860
18686
|
'</div>' +
|
|
18861
|
-
'<p class="vr-cli-setup-
|
|
18862
|
-
'<button class="' + ctaClass + '" type="button" data-action="test-cli-connection" data-cli-agent="' + escapeHtml(targetId) + '" data-chat-index="' + String(index) + '">' + Icon('refresh') + escapeHtml(probeLabel) + '</button>' +
|
|
18863
|
-
'<p class="vr-cli-setup-hint">Type commands in the Studio terminal below, or run: <code>' + escapeHtml(setup.installCommand) + '</code> then <code>' + escapeHtml(setup.signInCommand) + '</code></p>';
|
|
18687
|
+
'<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
18688
|
}
|
|
18865
18689
|
|
|
18866
18690
|
function appendTerminalLines(lines) {
|
|
@@ -18924,7 +18748,7 @@ function selectTerminalCli(agentId) {
|
|
|
18924
18748
|
if (!demo.cliTerminalLines.length) {
|
|
18925
18749
|
demo.cliTerminalLines = [
|
|
18926
18750
|
'VibeRaven Studio shell',
|
|
18927
|
-
'Run install, run sign in, then
|
|
18751
|
+
'Run install, run sign in, then use Test connection to continue.',
|
|
18928
18752
|
''
|
|
18929
18753
|
];
|
|
18930
18754
|
} else {
|
|
@@ -18956,8 +18780,8 @@ function StudioTerminalView() {
|
|
|
18956
18780
|
const lines = demo.cliTerminalLines.length
|
|
18957
18781
|
? demo.cliTerminalLines
|
|
18958
18782
|
: [
|
|
18959
|
-
|
|
18960
|
-
'Type commands at the $ prompt. Use
|
|
18783
|
+
'VibeRaven Studio shell',
|
|
18784
|
+
'Type commands at the $ prompt. Use Test connection after sign-in.',
|
|
18961
18785
|
''
|
|
18962
18786
|
];
|
|
18963
18787
|
const title = terminalConnectTitle(agent);
|
|
@@ -19300,7 +19124,7 @@ async function runCliSignInInStudio(agentId, chatIndex) {
|
|
|
19300
19124
|
String(payload?.output || payload?.message || 'Sign-in command finished.'),
|
|
19301
19125
|
payload?.interactiveNote ? String(payload.interactiveNote) : '',
|
|
19302
19126
|
'',
|
|
19303
|
-
'Complete any browser login, then click Test connection
|
|
19127
|
+
'Complete any browser login, then click Test connection.'
|
|
19304
19128
|
]);
|
|
19305
19129
|
demo.cliTerminalDraft = setupCommandFallback(agentId, 'sign-in');
|
|
19306
19130
|
demo.notice = 'Sign-in ran in Studio terminal. Finish login if prompted, then test the connection.';
|
|
@@ -19332,7 +19156,7 @@ async function openCliOsTerminal(agentId, chatIndex) {
|
|
|
19332
19156
|
'',
|
|
19333
19157
|
String(payload?.message || 'Complete sign-in in the OS terminal window that opened.'),
|
|
19334
19158
|
'',
|
|
19335
|
-
'When login finishes, return here and click Test connection
|
|
19159
|
+
'When login finishes, return here and click Test connection.'
|
|
19336
19160
|
]);
|
|
19337
19161
|
demo.notice = payload?.ok ? 'OS terminal opened for sign-in fallback.' : 'Could not open an OS terminal window.';
|
|
19338
19162
|
} catch {
|
|
@@ -19347,11 +19171,12 @@ function ModelPicker(index) {
|
|
|
19347
19171
|
const models = allModelOptions(index);
|
|
19348
19172
|
const selectedModel = selectedModelLabel(index);
|
|
19349
19173
|
const scoped = demo.pickerChatIndex === index;
|
|
19174
|
+
const access = accessModes.find((mode) => mode.id === chat.accessMode) || accessModes[1];
|
|
19350
19175
|
return '<div class="vr-model-picker">' +
|
|
19351
19176
|
'<button type="button" data-action="toggle-reasoning" data-chat-index="' + String(index) + '"><span>Reasoning</span><strong>' + escapeHtml(chat.reasoning) + '</strong><i></i></button>' +
|
|
19352
19177
|
'<button type="button" data-action="toggle-models" data-chat-index="' + String(index) + '"><span>Model</span><strong>' + escapeHtml(selectedModel) + '</strong><i></i></button>' +
|
|
19353
19178
|
'<button type="button" data-action="toggle-context" data-chat-index="' + String(index) + '"><span>Context</span><strong>' + escapeHtml(chat.context) + '</strong><i></i></button>' +
|
|
19354
|
-
|
|
19179
|
+
'<button type="button" data-action="toggle-access" data-chat-index="' + String(index) + '"><span>Access</span><strong>' + escapeHtml(access.label) + '</strong><i></i></button>' +
|
|
19355
19180
|
(scoped && demo.reasoningMenuOpen ? '<div class="vr-model-menu is-reasoning" role="menu"><p>Reasoning</p>' + reasoningLevels.map((level) =>
|
|
19356
19181
|
'<button type="button" data-reasoning="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.reasoning === level ? '<b></b>' : '') + '</button>'
|
|
19357
19182
|
).join('') + '</div>' : '') +
|
|
@@ -19361,14 +19186,9 @@ function ModelPicker(index) {
|
|
|
19361
19186
|
(scoped && demo.contextMenuOpen ? '<div class="vr-model-menu is-context" role="menu"><p>Context</p>' + contextLevels.map((level) =>
|
|
19362
19187
|
'<button type="button" data-context="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.context === level ? '<b></b>' : '') + '</button>'
|
|
19363
19188
|
).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>' +
|
|
19189
|
+
(scoped && demo.accessMenuOpen ? '<div class="vr-model-menu is-access" role="menu"><p>Access</p>' + accessModes.map((mode) =>
|
|
19190
|
+
'<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>'
|
|
19191
|
+
).join('') + '</div>' : '') +
|
|
19372
19192
|
'</div>';
|
|
19373
19193
|
}
|
|
19374
19194
|
|
|
@@ -19388,10 +19208,10 @@ function ChatBlockersSummary(cards) {
|
|
|
19388
19208
|
function ChatPlanCard(steps, chatIndex) {
|
|
19389
19209
|
const rows = Array.isArray(steps) ? steps : [];
|
|
19390
19210
|
if (!rows.length) return '';
|
|
19391
|
-
return '<section class="vr-chat-card vr-chat-plan-card"><header><strong>
|
|
19211
|
+
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
19212
|
rows.map((step, index) =>
|
|
19393
19213
|
'<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"
|
|
19214
|
+
'<span class="vr-plan-step-num"></span>' +
|
|
19395
19215
|
'<span class="vr-plan-step-body">' +
|
|
19396
19216
|
'<span class="vr-plan-step-title">' + escapeHtml(step.title || 'Fix step') + '</span>' +
|
|
19397
19217
|
'<span class="vr-plan-step-tag">' + escapeHtml(step.category || 'Quality') + '</span>' +
|
|
@@ -19428,7 +19248,7 @@ function ChatMissionCards(cards, chatIndex, options) {
|
|
|
19428
19248
|
if (showPlan && planSteps.length) html += ChatPlanCard(planSteps, chatIndex);
|
|
19429
19249
|
if (connectProviders.length) html += ChatProviderConnectCard(connectProviders, chatIndex);
|
|
19430
19250
|
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
|
|
19251
|
+
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
19252
|
}
|
|
19433
19253
|
html += '</div>';
|
|
19434
19254
|
return html;
|
|
@@ -19555,9 +19375,9 @@ function renderAgentListItems(items, chatIndex) {
|
|
|
19555
19375
|
|
|
19556
19376
|
function normalizeAgentSectionKey(raw) {
|
|
19557
19377
|
const key = String(raw || '').trim().toLowerCase().replace(/\\s*\\(\\d+\\)\\s*$/, '').trim();
|
|
19558
|
-
if (/^(gate|
|
|
19378
|
+
if (/^(gate|production gate)$/.test(key)) return null;
|
|
19559
19379
|
if (/^(blockers?|launch blockers?)$/.test(key)) return 'Blockers';
|
|
19560
|
-
if (/^(suggested steps?|fix plan
|
|
19380
|
+
if (/^(suggested steps?|fix plan)$/.test(key)) return 'Suggested steps';
|
|
19561
19381
|
if (/^(summary|tl;dr|tldr)$/.test(key)) return 'Summary';
|
|
19562
19382
|
if (key === 'findings') return 'Findings';
|
|
19563
19383
|
if (key === 'changes made') return 'Changes made';
|
|
@@ -19590,15 +19410,7 @@ function dedupeAgentMarkdownBody(text, cards) {
|
|
|
19590
19410
|
}
|
|
19591
19411
|
|
|
19592
19412
|
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>';
|
|
19413
|
+
return '';
|
|
19602
19414
|
}
|
|
19603
19415
|
|
|
19604
19416
|
function parseAgentSections(text, options) {
|
|
@@ -19645,8 +19457,7 @@ function renderAgentSectionCard(section, chatIndex) {
|
|
|
19645
19457
|
const name = section.name;
|
|
19646
19458
|
const lower = name.toLowerCase();
|
|
19647
19459
|
if (lower === 'gate') {
|
|
19648
|
-
|
|
19649
|
-
return AgentGateStrip(gateText, currentState.gate || null);
|
|
19460
|
+
return '';
|
|
19650
19461
|
}
|
|
19651
19462
|
const isNext = lower === 'next step';
|
|
19652
19463
|
const isBlockers = lower === 'blockers';
|
|
@@ -19835,7 +19646,7 @@ function readOnlyContextChipsHtml(providerId, releaseId) {
|
|
|
19835
19646
|
kind: 'provider',
|
|
19836
19647
|
index: 0,
|
|
19837
19648
|
id: provider.id,
|
|
19838
|
-
iconHtml: '<img src="' + (
|
|
19649
|
+
iconHtml: provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />',
|
|
19839
19650
|
mutedLabel: provider.area,
|
|
19840
19651
|
label: provider.name,
|
|
19841
19652
|
readOnly: true,
|
|
@@ -19926,7 +19737,7 @@ function ContextDropZone(index, showAttached) {
|
|
|
19926
19737
|
kind: 'provider',
|
|
19927
19738
|
index,
|
|
19928
19739
|
id: provider.id,
|
|
19929
|
-
iconHtml: '<img src="' + (
|
|
19740
|
+
iconHtml: provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />',
|
|
19930
19741
|
mutedLabel: provider.area,
|
|
19931
19742
|
label: provider.name,
|
|
19932
19743
|
}) : '') +
|
|
@@ -20204,7 +20015,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20204
20015
|
if (demo.activeStudioTab === 'terminal' && !demo.cliTerminalLines.length) {
|
|
20205
20016
|
demo.cliTerminalLines = [
|
|
20206
20017
|
'VibeRaven Studio shell',
|
|
20207
|
-
'Type commands at the $ prompt. Use
|
|
20018
|
+
'Type commands at the $ prompt. Use Test connection after sign-in.',
|
|
20208
20019
|
''
|
|
20209
20020
|
];
|
|
20210
20021
|
}
|
|
@@ -20302,6 +20113,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20302
20113
|
demo.modelMenuOpen = false;
|
|
20303
20114
|
demo.reasoningMenuOpen = false;
|
|
20304
20115
|
demo.contextMenuOpen = false;
|
|
20116
|
+
demo.accessMenuOpen = false;
|
|
20305
20117
|
demo.cliProbeStatus = 'idle';
|
|
20306
20118
|
demo.cliProbeMessage = '';
|
|
20307
20119
|
demo.pickerChatIndex = chatIndex;
|
|
@@ -20329,6 +20141,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20329
20141
|
demo.modelMenuOpen = false;
|
|
20330
20142
|
demo.reasoningMenuOpen = false;
|
|
20331
20143
|
demo.contextMenuOpen = false;
|
|
20144
|
+
demo.accessMenuOpen = false;
|
|
20332
20145
|
demo.notice = (cliAgents.find((item) => item.id === chat.cliId)?.label || chat.cliId) + ' selected for this chat.';
|
|
20333
20146
|
render();
|
|
20334
20147
|
return;
|
|
@@ -20346,6 +20159,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20346
20159
|
demo.modelMenuOpen = false;
|
|
20347
20160
|
demo.reasoningMenuOpen = false;
|
|
20348
20161
|
demo.contextMenuOpen = false;
|
|
20162
|
+
demo.accessMenuOpen = false;
|
|
20349
20163
|
demo.activeStudioTab = 'chat';
|
|
20350
20164
|
demo.pickerChatIndex = chatIndex;
|
|
20351
20165
|
demo.notice = selectedModelLabel(chatIndex) + ' selected for this chat.';
|
|
@@ -20364,6 +20178,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20364
20178
|
demo.reasoningMenuOpen = false;
|
|
20365
20179
|
demo.modelMenuOpen = false;
|
|
20366
20180
|
demo.contextMenuOpen = false;
|
|
20181
|
+
demo.accessMenuOpen = false;
|
|
20367
20182
|
demo.activeStudioTab = 'chat';
|
|
20368
20183
|
demo.pickerChatIndex = chatIndex;
|
|
20369
20184
|
demo.notice = chat.reasoning + ' reasoning selected for this chat.';
|
|
@@ -20382,6 +20197,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20382
20197
|
demo.contextMenuOpen = false;
|
|
20383
20198
|
demo.modelMenuOpen = false;
|
|
20384
20199
|
demo.reasoningMenuOpen = false;
|
|
20200
|
+
demo.accessMenuOpen = false;
|
|
20385
20201
|
demo.activeStudioTab = 'chat';
|
|
20386
20202
|
demo.pickerChatIndex = chatIndex;
|
|
20387
20203
|
demo.notice = chat.context + ' context selected for this chat.';
|
|
@@ -20390,21 +20206,23 @@ app.addEventListener('click', async (event) => {
|
|
|
20390
20206
|
return;
|
|
20391
20207
|
}
|
|
20392
20208
|
|
|
20393
|
-
const
|
|
20394
|
-
if (
|
|
20209
|
+
const accessButton = event.target.closest('[data-access-mode]');
|
|
20210
|
+
if (accessButton) {
|
|
20395
20211
|
event.preventDefault();
|
|
20396
|
-
const
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
|
|
20400
|
-
demo.
|
|
20212
|
+
const chatIndex = Number(accessButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
|
|
20213
|
+
const chat = chatContext(chatIndex);
|
|
20214
|
+
const selected = accessModes.find((mode) => mode.id === accessButton.getAttribute('data-access-mode')) || accessModes[1];
|
|
20215
|
+
chat.accessMode = selected.id;
|
|
20216
|
+
demo.selectedAccessMode = selected.id;
|
|
20217
|
+
demo.accessMenuOpen = false;
|
|
20218
|
+
demo.contextMenuOpen = false;
|
|
20401
20219
|
demo.modelMenuOpen = false;
|
|
20402
20220
|
demo.reasoningMenuOpen = false;
|
|
20403
|
-
demo.
|
|
20404
|
-
demo.
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20221
|
+
demo.activeStudioTab = 'chat';
|
|
20222
|
+
demo.pickerChatIndex = chatIndex;
|
|
20223
|
+
demo.notice = selected.label + ' selected for this chat.';
|
|
20224
|
+
refreshPickerMenus();
|
|
20225
|
+
refreshBottomTip();
|
|
20408
20226
|
return;
|
|
20409
20227
|
}
|
|
20410
20228
|
|
|
@@ -20415,6 +20233,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20415
20233
|
demo.modelMenuOpen = false;
|
|
20416
20234
|
demo.reasoningMenuOpen = false;
|
|
20417
20235
|
demo.contextMenuOpen = false;
|
|
20236
|
+
demo.accessMenuOpen = false;
|
|
20418
20237
|
if (stage === 'provider') {
|
|
20419
20238
|
demo.activeStudioTab = 'chat';
|
|
20420
20239
|
demo.providerPickerOpen = true;
|
|
@@ -20601,6 +20420,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20601
20420
|
demo.modelMenuOpen = !samePicker;
|
|
20602
20421
|
demo.reasoningMenuOpen = false;
|
|
20603
20422
|
demo.contextMenuOpen = false;
|
|
20423
|
+
demo.accessMenuOpen = false;
|
|
20604
20424
|
refreshPickerMenus();
|
|
20605
20425
|
return;
|
|
20606
20426
|
}
|
|
@@ -20613,6 +20433,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20613
20433
|
demo.reasoningMenuOpen = !samePicker;
|
|
20614
20434
|
demo.modelMenuOpen = false;
|
|
20615
20435
|
demo.contextMenuOpen = false;
|
|
20436
|
+
demo.accessMenuOpen = false;
|
|
20616
20437
|
refreshPickerMenus();
|
|
20617
20438
|
return;
|
|
20618
20439
|
}
|
|
@@ -20625,6 +20446,20 @@ app.addEventListener('click', async (event) => {
|
|
|
20625
20446
|
demo.contextMenuOpen = !samePicker;
|
|
20626
20447
|
demo.modelMenuOpen = false;
|
|
20627
20448
|
demo.reasoningMenuOpen = false;
|
|
20449
|
+
demo.accessMenuOpen = false;
|
|
20450
|
+
refreshPickerMenus();
|
|
20451
|
+
return;
|
|
20452
|
+
}
|
|
20453
|
+
if (action === 'toggle-access') {
|
|
20454
|
+
event.preventDefault();
|
|
20455
|
+
const chatIndex = Number(actionButton.getAttribute('data-chat-index') || '0');
|
|
20456
|
+
const samePicker = demo.pickerChatIndex === chatIndex && demo.accessMenuOpen;
|
|
20457
|
+
demo.activeStudioTab = 'chat';
|
|
20458
|
+
demo.pickerChatIndex = chatIndex;
|
|
20459
|
+
demo.accessMenuOpen = !samePicker;
|
|
20460
|
+
demo.modelMenuOpen = false;
|
|
20461
|
+
demo.reasoningMenuOpen = false;
|
|
20462
|
+
demo.contextMenuOpen = false;
|
|
20628
20463
|
refreshPickerMenus();
|
|
20629
20464
|
return;
|
|
20630
20465
|
}
|
|
@@ -20728,6 +20563,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20728
20563
|
demo.modelMenuOpen = false;
|
|
20729
20564
|
demo.reasoningMenuOpen = false;
|
|
20730
20565
|
demo.contextMenuOpen = false;
|
|
20566
|
+
demo.accessMenuOpen = false;
|
|
20731
20567
|
demo.notice = 'New chat opened.';
|
|
20732
20568
|
render();
|
|
20733
20569
|
return;
|
|
@@ -20833,7 +20669,7 @@ app.addEventListener('click', async (event) => {
|
|
|
20833
20669
|
const chatIndex = Number(actionButton.getAttribute('data-chat-index') || String(actionChatIndex));
|
|
20834
20670
|
demo.fixPlanExpandedChatIndex = demo.fixPlanExpandedChatIndex === chatIndex ? null : chatIndex;
|
|
20835
20671
|
demo.pickerChatIndex = chatIndex;
|
|
20836
|
-
demo.notice = demo.fixPlanExpandedChatIndex === chatIndex ? '
|
|
20672
|
+
demo.notice = demo.fixPlanExpandedChatIndex === chatIndex ? 'Fix plan expanded in chat.' : 'Fix plan collapsed.';
|
|
20837
20673
|
render();
|
|
20838
20674
|
return;
|
|
20839
20675
|
}
|
|
@@ -20973,7 +20809,7 @@ app.addEventListener('dragstart', (event) => {
|
|
|
20973
20809
|
event,
|
|
20974
20810
|
provider ? provider.name : 'Provider',
|
|
20975
20811
|
provider ? provider.area : 'Drop into VibeRaven chat',
|
|
20976
|
-
provider ? '<img src="' +
|
|
20812
|
+
provider ? (provider.iconHtml || '<img src="' + providerAssetSrc(provider) + '" alt="" />') : ''
|
|
20977
20813
|
);
|
|
20978
20814
|
providerButton.classList.add('is-being-dragged');
|
|
20979
20815
|
demo.notice = 'Dragging provider context. Drop it into a chat composer or Split chat.';
|
|
@@ -23768,33 +23604,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
23768
23604
|
background: rgba(124, 58, 237, 0.92);
|
|
23769
23605
|
color: #fff;
|
|
23770
23606
|
}
|
|
23771
|
-
.vr-cli-setup-cta-hint {
|
|
23772
|
-
margin: 9px 0 5px;
|
|
23773
|
-
color: #c4b5fd;
|
|
23774
|
-
font-size: 12px;
|
|
23775
|
-
font-weight: 650;
|
|
23776
|
-
line-height: 1.4;
|
|
23777
|
-
}
|
|
23778
|
-
.vr-cli-action-button.is-cta {
|
|
23779
|
-
width: 100%;
|
|
23780
|
-
justify-content: center;
|
|
23781
|
-
min-height: 42px;
|
|
23782
|
-
font-size: 13.5px;
|
|
23783
|
-
font-weight: 750;
|
|
23784
|
-
letter-spacing: 0.1px;
|
|
23785
|
-
}
|
|
23786
|
-
.vr-cli-action-button.is-cta svg {
|
|
23787
|
-
width: 16px;
|
|
23788
|
-
height: 16px;
|
|
23789
|
-
}
|
|
23790
|
-
.vr-cli-action-button.is-cta.is-pending {
|
|
23791
|
-
border-color: rgba(168, 85, 247, 0.65);
|
|
23792
|
-
animation: vr-cli-cta-pulse 2.2s ease-in-out infinite;
|
|
23793
|
-
}
|
|
23794
|
-
@keyframes vr-cli-cta-pulse {
|
|
23795
|
-
0%, 100% { box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.3), 0 5px 16px rgba(124, 58, 237, 0.22); }
|
|
23796
|
-
50% { box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.6), 0 8px 22px rgba(124, 58, 237, 0.42); }
|
|
23797
|
-
}
|
|
23798
23607
|
.vr-cli-strip button.is-connect-target {
|
|
23799
23608
|
border-color: rgba(248, 250, 252, 0.34);
|
|
23800
23609
|
box-shadow: inset 0 0 0 1px rgba(248, 250, 252, 0.08);
|
|
@@ -24519,16 +24328,15 @@ body:has(.vr-app.is-dragging) {
|
|
|
24519
24328
|
border-color: rgba(168, 85, 247, 0.38);
|
|
24520
24329
|
}
|
|
24521
24330
|
.vr-plan-step-num {
|
|
24522
|
-
width:
|
|
24523
|
-
height:
|
|
24331
|
+
width: 10px;
|
|
24332
|
+
height: 10px;
|
|
24524
24333
|
flex: 0 0 auto;
|
|
24525
24334
|
display: grid;
|
|
24526
24335
|
place-items: center;
|
|
24527
|
-
border: 1px solid rgba(168, 85, 247, 0.
|
|
24336
|
+
border: 1px solid rgba(168, 85, 247, 0.5);
|
|
24528
24337
|
border-radius: 999px;
|
|
24529
|
-
|
|
24530
|
-
|
|
24531
|
-
font-weight: 700;
|
|
24338
|
+
background: rgba(168, 85, 247, 0.28);
|
|
24339
|
+
box-shadow: 0 0 10px rgba(168, 85, 247, 0.22);
|
|
24532
24340
|
}
|
|
24533
24341
|
.vr-plan-step-body {
|
|
24534
24342
|
flex: 1 1 0;
|
|
@@ -25140,6 +24948,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
25140
24948
|
.vr-model-menu.is-context {
|
|
25141
24949
|
right: 0;
|
|
25142
24950
|
}
|
|
24951
|
+
.vr-model-menu.is-access {
|
|
24952
|
+
right: 0;
|
|
24953
|
+
min-width: 270px;
|
|
24954
|
+
}
|
|
25143
24955
|
.vr-studio-chat.is-split .vr-model-menu {
|
|
25144
24956
|
bottom: calc(100% + 10px);
|
|
25145
24957
|
min-width: min(245px, calc(100vw - 32px));
|
|
@@ -25156,6 +24968,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
25156
24968
|
left: auto;
|
|
25157
24969
|
right: 0;
|
|
25158
24970
|
}
|
|
24971
|
+
.vr-studio-chat.is-split .vr-model-menu.is-access {
|
|
24972
|
+
left: auto;
|
|
24973
|
+
right: 0;
|
|
24974
|
+
}
|
|
25159
24975
|
.vr-model-menu p {
|
|
25160
24976
|
margin: 2px 4px 6px;
|
|
25161
24977
|
color: #a8a29e;
|
|
@@ -25300,7 +25116,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25300
25116
|
}
|
|
25301
25117
|
.vr-bottom-inventory .vr-provider-card {
|
|
25302
25118
|
min-height: 48px;
|
|
25303
|
-
grid-template-columns: 34px minmax(0, 1fr)
|
|
25119
|
+
grid-template-columns: 34px minmax(0, 1fr) 18px 22px;
|
|
25304
25120
|
grid-template-rows: 1fr;
|
|
25305
25121
|
align-items: center;
|
|
25306
25122
|
gap: 8px;
|
|
@@ -25357,14 +25173,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
25357
25173
|
fill: none !important;
|
|
25358
25174
|
stroke: currentColor !important;
|
|
25359
25175
|
}
|
|
25360
|
-
.vr-bottom-inventory .vr-provider-light {
|
|
25361
|
-
right: 36px;
|
|
25362
|
-
top: 50%;
|
|
25363
|
-
width: 7px;
|
|
25364
|
-
height: 7px;
|
|
25365
|
-
transform: translateY(-50%);
|
|
25366
|
-
box-shadow: 0 0 9px rgba(34, 197, 94, 0.42);
|
|
25367
|
-
}
|
|
25368
25176
|
.vr-bottom-inventory .vr-provider-card .vr-status-badge {
|
|
25369
25177
|
grid-column: 3;
|
|
25370
25178
|
min-height: 18px;
|
|
@@ -25651,8 +25459,35 @@ body:has(.vr-app.is-dragging) {
|
|
|
25651
25459
|
filter: saturate(1.04) contrast(1.02);
|
|
25652
25460
|
transition: transform 180ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
25653
25461
|
}
|
|
25462
|
+
.vr-provider-token .provider-logo__img {
|
|
25463
|
+
filter: saturate(1.22) contrast(1.14);
|
|
25464
|
+
}
|
|
25465
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="github"],
|
|
25466
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="vercel"],
|
|
25467
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="resend"] {
|
|
25468
|
+
filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.18));
|
|
25469
|
+
}
|
|
25470
|
+
.vr-provider-token .provider-logo__img[data-provider-logo-key="sentry"] {
|
|
25471
|
+
filter: saturate(1.34) contrast(1.16) drop-shadow(0 0 9px rgba(139, 92, 246, 0.26));
|
|
25472
|
+
}
|
|
25473
|
+
.vr-provider-token svg {
|
|
25474
|
+
position: relative;
|
|
25475
|
+
z-index: 1;
|
|
25476
|
+
width: 26px;
|
|
25477
|
+
height: 26px;
|
|
25478
|
+
display: block;
|
|
25479
|
+
}
|
|
25480
|
+
.vr-provider-token .vr-provider-logo,
|
|
25481
|
+
.vr-provider-token .vr-provider-logo img {
|
|
25482
|
+
width: 26px;
|
|
25483
|
+
height: 26px;
|
|
25484
|
+
display: block;
|
|
25485
|
+
object-fit: contain;
|
|
25486
|
+
}
|
|
25654
25487
|
.vr-provider-card:hover .vr-provider-token img,
|
|
25655
|
-
.vr-provider-card.is-selected .vr-provider-token img
|
|
25488
|
+
.vr-provider-card.is-selected .vr-provider-token img,
|
|
25489
|
+
.vr-provider-card:hover .vr-provider-token svg,
|
|
25490
|
+
.vr-provider-card.is-selected .vr-provider-token svg {
|
|
25656
25491
|
transform: scale(1.08);
|
|
25657
25492
|
}
|
|
25658
25493
|
.vr-provider-token.is-picker {
|
|
@@ -25673,15 +25508,11 @@ body:has(.vr-app.is-dragging) {
|
|
|
25673
25508
|
width: 34px;
|
|
25674
25509
|
height: 34px;
|
|
25675
25510
|
}
|
|
25676
|
-
.vr-provider-
|
|
25677
|
-
|
|
25678
|
-
|
|
25679
|
-
|
|
25680
|
-
|
|
25681
|
-
height: 8px;
|
|
25682
|
-
border-radius: 999px;
|
|
25683
|
-
background: var(--vr-green);
|
|
25684
|
-
box-shadow: 0 0 8px rgba(34, 197, 94, 0.36);
|
|
25511
|
+
.vr-provider-token.is-large svg,
|
|
25512
|
+
.vr-provider-token.is-large .vr-provider-logo,
|
|
25513
|
+
.vr-provider-token.is-large .vr-provider-logo img {
|
|
25514
|
+
width: 34px;
|
|
25515
|
+
height: 34px;
|
|
25685
25516
|
}
|
|
25686
25517
|
.vr-provider-card small,
|
|
25687
25518
|
.vr-provider-card strong,
|
|
@@ -25711,6 +25542,15 @@ body:has(.vr-app.is-dragging) {
|
|
|
25711
25542
|
font-size: 11px;
|
|
25712
25543
|
font-weight: 520;
|
|
25713
25544
|
}
|
|
25545
|
+
.vr-provider-card[data-provider-tone="orange"] em {
|
|
25546
|
+
color: #fbbf24;
|
|
25547
|
+
}
|
|
25548
|
+
.vr-provider-card[data-provider-tone="red"] em {
|
|
25549
|
+
color: #fb7185;
|
|
25550
|
+
}
|
|
25551
|
+
.vr-provider-card[data-provider-tone="neutral"] em {
|
|
25552
|
+
color: #aeb7c6;
|
|
25553
|
+
}
|
|
25714
25554
|
.vr-provider-proof-chip {
|
|
25715
25555
|
grid-column: 1 / -1;
|
|
25716
25556
|
display: inline-flex;
|
|
@@ -25742,6 +25582,130 @@ body:has(.vr-app.is-dragging) {
|
|
|
25742
25582
|
height: 13px;
|
|
25743
25583
|
stroke: currentColor;
|
|
25744
25584
|
}
|
|
25585
|
+
.vr-provider-mcp-chip {
|
|
25586
|
+
grid-column: 2;
|
|
25587
|
+
grid-row: 2;
|
|
25588
|
+
justify-self: end;
|
|
25589
|
+
min-width: 0;
|
|
25590
|
+
width: 8px;
|
|
25591
|
+
height: 8px;
|
|
25592
|
+
display: inline-flex;
|
|
25593
|
+
align-items: center;
|
|
25594
|
+
justify-content: center;
|
|
25595
|
+
gap: 0;
|
|
25596
|
+
border: 0;
|
|
25597
|
+
border-radius: 999px;
|
|
25598
|
+
padding: 0;
|
|
25599
|
+
color: #fbbf24;
|
|
25600
|
+
font-size: 10px;
|
|
25601
|
+
font-weight: 720;
|
|
25602
|
+
line-height: 1;
|
|
25603
|
+
background: transparent;
|
|
25604
|
+
}
|
|
25605
|
+
.vr-provider-mcp-chip i {
|
|
25606
|
+
width: 8px;
|
|
25607
|
+
height: 8px;
|
|
25608
|
+
flex: 0 0 auto;
|
|
25609
|
+
border-radius: 999px;
|
|
25610
|
+
background: #f59e0b;
|
|
25611
|
+
box-shadow: 0 0 8px rgba(245, 158, 11, 0.36);
|
|
25612
|
+
animation: vrStatusPulse 2.7s ease-in-out infinite;
|
|
25613
|
+
}
|
|
25614
|
+
.vr-provider-mcp-chip span {
|
|
25615
|
+
position: absolute;
|
|
25616
|
+
width: 1px;
|
|
25617
|
+
height: 1px;
|
|
25618
|
+
overflow: hidden;
|
|
25619
|
+
clip: rect(0 0 0 0);
|
|
25620
|
+
}
|
|
25621
|
+
.vr-provider-mcp-chip.is-connected {
|
|
25622
|
+
border-color: transparent;
|
|
25623
|
+
background: transparent;
|
|
25624
|
+
color: #bbf7d0;
|
|
25625
|
+
}
|
|
25626
|
+
.vr-provider-mcp-chip.is-connected i {
|
|
25627
|
+
background: #22c55e;
|
|
25628
|
+
box-shadow: 0 0 8px rgba(34, 197, 94, 0.42);
|
|
25629
|
+
}
|
|
25630
|
+
@keyframes vrStatusPulse {
|
|
25631
|
+
0%, 100% {
|
|
25632
|
+
opacity: 0.72;
|
|
25633
|
+
transform: scale(0.92);
|
|
25634
|
+
}
|
|
25635
|
+
50% {
|
|
25636
|
+
opacity: 1;
|
|
25637
|
+
transform: scale(1.08);
|
|
25638
|
+
}
|
|
25639
|
+
}
|
|
25640
|
+
.vr-provider-mcp-panel {
|
|
25641
|
+
display: grid;
|
|
25642
|
+
gap: 10px;
|
|
25643
|
+
border: 1px solid rgba(148, 163, 184, 0.13);
|
|
25644
|
+
border-radius: 10px;
|
|
25645
|
+
padding: 10px;
|
|
25646
|
+
background: rgba(255, 255, 255, 0.035);
|
|
25647
|
+
}
|
|
25648
|
+
.vr-provider-mcp-panel header {
|
|
25649
|
+
display: grid;
|
|
25650
|
+
grid-template-columns: 30px minmax(0, 1fr);
|
|
25651
|
+
gap: 10px;
|
|
25652
|
+
align-items: center;
|
|
25653
|
+
}
|
|
25654
|
+
.vr-provider-mcp-panel header > span {
|
|
25655
|
+
width: 30px;
|
|
25656
|
+
height: 30px;
|
|
25657
|
+
display: inline-grid;
|
|
25658
|
+
place-items: center;
|
|
25659
|
+
border-radius: 8px;
|
|
25660
|
+
background: rgba(245, 158, 11, 0.11);
|
|
25661
|
+
color: #fbbf24;
|
|
25662
|
+
}
|
|
25663
|
+
.vr-provider-mcp-panel strong,
|
|
25664
|
+
.vr-provider-mcp-panel em {
|
|
25665
|
+
display: block;
|
|
25666
|
+
min-width: 0;
|
|
25667
|
+
}
|
|
25668
|
+
.vr-provider-mcp-panel strong {
|
|
25669
|
+
color: #f8fafc;
|
|
25670
|
+
font-size: 13px;
|
|
25671
|
+
}
|
|
25672
|
+
.vr-provider-mcp-panel em {
|
|
25673
|
+
margin-top: 2px;
|
|
25674
|
+
color: #98a2b3;
|
|
25675
|
+
font-size: 11px;
|
|
25676
|
+
font-style: normal;
|
|
25677
|
+
}
|
|
25678
|
+
.vr-provider-mcp-panel > div {
|
|
25679
|
+
display: flex;
|
|
25680
|
+
flex-wrap: wrap;
|
|
25681
|
+
gap: 6px;
|
|
25682
|
+
}
|
|
25683
|
+
.vr-provider-mcp-panel small {
|
|
25684
|
+
border-radius: 999px;
|
|
25685
|
+
border: 1px solid rgba(148, 163, 184, 0.13);
|
|
25686
|
+
padding: 4px 7px;
|
|
25687
|
+
color: #b9c2cf;
|
|
25688
|
+
font-size: 10px;
|
|
25689
|
+
font-weight: 680;
|
|
25690
|
+
}
|
|
25691
|
+
.vr-provider-mcp-panel.is-connected {
|
|
25692
|
+
border-color: rgba(34, 197, 94, 0.24);
|
|
25693
|
+
background: rgba(34, 197, 94, 0.055);
|
|
25694
|
+
}
|
|
25695
|
+
.vr-provider-mcp-panel.is-connected header > span {
|
|
25696
|
+
background: rgba(34, 197, 94, 0.12);
|
|
25697
|
+
color: #86efac;
|
|
25698
|
+
}
|
|
25699
|
+
.vr-bottom-inventory .vr-provider-mcp-chip {
|
|
25700
|
+
grid-column: 3;
|
|
25701
|
+
grid-row: 1;
|
|
25702
|
+
justify-self: end;
|
|
25703
|
+
min-width: 0;
|
|
25704
|
+
width: 8px;
|
|
25705
|
+
height: 8px;
|
|
25706
|
+
padding: 0;
|
|
25707
|
+
font-size: 0;
|
|
25708
|
+
}
|
|
25745
25709
|
.vr-bottom-inventory .vr-provider-proof-chip {
|
|
25746
25710
|
grid-column: 4;
|
|
25747
25711
|
justify-self: end;
|
|
@@ -25763,13 +25727,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
25763
25727
|
height: 15px;
|
|
25764
25728
|
stroke-width: 2.35;
|
|
25765
25729
|
}
|
|
25766
|
-
.vr-bottom-inventory .vr-provider-light {
|
|
25767
|
-
right: 36px;
|
|
25768
|
-
top: 50%;
|
|
25769
|
-
width: 7px;
|
|
25770
|
-
height: 7px;
|
|
25771
|
-
transform: translateY(-50%);
|
|
25772
|
-
}
|
|
25773
25730
|
.vr-bottom-inventory .vr-provider-card:hover .vr-provider-proof-chip,
|
|
25774
25731
|
.vr-bottom-inventory .vr-provider-card.is-selected .vr-provider-proof-chip {
|
|
25775
25732
|
background: transparent;
|
|
@@ -26364,33 +26321,48 @@ body:has(.vr-app.is-dragging) {
|
|
|
26364
26321
|
width: 18px;
|
|
26365
26322
|
height: 18px;
|
|
26366
26323
|
}
|
|
26324
|
+
.vr-bottom-tip-bar .vr-inline-brand-mark.is-github {
|
|
26325
|
+
display: inline-grid;
|
|
26326
|
+
place-items: center;
|
|
26327
|
+
color: #f8fafc;
|
|
26328
|
+
}
|
|
26329
|
+
.vr-bottom-tip-bar .vr-inline-brand-mark.is-github svg {
|
|
26330
|
+
width: 17px;
|
|
26331
|
+
height: 17px;
|
|
26332
|
+
display: block;
|
|
26333
|
+
fill: currentColor;
|
|
26334
|
+
}
|
|
26367
26335
|
.vr-tip-mascot {
|
|
26336
|
+
width: 34px;
|
|
26337
|
+
height: 34px;
|
|
26368
26338
|
align-self: stretch;
|
|
26369
26339
|
position: relative;
|
|
26370
26340
|
display: grid;
|
|
26371
26341
|
place-items: end center;
|
|
26372
26342
|
overflow: hidden;
|
|
26343
|
+
border-right: 1px solid rgba(148, 163, 184, 0.16);
|
|
26373
26344
|
}
|
|
26374
26345
|
.vr-tip-mascot::before {
|
|
26375
26346
|
content: "";
|
|
26376
26347
|
position: absolute;
|
|
26377
|
-
left:
|
|
26378
|
-
right:
|
|
26379
|
-
bottom:
|
|
26380
|
-
height:
|
|
26348
|
+
left: 8px;
|
|
26349
|
+
right: 8px;
|
|
26350
|
+
bottom: 2px;
|
|
26351
|
+
height: 10px;
|
|
26381
26352
|
border-radius: 999px;
|
|
26382
|
-
background: rgba(124, 58, 237, 0.
|
|
26383
|
-
filter: blur(
|
|
26353
|
+
background: rgba(124, 58, 237, 0.24);
|
|
26354
|
+
filter: blur(8px);
|
|
26384
26355
|
}
|
|
26385
26356
|
.vr-tip-mascot img {
|
|
26386
26357
|
position: relative;
|
|
26358
|
+
z-index: 1;
|
|
26387
26359
|
align-self: end;
|
|
26388
|
-
width:
|
|
26389
|
-
height:
|
|
26360
|
+
width: 32px;
|
|
26361
|
+
height: 32px;
|
|
26390
26362
|
object-fit: contain;
|
|
26391
26363
|
object-position: bottom;
|
|
26392
|
-
transform: translateY(
|
|
26393
|
-
filter: saturate(1.
|
|
26364
|
+
transform: translateY(3px);
|
|
26365
|
+
filter: saturate(1.16) drop-shadow(0 0 12px rgba(168, 85, 247, 0.46));
|
|
26394
26366
|
}
|
|
26395
26367
|
.vr-bottom-tip-bar span {
|
|
26396
26368
|
color: #cbd5e1;
|
|
@@ -26713,6 +26685,18 @@ body:has(.vr-app.is-dragging) {
|
|
|
26713
26685
|
box-shadow: var(--vr-glow-purple);
|
|
26714
26686
|
transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1), box-shadow 200ms ease;
|
|
26715
26687
|
}
|
|
26688
|
+
.vr-modal-provider-logo.is-logo-html {
|
|
26689
|
+
display: grid;
|
|
26690
|
+
place-items: center;
|
|
26691
|
+
}
|
|
26692
|
+
.vr-modal-provider-logo.is-logo-html img,
|
|
26693
|
+
.vr-modal-provider-logo.is-logo-html svg,
|
|
26694
|
+
.vr-modal-provider-logo.is-logo-html .vr-provider-logo {
|
|
26695
|
+
width: 74px;
|
|
26696
|
+
height: 74px;
|
|
26697
|
+
display: block;
|
|
26698
|
+
object-fit: contain;
|
|
26699
|
+
}
|
|
26716
26700
|
|
|
26717
26701
|
.vr-modal-provider-logo:hover {
|
|
26718
26702
|
transform: translateY(-3px) rotate(-2deg);
|
|
@@ -28058,46 +28042,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
28058
28042
|
display: none;
|
|
28059
28043
|
}
|
|
28060
28044
|
}
|
|
28061
|
-
.vr-permission-toggle {
|
|
28062
|
-
display: inline-flex;
|
|
28063
|
-
align-items: center;
|
|
28064
|
-
gap: 0;
|
|
28065
|
-
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
28066
|
-
border-radius: 8px;
|
|
28067
|
-
overflow: hidden;
|
|
28068
|
-
background: rgba(39, 40, 44, 0.92);
|
|
28069
|
-
}
|
|
28070
|
-
.vr-permission-btn {
|
|
28071
|
-
min-height: 28px;
|
|
28072
|
-
padding: 0 10px;
|
|
28073
|
-
font-size: 11px;
|
|
28074
|
-
font-weight: 640;
|
|
28075
|
-
color: #94a3b8;
|
|
28076
|
-
background: transparent;
|
|
28077
|
-
border: none;
|
|
28078
|
-
border-radius: 0;
|
|
28079
|
-
cursor: pointer;
|
|
28080
|
-
transition: background 0.12s, color 0.12s;
|
|
28081
|
-
white-space: nowrap;
|
|
28082
|
-
}
|
|
28083
|
-
.vr-permission-btn + .vr-permission-btn {
|
|
28084
|
-
border-left: 1px solid rgba(148, 163, 184, 0.14);
|
|
28085
|
-
}
|
|
28086
|
-
.vr-permission-btn.is-active {
|
|
28087
|
-
background: rgba(100, 116, 139, 0.28);
|
|
28088
|
-
color: #f1f5f9;
|
|
28089
|
-
}
|
|
28090
|
-
.vr-permission-btn.is-danger {
|
|
28091
|
-
color: #f59e0b;
|
|
28092
|
-
}
|
|
28093
|
-
.vr-permission-btn.is-danger.is-active {
|
|
28094
|
-
background: rgba(245, 158, 11, 0.18);
|
|
28095
|
-
color: #fbbf24;
|
|
28096
|
-
}
|
|
28097
|
-
.vr-permission-btn:hover:not(.is-active) {
|
|
28098
|
-
background: rgba(148, 163, 184, 0.1);
|
|
28099
|
-
color: #e2e8f0;
|
|
28100
|
-
}
|
|
28101
28045
|
`;
|
|
28102
28046
|
}
|
|
28103
28047
|
});
|
|
@@ -28114,8 +28058,9 @@ function renderLocalUiHtml(state) {
|
|
|
28114
28058
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
28115
28059
|
<meta name="theme-color" content="#050816" />
|
|
28116
28060
|
<title>VibeRaven</title>
|
|
28117
|
-
<link rel="icon" type="image/png" href="/report/assets/viberaven-
|
|
28118
|
-
<link rel="
|
|
28061
|
+
<link rel="icon" type="image/png" sizes="64x64" href="/report/assets/viberaven-favicon.png" />
|
|
28062
|
+
<link rel="shortcut icon" type="image/png" href="/report/assets/viberaven-favicon.png" />
|
|
28063
|
+
<link rel="apple-touch-icon" href="/report/assets/viberaven-mascot.png" />
|
|
28119
28064
|
<style>${localUiCss}</style>
|
|
28120
28065
|
</head>
|
|
28121
28066
|
<body>
|
|
@@ -28378,6 +28323,19 @@ async function releaseChangelogBetween(cwd, fromRef, toRef) {
|
|
|
28378
28323
|
});
|
|
28379
28324
|
return { from: fromRef, to: toRef, fromLabel: fromRef, toLabel: toRef, entries };
|
|
28380
28325
|
}
|
|
28326
|
+
async function releaseDiffContextBlock(cwd, releaseId) {
|
|
28327
|
+
const ref = safeGitRef(releaseId);
|
|
28328
|
+
if (!ref || ref === "workspace") return void 0;
|
|
28329
|
+
if (!await gitRefExists(cwd, ref)) return void 0;
|
|
28330
|
+
const comparison = await compareReleaseRefs(cwd, ref, "HEAD");
|
|
28331
|
+
const stats = comparison.stats;
|
|
28332
|
+
const diffPreview = comparison.diff.length > 6e3 ? comparison.diff.slice(0, 6e3) + "\n[diff truncated]" : comparison.diff;
|
|
28333
|
+
return [
|
|
28334
|
+
`Attached release diff (${comparison.fromLabel} -> ${comparison.toLabel}):`,
|
|
28335
|
+
`Files changed: ${stats.files}; insertions: ${stats.insertions}; deletions: ${stats.deletions}`,
|
|
28336
|
+
diffPreview
|
|
28337
|
+
].join("\n");
|
|
28338
|
+
}
|
|
28381
28339
|
async function rollbackReleaseRef(cwd, targetRef) {
|
|
28382
28340
|
if (!await gitRefExists(cwd, targetRef)) {
|
|
28383
28341
|
return { ok: false, message: `Release ref "${targetRef}" was not found in this repo.`, checkedOut: "" };
|
|
@@ -28570,7 +28528,7 @@ async function detectLocalCliAgents(cwd, options = {}) {
|
|
|
28570
28528
|
return {
|
|
28571
28529
|
...agent,
|
|
28572
28530
|
installed,
|
|
28573
|
-
connected:
|
|
28531
|
+
connected: agent.id === "terminal",
|
|
28574
28532
|
source: simulateDisconnected ? "simulated" : installed ? "detected" : "fallback",
|
|
28575
28533
|
models: cliModelDefaults(agent.id),
|
|
28576
28534
|
setup: CLI_AGENT_SETUP[agent.id]
|
|
@@ -28588,6 +28546,60 @@ function isPlaceholderProjectName(value) {
|
|
|
28588
28546
|
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
28589
28547
|
return normalized === "" || normalized === "project" || normalized === "npx-open-source-check" || normalized.startsWith("viberaven-local-ui");
|
|
28590
28548
|
}
|
|
28549
|
+
async function readMcpEvidence(cwd) {
|
|
28550
|
+
const candidates = MCP_CONFIG_PATHS.map((relativePath) => ({
|
|
28551
|
+
source: relativePath.replace(/\\/g, "/"),
|
|
28552
|
+
path: (0, import_node_path31.resolve)(cwd, relativePath)
|
|
28553
|
+
}));
|
|
28554
|
+
const home = process.env.USERPROFILE || process.env.HOME;
|
|
28555
|
+
if (home) {
|
|
28556
|
+
candidates.push({
|
|
28557
|
+
source: "~/.codex/config.toml",
|
|
28558
|
+
path: (0, import_node_path31.resolve)(home, ".codex", "config.toml")
|
|
28559
|
+
});
|
|
28560
|
+
}
|
|
28561
|
+
const evidence = [];
|
|
28562
|
+
for (const candidate of candidates) {
|
|
28563
|
+
try {
|
|
28564
|
+
const text = await (0, import_promises24.readFile)(candidate.path, "utf8");
|
|
28565
|
+
if (/mcp/i.test(text)) evidence.push({ source: candidate.source, text });
|
|
28566
|
+
} catch {
|
|
28567
|
+
}
|
|
28568
|
+
}
|
|
28569
|
+
return evidence;
|
|
28570
|
+
}
|
|
28571
|
+
function mcpForProvider(provider2, evidence) {
|
|
28572
|
+
const needles = MCP_PROVIDER_NEEDLES[provider2.id] ?? [provider2.id];
|
|
28573
|
+
const match = evidence.find((item4) => {
|
|
28574
|
+
const lower = item4.text.toLowerCase();
|
|
28575
|
+
return needles.some((needle) => lower.includes(needle.toLowerCase()));
|
|
28576
|
+
});
|
|
28577
|
+
if (match) {
|
|
28578
|
+
return {
|
|
28579
|
+
status: "connected",
|
|
28580
|
+
label: "MCP connected",
|
|
28581
|
+
source: match.source,
|
|
28582
|
+
connectCommand: MCP_CONNECT_COMMANDS[provider2.id],
|
|
28583
|
+
capabilities: ["repo context", provider2.area, "provider-aware chat"]
|
|
28584
|
+
};
|
|
28585
|
+
}
|
|
28586
|
+
return {
|
|
28587
|
+
status: "disconnected",
|
|
28588
|
+
label: "Connect MCP",
|
|
28589
|
+
connectCommand: MCP_CONNECT_COMMANDS[provider2.id] ?? `Add a ${provider2.name} MCP server entry, then drag ${provider2.name} into chat.`,
|
|
28590
|
+
capabilities: []
|
|
28591
|
+
};
|
|
28592
|
+
}
|
|
28593
|
+
async function applyMcpDetection(state, cwd) {
|
|
28594
|
+
const evidence = await readMcpEvidence(cwd);
|
|
28595
|
+
return {
|
|
28596
|
+
...state,
|
|
28597
|
+
providers: state.providers.map((provider2) => ({
|
|
28598
|
+
...provider2,
|
|
28599
|
+
mcp: mcpForProvider(provider2, evidence)
|
|
28600
|
+
}))
|
|
28601
|
+
};
|
|
28602
|
+
}
|
|
28591
28603
|
async function enrichProjectMetadata(state, cwd) {
|
|
28592
28604
|
const packageJson = await readPackageJson2(cwd);
|
|
28593
28605
|
const metadata = {
|
|
@@ -28596,7 +28608,7 @@ async function enrichProjectMetadata(state, cwd) {
|
|
|
28596
28608
|
};
|
|
28597
28609
|
const files = await listProjectFiles(cwd);
|
|
28598
28610
|
const deps = dependencyNames(packageJson);
|
|
28599
|
-
const detectedState = state.empty ? applyProviderDetection(state, deps, files) : state;
|
|
28611
|
+
const detectedState = await applyMcpDetection(state.empty ? applyProviderDetection(state, deps, files) : state, cwd);
|
|
28600
28612
|
const releases = await detectReleases(cwd, metadata.version);
|
|
28601
28613
|
const missionCards = state.empty ? buildMissionCards(
|
|
28602
28614
|
{
|
|
@@ -28707,19 +28719,19 @@ function parseAgentChatRequest(value) {
|
|
|
28707
28719
|
if (rawCliId !== "codex" && rawCliId !== "claude" && rawCliId !== "gemini") return { error: "Unsupported coding CLI" };
|
|
28708
28720
|
const prompt = stringField(value.prompt, 12e3);
|
|
28709
28721
|
if (!prompt) return { error: "Agent chat prompt is required" };
|
|
28710
|
-
const provider2 = isRecord7(value.provider) ? { area: stringField(value.provider.area, 120), name: stringField(value.provider.name, 120) } : void 0;
|
|
28711
|
-
const release = isRecord7(value.release) ? { label: stringField(value.release.label, 120) } : void 0;
|
|
28712
|
-
const
|
|
28713
|
-
const
|
|
28722
|
+
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;
|
|
28723
|
+
const release = isRecord7(value.release) ? { id: stringField(value.release.id, 200), label: stringField(value.release.label, 120) } : void 0;
|
|
28724
|
+
const requestedAccessMode = stringField(value.accessMode, 40);
|
|
28725
|
+
const accessMode = requestedAccessMode === "ask" || requestedAccessMode === "approve" || requestedAccessMode === "full" ? requestedAccessMode : "approve";
|
|
28714
28726
|
return {
|
|
28715
28727
|
cliId: rawCliId,
|
|
28716
28728
|
modelId: stringField(value.modelId, 120),
|
|
28717
28729
|
reasoning: stringField(value.reasoning, 80),
|
|
28718
28730
|
context: stringField(value.context, 80),
|
|
28731
|
+
accessMode,
|
|
28719
28732
|
prompt,
|
|
28720
28733
|
displayPrompt: stringField(value.displayPrompt, 240),
|
|
28721
28734
|
taskKind: stringField(value.taskKind, 40),
|
|
28722
|
-
permissionMode,
|
|
28723
28735
|
provider: provider2,
|
|
28724
28736
|
release
|
|
28725
28737
|
};
|
|
@@ -28762,22 +28774,28 @@ async function buildAgentChatPrompt(request, cwd) {
|
|
|
28762
28774
|
const state = await readState(cwd);
|
|
28763
28775
|
const executionBlock = taskKindExecutionBlock(request.taskKind);
|
|
28764
28776
|
const cardsBlock = missionCardsContextBlock(state);
|
|
28777
|
+
const providerState2 = request.provider?.id ? state.providers.find((provider2) => provider2.id === request.provider?.id) : state.providers.find((provider2) => provider2.name === request.provider?.name);
|
|
28778
|
+
const mcp = providerState2?.mcp;
|
|
28779
|
+
const releaseDiffBlock = await releaseDiffContextBlock(cwd, request.release?.id);
|
|
28765
28780
|
const lines = [
|
|
28766
28781
|
"You are VibeRaven Studio, a production-readiness coding agent for an open-source local runner.",
|
|
28767
28782
|
`Project folder: ${cwd}`,
|
|
28768
28783
|
request.modelId ? `Selected model label: ${request.modelId}` : void 0,
|
|
28769
28784
|
request.reasoning ? `Reasoning: ${request.reasoning}` : void 0,
|
|
28770
28785
|
request.context ? `Context: ${request.context}` : void 0,
|
|
28786
|
+
`Access mode: ${request.accessMode ?? "approve"}`,
|
|
28771
28787
|
request.provider?.name ? `Provider context: ${request.provider.area ?? "Provider"} / ${request.provider.name}` : void 0,
|
|
28788
|
+
mcp ? `Provider MCP: ${mcp.label}${mcp.source ? ` (${mcp.source})` : ""}` : void 0,
|
|
28772
28789
|
request.release?.label ? `Release context: ${request.release.label}` : void 0,
|
|
28773
|
-
|
|
28790
|
+
releaseDiffBlock,
|
|
28791
|
+
state.gate?.label ? `Project status: ${state.gate.label} (${state.gate.status ?? "unknown"})` : void 0,
|
|
28774
28792
|
state.missionControl?.mainBlocker ? `Main blocker: ${state.missionControl.mainBlocker}` : void 0,
|
|
28775
28793
|
executionBlock,
|
|
28776
28794
|
cardsBlock,
|
|
28777
28795
|
"",
|
|
28778
28796
|
"Safety rules:",
|
|
28779
28797
|
"- Stay scoped to this project folder.",
|
|
28780
|
-
"-
|
|
28798
|
+
(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.",
|
|
28781
28799
|
"- Do not claim provider dashboard setup is complete from repo edits alone.",
|
|
28782
28800
|
"- Keep the answer focused on production readiness.",
|
|
28783
28801
|
"- Return only the final user-facing answer. Do not echo this prompt, session metadata, logs, or command transcripts.",
|
|
@@ -28811,24 +28829,19 @@ function insertCodexExecOptions(codexArgs, pairs) {
|
|
|
28811
28829
|
const insertAt = execIndex >= 0 ? execIndex + 1 : codexArgs.length;
|
|
28812
28830
|
codexArgs.splice(insertAt, 0, ...pairs);
|
|
28813
28831
|
}
|
|
28814
|
-
function
|
|
28815
|
-
if (
|
|
28816
|
-
|
|
28817
|
-
|
|
28818
|
-
if (platform === "win32") {
|
|
28819
|
-
return ["--sandbox", "danger-full-access", "--ask-for-approval", "on-request"];
|
|
28820
|
-
}
|
|
28821
|
-
return ["--sandbox", "workspace-write", "--ask-for-approval", "on-request"];
|
|
28832
|
+
function codexAccessFlags(accessMode) {
|
|
28833
|
+
if (accessMode === "ask") return ["--sandbox", "workspace-write", "--ask-for-approval", "on-request"];
|
|
28834
|
+
if (accessMode === "full") return ["--sandbox", "danger-full-access", "--ask-for-approval", "never"];
|
|
28835
|
+
return ["--sandbox", "workspace-write", "--ask-for-approval", "on-failure"];
|
|
28822
28836
|
}
|
|
28823
|
-
function commandForAgentChat(request, prompt, cwd, outputPath
|
|
28824
|
-
const command = platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
|
|
28837
|
+
function commandForAgentChat(request, prompt, cwd, outputPath) {
|
|
28838
|
+
const command = process.platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
|
|
28825
28839
|
const promptArg = prompt.replace(/\s*\r?\n\s*/g, " ");
|
|
28826
28840
|
const model = normalizeCliModelId(request.modelId);
|
|
28827
28841
|
const effort = resolveCliReasoningEffort(request.cliId, request.reasoning);
|
|
28828
|
-
const permissionMode = request.permissionMode ?? "ask";
|
|
28829
28842
|
if (request.cliId === "gemini") {
|
|
28830
28843
|
const geminiArgs = ["-p", promptArg, "--output-format", "text"];
|
|
28831
|
-
if (
|
|
28844
|
+
if (request.accessMode !== "ask") geminiArgs.push("--skip-trust");
|
|
28832
28845
|
if (model) geminiArgs.splice(0, 0, "-m", model);
|
|
28833
28846
|
return { command, args: geminiArgs };
|
|
28834
28847
|
}
|
|
@@ -28836,13 +28849,12 @@ function commandForAgentChat(request, prompt, cwd, outputPath, platform = proces
|
|
|
28836
28849
|
const claudeArgs = ["-p", promptArg];
|
|
28837
28850
|
if (model) claudeArgs.unshift("--model", model);
|
|
28838
28851
|
if (effort) claudeArgs.unshift("--effort", effort);
|
|
28839
|
-
if (
|
|
28852
|
+
if (request.accessMode === "full") {
|
|
28840
28853
|
claudeArgs.push("--dangerously-skip-permissions");
|
|
28841
28854
|
}
|
|
28842
28855
|
return { command, args: claudeArgs };
|
|
28843
28856
|
}
|
|
28844
|
-
const
|
|
28845
|
-
const codexArgs = ["--cd", cwd, ...sandboxArgs, "exec", "--color", "never"];
|
|
28857
|
+
const codexArgs = ["--cd", cwd, ...codexAccessFlags(request.accessMode), "exec", "--color", "never"];
|
|
28846
28858
|
const codexExecOptions = [];
|
|
28847
28859
|
if (model) codexExecOptions.push("-m", model);
|
|
28848
28860
|
if (effort) codexExecOptions.push("-c", `model_reasoning_effort="${effort}"`);
|
|
@@ -28983,7 +28995,7 @@ async function runLocalAction(cwd, intent) {
|
|
|
28983
28995
|
"# VibeRaven preview rehearsal",
|
|
28984
28996
|
"",
|
|
28985
28997
|
`Project: ${projectName}`,
|
|
28986
|
-
`
|
|
28998
|
+
`Project status: ${gateLabel}`,
|
|
28987
28999
|
`Blocker: ${blocker}`,
|
|
28988
29000
|
"",
|
|
28989
29001
|
"## Recording flow",
|
|
@@ -29583,7 +29595,7 @@ async function waitForServerShutdown() {
|
|
|
29583
29595
|
process.once("SIGTERM", done);
|
|
29584
29596
|
});
|
|
29585
29597
|
}
|
|
29586
|
-
var import_node_http, import_node_child_process4, import_promises24, import_node_path31, CLI_AGENT_SETUP, CLI_AUTH_PROBE;
|
|
29598
|
+
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;
|
|
29587
29599
|
var init_server = __esm({
|
|
29588
29600
|
"src/local-ui/server.ts"() {
|
|
29589
29601
|
"use strict";
|
|
@@ -29624,6 +29636,30 @@ var init_server = __esm({
|
|
|
29624
29636
|
docsUrl: "https://viberaven.dev"
|
|
29625
29637
|
}
|
|
29626
29638
|
};
|
|
29639
|
+
MCP_CONFIG_PATHS = [
|
|
29640
|
+
".mcp.json",
|
|
29641
|
+
"mcp.json",
|
|
29642
|
+
(0, import_node_path31.join)(".cursor", "mcp.json"),
|
|
29643
|
+
(0, import_node_path31.join)(".vscode", "mcp.json")
|
|
29644
|
+
];
|
|
29645
|
+
MCP_PROVIDER_NEEDLES = {
|
|
29646
|
+
supabase: ["supabase", "@supabase/mcp", "mcp-server-supabase"],
|
|
29647
|
+
vercel: ["vercel"],
|
|
29648
|
+
stripe: ["stripe"],
|
|
29649
|
+
github: ["github"],
|
|
29650
|
+
sentry: ["sentry"],
|
|
29651
|
+
posthog: ["posthog"],
|
|
29652
|
+
clerk: ["clerk"],
|
|
29653
|
+
authjs: ["authjs", "next-auth", "nextauth"],
|
|
29654
|
+
resend: ["resend"],
|
|
29655
|
+
upstash: ["upstash"]
|
|
29656
|
+
};
|
|
29657
|
+
MCP_CONNECT_COMMANDS = {
|
|
29658
|
+
supabase: "Add the Supabase MCP server to your local MCP config, then drag Supabase into chat.",
|
|
29659
|
+
vercel: "Add a Vercel MCP server entry to your local MCP config, then drag Vercel into chat.",
|
|
29660
|
+
stripe: "Add a Stripe MCP server entry to your local MCP config, then drag Stripe into chat.",
|
|
29661
|
+
github: "Add the GitHub MCP server to your local MCP config, then drag GitHub into chat."
|
|
29662
|
+
};
|
|
29627
29663
|
CLI_AUTH_PROBE = {
|
|
29628
29664
|
codex: "codex login status",
|
|
29629
29665
|
claude: "claude auth status",
|
|
@@ -29646,11 +29682,7 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29646
29682
|
return {
|
|
29647
29683
|
...base,
|
|
29648
29684
|
type: "stalled",
|
|
29649
|
-
title: "Loop stalled
|
|
29650
|
-
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.",
|
|
29651
|
-
executionPlan: [
|
|
29652
|
-
{ kind: "stop", note: "Do not keep spending scans while the loop is stalled." }
|
|
29653
|
-
],
|
|
29685
|
+
title: "Loop stalled \u2014 no gap reduction after 2+ consecutive scans",
|
|
29654
29686
|
requiresUserAction: true,
|
|
29655
29687
|
stallReason
|
|
29656
29688
|
};
|
|
@@ -29659,67 +29691,42 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29659
29691
|
return {
|
|
29660
29692
|
...base,
|
|
29661
29693
|
type: "verify",
|
|
29662
|
-
title: "Batch complete
|
|
29663
|
-
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.",
|
|
29664
|
-
executionPlan: [
|
|
29665
|
-
{ kind: "verify", command: "viberaven_verify" },
|
|
29666
|
-
{ kind: "continue-loop", note: "After verify, continue until the gate is clear or a provider/user blocker remains." }
|
|
29667
|
-
],
|
|
29694
|
+
title: "Batch complete \u2014 run verify to rescan before next batch",
|
|
29668
29695
|
mcpTool: "viberaven_verify",
|
|
29669
29696
|
mcpArgs: {},
|
|
29670
29697
|
requiresUserAction: false
|
|
29671
29698
|
};
|
|
29672
29699
|
}
|
|
29673
|
-
const repoCodeTask = tasks.find((
|
|
29700
|
+
const repoCodeTask = tasks.find((t) => t.fixType === "repo-code" && !t.requiresUserAction);
|
|
29674
29701
|
if (repoCodeTask) {
|
|
29675
|
-
const fallbackCommand = repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0;
|
|
29676
29702
|
return {
|
|
29677
29703
|
...base,
|
|
29678
29704
|
type: "repo-code",
|
|
29679
29705
|
gapId: repoCodeTask.gapId,
|
|
29680
29706
|
title: repoCodeTask.title,
|
|
29681
|
-
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.",
|
|
29682
|
-
executionPlan: [
|
|
29683
|
-
{
|
|
29684
|
-
kind: "apply-repo-fix",
|
|
29685
|
-
command: repoCodeTask.mcpTool ?? fallbackCommand,
|
|
29686
|
-
note: "Patch only this gap and preserve unrelated user changes."
|
|
29687
|
-
},
|
|
29688
|
-
{ kind: "continue-loop", note: "Apply remaining safe repo fixes until the batch is full, then verify once." }
|
|
29689
|
-
],
|
|
29690
29707
|
mcpTool: repoCodeTask.mcpTool,
|
|
29691
29708
|
mcpArgs: repoCodeTask.mcpArgs,
|
|
29692
|
-
fallbackCommand,
|
|
29709
|
+
fallbackCommand: repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0,
|
|
29693
29710
|
requiresUserAction: false
|
|
29694
29711
|
};
|
|
29695
29712
|
}
|
|
29696
|
-
const providerTask = tasks.find((
|
|
29713
|
+
const providerTask = tasks.find((t) => t.fixType === "provider-action");
|
|
29697
29714
|
if (providerTask) {
|
|
29698
29715
|
return {
|
|
29699
29716
|
...base,
|
|
29700
29717
|
type: "provider-action",
|
|
29701
29718
|
gapId: providerTask.gapId,
|
|
29702
29719
|
title: providerTask.title,
|
|
29703
|
-
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.",
|
|
29704
|
-
executionPlan: [
|
|
29705
|
-
{ kind: "open-provider-step", note: "Use VIBERAVEN_PROVIDER_ACTION for the exact dashboard step and URL." },
|
|
29706
|
-
{ kind: "wait-for-user", note: "Wait for confirmation or read-only MCP evidence before verifying." }
|
|
29707
|
-
],
|
|
29708
29720
|
requiresUserAction: true
|
|
29709
29721
|
};
|
|
29710
29722
|
}
|
|
29711
|
-
const upgradeTask = tasks.find((
|
|
29723
|
+
const upgradeTask = tasks.find((t) => t.fixType === "upgrade-required");
|
|
29712
29724
|
if (upgradeTask) {
|
|
29713
29725
|
return {
|
|
29714
29726
|
...base,
|
|
29715
29727
|
type: "upgrade-required",
|
|
29716
29728
|
gapId: upgradeTask.gapId,
|
|
29717
29729
|
title: upgradeTask.title,
|
|
29718
|
-
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.",
|
|
29719
|
-
executionPlan: [
|
|
29720
|
-
{ kind: "upgrade", command: "https://viberaven.dev/pricing" },
|
|
29721
|
-
{ kind: "stop", note: "Do not pretend locked lanes or provider state were fixed locally." }
|
|
29722
|
-
],
|
|
29723
29730
|
requiresUserAction: true,
|
|
29724
29731
|
upgradeUrl: "https://viberaven.dev/pricing"
|
|
29725
29732
|
};
|
|
@@ -29727,20 +29734,15 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29727
29734
|
return {
|
|
29728
29735
|
...base,
|
|
29729
29736
|
type: "done",
|
|
29730
|
-
title: "All gaps resolved
|
|
29731
|
-
agentInstruction: "The repo-code gate is clear. Run strict before deploy and still verify provider dashboard state through MCP or the provider dashboard.",
|
|
29732
|
-
executionPlan: [
|
|
29733
|
-
{ kind: "verify", command: "npx -y viberaven --strict" },
|
|
29734
|
-
{ kind: "stop", note: "Do not deploy until provider dashboard state is verified where applicable." }
|
|
29735
|
-
],
|
|
29737
|
+
title: "All gaps resolved \u2014 production gate is clear",
|
|
29736
29738
|
requiresUserAction: false
|
|
29737
29739
|
};
|
|
29738
29740
|
}
|
|
29739
29741
|
function resolveStallReason(tasks) {
|
|
29740
29742
|
if (tasks.length === 0) return "no-recipes";
|
|
29741
|
-
const allUpgradeOrEmpty = tasks.every((
|
|
29743
|
+
const allUpgradeOrEmpty = tasks.every((t) => t.fixType === "upgrade-required");
|
|
29742
29744
|
if (allUpgradeOrEmpty) return "no-recipes";
|
|
29743
|
-
const allProviderAction = tasks.every((
|
|
29745
|
+
const allProviderAction = tasks.every((t) => t.fixType === "provider-action");
|
|
29744
29746
|
if (allProviderAction) return "provider-action-required";
|
|
29745
29747
|
return "unknown";
|
|
29746
29748
|
}
|
|
@@ -29765,7 +29767,7 @@ function buildProviderActionBlock(task) {
|
|
|
29765
29767
|
}
|
|
29766
29768
|
function printProviderActionBlock(tasks) {
|
|
29767
29769
|
const task = tasks.find(
|
|
29768
|
-
(
|
|
29770
|
+
(t) => t.fixType === "provider-action" && t.requiresUserAction === true
|
|
29769
29771
|
);
|
|
29770
29772
|
if (!task) return;
|
|
29771
29773
|
const block = buildProviderActionBlock(task);
|
|
@@ -29914,6 +29916,7 @@ Usage:
|
|
|
29914
29916
|
viberaven Open the local launch console for human TTY use
|
|
29915
29917
|
|
|
29916
29918
|
viberaven ui [path] Open the local launch console
|
|
29919
|
+
|
|
29917
29920
|
viberaven tui Same interactive menu
|
|
29918
29921
|
|
|
29919
29922
|
viberaven login [--api-url <url>]
|
|
@@ -30022,9 +30025,6 @@ function parseArgs(argv) {
|
|
|
30022
30025
|
if (arg.startsWith("--")) {
|
|
30023
30026
|
const equalsIndex = arg.indexOf("=");
|
|
30024
30027
|
const key = equalsIndex === -1 ? arg.slice(2) : arg.slice(2, equalsIndex);
|
|
30025
|
-
if (key === "pet") {
|
|
30026
|
-
continue;
|
|
30027
|
-
}
|
|
30028
30028
|
if (equalsIndex !== -1) {
|
|
30029
30029
|
flags[key] = arg.slice(equalsIndex + 1);
|
|
30030
30030
|
continue;
|
|
@@ -30120,9 +30120,6 @@ function resolveDefaultEntrypointMode(options) {
|
|
|
30120
30120
|
if (options.env.VIBERAVEN_AGENT === "1") return "agent-scan";
|
|
30121
30121
|
return "local-ui";
|
|
30122
30122
|
}
|
|
30123
|
-
function resolvePositionalCwd(positional) {
|
|
30124
|
-
return positional[0] ? (0, import_node_path33.resolve)(process.cwd(), positional[0]) : process.cwd();
|
|
30125
|
-
}
|
|
30126
30123
|
function formatScanJsonStdout(artifact) {
|
|
30127
30124
|
return JSON.stringify(sanitizeArtifactForDisk(artifact), null, 2);
|
|
30128
30125
|
}
|
|
@@ -30163,7 +30160,7 @@ async function cmdStatus(flags, positional) {
|
|
|
30163
30160
|
console.log("Not signed in. Run: viberaven login");
|
|
30164
30161
|
return 1;
|
|
30165
30162
|
}
|
|
30166
|
-
const startDir =
|
|
30163
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30167
30164
|
let artifact;
|
|
30168
30165
|
try {
|
|
30169
30166
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -30317,7 +30314,7 @@ async function cmdWatch(flags) {
|
|
|
30317
30314
|
}
|
|
30318
30315
|
}
|
|
30319
30316
|
async function runScanCommand(flags, positional, options) {
|
|
30320
|
-
const workspacePath = positional[0] ?
|
|
30317
|
+
const workspacePath = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : await resolveWorkspaceRoot(process.cwd());
|
|
30321
30318
|
const apiBaseUrl = resolveApiBaseUrl(typeof flags["api-url"] === "string" ? flags["api-url"] : void 0);
|
|
30322
30319
|
let accessToken;
|
|
30323
30320
|
try {
|
|
@@ -30401,7 +30398,7 @@ async function runScanCommand(flags, positional, options) {
|
|
|
30401
30398
|
return { exitCode: 0, artifacts: paths };
|
|
30402
30399
|
}
|
|
30403
30400
|
async function cmdReport(flags, positional) {
|
|
30404
|
-
const startDir =
|
|
30401
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30405
30402
|
try {
|
|
30406
30403
|
const paths = await refreshReportFromDisk(startDir);
|
|
30407
30404
|
console.log(`Report refreshed: ${paths.reportPath}`);
|
|
@@ -30423,7 +30420,7 @@ async function cmdReport(flags, positional) {
|
|
|
30423
30420
|
}
|
|
30424
30421
|
}
|
|
30425
30422
|
async function cmdPrompt(flags, positional) {
|
|
30426
|
-
const startDir =
|
|
30423
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30427
30424
|
let artifact;
|
|
30428
30425
|
try {
|
|
30429
30426
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -30520,7 +30517,7 @@ async function main() {
|
|
|
30520
30517
|
const wantsJsonl = hasFlag(flags, "jsonl");
|
|
30521
30518
|
const wantsStrict = hasFlag(flags, "strict");
|
|
30522
30519
|
if (flags.condense) {
|
|
30523
|
-
const cwd =
|
|
30520
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30524
30521
|
const result = await runCondenseCommand({ cwd });
|
|
30525
30522
|
console.log(`VibeRaven context map refreshed: ${result.contextMapPath}`);
|
|
30526
30523
|
return 0;
|
|
@@ -30540,7 +30537,7 @@ async function main() {
|
|
|
30540
30537
|
}
|
|
30541
30538
|
if (!command && flags.verify === true && typeof flags.action === "string") {
|
|
30542
30539
|
return runVerifyActionCommand({
|
|
30543
|
-
cwd:
|
|
30540
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30544
30541
|
actionId: flags.action
|
|
30545
30542
|
});
|
|
30546
30543
|
}
|
|
@@ -30577,7 +30574,7 @@ async function main() {
|
|
|
30577
30574
|
env: process.env
|
|
30578
30575
|
});
|
|
30579
30576
|
if (mode === "local-ui") {
|
|
30580
|
-
const cwd =
|
|
30577
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30581
30578
|
const handle = await startLocalUiServer({ cwd });
|
|
30582
30579
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
30583
30580
|
await waitForServerShutdown();
|
|
@@ -30597,7 +30594,7 @@ async function main() {
|
|
|
30597
30594
|
await runInteractiveSession();
|
|
30598
30595
|
return 0;
|
|
30599
30596
|
case "ui": {
|
|
30600
|
-
const cwd =
|
|
30597
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30601
30598
|
const handle = await startLocalUiServer({ cwd });
|
|
30602
30599
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
30603
30600
|
await waitForServerShutdown();
|
|
@@ -30614,19 +30611,19 @@ async function main() {
|
|
|
30614
30611
|
return cmdStatus(flags, positional);
|
|
30615
30612
|
case "actions":
|
|
30616
30613
|
return runActionsCommand({
|
|
30617
|
-
cwd:
|
|
30614
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30618
30615
|
json: Boolean(flags.json)
|
|
30619
30616
|
});
|
|
30620
30617
|
case "preview":
|
|
30621
30618
|
return runPreviewCommand({
|
|
30622
|
-
cwd:
|
|
30619
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30623
30620
|
agentMode: flags["agent-mode"] === true,
|
|
30624
30621
|
json: Boolean(flags.json)
|
|
30625
30622
|
});
|
|
30626
30623
|
case "next":
|
|
30627
30624
|
return runNextCommand({
|
|
30628
30625
|
json: Boolean(flags.json),
|
|
30629
|
-
cwd:
|
|
30626
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd()
|
|
30630
30627
|
});
|
|
30631
30628
|
case "guide": {
|
|
30632
30629
|
const provider2 = positional[0];
|
|
@@ -30664,7 +30661,7 @@ async function main() {
|
|
|
30664
30661
|
case "provider-verify":
|
|
30665
30662
|
return cmdProviderVerify(flags, positional);
|
|
30666
30663
|
case "init": {
|
|
30667
|
-
const cwd =
|
|
30664
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30668
30665
|
const agents = typeof flags.agents === "string" ? flags.agents : void 0;
|
|
30669
30666
|
return runInitCommand({
|
|
30670
30667
|
cwd,
|
|
@@ -30678,7 +30675,7 @@ async function main() {
|
|
|
30678
30675
|
return 1;
|
|
30679
30676
|
}
|
|
30680
30677
|
return runDoctorAgentsCommand({
|
|
30681
|
-
cwd:
|
|
30678
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd()
|
|
30682
30679
|
});
|
|
30683
30680
|
case "validate-npm-package":
|
|
30684
30681
|
return runValidateNpmPackageCommand({
|
|
@@ -30691,7 +30688,7 @@ async function main() {
|
|
|
30691
30688
|
return 1;
|
|
30692
30689
|
}
|
|
30693
30690
|
return runAuditCommand({
|
|
30694
|
-
cwd:
|
|
30691
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30695
30692
|
json: Boolean(flags.json)
|
|
30696
30693
|
});
|
|
30697
30694
|
default:
|