@viberaven/cli 1.2.3 → 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 +73 -33
- 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 +559 -550
- 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
|
-
|
|
18856
|
-
const ctaClass = 'vr-cli-action-button is-primary' + (ctaPending ? ' is-pending' : '');
|
|
18857
|
-
return '<p class="vr-cli-setup-cta-hint">After sign-in, click <strong>Test connection</strong> \u2014 chat only works once verified.</p>' +
|
|
18858
|
-
'<div class="vr-cli-connect-expand-actions">' +
|
|
18682
|
+
return '<div class="vr-cli-connect-expand-actions">' +
|
|
18859
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>' +
|
|
18860
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>' +
|
|
18861
|
-
'<button class="
|
|
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>' +
|
|
18862
18686
|
'</div>' +
|
|
18863
|
-
'<p class="vr-cli-setup-hint">
|
|
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,21 +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: 0 0 6px;
|
|
23773
|
-
color: #94a3b8;
|
|
23774
|
-
font-size: 11px;
|
|
23775
|
-
font-weight: 500;
|
|
23776
|
-
line-height: 1.35;
|
|
23777
|
-
}
|
|
23778
|
-
.vr-cli-setup-cta-hint strong {
|
|
23779
|
-
color: #c4b5fd;
|
|
23780
|
-
font-weight: 650;
|
|
23781
|
-
}
|
|
23782
|
-
.vr-cli-action-button.is-primary.is-pending {
|
|
23783
|
-
border-color: rgba(168, 85, 247, 0.55);
|
|
23784
|
-
box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.25);
|
|
23785
|
-
}
|
|
23786
23607
|
.vr-cli-strip button.is-connect-target {
|
|
23787
23608
|
border-color: rgba(248, 250, 252, 0.34);
|
|
23788
23609
|
box-shadow: inset 0 0 0 1px rgba(248, 250, 252, 0.08);
|
|
@@ -24507,16 +24328,15 @@ body:has(.vr-app.is-dragging) {
|
|
|
24507
24328
|
border-color: rgba(168, 85, 247, 0.38);
|
|
24508
24329
|
}
|
|
24509
24330
|
.vr-plan-step-num {
|
|
24510
|
-
width:
|
|
24511
|
-
height:
|
|
24331
|
+
width: 10px;
|
|
24332
|
+
height: 10px;
|
|
24512
24333
|
flex: 0 0 auto;
|
|
24513
24334
|
display: grid;
|
|
24514
24335
|
place-items: center;
|
|
24515
|
-
border: 1px solid rgba(168, 85, 247, 0.
|
|
24336
|
+
border: 1px solid rgba(168, 85, 247, 0.5);
|
|
24516
24337
|
border-radius: 999px;
|
|
24517
|
-
|
|
24518
|
-
|
|
24519
|
-
font-weight: 700;
|
|
24338
|
+
background: rgba(168, 85, 247, 0.28);
|
|
24339
|
+
box-shadow: 0 0 10px rgba(168, 85, 247, 0.22);
|
|
24520
24340
|
}
|
|
24521
24341
|
.vr-plan-step-body {
|
|
24522
24342
|
flex: 1 1 0;
|
|
@@ -25128,6 +24948,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
25128
24948
|
.vr-model-menu.is-context {
|
|
25129
24949
|
right: 0;
|
|
25130
24950
|
}
|
|
24951
|
+
.vr-model-menu.is-access {
|
|
24952
|
+
right: 0;
|
|
24953
|
+
min-width: 270px;
|
|
24954
|
+
}
|
|
25131
24955
|
.vr-studio-chat.is-split .vr-model-menu {
|
|
25132
24956
|
bottom: calc(100% + 10px);
|
|
25133
24957
|
min-width: min(245px, calc(100vw - 32px));
|
|
@@ -25144,6 +24968,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
25144
24968
|
left: auto;
|
|
25145
24969
|
right: 0;
|
|
25146
24970
|
}
|
|
24971
|
+
.vr-studio-chat.is-split .vr-model-menu.is-access {
|
|
24972
|
+
left: auto;
|
|
24973
|
+
right: 0;
|
|
24974
|
+
}
|
|
25147
24975
|
.vr-model-menu p {
|
|
25148
24976
|
margin: 2px 4px 6px;
|
|
25149
24977
|
color: #a8a29e;
|
|
@@ -25288,7 +25116,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
25288
25116
|
}
|
|
25289
25117
|
.vr-bottom-inventory .vr-provider-card {
|
|
25290
25118
|
min-height: 48px;
|
|
25291
|
-
grid-template-columns: 34px minmax(0, 1fr)
|
|
25119
|
+
grid-template-columns: 34px minmax(0, 1fr) 18px 22px;
|
|
25292
25120
|
grid-template-rows: 1fr;
|
|
25293
25121
|
align-items: center;
|
|
25294
25122
|
gap: 8px;
|
|
@@ -25345,14 +25173,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
25345
25173
|
fill: none !important;
|
|
25346
25174
|
stroke: currentColor !important;
|
|
25347
25175
|
}
|
|
25348
|
-
.vr-bottom-inventory .vr-provider-light {
|
|
25349
|
-
right: 36px;
|
|
25350
|
-
top: 50%;
|
|
25351
|
-
width: 7px;
|
|
25352
|
-
height: 7px;
|
|
25353
|
-
transform: translateY(-50%);
|
|
25354
|
-
box-shadow: 0 0 9px rgba(34, 197, 94, 0.42);
|
|
25355
|
-
}
|
|
25356
25176
|
.vr-bottom-inventory .vr-provider-card .vr-status-badge {
|
|
25357
25177
|
grid-column: 3;
|
|
25358
25178
|
min-height: 18px;
|
|
@@ -25639,8 +25459,35 @@ body:has(.vr-app.is-dragging) {
|
|
|
25639
25459
|
filter: saturate(1.04) contrast(1.02);
|
|
25640
25460
|
transition: transform 180ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
25641
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
|
+
}
|
|
25642
25487
|
.vr-provider-card:hover .vr-provider-token img,
|
|
25643
|
-
.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 {
|
|
25644
25491
|
transform: scale(1.08);
|
|
25645
25492
|
}
|
|
25646
25493
|
.vr-provider-token.is-picker {
|
|
@@ -25661,15 +25508,11 @@ body:has(.vr-app.is-dragging) {
|
|
|
25661
25508
|
width: 34px;
|
|
25662
25509
|
height: 34px;
|
|
25663
25510
|
}
|
|
25664
|
-
.vr-provider-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
25669
|
-
height: 8px;
|
|
25670
|
-
border-radius: 999px;
|
|
25671
|
-
background: var(--vr-green);
|
|
25672
|
-
box-shadow: 0 0 8px rgba(34, 197, 94, 0.36);
|
|
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;
|
|
25673
25516
|
}
|
|
25674
25517
|
.vr-provider-card small,
|
|
25675
25518
|
.vr-provider-card strong,
|
|
@@ -25699,6 +25542,15 @@ body:has(.vr-app.is-dragging) {
|
|
|
25699
25542
|
font-size: 11px;
|
|
25700
25543
|
font-weight: 520;
|
|
25701
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
|
+
}
|
|
25702
25554
|
.vr-provider-proof-chip {
|
|
25703
25555
|
grid-column: 1 / -1;
|
|
25704
25556
|
display: inline-flex;
|
|
@@ -25730,6 +25582,130 @@ body:has(.vr-app.is-dragging) {
|
|
|
25730
25582
|
height: 13px;
|
|
25731
25583
|
stroke: currentColor;
|
|
25732
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
|
+
}
|
|
25733
25709
|
.vr-bottom-inventory .vr-provider-proof-chip {
|
|
25734
25710
|
grid-column: 4;
|
|
25735
25711
|
justify-self: end;
|
|
@@ -25751,13 +25727,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
25751
25727
|
height: 15px;
|
|
25752
25728
|
stroke-width: 2.35;
|
|
25753
25729
|
}
|
|
25754
|
-
.vr-bottom-inventory .vr-provider-light {
|
|
25755
|
-
right: 36px;
|
|
25756
|
-
top: 50%;
|
|
25757
|
-
width: 7px;
|
|
25758
|
-
height: 7px;
|
|
25759
|
-
transform: translateY(-50%);
|
|
25760
|
-
}
|
|
25761
25730
|
.vr-bottom-inventory .vr-provider-card:hover .vr-provider-proof-chip,
|
|
25762
25731
|
.vr-bottom-inventory .vr-provider-card.is-selected .vr-provider-proof-chip {
|
|
25763
25732
|
background: transparent;
|
|
@@ -26352,33 +26321,48 @@ body:has(.vr-app.is-dragging) {
|
|
|
26352
26321
|
width: 18px;
|
|
26353
26322
|
height: 18px;
|
|
26354
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
|
+
}
|
|
26355
26335
|
.vr-tip-mascot {
|
|
26336
|
+
width: 34px;
|
|
26337
|
+
height: 34px;
|
|
26356
26338
|
align-self: stretch;
|
|
26357
26339
|
position: relative;
|
|
26358
26340
|
display: grid;
|
|
26359
26341
|
place-items: end center;
|
|
26360
26342
|
overflow: hidden;
|
|
26343
|
+
border-right: 1px solid rgba(148, 163, 184, 0.16);
|
|
26361
26344
|
}
|
|
26362
26345
|
.vr-tip-mascot::before {
|
|
26363
26346
|
content: "";
|
|
26364
26347
|
position: absolute;
|
|
26365
|
-
left:
|
|
26366
|
-
right:
|
|
26367
|
-
bottom:
|
|
26368
|
-
height:
|
|
26348
|
+
left: 8px;
|
|
26349
|
+
right: 8px;
|
|
26350
|
+
bottom: 2px;
|
|
26351
|
+
height: 10px;
|
|
26369
26352
|
border-radius: 999px;
|
|
26370
|
-
background: rgba(124, 58, 237, 0.
|
|
26371
|
-
filter: blur(
|
|
26353
|
+
background: rgba(124, 58, 237, 0.24);
|
|
26354
|
+
filter: blur(8px);
|
|
26372
26355
|
}
|
|
26373
26356
|
.vr-tip-mascot img {
|
|
26374
26357
|
position: relative;
|
|
26358
|
+
z-index: 1;
|
|
26375
26359
|
align-self: end;
|
|
26376
|
-
width:
|
|
26377
|
-
height:
|
|
26360
|
+
width: 32px;
|
|
26361
|
+
height: 32px;
|
|
26378
26362
|
object-fit: contain;
|
|
26379
26363
|
object-position: bottom;
|
|
26380
|
-
transform: translateY(
|
|
26381
|
-
filter: saturate(1.
|
|
26364
|
+
transform: translateY(3px);
|
|
26365
|
+
filter: saturate(1.16) drop-shadow(0 0 12px rgba(168, 85, 247, 0.46));
|
|
26382
26366
|
}
|
|
26383
26367
|
.vr-bottom-tip-bar span {
|
|
26384
26368
|
color: #cbd5e1;
|
|
@@ -26701,6 +26685,18 @@ body:has(.vr-app.is-dragging) {
|
|
|
26701
26685
|
box-shadow: var(--vr-glow-purple);
|
|
26702
26686
|
transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1), box-shadow 200ms ease;
|
|
26703
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
|
+
}
|
|
26704
26700
|
|
|
26705
26701
|
.vr-modal-provider-logo:hover {
|
|
26706
26702
|
transform: translateY(-3px) rotate(-2deg);
|
|
@@ -28046,46 +28042,6 @@ body:has(.vr-app.is-dragging) {
|
|
|
28046
28042
|
display: none;
|
|
28047
28043
|
}
|
|
28048
28044
|
}
|
|
28049
|
-
.vr-permission-toggle {
|
|
28050
|
-
display: inline-flex;
|
|
28051
|
-
align-items: center;
|
|
28052
|
-
gap: 0;
|
|
28053
|
-
border: 1px solid rgba(148, 163, 184, 0.18);
|
|
28054
|
-
border-radius: 8px;
|
|
28055
|
-
overflow: hidden;
|
|
28056
|
-
background: rgba(39, 40, 44, 0.92);
|
|
28057
|
-
}
|
|
28058
|
-
.vr-permission-btn {
|
|
28059
|
-
min-height: 28px;
|
|
28060
|
-
padding: 0 10px;
|
|
28061
|
-
font-size: 11px;
|
|
28062
|
-
font-weight: 640;
|
|
28063
|
-
color: #94a3b8;
|
|
28064
|
-
background: transparent;
|
|
28065
|
-
border: none;
|
|
28066
|
-
border-radius: 0;
|
|
28067
|
-
cursor: pointer;
|
|
28068
|
-
transition: background 0.12s, color 0.12s;
|
|
28069
|
-
white-space: nowrap;
|
|
28070
|
-
}
|
|
28071
|
-
.vr-permission-btn + .vr-permission-btn {
|
|
28072
|
-
border-left: 1px solid rgba(148, 163, 184, 0.14);
|
|
28073
|
-
}
|
|
28074
|
-
.vr-permission-btn.is-active {
|
|
28075
|
-
background: rgba(100, 116, 139, 0.28);
|
|
28076
|
-
color: #f1f5f9;
|
|
28077
|
-
}
|
|
28078
|
-
.vr-permission-btn.is-danger {
|
|
28079
|
-
color: #f59e0b;
|
|
28080
|
-
}
|
|
28081
|
-
.vr-permission-btn.is-danger.is-active {
|
|
28082
|
-
background: rgba(245, 158, 11, 0.18);
|
|
28083
|
-
color: #fbbf24;
|
|
28084
|
-
}
|
|
28085
|
-
.vr-permission-btn:hover:not(.is-active) {
|
|
28086
|
-
background: rgba(148, 163, 184, 0.1);
|
|
28087
|
-
color: #e2e8f0;
|
|
28088
|
-
}
|
|
28089
28045
|
`;
|
|
28090
28046
|
}
|
|
28091
28047
|
});
|
|
@@ -28102,8 +28058,9 @@ function renderLocalUiHtml(state) {
|
|
|
28102
28058
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
28103
28059
|
<meta name="theme-color" content="#050816" />
|
|
28104
28060
|
<title>VibeRaven</title>
|
|
28105
|
-
<link rel="icon" type="image/png" href="/report/assets/viberaven-
|
|
28106
|
-
<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" />
|
|
28107
28064
|
<style>${localUiCss}</style>
|
|
28108
28065
|
</head>
|
|
28109
28066
|
<body>
|
|
@@ -28366,6 +28323,19 @@ async function releaseChangelogBetween(cwd, fromRef, toRef) {
|
|
|
28366
28323
|
});
|
|
28367
28324
|
return { from: fromRef, to: toRef, fromLabel: fromRef, toLabel: toRef, entries };
|
|
28368
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
|
+
}
|
|
28369
28339
|
async function rollbackReleaseRef(cwd, targetRef) {
|
|
28370
28340
|
if (!await gitRefExists(cwd, targetRef)) {
|
|
28371
28341
|
return { ok: false, message: `Release ref "${targetRef}" was not found in this repo.`, checkedOut: "" };
|
|
@@ -28558,7 +28528,7 @@ async function detectLocalCliAgents(cwd, options = {}) {
|
|
|
28558
28528
|
return {
|
|
28559
28529
|
...agent,
|
|
28560
28530
|
installed,
|
|
28561
|
-
connected:
|
|
28531
|
+
connected: agent.id === "terminal",
|
|
28562
28532
|
source: simulateDisconnected ? "simulated" : installed ? "detected" : "fallback",
|
|
28563
28533
|
models: cliModelDefaults(agent.id),
|
|
28564
28534
|
setup: CLI_AGENT_SETUP[agent.id]
|
|
@@ -28576,6 +28546,60 @@ function isPlaceholderProjectName(value) {
|
|
|
28576
28546
|
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
28577
28547
|
return normalized === "" || normalized === "project" || normalized === "npx-open-source-check" || normalized.startsWith("viberaven-local-ui");
|
|
28578
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
|
+
}
|
|
28579
28603
|
async function enrichProjectMetadata(state, cwd) {
|
|
28580
28604
|
const packageJson = await readPackageJson2(cwd);
|
|
28581
28605
|
const metadata = {
|
|
@@ -28584,7 +28608,7 @@ async function enrichProjectMetadata(state, cwd) {
|
|
|
28584
28608
|
};
|
|
28585
28609
|
const files = await listProjectFiles(cwd);
|
|
28586
28610
|
const deps = dependencyNames(packageJson);
|
|
28587
|
-
const detectedState = state.empty ? applyProviderDetection(state, deps, files) : state;
|
|
28611
|
+
const detectedState = await applyMcpDetection(state.empty ? applyProviderDetection(state, deps, files) : state, cwd);
|
|
28588
28612
|
const releases = await detectReleases(cwd, metadata.version);
|
|
28589
28613
|
const missionCards = state.empty ? buildMissionCards(
|
|
28590
28614
|
{
|
|
@@ -28695,19 +28719,19 @@ function parseAgentChatRequest(value) {
|
|
|
28695
28719
|
if (rawCliId !== "codex" && rawCliId !== "claude" && rawCliId !== "gemini") return { error: "Unsupported coding CLI" };
|
|
28696
28720
|
const prompt = stringField(value.prompt, 12e3);
|
|
28697
28721
|
if (!prompt) return { error: "Agent chat prompt is required" };
|
|
28698
|
-
const provider2 = isRecord7(value.provider) ? { area: stringField(value.provider.area, 120), name: stringField(value.provider.name, 120) } : void 0;
|
|
28699
|
-
const release = isRecord7(value.release) ? { label: stringField(value.release.label, 120) } : void 0;
|
|
28700
|
-
const
|
|
28701
|
-
const
|
|
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";
|
|
28702
28726
|
return {
|
|
28703
28727
|
cliId: rawCliId,
|
|
28704
28728
|
modelId: stringField(value.modelId, 120),
|
|
28705
28729
|
reasoning: stringField(value.reasoning, 80),
|
|
28706
28730
|
context: stringField(value.context, 80),
|
|
28731
|
+
accessMode,
|
|
28707
28732
|
prompt,
|
|
28708
28733
|
displayPrompt: stringField(value.displayPrompt, 240),
|
|
28709
28734
|
taskKind: stringField(value.taskKind, 40),
|
|
28710
|
-
permissionMode,
|
|
28711
28735
|
provider: provider2,
|
|
28712
28736
|
release
|
|
28713
28737
|
};
|
|
@@ -28750,22 +28774,28 @@ async function buildAgentChatPrompt(request, cwd) {
|
|
|
28750
28774
|
const state = await readState(cwd);
|
|
28751
28775
|
const executionBlock = taskKindExecutionBlock(request.taskKind);
|
|
28752
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);
|
|
28753
28780
|
const lines = [
|
|
28754
28781
|
"You are VibeRaven Studio, a production-readiness coding agent for an open-source local runner.",
|
|
28755
28782
|
`Project folder: ${cwd}`,
|
|
28756
28783
|
request.modelId ? `Selected model label: ${request.modelId}` : void 0,
|
|
28757
28784
|
request.reasoning ? `Reasoning: ${request.reasoning}` : void 0,
|
|
28758
28785
|
request.context ? `Context: ${request.context}` : void 0,
|
|
28786
|
+
`Access mode: ${request.accessMode ?? "approve"}`,
|
|
28759
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,
|
|
28760
28789
|
request.release?.label ? `Release context: ${request.release.label}` : void 0,
|
|
28761
|
-
|
|
28790
|
+
releaseDiffBlock,
|
|
28791
|
+
state.gate?.label ? `Project status: ${state.gate.label} (${state.gate.status ?? "unknown"})` : void 0,
|
|
28762
28792
|
state.missionControl?.mainBlocker ? `Main blocker: ${state.missionControl.mainBlocker}` : void 0,
|
|
28763
28793
|
executionBlock,
|
|
28764
28794
|
cardsBlock,
|
|
28765
28795
|
"",
|
|
28766
28796
|
"Safety rules:",
|
|
28767
28797
|
"- Stay scoped to this project folder.",
|
|
28768
|
-
"-
|
|
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.",
|
|
28769
28799
|
"- Do not claim provider dashboard setup is complete from repo edits alone.",
|
|
28770
28800
|
"- Keep the answer focused on production readiness.",
|
|
28771
28801
|
"- Return only the final user-facing answer. Do not echo this prompt, session metadata, logs, or command transcripts.",
|
|
@@ -28799,24 +28829,19 @@ function insertCodexExecOptions(codexArgs, pairs) {
|
|
|
28799
28829
|
const insertAt = execIndex >= 0 ? execIndex + 1 : codexArgs.length;
|
|
28800
28830
|
codexArgs.splice(insertAt, 0, ...pairs);
|
|
28801
28831
|
}
|
|
28802
|
-
function
|
|
28803
|
-
if (
|
|
28804
|
-
|
|
28805
|
-
|
|
28806
|
-
if (platform === "win32") {
|
|
28807
|
-
return ["--sandbox", "danger-full-access", "--ask-for-approval", "on-request"];
|
|
28808
|
-
}
|
|
28809
|
-
return ["--sandbox", "workspace-write", "--ask-for-approval", "on-request"];
|
|
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"];
|
|
28810
28836
|
}
|
|
28811
|
-
function commandForAgentChat(request, prompt, cwd, outputPath
|
|
28812
|
-
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;
|
|
28813
28839
|
const promptArg = prompt.replace(/\s*\r?\n\s*/g, " ");
|
|
28814
28840
|
const model = normalizeCliModelId(request.modelId);
|
|
28815
28841
|
const effort = resolveCliReasoningEffort(request.cliId, request.reasoning);
|
|
28816
|
-
const permissionMode = request.permissionMode ?? "ask";
|
|
28817
28842
|
if (request.cliId === "gemini") {
|
|
28818
28843
|
const geminiArgs = ["-p", promptArg, "--output-format", "text"];
|
|
28819
|
-
if (
|
|
28844
|
+
if (request.accessMode !== "ask") geminiArgs.push("--skip-trust");
|
|
28820
28845
|
if (model) geminiArgs.splice(0, 0, "-m", model);
|
|
28821
28846
|
return { command, args: geminiArgs };
|
|
28822
28847
|
}
|
|
@@ -28824,13 +28849,12 @@ function commandForAgentChat(request, prompt, cwd, outputPath, platform = proces
|
|
|
28824
28849
|
const claudeArgs = ["-p", promptArg];
|
|
28825
28850
|
if (model) claudeArgs.unshift("--model", model);
|
|
28826
28851
|
if (effort) claudeArgs.unshift("--effort", effort);
|
|
28827
|
-
if (
|
|
28852
|
+
if (request.accessMode === "full") {
|
|
28828
28853
|
claudeArgs.push("--dangerously-skip-permissions");
|
|
28829
28854
|
}
|
|
28830
28855
|
return { command, args: claudeArgs };
|
|
28831
28856
|
}
|
|
28832
|
-
const
|
|
28833
|
-
const codexArgs = ["--cd", cwd, ...sandboxArgs, "exec", "--color", "never"];
|
|
28857
|
+
const codexArgs = ["--cd", cwd, ...codexAccessFlags(request.accessMode), "exec", "--color", "never"];
|
|
28834
28858
|
const codexExecOptions = [];
|
|
28835
28859
|
if (model) codexExecOptions.push("-m", model);
|
|
28836
28860
|
if (effort) codexExecOptions.push("-c", `model_reasoning_effort="${effort}"`);
|
|
@@ -28971,7 +28995,7 @@ async function runLocalAction(cwd, intent) {
|
|
|
28971
28995
|
"# VibeRaven preview rehearsal",
|
|
28972
28996
|
"",
|
|
28973
28997
|
`Project: ${projectName}`,
|
|
28974
|
-
`
|
|
28998
|
+
`Project status: ${gateLabel}`,
|
|
28975
28999
|
`Blocker: ${blocker}`,
|
|
28976
29000
|
"",
|
|
28977
29001
|
"## Recording flow",
|
|
@@ -29571,7 +29595,7 @@ async function waitForServerShutdown() {
|
|
|
29571
29595
|
process.once("SIGTERM", done);
|
|
29572
29596
|
});
|
|
29573
29597
|
}
|
|
29574
|
-
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;
|
|
29575
29599
|
var init_server = __esm({
|
|
29576
29600
|
"src/local-ui/server.ts"() {
|
|
29577
29601
|
"use strict";
|
|
@@ -29612,6 +29636,30 @@ var init_server = __esm({
|
|
|
29612
29636
|
docsUrl: "https://viberaven.dev"
|
|
29613
29637
|
}
|
|
29614
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
|
+
};
|
|
29615
29663
|
CLI_AUTH_PROBE = {
|
|
29616
29664
|
codex: "codex login status",
|
|
29617
29665
|
claude: "claude auth status",
|
|
@@ -29634,11 +29682,7 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29634
29682
|
return {
|
|
29635
29683
|
...base,
|
|
29636
29684
|
type: "stalled",
|
|
29637
|
-
title: "Loop stalled
|
|
29638
|
-
agentInstruction: "Stop the scan loop. Explain the blocker plainly, then either guide the provider/user action or report that no safe repo-code recipe is available.",
|
|
29639
|
-
executionPlan: [
|
|
29640
|
-
{ kind: "stop", note: "Do not keep spending scans while the loop is stalled." }
|
|
29641
|
-
],
|
|
29685
|
+
title: "Loop stalled \u2014 no gap reduction after 2+ consecutive scans",
|
|
29642
29686
|
requiresUserAction: true,
|
|
29643
29687
|
stallReason
|
|
29644
29688
|
};
|
|
@@ -29647,67 +29691,42 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29647
29691
|
return {
|
|
29648
29692
|
...base,
|
|
29649
29693
|
type: "verify",
|
|
29650
|
-
title: "Batch complete
|
|
29651
|
-
agentInstruction: "Run verify now, read the refreshed VibeRaven artifacts, then continue with the next safe repo fix or provider step. Do not stop at a summary.",
|
|
29652
|
-
executionPlan: [
|
|
29653
|
-
{ kind: "verify", command: "viberaven_verify" },
|
|
29654
|
-
{ kind: "continue-loop", note: "After verify, continue until the gate is clear or a provider/user blocker remains." }
|
|
29655
|
-
],
|
|
29694
|
+
title: "Batch complete \u2014 run verify to rescan before next batch",
|
|
29656
29695
|
mcpTool: "viberaven_verify",
|
|
29657
29696
|
mcpArgs: {},
|
|
29658
29697
|
requiresUserAction: false
|
|
29659
29698
|
};
|
|
29660
29699
|
}
|
|
29661
|
-
const repoCodeTask = tasks.find((
|
|
29700
|
+
const repoCodeTask = tasks.find((t) => t.fixType === "repo-code" && !t.requiresUserAction);
|
|
29662
29701
|
if (repoCodeTask) {
|
|
29663
|
-
const fallbackCommand = repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0;
|
|
29664
29702
|
return {
|
|
29665
29703
|
...base,
|
|
29666
29704
|
type: "repo-code",
|
|
29667
29705
|
gapId: repoCodeTask.gapId,
|
|
29668
29706
|
title: repoCodeTask.title,
|
|
29669
|
-
agentInstruction: "Apply this repo-code fix now using the MCP tool or fallback command, then continue the local VibeRaven loop. Do not stop at a summary.",
|
|
29670
|
-
executionPlan: [
|
|
29671
|
-
{
|
|
29672
|
-
kind: "apply-repo-fix",
|
|
29673
|
-
command: repoCodeTask.mcpTool ?? fallbackCommand,
|
|
29674
|
-
note: "Patch only this gap and preserve unrelated user changes."
|
|
29675
|
-
},
|
|
29676
|
-
{ kind: "continue-loop", note: "Apply remaining safe repo fixes until the batch is full, then verify once." }
|
|
29677
|
-
],
|
|
29678
29707
|
mcpTool: repoCodeTask.mcpTool,
|
|
29679
29708
|
mcpArgs: repoCodeTask.mcpArgs,
|
|
29680
|
-
fallbackCommand,
|
|
29709
|
+
fallbackCommand: repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0,
|
|
29681
29710
|
requiresUserAction: false
|
|
29682
29711
|
};
|
|
29683
29712
|
}
|
|
29684
|
-
const providerTask = tasks.find((
|
|
29713
|
+
const providerTask = tasks.find((t) => t.fixType === "provider-action");
|
|
29685
29714
|
if (providerTask) {
|
|
29686
29715
|
return {
|
|
29687
29716
|
...base,
|
|
29688
29717
|
type: "provider-action",
|
|
29689
29718
|
gapId: providerTask.gapId,
|
|
29690
29719
|
title: providerTask.title,
|
|
29691
|
-
agentInstruction: "Open or present the provider step now. If browser/tool access is available, open the dashboard link for the user; otherwise show the exact step and copy values. Do not keep telling the user to verify until the provider step is done.",
|
|
29692
|
-
executionPlan: [
|
|
29693
|
-
{ kind: "open-provider-step", note: "Use VIBERAVEN_PROVIDER_ACTION for the exact dashboard step and URL." },
|
|
29694
|
-
{ kind: "wait-for-user", note: "Wait for confirmation or read-only MCP evidence before verifying." }
|
|
29695
|
-
],
|
|
29696
29720
|
requiresUserAction: true
|
|
29697
29721
|
};
|
|
29698
29722
|
}
|
|
29699
|
-
const upgradeTask = tasks.find((
|
|
29723
|
+
const upgradeTask = tasks.find((t) => t.fixType === "upgrade-required");
|
|
29700
29724
|
if (upgradeTask) {
|
|
29701
29725
|
return {
|
|
29702
29726
|
...base,
|
|
29703
29727
|
type: "upgrade-required",
|
|
29704
29728
|
gapId: upgradeTask.gapId,
|
|
29705
29729
|
title: upgradeTask.title,
|
|
29706
|
-
agentInstruction: "Explain that this production lane needs an upgrade or connected provider evidence. Continue with any remaining unlocked repo-code fixes if present; otherwise stop cleanly.",
|
|
29707
|
-
executionPlan: [
|
|
29708
|
-
{ kind: "upgrade", command: "https://viberaven.dev/pricing" },
|
|
29709
|
-
{ kind: "stop", note: "Do not pretend locked lanes or provider state were fixed locally." }
|
|
29710
|
-
],
|
|
29711
29730
|
requiresUserAction: true,
|
|
29712
29731
|
upgradeUrl: "https://viberaven.dev/pricing"
|
|
29713
29732
|
};
|
|
@@ -29715,20 +29734,15 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
29715
29734
|
return {
|
|
29716
29735
|
...base,
|
|
29717
29736
|
type: "done",
|
|
29718
|
-
title: "All gaps resolved
|
|
29719
|
-
agentInstruction: "The repo-code gate is clear. Run strict before deploy and still verify provider dashboard state through MCP or the provider dashboard.",
|
|
29720
|
-
executionPlan: [
|
|
29721
|
-
{ kind: "verify", command: "npx -y viberaven --strict" },
|
|
29722
|
-
{ kind: "stop", note: "Do not deploy until provider dashboard state is verified where applicable." }
|
|
29723
|
-
],
|
|
29737
|
+
title: "All gaps resolved \u2014 production gate is clear",
|
|
29724
29738
|
requiresUserAction: false
|
|
29725
29739
|
};
|
|
29726
29740
|
}
|
|
29727
29741
|
function resolveStallReason(tasks) {
|
|
29728
29742
|
if (tasks.length === 0) return "no-recipes";
|
|
29729
|
-
const allUpgradeOrEmpty = tasks.every((
|
|
29743
|
+
const allUpgradeOrEmpty = tasks.every((t) => t.fixType === "upgrade-required");
|
|
29730
29744
|
if (allUpgradeOrEmpty) return "no-recipes";
|
|
29731
|
-
const allProviderAction = tasks.every((
|
|
29745
|
+
const allProviderAction = tasks.every((t) => t.fixType === "provider-action");
|
|
29732
29746
|
if (allProviderAction) return "provider-action-required";
|
|
29733
29747
|
return "unknown";
|
|
29734
29748
|
}
|
|
@@ -29753,7 +29767,7 @@ function buildProviderActionBlock(task) {
|
|
|
29753
29767
|
}
|
|
29754
29768
|
function printProviderActionBlock(tasks) {
|
|
29755
29769
|
const task = tasks.find(
|
|
29756
|
-
(
|
|
29770
|
+
(t) => t.fixType === "provider-action" && t.requiresUserAction === true
|
|
29757
29771
|
);
|
|
29758
29772
|
if (!task) return;
|
|
29759
29773
|
const block = buildProviderActionBlock(task);
|
|
@@ -29902,6 +29916,7 @@ Usage:
|
|
|
29902
29916
|
viberaven Open the local launch console for human TTY use
|
|
29903
29917
|
|
|
29904
29918
|
viberaven ui [path] Open the local launch console
|
|
29919
|
+
|
|
29905
29920
|
viberaven tui Same interactive menu
|
|
29906
29921
|
|
|
29907
29922
|
viberaven login [--api-url <url>]
|
|
@@ -30010,9 +30025,6 @@ function parseArgs(argv) {
|
|
|
30010
30025
|
if (arg.startsWith("--")) {
|
|
30011
30026
|
const equalsIndex = arg.indexOf("=");
|
|
30012
30027
|
const key = equalsIndex === -1 ? arg.slice(2) : arg.slice(2, equalsIndex);
|
|
30013
|
-
if (key === "pet") {
|
|
30014
|
-
continue;
|
|
30015
|
-
}
|
|
30016
30028
|
if (equalsIndex !== -1) {
|
|
30017
30029
|
flags[key] = arg.slice(equalsIndex + 1);
|
|
30018
30030
|
continue;
|
|
@@ -30108,9 +30120,6 @@ function resolveDefaultEntrypointMode(options) {
|
|
|
30108
30120
|
if (options.env.VIBERAVEN_AGENT === "1") return "agent-scan";
|
|
30109
30121
|
return "local-ui";
|
|
30110
30122
|
}
|
|
30111
|
-
function resolvePositionalCwd(positional) {
|
|
30112
|
-
return positional[0] ? (0, import_node_path33.resolve)(process.cwd(), positional[0]) : process.cwd();
|
|
30113
|
-
}
|
|
30114
30123
|
function formatScanJsonStdout(artifact) {
|
|
30115
30124
|
return JSON.stringify(sanitizeArtifactForDisk(artifact), null, 2);
|
|
30116
30125
|
}
|
|
@@ -30151,7 +30160,7 @@ async function cmdStatus(flags, positional) {
|
|
|
30151
30160
|
console.log("Not signed in. Run: viberaven login");
|
|
30152
30161
|
return 1;
|
|
30153
30162
|
}
|
|
30154
|
-
const startDir =
|
|
30163
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30155
30164
|
let artifact;
|
|
30156
30165
|
try {
|
|
30157
30166
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -30305,7 +30314,7 @@ async function cmdWatch(flags) {
|
|
|
30305
30314
|
}
|
|
30306
30315
|
}
|
|
30307
30316
|
async function runScanCommand(flags, positional, options) {
|
|
30308
|
-
const workspacePath = positional[0] ?
|
|
30317
|
+
const workspacePath = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : await resolveWorkspaceRoot(process.cwd());
|
|
30309
30318
|
const apiBaseUrl = resolveApiBaseUrl(typeof flags["api-url"] === "string" ? flags["api-url"] : void 0);
|
|
30310
30319
|
let accessToken;
|
|
30311
30320
|
try {
|
|
@@ -30389,7 +30398,7 @@ async function runScanCommand(flags, positional, options) {
|
|
|
30389
30398
|
return { exitCode: 0, artifacts: paths };
|
|
30390
30399
|
}
|
|
30391
30400
|
async function cmdReport(flags, positional) {
|
|
30392
|
-
const startDir =
|
|
30401
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30393
30402
|
try {
|
|
30394
30403
|
const paths = await refreshReportFromDisk(startDir);
|
|
30395
30404
|
console.log(`Report refreshed: ${paths.reportPath}`);
|
|
@@ -30411,7 +30420,7 @@ async function cmdReport(flags, positional) {
|
|
|
30411
30420
|
}
|
|
30412
30421
|
}
|
|
30413
30422
|
async function cmdPrompt(flags, positional) {
|
|
30414
|
-
const startDir =
|
|
30423
|
+
const startDir = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30415
30424
|
let artifact;
|
|
30416
30425
|
try {
|
|
30417
30426
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -30508,7 +30517,7 @@ async function main() {
|
|
|
30508
30517
|
const wantsJsonl = hasFlag(flags, "jsonl");
|
|
30509
30518
|
const wantsStrict = hasFlag(flags, "strict");
|
|
30510
30519
|
if (flags.condense) {
|
|
30511
|
-
const cwd =
|
|
30520
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30512
30521
|
const result = await runCondenseCommand({ cwd });
|
|
30513
30522
|
console.log(`VibeRaven context map refreshed: ${result.contextMapPath}`);
|
|
30514
30523
|
return 0;
|
|
@@ -30528,7 +30537,7 @@ async function main() {
|
|
|
30528
30537
|
}
|
|
30529
30538
|
if (!command && flags.verify === true && typeof flags.action === "string") {
|
|
30530
30539
|
return runVerifyActionCommand({
|
|
30531
|
-
cwd:
|
|
30540
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30532
30541
|
actionId: flags.action
|
|
30533
30542
|
});
|
|
30534
30543
|
}
|
|
@@ -30565,7 +30574,7 @@ async function main() {
|
|
|
30565
30574
|
env: process.env
|
|
30566
30575
|
});
|
|
30567
30576
|
if (mode === "local-ui") {
|
|
30568
|
-
const cwd =
|
|
30577
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30569
30578
|
const handle = await startLocalUiServer({ cwd });
|
|
30570
30579
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
30571
30580
|
await waitForServerShutdown();
|
|
@@ -30585,7 +30594,7 @@ async function main() {
|
|
|
30585
30594
|
await runInteractiveSession();
|
|
30586
30595
|
return 0;
|
|
30587
30596
|
case "ui": {
|
|
30588
|
-
const cwd =
|
|
30597
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30589
30598
|
const handle = await startLocalUiServer({ cwd });
|
|
30590
30599
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
30591
30600
|
await waitForServerShutdown();
|
|
@@ -30602,19 +30611,19 @@ async function main() {
|
|
|
30602
30611
|
return cmdStatus(flags, positional);
|
|
30603
30612
|
case "actions":
|
|
30604
30613
|
return runActionsCommand({
|
|
30605
|
-
cwd:
|
|
30614
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30606
30615
|
json: Boolean(flags.json)
|
|
30607
30616
|
});
|
|
30608
30617
|
case "preview":
|
|
30609
30618
|
return runPreviewCommand({
|
|
30610
|
-
cwd:
|
|
30619
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30611
30620
|
agentMode: flags["agent-mode"] === true,
|
|
30612
30621
|
json: Boolean(flags.json)
|
|
30613
30622
|
});
|
|
30614
30623
|
case "next":
|
|
30615
30624
|
return runNextCommand({
|
|
30616
30625
|
json: Boolean(flags.json),
|
|
30617
|
-
cwd:
|
|
30626
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd()
|
|
30618
30627
|
});
|
|
30619
30628
|
case "guide": {
|
|
30620
30629
|
const provider2 = positional[0];
|
|
@@ -30652,7 +30661,7 @@ async function main() {
|
|
|
30652
30661
|
case "provider-verify":
|
|
30653
30662
|
return cmdProviderVerify(flags, positional);
|
|
30654
30663
|
case "init": {
|
|
30655
|
-
const cwd =
|
|
30664
|
+
const cwd = positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd();
|
|
30656
30665
|
const agents = typeof flags.agents === "string" ? flags.agents : void 0;
|
|
30657
30666
|
return runInitCommand({
|
|
30658
30667
|
cwd,
|
|
@@ -30666,7 +30675,7 @@ async function main() {
|
|
|
30666
30675
|
return 1;
|
|
30667
30676
|
}
|
|
30668
30677
|
return runDoctorAgentsCommand({
|
|
30669
|
-
cwd:
|
|
30678
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd()
|
|
30670
30679
|
});
|
|
30671
30680
|
case "validate-npm-package":
|
|
30672
30681
|
return runValidateNpmPackageCommand({
|
|
@@ -30679,7 +30688,7 @@ async function main() {
|
|
|
30679
30688
|
return 1;
|
|
30680
30689
|
}
|
|
30681
30690
|
return runAuditCommand({
|
|
30682
|
-
cwd:
|
|
30691
|
+
cwd: positional[0] ? (0, import_node_path33.join)(process.cwd(), positional[0]) : process.cwd(),
|
|
30683
30692
|
json: Boolean(flags.json)
|
|
30684
30693
|
});
|
|
30685
30694
|
default:
|