@viberaven/cli 1.1.13 → 1.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1236 -188
- package/dist/cli.js.map +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -545,12 +545,12 @@ function createAppWindowOpenCommands(target, platform = process.platform, env =
|
|
|
545
545
|
}
|
|
546
546
|
async function openWithSystemDefault(target) {
|
|
547
547
|
const { command, args, shell } = createOpenCommand(target);
|
|
548
|
-
await new Promise((
|
|
548
|
+
await new Promise((resolve7, reject) => {
|
|
549
549
|
const child = (0, import_node_child_process.spawn)(command, args, { stdio: "ignore", shell });
|
|
550
550
|
child.on("error", reject);
|
|
551
551
|
child.on("exit", (code) => {
|
|
552
552
|
if (code === 0) {
|
|
553
|
-
|
|
553
|
+
resolve7();
|
|
554
554
|
} else {
|
|
555
555
|
reject(new Error(`Could not open browser (exit ${code ?? "unknown"}). Open manually: ${target}`));
|
|
556
556
|
}
|
|
@@ -561,7 +561,7 @@ async function spawnDetached(command) {
|
|
|
561
561
|
if (/^[A-Za-z]:[\\/]/.test(command.command) && !(0, import_node_fs2.existsSync)(command.command)) {
|
|
562
562
|
throw new Error(`Browser not found: ${command.command}`);
|
|
563
563
|
}
|
|
564
|
-
await new Promise((
|
|
564
|
+
await new Promise((resolve7, reject) => {
|
|
565
565
|
const child = (0, import_node_child_process.spawn)(command.command, command.args, {
|
|
566
566
|
detached: true,
|
|
567
567
|
stdio: "ignore",
|
|
@@ -569,7 +569,7 @@ async function spawnDetached(command) {
|
|
|
569
569
|
});
|
|
570
570
|
child.once("spawn", () => {
|
|
571
571
|
child.unref();
|
|
572
|
-
|
|
572
|
+
resolve7();
|
|
573
573
|
});
|
|
574
574
|
child.once("error", reject);
|
|
575
575
|
});
|
|
@@ -638,7 +638,7 @@ var init_commands = __esm({
|
|
|
638
638
|
|
|
639
639
|
// src/auth.ts
|
|
640
640
|
function sleep(ms) {
|
|
641
|
-
return new Promise((
|
|
641
|
+
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
642
642
|
}
|
|
643
643
|
async function runDeviceLogin(apiBaseUrl) {
|
|
644
644
|
const signIn = await startManagedSignIn(apiBaseUrl);
|
|
@@ -10442,12 +10442,12 @@ async function copyToClipboard(text) {
|
|
|
10442
10442
|
}
|
|
10443
10443
|
}
|
|
10444
10444
|
function pipeToCommand(command, text, extraArgs = []) {
|
|
10445
|
-
return new Promise((
|
|
10445
|
+
return new Promise((resolve7, reject) => {
|
|
10446
10446
|
const child = (0, import_node_child_process2.spawn)(command, extraArgs, { stdio: ["pipe", "ignore", "ignore"] });
|
|
10447
10447
|
child.on("error", reject);
|
|
10448
10448
|
child.on("close", (code) => {
|
|
10449
10449
|
if (code === 0) {
|
|
10450
|
-
|
|
10450
|
+
resolve7();
|
|
10451
10451
|
} else {
|
|
10452
10452
|
reject(new Error(`${command} exited with code ${code ?? "unknown"}`));
|
|
10453
10453
|
}
|
|
@@ -10925,10 +10925,10 @@ function sleepForRunnerPoll(ms, signal) {
|
|
|
10925
10925
|
if (signal?.aborted) {
|
|
10926
10926
|
return Promise.reject(createRunnerWatchAbortError());
|
|
10927
10927
|
}
|
|
10928
|
-
return new Promise((
|
|
10928
|
+
return new Promise((resolve7, reject) => {
|
|
10929
10929
|
const timer = setTimeout(() => {
|
|
10930
10930
|
cleanup();
|
|
10931
|
-
|
|
10931
|
+
resolve7();
|
|
10932
10932
|
}, ms);
|
|
10933
10933
|
const onAbort = () => {
|
|
10934
10934
|
cleanup();
|
|
@@ -11500,9 +11500,9 @@ function formatRepoMatch(repoMatch) {
|
|
|
11500
11500
|
}
|
|
11501
11501
|
}
|
|
11502
11502
|
async function runCommand(command, args, cwd) {
|
|
11503
|
-
return new Promise((
|
|
11503
|
+
return new Promise((resolve7) => {
|
|
11504
11504
|
(0, import_node_child_process3.execFile)(command, args, { cwd, windowsHide: true }, (error, stdout, stderr) => {
|
|
11505
|
-
|
|
11505
|
+
resolve7({
|
|
11506
11506
|
ok: !error,
|
|
11507
11507
|
stdout: String(stdout ?? ""),
|
|
11508
11508
|
stderr: String(stderr ?? "")
|
|
@@ -12306,7 +12306,7 @@ var VERSION;
|
|
|
12306
12306
|
var init_version = __esm({
|
|
12307
12307
|
"src/version.ts"() {
|
|
12308
12308
|
"use strict";
|
|
12309
|
-
VERSION = "1.1.
|
|
12309
|
+
VERSION = "1.1.14";
|
|
12310
12310
|
}
|
|
12311
12311
|
});
|
|
12312
12312
|
|
|
@@ -16921,6 +16921,56 @@ function emptyLocalUiState(cwd) {
|
|
|
16921
16921
|
...state.project,
|
|
16922
16922
|
name: "Project"
|
|
16923
16923
|
},
|
|
16924
|
+
gate: {
|
|
16925
|
+
...state.gate,
|
|
16926
|
+
status: "unknown",
|
|
16927
|
+
label: "Waiting for project evidence"
|
|
16928
|
+
},
|
|
16929
|
+
providers: state.providers.map((provider2) => ({
|
|
16930
|
+
...provider2,
|
|
16931
|
+
state: "not_detected",
|
|
16932
|
+
statusText: "Add when needed",
|
|
16933
|
+
connectLabel: "Add provider",
|
|
16934
|
+
launchPath: provider2.launchPath.map((item4) => ({
|
|
16935
|
+
...item4,
|
|
16936
|
+
state: "not_checked",
|
|
16937
|
+
shortReason: "Waiting for local evidence"
|
|
16938
|
+
})),
|
|
16939
|
+
selectedItemId: provider2.launchPath[0]?.id,
|
|
16940
|
+
nextFix: provider2.nextFix ? {
|
|
16941
|
+
...provider2.nextFix,
|
|
16942
|
+
title: `Add ${provider2.name} when your app needs it`,
|
|
16943
|
+
whyItMatters: `${provider2.area} is available as a production slot. VibeRaven will use repo evidence before asking for live proof.`,
|
|
16944
|
+
whatToChange: `Drag ${provider2.name} into chat or open the slot when this project uses it.`,
|
|
16945
|
+
verifyInstruction: "Connect a coding CLI, add project context, then ask VibeRaven for the next safe step."
|
|
16946
|
+
} : provider2.nextFix
|
|
16947
|
+
})),
|
|
16948
|
+
releases: [
|
|
16949
|
+
{
|
|
16950
|
+
id: "v1.3.0",
|
|
16951
|
+
label: "v1.3.0",
|
|
16952
|
+
meta: "Local fixture",
|
|
16953
|
+
branch: "main",
|
|
16954
|
+
tone: "current",
|
|
16955
|
+
summary: "Client interaction fixture. The local server replaces this with real project release context."
|
|
16956
|
+
},
|
|
16957
|
+
{
|
|
16958
|
+
id: "v1.2.2",
|
|
16959
|
+
label: "v1.2.2",
|
|
16960
|
+
meta: "Previous fixture",
|
|
16961
|
+
branch: "main",
|
|
16962
|
+
tone: "prod",
|
|
16963
|
+
summary: "Previous release fixture for UI interaction tests."
|
|
16964
|
+
},
|
|
16965
|
+
{
|
|
16966
|
+
id: "workspace",
|
|
16967
|
+
label: "Workspace",
|
|
16968
|
+
meta: "Not released",
|
|
16969
|
+
branch: "local",
|
|
16970
|
+
tone: "planned",
|
|
16971
|
+
summary: "No git release was detected yet."
|
|
16972
|
+
}
|
|
16973
|
+
],
|
|
16924
16974
|
empty: true
|
|
16925
16975
|
};
|
|
16926
16976
|
}
|
|
@@ -17014,12 +17064,16 @@ const demo = {
|
|
|
17014
17064
|
reasoningMenuOpen: false,
|
|
17015
17065
|
contextMenuOpen: false,
|
|
17016
17066
|
pickerChatIndex: 0,
|
|
17017
|
-
chatContexts: [{ providerId: null, releaseId: null }],
|
|
17018
|
-
activeRecentChatId:
|
|
17067
|
+
chatContexts: [{ providerId: null, releaseId: null, cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production' }],
|
|
17068
|
+
activeRecentChatId: null,
|
|
17019
17069
|
chatTaskKind: null,
|
|
17020
17070
|
chatTaskPhase: 'idle',
|
|
17021
17071
|
chatTaskPrompt: '',
|
|
17072
|
+
chatTaskResponse: '',
|
|
17073
|
+
chatTaskError: '',
|
|
17022
17074
|
chatTaskProviderId: null,
|
|
17075
|
+
chatTaskReleaseId: null,
|
|
17076
|
+
chatTaskChatIndex: 0,
|
|
17023
17077
|
droppedProviderId: null,
|
|
17024
17078
|
dragKind: null,
|
|
17025
17079
|
dragProviderId: null,
|
|
@@ -17040,6 +17094,7 @@ const providerAssets = {
|
|
|
17040
17094
|
sentry: '/report/assets/provider-sentry.png',
|
|
17041
17095
|
posthog: '/report/assets/provider-posthog.png',
|
|
17042
17096
|
clerk: '/report/assets/provider-clerk.png',
|
|
17097
|
+
authjs: '/report/assets/provider-clerk.png',
|
|
17043
17098
|
resend: '/report/assets/provider-resend.png',
|
|
17044
17099
|
upstash: '/report/assets/provider-upstash.png',
|
|
17045
17100
|
};
|
|
@@ -17052,6 +17107,7 @@ const providerMarkAssets = {
|
|
|
17052
17107
|
sentry: '/report/assets/provider-sentry-mark.svg',
|
|
17053
17108
|
posthog: '/report/assets/provider-posthog-mark.svg',
|
|
17054
17109
|
clerk: '/report/assets/provider-clerk-mark.svg',
|
|
17110
|
+
authjs: '/report/assets/provider-clerk-mark.svg',
|
|
17055
17111
|
resend: '/report/assets/provider-resend-mark.svg',
|
|
17056
17112
|
upstash: '/report/assets/provider-upstash-mark.svg',
|
|
17057
17113
|
};
|
|
@@ -17071,6 +17127,7 @@ const providerDashboardUrls = {
|
|
|
17071
17127
|
sentry: 'https://sentry.io',
|
|
17072
17128
|
posthog: 'https://app.posthog.com',
|
|
17073
17129
|
clerk: 'https://dashboard.clerk.com',
|
|
17130
|
+
authjs: 'https://authjs.dev',
|
|
17074
17131
|
resend: 'https://resend.com/emails',
|
|
17075
17132
|
upstash: 'https://console.upstash.com',
|
|
17076
17133
|
};
|
|
@@ -17092,25 +17149,61 @@ const githubStats = {
|
|
|
17092
17149
|
let lastRenderedModal = demo.activeModal;
|
|
17093
17150
|
let chatTaskTimer = null;
|
|
17094
17151
|
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
|
|
17103
|
-
{ id: 'resend', name: 'Resend', area: 'Email', status: 'Connected', tone: 'green', detail: 'Sender identity and delivery proof are connected.', region: 'global', lastSync: '9m ago', checks: '3/3' },
|
|
17104
|
-
{ id: 'upstash', name: 'Upstash', area: 'Queue / Cache', status: 'Connected', tone: 'green', detail: 'Quota and rate-limit provider is connected.', region: 'global', lastSync: '10m ago', checks: '3/3' },
|
|
17105
|
-
];
|
|
17152
|
+
function providerTone(state, status) {
|
|
17153
|
+
const text = String(status || '').toLowerCase();
|
|
17154
|
+
if (state === 'live_verified' || text.includes('connected') || text.includes('verified')) return 'green';
|
|
17155
|
+
if (state === 'needs_repo_fix' || state === 'blocked' || text.includes('fix') || text.includes('blocked')) return 'red';
|
|
17156
|
+
if (state === 'repo_evidence_found' || text.includes('detected')) return 'green';
|
|
17157
|
+
if (state === 'requires_user_action' || state === 'connect_live') return 'orange';
|
|
17158
|
+
return 'neutral';
|
|
17159
|
+
}
|
|
17106
17160
|
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
|
|
17113
|
-
|
|
17161
|
+
function providerChecks(provider) {
|
|
17162
|
+
const items = Array.isArray(provider.launchPath) ? provider.launchPath : [];
|
|
17163
|
+
if (!items.length) return provider.state === 'not_detected' ? '0/0' : '1/1';
|
|
17164
|
+
const ready = items.filter((item) => item.state === 'ready').length;
|
|
17165
|
+
return ready + '/' + items.length;
|
|
17166
|
+
}
|
|
17167
|
+
|
|
17168
|
+
function providerDetail(provider) {
|
|
17169
|
+
if (provider.nextFix && provider.nextFix.whyItMatters) return provider.nextFix.whyItMatters;
|
|
17170
|
+
if (provider.cockpit && provider.cockpit.proof && provider.cockpit.proof.summary) return provider.cockpit.proof.summary;
|
|
17171
|
+
if (provider.state === 'not_detected') return provider.area + ' is available as a production slot. Add it when your app uses ' + provider.name + '.';
|
|
17172
|
+
return provider.area + ' evidence was detected in this project. Drag this slot into chat for a scoped production check.';
|
|
17173
|
+
}
|
|
17174
|
+
|
|
17175
|
+
function normalizeProvider(provider) {
|
|
17176
|
+
return {
|
|
17177
|
+
id: provider.id,
|
|
17178
|
+
name: provider.name,
|
|
17179
|
+
area: provider.area,
|
|
17180
|
+
status: provider.statusText || (provider.state === 'not_detected' ? 'Add when needed' : 'Detected in repo'),
|
|
17181
|
+
tone: providerTone(provider.state, provider.statusText),
|
|
17182
|
+
detail: providerDetail(provider),
|
|
17183
|
+
region: provider.state === 'not_detected' ? 'not linked' : 'local repo',
|
|
17184
|
+
lastSync: currentState.project && currentState.project.scannedAt ? 'scan artifact' : 'startup',
|
|
17185
|
+
checks: providerChecks(provider),
|
|
17186
|
+
state: provider.state || 'not_detected',
|
|
17187
|
+
};
|
|
17188
|
+
}
|
|
17189
|
+
|
|
17190
|
+
const providers = Array.isArray(currentState.providers) && currentState.providers.length
|
|
17191
|
+
? currentState.providers.map(normalizeProvider)
|
|
17192
|
+
: [];
|
|
17193
|
+
|
|
17194
|
+
const releases = Array.isArray(currentState.releases) && currentState.releases.length
|
|
17195
|
+
? currentState.releases.map((release, index) => ({
|
|
17196
|
+
id: release.id || release.label || 'workspace',
|
|
17197
|
+
label: release.label || release.id || 'Workspace',
|
|
17198
|
+
meta: release.meta || (index === 0 ? 'current workspace' : 'local history'),
|
|
17199
|
+
branch: release.branch || 'local',
|
|
17200
|
+
tone: release.tone || (index === 0 ? 'current' : 'prod'),
|
|
17201
|
+
summary: release.summary || '',
|
|
17202
|
+
}))
|
|
17203
|
+
: [{ id: 'workspace', label: 'Workspace', meta: 'not released', branch: 'local', tone: 'current', summary: 'No release detected yet.' }];
|
|
17204
|
+
|
|
17205
|
+
demo.selectedProviderId = currentState.selectedProviderId || (providers[0] && providers[0].id) || 'supabase';
|
|
17206
|
+
demo.selectedReleaseId = (releases[0] && releases[0].id) || 'workspace';
|
|
17114
17207
|
|
|
17115
17208
|
let cliAgents = [
|
|
17116
17209
|
{ id: 'codex', label: 'Codex CLI', caption: 'Connect OpenAI agent', tone: 'green' },
|
|
@@ -17145,26 +17238,47 @@ const stackSlots = {
|
|
|
17145
17238
|
sentry: 'Monitoring',
|
|
17146
17239
|
posthog: 'Analytics',
|
|
17147
17240
|
clerk: 'Auth',
|
|
17241
|
+
authjs: 'Auth',
|
|
17148
17242
|
resend: 'Email',
|
|
17149
17243
|
upstash: 'Cache',
|
|
17150
17244
|
};
|
|
17151
17245
|
|
|
17152
|
-
const providerBoardOrder = ['supabase', 'clerk', 'vercel', 'stripe', 'sentry', 'resend', 'posthog', 'upstash', 'github'];
|
|
17246
|
+
const providerBoardOrder = ['supabase', 'clerk', 'authjs', 'vercel', 'stripe', 'sentry', 'resend', 'posthog', 'upstash', 'github'];
|
|
17247
|
+
|
|
17248
|
+
function visibleBoardProviders() {
|
|
17249
|
+
const authProviders = providers.filter((provider) => provider.id === 'clerk' || provider.id === 'authjs');
|
|
17250
|
+
if (authProviders.length <= 1) return providers;
|
|
17251
|
+
const detectedAuth = authProviders.find((provider) => provider.state !== 'not_detected');
|
|
17252
|
+
const visibleAuth = detectedAuth || authProviders.find((provider) => provider.id === 'clerk') || authProviders[0];
|
|
17253
|
+
return providers.filter((provider) => provider.id !== 'clerk' && provider.id !== 'authjs').concat(visibleAuth);
|
|
17254
|
+
}
|
|
17153
17255
|
|
|
17154
17256
|
function orderedProviders() {
|
|
17155
|
-
|
|
17156
|
-
|
|
17257
|
+
const visible = visibleBoardProviders();
|
|
17258
|
+
const ordered = providerBoardOrder
|
|
17259
|
+
.map((id) => visible.find((provider) => provider.id === id))
|
|
17157
17260
|
.filter(Boolean);
|
|
17261
|
+
return ordered.concat(visible.filter((provider) => !providerBoardOrder.includes(provider.id)));
|
|
17158
17262
|
}
|
|
17159
17263
|
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
|
|
17167
|
-
|
|
17264
|
+
let recentChats = [];
|
|
17265
|
+
|
|
17266
|
+
function rememberRecentChat(prompt, provider, release) {
|
|
17267
|
+
const text = String(prompt || '').trim();
|
|
17268
|
+
if (!text) return;
|
|
17269
|
+
const title = text.length > 38 ? text.slice(0, 35).trim() + '...' : text;
|
|
17270
|
+
const context = provider ? (stackSlots[provider.id] || provider.area) + ' / ' + provider.name : release ? 'Release / ' + release.label : 'Production';
|
|
17271
|
+
const entry = {
|
|
17272
|
+
id: 'chat-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 7),
|
|
17273
|
+
title,
|
|
17274
|
+
caption: context,
|
|
17275
|
+
time: 'Just now',
|
|
17276
|
+
providerId: provider?.id || null,
|
|
17277
|
+
releaseId: release?.id || null
|
|
17278
|
+
};
|
|
17279
|
+
recentChats = [entry].concat(recentChats).slice(0, 6);
|
|
17280
|
+
demo.activeRecentChatId = entry.id;
|
|
17281
|
+
}
|
|
17168
17282
|
|
|
17169
17283
|
function escapeHtml(value) {
|
|
17170
17284
|
return String(value)
|
|
@@ -17330,9 +17444,30 @@ function selectedProvider() {
|
|
|
17330
17444
|
return providers.find((item) => item.id === demo.selectedProviderId) || providers[0];
|
|
17331
17445
|
}
|
|
17332
17446
|
|
|
17447
|
+
function defaultChatContext(seed) {
|
|
17448
|
+
const source = seed || {};
|
|
17449
|
+
const cliId = source.cliId || demo.selectedCliId || 'codex';
|
|
17450
|
+
const models = cliModels[cliId] || cliModels.codex;
|
|
17451
|
+
return {
|
|
17452
|
+
providerId: source.providerId || null,
|
|
17453
|
+
releaseId: source.releaseId || null,
|
|
17454
|
+
cliId,
|
|
17455
|
+
modelId: source.modelId || demo.selectedModelId || normalizeModelId(models[0]),
|
|
17456
|
+
reasoning: source.reasoning || demo.selectedReasoning || 'High',
|
|
17457
|
+
context: source.context || demo.selectedContext || 'Production',
|
|
17458
|
+
draft: source.draft || '',
|
|
17459
|
+
};
|
|
17460
|
+
}
|
|
17461
|
+
|
|
17333
17462
|
function chatContext(index) {
|
|
17334
|
-
|
|
17335
|
-
|
|
17463
|
+
const safeIndex = Math.max(0, Number(index) || 0);
|
|
17464
|
+
while (!demo.chatContexts[safeIndex]) {
|
|
17465
|
+
demo.chatContexts.push(defaultChatContext(demo.chatContexts[demo.chatContexts.length - 1]));
|
|
17466
|
+
}
|
|
17467
|
+
const context = demo.chatContexts[safeIndex];
|
|
17468
|
+
const hydrated = defaultChatContext(context);
|
|
17469
|
+
Object.assign(context, hydrated);
|
|
17470
|
+
return context;
|
|
17336
17471
|
}
|
|
17337
17472
|
|
|
17338
17473
|
function syncPrimaryContext() {
|
|
@@ -17398,25 +17533,43 @@ function taskMeta(kind) {
|
|
|
17398
17533
|
return base[kind] || base.analyze;
|
|
17399
17534
|
}
|
|
17400
17535
|
|
|
17401
|
-
function runChatTask(kind) {
|
|
17536
|
+
function runChatTask(kind, promptOverride) {
|
|
17402
17537
|
const meta = taskMeta(kind);
|
|
17403
17538
|
if (chatTaskTimer) window.clearTimeout(chatTaskTimer);
|
|
17539
|
+
const chatIndex = Math.max(0, Math.min(demo.pickerChatIndex || 0, demo.activeChatCount - 1));
|
|
17540
|
+
const chat = chatContext(chatIndex);
|
|
17541
|
+
const attachedProviderId = chat.providerId || null;
|
|
17542
|
+
const attachedReleaseId = chat.releaseId || null;
|
|
17543
|
+
const providerId = attachedProviderId || demo.selectedProviderId;
|
|
17544
|
+
const releaseId = attachedReleaseId || demo.selectedReleaseId;
|
|
17545
|
+
const provider = providers.find((item) => item.id === providerId) || selectedProvider();
|
|
17546
|
+
const release = releases.find((item) => item.id === releaseId);
|
|
17547
|
+
const prompt = String(promptOverride || '').trim() || meta.prompt;
|
|
17404
17548
|
demo.activeStudioTab = 'chat';
|
|
17405
|
-
demo.activeRecentChatId = demo.activeRecentChatId || 'rollout';
|
|
17406
17549
|
demo.activeChatCount = Math.max(1, demo.activeChatCount);
|
|
17407
17550
|
demo.activeModal = null;
|
|
17408
17551
|
demo.chatTaskKind = kind;
|
|
17409
17552
|
demo.chatTaskPhase = 'working';
|
|
17410
|
-
demo.chatTaskPrompt =
|
|
17411
|
-
demo.
|
|
17553
|
+
demo.chatTaskPrompt = prompt;
|
|
17554
|
+
demo.chatTaskResponse = '';
|
|
17555
|
+
demo.chatTaskError = '';
|
|
17556
|
+
demo.chatTaskProviderId = attachedProviderId || (kind === 'provider' ? provider?.id : null);
|
|
17557
|
+
demo.chatTaskReleaseId = attachedReleaseId || null;
|
|
17558
|
+
demo.chatTaskChatIndex = chatIndex;
|
|
17559
|
+
rememberRecentChat(prompt, provider, release);
|
|
17560
|
+
chat.providerId = null;
|
|
17561
|
+
chat.releaseId = null;
|
|
17562
|
+
if (chatIndex === 0) syncPrimaryContext();
|
|
17412
17563
|
demo.agentFixing = kind !== 'diff' && kind !== 'explain';
|
|
17413
17564
|
demo.verified = kind === 'verify' ? false : demo.verified;
|
|
17414
17565
|
demo.activeStepId = kind === 'verify' ? 'verify' : kind === 'provider' ? 'provider' : 'agent';
|
|
17415
17566
|
demo.notice = meta.notice;
|
|
17416
17567
|
render();
|
|
17417
|
-
|
|
17568
|
+
const finish = (message, isError) => {
|
|
17418
17569
|
demo.chatTaskPhase = 'complete';
|
|
17419
17570
|
demo.agentFixing = false;
|
|
17571
|
+
demo.chatTaskResponse = isError ? '' : (message || '');
|
|
17572
|
+
demo.chatTaskError = isError ? (message || 'The connected CLI did not return a usable response.') : '';
|
|
17420
17573
|
if (kind === 'verify') {
|
|
17421
17574
|
demo.verified = true;
|
|
17422
17575
|
demo.activeStepId = 'clear';
|
|
@@ -17429,7 +17582,55 @@ function runChatTask(kind) {
|
|
|
17429
17582
|
demo.notice = taskMeta(kind).title + ' finished in chat.';
|
|
17430
17583
|
}
|
|
17431
17584
|
render();
|
|
17432
|
-
}
|
|
17585
|
+
};
|
|
17586
|
+
if (chat.cliId === 'terminal') {
|
|
17587
|
+
finish('Terminal chat execution is blocked. Use the Terminal tab for explicit commands.', true);
|
|
17588
|
+
return;
|
|
17589
|
+
}
|
|
17590
|
+
if (typeof fetch !== 'function') {
|
|
17591
|
+
chatTaskTimer = window.setTimeout(() => finish('', false), kind === 'verify' ? 1500 : 1250);
|
|
17592
|
+
return;
|
|
17593
|
+
}
|
|
17594
|
+
fetch('/api/agent-chat', {
|
|
17595
|
+
method: 'POST',
|
|
17596
|
+
headers: { 'content-type': 'application/json' },
|
|
17597
|
+
body: JSON.stringify({
|
|
17598
|
+
cliId: chat.cliId,
|
|
17599
|
+
modelId: selectedModelLabel(chatIndex),
|
|
17600
|
+
reasoning: chat.reasoning,
|
|
17601
|
+
context: chat.context,
|
|
17602
|
+
prompt,
|
|
17603
|
+
provider: { area: provider.area, name: provider.name },
|
|
17604
|
+
release: release ? { label: release.label } : undefined
|
|
17605
|
+
})
|
|
17606
|
+
})
|
|
17607
|
+
.then(async (response) => {
|
|
17608
|
+
if (!response.ok) throw new Error(await response.text());
|
|
17609
|
+
const payload = await response.json();
|
|
17610
|
+
const run = payload && payload.agentRun ? payload.agentRun : {};
|
|
17611
|
+
const output = String(run.output || run.stderr || '').trim();
|
|
17612
|
+
const failed = Boolean(run.timedOut || run.exitCode === null || Number(run.exitCode) !== 0);
|
|
17613
|
+
finish(output || 'The selected local CLI did not return output. Check that it is installed, signed in, and available on PATH.', failed || !output);
|
|
17614
|
+
})
|
|
17615
|
+
.catch((error) => {
|
|
17616
|
+
finish(error && error.message ? error.message : 'The connected CLI could not be reached.', true);
|
|
17617
|
+
});
|
|
17618
|
+
}
|
|
17619
|
+
|
|
17620
|
+
function sendChatInput(chatIndex) {
|
|
17621
|
+
const safeIndex = Math.max(0, Math.min(Number(chatIndex) || 0, demo.activeChatCount - 1));
|
|
17622
|
+
const input = app.querySelector('[data-chat-input="' + String(safeIndex) + '"]');
|
|
17623
|
+
const chat = chatContext(safeIndex);
|
|
17624
|
+
const value = String(chat.draft || (input && 'value' in input ? input.value : '') || '').trim();
|
|
17625
|
+
demo.pickerChatIndex = safeIndex;
|
|
17626
|
+
if (!value) {
|
|
17627
|
+
demo.notice = 'Type a mission first, or use a VibeRaven quick action.';
|
|
17628
|
+
render();
|
|
17629
|
+
return;
|
|
17630
|
+
}
|
|
17631
|
+
chat.draft = '';
|
|
17632
|
+
if (input && 'value' in input) input.value = '';
|
|
17633
|
+
runChatTask(chat.providerId ? 'provider' : 'analyze', value);
|
|
17433
17634
|
}
|
|
17434
17635
|
|
|
17435
17636
|
function resetLaunchPreview() {
|
|
@@ -17453,13 +17654,17 @@ function resetLaunchPreview() {
|
|
|
17453
17654
|
demo.reasoningMenuOpen = false;
|
|
17454
17655
|
demo.contextMenuOpen = false;
|
|
17455
17656
|
demo.pickerChatIndex = 0;
|
|
17456
|
-
demo.chatContexts = [{
|
|
17657
|
+
demo.chatContexts = [defaultChatContext({ cliId: 'codex', modelId: 'gpt-5.5', reasoning: 'High', context: 'Production' })];
|
|
17457
17658
|
demo.droppedProviderId = null;
|
|
17458
17659
|
demo.droppedReleaseId = null;
|
|
17459
17660
|
demo.chatTaskKind = null;
|
|
17460
17661
|
demo.chatTaskPhase = 'idle';
|
|
17461
17662
|
demo.chatTaskPrompt = '';
|
|
17663
|
+
demo.chatTaskResponse = '';
|
|
17664
|
+
demo.chatTaskError = '';
|
|
17462
17665
|
demo.chatTaskProviderId = null;
|
|
17666
|
+
demo.chatTaskReleaseId = null;
|
|
17667
|
+
demo.chatTaskChatIndex = 0;
|
|
17463
17668
|
demo.selectedEnvironment = 'us-east-1';
|
|
17464
17669
|
demo.selectedBranch = 'main';
|
|
17465
17670
|
demo.topbarMenuOpen = null;
|
|
@@ -17533,7 +17738,7 @@ function RecentChatRail() {
|
|
|
17533
17738
|
'<span><strong>' + escapeHtml(chat.title) + '</strong><em>' + escapeHtml(chat.caption) + '</em></span>' +
|
|
17534
17739
|
'<small>' + escapeHtml(chat.time) + '</small>' +
|
|
17535
17740
|
'</button>'
|
|
17536
|
-
).join('') + '</div>' +
|
|
17741
|
+
).join('') + (recentChats.length ? '' : '<p class="vr-recent-empty">No saved chats yet. Split a mission when you need another lane.</p>') + '</div>' +
|
|
17537
17742
|
'<button class="vr-view-all-chats" type="button" data-action="view-all-chats">View all chats <b></b></button>' +
|
|
17538
17743
|
'</aside>';
|
|
17539
17744
|
}
|
|
@@ -17551,7 +17756,7 @@ function ProviderCard(provider) {
|
|
|
17551
17756
|
function ProviderDetailPanel() {
|
|
17552
17757
|
const provider = providers.find((item) => item.id === demo.selectedProviderId) || providers[0];
|
|
17553
17758
|
return '<aside class="vr-provider-detail-panel">' +
|
|
17554
|
-
'<div class="vr-detail-head"><span class="vr-provider-token is-large"><img src="' + (providerMarkAssets[provider.id] || providerAssets[provider.id]) + '" alt="" /></span><div><span>' + escapeHtml(provider.area) + '</span><strong>' + escapeHtml(provider.name) + '</strong></div>' + StatusBadge(provider.status,
|
|
17759
|
+
'<div class="vr-detail-head"><span class="vr-provider-token is-large"><img src="' + (providerMarkAssets[provider.id] || providerAssets[provider.id]) + '" alt="" /></span><div><span>' + escapeHtml(provider.area) + '</span><strong>' + escapeHtml(provider.name) + '</strong></div>' + StatusBadge(provider.status, provider.tone) + '</div>' +
|
|
17555
17760
|
'<p>' + escapeHtml(provider.detail) + '</p>' +
|
|
17556
17761
|
'<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>' +
|
|
17557
17762
|
'<a class="vr-provider-dashboard" href="' + escapeHtml(providerDashboardUrls[provider.id] || docsUrl) + '" target="_blank" rel="noreferrer">Open dashboard ' + Icon('external') + '</a>' +
|
|
@@ -17560,8 +17765,10 @@ function ProviderDetailPanel() {
|
|
|
17560
17765
|
|
|
17561
17766
|
function ProviderGrid() {
|
|
17562
17767
|
const boardProviders = orderedProviders();
|
|
17768
|
+
const activeCount = boardProviders.filter((provider) => provider.state !== 'not_detected').length;
|
|
17769
|
+
const summary = activeCount > 0 ? activeCount + ' production slot' + (activeCount === 1 ? '' : 's') + ' detected locally.' : 'No production providers detected yet.';
|
|
17563
17770
|
return '<section class="vr-providers-panel" aria-label="Connected providers">' +
|
|
17564
|
-
'<div class="vr-panel-head"><div><h2>Provider Control Board</h2><p><b>
|
|
17771
|
+
'<div class="vr-panel-head"><div><h2>Provider Control Board</h2><p><b>Local project evidence</b> · ' + escapeHtml(summary) + '</p></div><button class="vr-add-provider-inline" type="button" data-action="add-provider">' + Icon('plus') + 'Add Provider</button></div>' +
|
|
17565
17772
|
(demo.providerPickerOpen ? ProviderPicker() : '') +
|
|
17566
17773
|
'<div class="vr-provider-composition"><div class="vr-provider-grid" aria-label="Production provider slots">' + boardProviders.map(ProviderCard).join('') + '</div>' + ProviderDetailPanel() + '</div>' +
|
|
17567
17774
|
'</section>';
|
|
@@ -17594,10 +17801,10 @@ function VersionTimeline() {
|
|
|
17594
17801
|
'<div class="vr-panel-head"><div><h2>Versions & Releases</h2><p>Current release, rollback context, and changelog actions.</p></div></div>' +
|
|
17595
17802
|
'<div class="vr-release-composition">' +
|
|
17596
17803
|
'<button class="vr-release-card vr-release-current ' + (currentRelease.id === demo.selectedReleaseId ? 'is-selected' : '') + '" draggable="true" data-release="' + escapeHtml(currentRelease.id) + '" data-tone="' + escapeHtml(currentRelease.tone) + '" type="button">' +
|
|
17597
|
-
'<small>Current Release</small><strong>' + escapeHtml(currentRelease.label) + '</strong><em>
|
|
17804
|
+
'<small>Current Release</small><strong>' + escapeHtml(currentRelease.label) + '</strong><em>' + escapeHtml(currentRelease.meta) + ' · ' + escapeHtml(currentRelease.branch) + '</em><span>' + escapeHtml(currentRelease.summary || 'Local release context') + '</span>' +
|
|
17598
17805
|
'</button>' +
|
|
17599
17806
|
'<section class="vr-release-list"><header><strong>Recent Versions</strong><button type="button" data-action="all-releases">View all</button></header>' +
|
|
17600
|
-
previousReleases.map((release) => '<button class="vr-release-row ' + (release.id === demo.selectedReleaseId ? 'is-selected' : '') + '" draggable="true" data-release="' + escapeHtml(release.id) + '" data-tone="' + escapeHtml(release.tone) + '" type="button"><span><strong>' + escapeHtml(release.label) + '</strong><em>
|
|
17807
|
+
(previousReleases.length > 0 ? previousReleases.map((release) => '<button class="vr-release-row ' + (release.id === demo.selectedReleaseId ? 'is-selected' : '') + '" draggable="true" data-release="' + escapeHtml(release.id) + '" data-tone="' + escapeHtml(release.tone) + '" type="button"><span><strong>' + escapeHtml(release.label) + '</strong><em>' + escapeHtml(release.summary || release.branch) + '</em></span><small>' + escapeHtml(release.meta) + '</small></button>').join('') : '<div class="vr-release-empty">No previous releases detected.</div>') +
|
|
17601
17808
|
'</section>' +
|
|
17602
17809
|
'</div>' +
|
|
17603
17810
|
'<div class="vr-release-actions"><button type="button" data-action="compare">' + Icon('branch') + 'Compare Releases</button><button type="button" data-action="changelog">' + Icon('report') + 'View Changelog</button><button type="button" data-action="release">' + Icon('refresh') + 'Rollback</button></div>' +
|
|
@@ -17821,17 +18028,19 @@ function StudioTabButton(id, label) {
|
|
|
17821
18028
|
return '<button class="' + (demo.activeStudioTab === id ? 'is-active' : '') + '" type="button" data-studio-tab="' + escapeHtml(id) + '">' + escapeHtml(label) + '</button>';
|
|
17822
18029
|
}
|
|
17823
18030
|
|
|
17824
|
-
function CliAgentButton(agent) {
|
|
18031
|
+
function CliAgentButton(agent, index) {
|
|
18032
|
+
const chat = chatContext(index);
|
|
17825
18033
|
const connected = agent.connected !== false;
|
|
17826
|
-
const label =
|
|
17827
|
-
return '<button class="' + (
|
|
18034
|
+
const label = chat.cliId === agent.id && connected ? 'Active' : connected ? 'Use' : 'Connect';
|
|
18035
|
+
return '<button class="' + (chat.cliId === agent.id ? 'is-selected' : '') + '" type="button" data-cli-agent="' + escapeHtml(agent.id) + '" data-chat-index="' + String(index) + '" data-tone="' + escapeHtml(agent.tone) + '" data-connected="' + (connected ? 'true' : 'false') + '">' +
|
|
17828
18036
|
'<span></span><strong>' + escapeHtml(agent.label) + '</strong><b>' + label + '</b>' +
|
|
17829
18037
|
'</button>';
|
|
17830
18038
|
}
|
|
17831
18039
|
|
|
17832
|
-
function CliConnectPanel() {
|
|
18040
|
+
function CliConnectPanel(index) {
|
|
18041
|
+
const codingAgents = cliAgents.filter((agent) => agent.id !== 'terminal');
|
|
17833
18042
|
return '<section class="vr-cli-connect" aria-label="Connect coding CLI">' +
|
|
17834
|
-
'<div class="vr-cli-strip">' +
|
|
18043
|
+
'<div class="vr-cli-strip">' + codingAgents.map((agent) => CliAgentButton(agent, index)).join('') + '</div>' +
|
|
17835
18044
|
'</section>';
|
|
17836
18045
|
}
|
|
17837
18046
|
|
|
@@ -17839,23 +18048,24 @@ function normalizeModelId(label) {
|
|
|
17839
18048
|
return String(label).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
|
17840
18049
|
}
|
|
17841
18050
|
|
|
17842
|
-
function allModelOptions(
|
|
17843
|
-
const
|
|
17844
|
-
const
|
|
18051
|
+
function allModelOptions(index) {
|
|
18052
|
+
const chat = chatContext(index);
|
|
18053
|
+
const selectedCli = chat.cliId || demo.selectedCliId;
|
|
18054
|
+
const connectedAgents = cliAgents.filter((item) => item.id !== 'terminal' && item.connected !== false);
|
|
17845
18055
|
const agent = connectedAgents.find((item) => item.id === selectedCli) || connectedAgents[0] || cliAgents[0];
|
|
17846
18056
|
const modelCliId = agent?.id || selectedCli;
|
|
17847
18057
|
return (cliModels[modelCliId] || cliModels[selectedCli] || cliModels.codex).map((label) => ({
|
|
17848
18058
|
cliId: modelCliId,
|
|
17849
18059
|
label,
|
|
17850
18060
|
id: normalizeModelId(label),
|
|
17851
|
-
agentLabel: (agent?.label || 'CLI').replace(' CLI', '').replace(' Code', ''),
|
|
17852
18061
|
}));
|
|
17853
18062
|
}
|
|
17854
18063
|
|
|
17855
|
-
function selectedModelLabel() {
|
|
17856
|
-
const
|
|
18064
|
+
function selectedModelLabel(index) {
|
|
18065
|
+
const chat = chatContext(index || 0);
|
|
18066
|
+
const option = allModelOptions(index || 0).find((item) => item.id === chat.modelId);
|
|
17857
18067
|
if (option) return option.label;
|
|
17858
|
-
const models = cliModels[
|
|
18068
|
+
const models = cliModels[chat.cliId] || cliModels.codex;
|
|
17859
18069
|
return models[0];
|
|
17860
18070
|
}
|
|
17861
18071
|
|
|
@@ -17889,6 +18099,13 @@ async function hydrateCliAgents() {
|
|
|
17889
18099
|
if (!models.map(normalizeModelId).includes(demo.selectedModelId)) {
|
|
17890
18100
|
demo.selectedModelId = normalizeModelId(models[0]);
|
|
17891
18101
|
}
|
|
18102
|
+
demo.chatContexts.forEach((context, index) => {
|
|
18103
|
+
const chat = chatContext(index);
|
|
18104
|
+
const connected = connectedAgents.some((agent) => agent.id === chat.cliId);
|
|
18105
|
+
if (!connected || !cliModels[chat.cliId]) chat.cliId = selected;
|
|
18106
|
+
const chatModels = cliModels[chat.cliId] || models;
|
|
18107
|
+
if (!chatModels.map(normalizeModelId).includes(chat.modelId)) chat.modelId = normalizeModelId(chatModels[0]);
|
|
18108
|
+
});
|
|
17892
18109
|
demo.cliConnected = cliAgents.some((agent) => agent.id === demo.selectedCliId && agent.connected !== false);
|
|
17893
18110
|
render();
|
|
17894
18111
|
} catch {
|
|
@@ -17897,25 +18114,22 @@ async function hydrateCliAgents() {
|
|
|
17897
18114
|
}
|
|
17898
18115
|
|
|
17899
18116
|
function ModelPicker(index) {
|
|
17900
|
-
const
|
|
17901
|
-
const
|
|
18117
|
+
const chat = chatContext(index);
|
|
18118
|
+
const models = allModelOptions(index);
|
|
18119
|
+
const selectedModel = selectedModelLabel(index);
|
|
17902
18120
|
const scoped = demo.pickerChatIndex === index;
|
|
17903
|
-
const connectedAgents = cliAgents.filter((agent) => agent.connected !== false);
|
|
17904
|
-
const cliSourceRow = '<div class="vr-cli-source-row"><span>Connected CLI</span>' + connectedAgents.map((agent) =>
|
|
17905
|
-
'<button class="' + (demo.selectedCliId === agent.id ? 'is-selected' : '') + '" type="button" data-cli-agent="' + escapeHtml(agent.id) + '" data-tone="' + escapeHtml(agent.tone) + '" data-connected="' + (agent.connected === false ? 'false' : 'true') + '">' + escapeHtml(agent.label.replace(' Code', '').replace(' CLI', '')) + '</button>'
|
|
17906
|
-
).join('') + (connectedAgents.length === 0 ? '<em>No local CLI detected</em>' : '') + '</div>';
|
|
17907
18121
|
return '<div class="vr-model-picker">' +
|
|
17908
|
-
'<button type="button" data-action="toggle-reasoning" data-chat-index="' + String(index) + '"><span>Reasoning</span><strong>' + escapeHtml(
|
|
18122
|
+
'<button type="button" data-action="toggle-reasoning" data-chat-index="' + String(index) + '"><span>Reasoning</span><strong>' + escapeHtml(chat.reasoning) + '</strong><i></i></button>' +
|
|
17909
18123
|
'<button type="button" data-action="toggle-models" data-chat-index="' + String(index) + '"><span>Model</span><strong>' + escapeHtml(selectedModel) + '</strong><i></i></button>' +
|
|
17910
|
-
'<button type="button" data-action="toggle-context" data-chat-index="' + String(index) + '"><span>Context</span><strong>' + escapeHtml(
|
|
18124
|
+
'<button type="button" data-action="toggle-context" data-chat-index="' + String(index) + '"><span>Context</span><strong>' + escapeHtml(chat.context) + '</strong><i></i></button>' +
|
|
17911
18125
|
(scoped && demo.reasoningMenuOpen ? '<div class="vr-model-menu is-reasoning" role="menu"><p>Reasoning</p>' + reasoningLevels.map((level) =>
|
|
17912
|
-
'<button type="button" data-reasoning="' + escapeHtml(level) + '">' + escapeHtml(level) + (
|
|
18126
|
+
'<button type="button" data-reasoning="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.reasoning === level ? '<b></b>' : '') + '</button>'
|
|
17913
18127
|
).join('') + '</div>' : '') +
|
|
17914
|
-
(scoped && demo.modelMenuOpen ? '<div class="vr-model-menu is-models" role="menu"><p>Model</p>' +
|
|
17915
|
-
'<button type="button" data-model="' + escapeHtml(model.id) + '" data-
|
|
18128
|
+
(scoped && demo.modelMenuOpen ? '<div class="vr-model-menu is-models" role="menu"><p>Model</p>' + models.map((model) =>
|
|
18129
|
+
'<button type="button" data-model="' + escapeHtml(model.id) + '" data-chat-index="' + String(index) + '"><span><strong>' + escapeHtml(model.label) + '</strong></span>' + (selectedModel === model.label ? '<b></b>' : '') + '</button>'
|
|
17916
18130
|
).join('') + '</div>' : '') +
|
|
17917
18131
|
(scoped && demo.contextMenuOpen ? '<div class="vr-model-menu is-context" role="menu"><p>Context</p>' + contextLevels.map((level) =>
|
|
17918
|
-
'<button type="button" data-context="' + escapeHtml(level) + '">' + escapeHtml(level) + (
|
|
18132
|
+
'<button type="button" data-context="' + escapeHtml(level) + '" data-chat-index="' + String(index) + '">' + escapeHtml(level) + (chat.context === level ? '<b></b>' : '') + '</button>'
|
|
17919
18133
|
).join('') + '</div>' : '') +
|
|
17920
18134
|
'</div>';
|
|
17921
18135
|
}
|
|
@@ -17951,25 +18165,87 @@ function ChatTaskAnimation() {
|
|
|
17951
18165
|
if (!demo.chatTaskKind) return '';
|
|
17952
18166
|
const meta = taskMeta(demo.chatTaskKind);
|
|
17953
18167
|
const complete = demo.chatTaskPhase === 'complete';
|
|
17954
|
-
|
|
17955
|
-
const
|
|
18168
|
+
if (complete) return ChatAgentResponse(meta, demo.chatTaskError || demo.chatTaskResponse, Boolean(demo.chatTaskError));
|
|
18169
|
+
const statusText = demo.chatTaskKind === 'verify' ? 'Verifying...' : demo.chatTaskKind === 'diff' ? 'Reviewing...' : demo.chatTaskKind === 'explain' ? 'Explaining...' : 'Effecting...';
|
|
18170
|
+
const thoughtText = 'thinking';
|
|
17956
18171
|
return '<section class="vr-chat-agent-task ' + (complete ? 'is-complete' : 'is-working') + '" data-task="' + escapeHtml(demo.chatTaskKind) + '">' +
|
|
17957
18172
|
'<header><span class="vr-task-glyph" aria-hidden="true"></span><div><strong>' + escapeHtml(statusText) + '</strong><em>(' + escapeHtml(thoughtText) + ' for launch)</em></div><b>' + escapeHtml(meta.title) + '</b></header>' +
|
|
17958
18173
|
'<div class="vr-task-rail" aria-hidden="true"><span></span></div>' +
|
|
17959
|
-
'<p>' +
|
|
18174
|
+
'<p>' + escapeHtml(meta.line) + '</p>' +
|
|
18175
|
+
'</section>';
|
|
18176
|
+
}
|
|
18177
|
+
|
|
18178
|
+
function formatAgentOutput(value) {
|
|
18179
|
+
let clean = String(value || '').replace(/\\r\\n/g, '\\n').trim();
|
|
18180
|
+
clean = clean
|
|
18181
|
+
.split('\\n')
|
|
18182
|
+
.filter((line) => !/^\\d{4}-\\d{2}-\\d{2}T.*\\s(WARN|ERROR)\\s/.test(line))
|
|
18183
|
+
.filter((line) => !/^(OpenAI Codex v|workdir:|model:|provider:|approval:|sandbox:|reasoning effort:|reasoning summaries:|session id:|--------$|user$)/.test(line.trim()))
|
|
18184
|
+
.join('\\n')
|
|
18185
|
+
.trim();
|
|
18186
|
+
if (/IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist/i.test(clean)) {
|
|
18187
|
+
return 'Gemini CLI is installed, but this account/client is not eligible for the current Gemini Code Assist CLI. Connect a supported Gemini CLI account, then retry this chat.';
|
|
18188
|
+
}
|
|
18189
|
+
if (/not running in a trusted directory|--skip-trust|GEMINI_CLI_TRUST_WORKSPACE/i.test(clean)) {
|
|
18190
|
+
return 'Gemini CLI needs this project trusted for headless chat. VibeRaven now passes the trust flag for Gemini runs; retry after your Gemini account is eligible.';
|
|
18191
|
+
}
|
|
18192
|
+
if (/command not found|not recognized as an internal or external command|ENOENT/i.test(clean)) {
|
|
18193
|
+
return 'The selected CLI is not available on PATH. Install it or sign in, then reconnect it from the chat header.';
|
|
18194
|
+
}
|
|
18195
|
+
if (/authentication|not logged in|login required|sign in/i.test(clean)) {
|
|
18196
|
+
return 'The selected CLI needs sign-in before VibeRaven can use it. Sign in with the CLI, then retry this mission.';
|
|
18197
|
+
}
|
|
18198
|
+
const missionIndex = clean.indexOf('User mission:');
|
|
18199
|
+
if (missionIndex >= 0) {
|
|
18200
|
+
const afterMission = clean.slice(missionIndex + 'User mission:'.length).trim();
|
|
18201
|
+
if (afterMission && afterMission.length < clean.length) clean = afterMission;
|
|
18202
|
+
}
|
|
18203
|
+
if (!clean) return 'Ready for the next safe action.';
|
|
18204
|
+
return clean.length > 2200 ? clean.slice(0, 2200) + '\\n\\n...output trimmed in Studio preview.' : clean;
|
|
18205
|
+
}
|
|
18206
|
+
|
|
18207
|
+
function ChatAgentResponse(meta, responseText, isError) {
|
|
18208
|
+
const provider = demo.chatTaskProviderId ? providers.find((item) => item.id === demo.chatTaskProviderId) : null;
|
|
18209
|
+
const release = demo.chatTaskReleaseId ? releases.find((item) => item.id === demo.chatTaskReleaseId) : null;
|
|
18210
|
+
const contextLine = provider || release
|
|
18211
|
+
? '<div class="vr-agent-context-line">' +
|
|
18212
|
+
(provider ? '<span><img src="' + (providerMarkAssets[provider.id] || providerAssets[provider.id]) + '" alt="" /><b>' + escapeHtml(provider.area) + '</b><em>' + escapeHtml(provider.name) + '</em></span>' : '') +
|
|
18213
|
+
(release ? '<span><i>' + Icon('repo') + '</i><b>Version</b><em>' + escapeHtml(release.label) + '</em></span>' : '') +
|
|
18214
|
+
'</div>'
|
|
18215
|
+
: '';
|
|
18216
|
+
return '<section class="vr-chat-message is-agent vr-chat-agent-response ' + (isError ? 'is-error' : 'is-ready') + '">' +
|
|
18217
|
+
'<div><span><img src="' + mascotUrl() + '" alt="" /></span><p><strong>VibeRaven Agent</strong><em>Just now</em></p></div>' +
|
|
18218
|
+
'<div class="vr-agent-response-meta"><span class="vr-agent-thinking-label">' + escapeHtml(isError ? 'Needs attention' : meta.title) + '</span></div>' +
|
|
18219
|
+
contextLine +
|
|
18220
|
+
'<p class="vr-agent-answer-text">' + escapeHtml(formatAgentOutput(responseText)) + '</p>' +
|
|
18221
|
+
'<div class="vr-chat-response-actions">' +
|
|
18222
|
+
'<button type="button" data-action="show-diff">' + Icon('code') + '<span>Open Diff</span></button>' +
|
|
18223
|
+
'<button type="button" data-action="verify-now">' + Icon('shield') + '<span>Run Verify</span></button>' +
|
|
18224
|
+
'<button type="button" data-action="add-context">' + Icon('plus') + '<span>Add Context</span></button>' +
|
|
18225
|
+
'</div>' +
|
|
17960
18226
|
'</section>';
|
|
17961
18227
|
}
|
|
17962
18228
|
|
|
17963
|
-
function
|
|
18229
|
+
function SentContextPills() {
|
|
18230
|
+
const provider = demo.chatTaskProviderId ? providers.find((item) => item.id === demo.chatTaskProviderId) : null;
|
|
18231
|
+
const release = demo.chatTaskReleaseId ? releases.find((item) => item.id === demo.chatTaskReleaseId) : null;
|
|
18232
|
+
if (!provider && !release) return '';
|
|
18233
|
+
return '<div class="vr-sent-context">' +
|
|
18234
|
+
(provider ? '<span><img src="' + (providerMarkAssets[provider.id] || providerAssets[provider.id]) + '" alt="" /><b>' + escapeHtml(provider.area) + '</b><em>' + escapeHtml(provider.name) + '</em></span>' : '') +
|
|
18235
|
+
(release ? '<span><i>' + Icon('repo') + '</i><b>Version</b><em>' + escapeHtml(release.label) + '</em></span>' : '') +
|
|
18236
|
+
'</div>';
|
|
18237
|
+
}
|
|
18238
|
+
|
|
18239
|
+
function ChatQuickActions(index) {
|
|
17964
18240
|
return '<div class="vr-chat-inline-actions">' +
|
|
17965
|
-
'<button type="button" data-action="plan">' + Icon('report') + 'Plan</button>' +
|
|
17966
|
-
'<button type="button" data-action="start-agent-fix">' + Icon('agent') + 'Agent Fix</button>' +
|
|
17967
|
-
'<button type="button" data-action="verify-now">' + Icon('shield') + 'Run Verify</button>' +
|
|
17968
|
-
'<button type="button" data-action="provider-proof">' + Icon('cube') + 'Provider Proof</button>' +
|
|
17969
|
-
'<button type="button" data-action="show-diff">' + Icon('code') + 'Open Diff</button>' +
|
|
17970
|
-
'<button type="button" data-action="explain-changes">' + Icon('prompt') + 'Explain Changes</button>' +
|
|
17971
|
-
'<button type="button" data-action="add-context">' + Icon('plus') + 'Add Context</button>' +
|
|
17972
|
-
'<button type="button" data-action="release">' + Icon('lock') + 'Release</button>' +
|
|
18241
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="plan">' + Icon('report') + 'Plan</button>' +
|
|
18242
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="start-agent-fix">' + Icon('agent') + 'Agent Fix</button>' +
|
|
18243
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="verify-now">' + Icon('shield') + 'Run Verify</button>' +
|
|
18244
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="provider-proof">' + Icon('cube') + 'Provider Proof</button>' +
|
|
18245
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="show-diff">' + Icon('code') + 'Open Diff</button>' +
|
|
18246
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="explain-changes">' + Icon('prompt') + 'Explain Changes</button>' +
|
|
18247
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="add-context">' + Icon('plus') + 'Add Context</button>' +
|
|
18248
|
+
'<button type="button" data-chat-index="' + String(index) + '" data-action="release">' + Icon('lock') + 'Release</button>' +
|
|
17973
18249
|
'</div>';
|
|
17974
18250
|
}
|
|
17975
18251
|
|
|
@@ -17995,24 +18271,31 @@ function ContextDropZone(index, showAttached) {
|
|
|
17995
18271
|
|
|
17996
18272
|
function StudioChatLane(index) {
|
|
17997
18273
|
const provider = providers.find((item) => item.id === demo.selectedProviderId) || providers[0];
|
|
17998
|
-
const
|
|
17999
|
-
const
|
|
18274
|
+
const chat = chatContext(index);
|
|
18275
|
+
const agent = cliAgents.find((item) => item.id === chat.cliId) || cliAgents[0];
|
|
18276
|
+
const model = selectedModelLabel(index);
|
|
18000
18277
|
const secondary = index > 0;
|
|
18001
|
-
const fresh = !secondary && !demo.activeRecentChatId;
|
|
18002
|
-
const
|
|
18003
|
-
const
|
|
18278
|
+
const fresh = !secondary && !demo.activeRecentChatId && !demo.chatTaskKind && !chat.providerId && !chat.releaseId;
|
|
18279
|
+
const laneHasTask = demo.chatTaskKind && Number(demo.chatTaskChatIndex || 0) === index;
|
|
18280
|
+
const introBlock = fresh
|
|
18281
|
+
? '<section class="vr-chat-empty-state"><strong>New mission chat</strong><span>Connect a CLI model, add provider context, then ask VibeRaven for the next safe launch step.</span></section>'
|
|
18282
|
+
: secondary
|
|
18283
|
+
? '<p class="vr-chat-copy">This chat is ready for a focused release or provider follow-up.</p>' + ChatPlanCard({ id: provider.id, name: provider.name, area: 'Release' })
|
|
18284
|
+
: (laneHasTask ? '' : ChatMissionSummary(provider));
|
|
18285
|
+
const sendAction = demo.agentFixing ? 'stop-agent' : 'send-chat-message';
|
|
18004
18286
|
const sendIcon = demo.agentFixing ? 'stop' : 'arrowUp';
|
|
18005
18287
|
const sendLabel = demo.agentFixing ? 'Stop connected agent' : 'Send mission to connected agent';
|
|
18006
18288
|
return '<article class="vr-chat-lane ' + (secondary ? 'is-secondary' : 'is-primary') + '" data-chat-index="' + String(index) + '">' +
|
|
18007
18289
|
(secondary ? '<button class="vr-chat-close" type="button" data-action="close-chat" data-chat-index="' + String(index) + '" aria-label="Close chat">' + Icon('x') + '</button>' : '') +
|
|
18290
|
+
CliConnectPanel(index) +
|
|
18008
18291
|
'<div class="vr-chat-transcript">' +
|
|
18009
18292
|
'<section class="vr-chat-message is-agent"><div><span><img src="' + mascotUrl() + '" alt="" /></span><p><strong>VibeRaven Agent</strong><em>' + (fresh ? 'Ready' : secondary ? '1m ago' : '5m ago') + '</em></p></div><p>' + (fresh ? 'Start a production mission. Drag a provider or version into this chat, or ask what blocks launch.' : demo.agentFixing ? 'Applying the production fix and watching the evidence.' : demo.verified ? 'Verification is green. Review the diff, then prepare the release.' : 'I analyzed the production rollout and found 3 blockers preventing a safe deploy.') + '</p></section>' +
|
|
18010
|
-
|
|
18011
|
-
(
|
|
18293
|
+
introBlock +
|
|
18294
|
+
(laneHasTask ? '<section class="vr-chat-message is-user"><p>' + escapeHtml(demo.chatTaskPrompt) + '</p>' + SentContextPills() + '</section>' + ChatTaskAnimation() : '') +
|
|
18012
18295
|
'</div>' +
|
|
18013
18296
|
'<footer class="vr-chat-command-bar">' +
|
|
18014
|
-
ChatQuickActions() +
|
|
18015
|
-
'<div class="vr-chat-composer" data-chat-drop="true" data-chat-index="' + String(index) + '"><
|
|
18297
|
+
ChatQuickActions(index) +
|
|
18298
|
+
'<div class="vr-chat-composer" data-chat-drop="true" data-chat-index="' + String(index) + '"><textarea class="vr-chat-input" data-chat-input="' + String(index) + '" rows="2" placeholder="Ask VibeRaven anything about this deployment...">' + escapeHtml(chat.draft || '') + '</textarea>' + ContextDropZone(index, true) + ModelPicker(index) + '<button class="vr-chat-send ' + (demo.agentFixing ? 'is-stop' : '') + '" type="button" data-action="' + sendAction + '" data-chat-index="' + String(index) + '" aria-label="' + sendLabel + '">' + Icon(sendIcon) + '</button></div>' +
|
|
18016
18299
|
'</footer>' +
|
|
18017
18300
|
'</article>';
|
|
18018
18301
|
}
|
|
@@ -18020,16 +18303,17 @@ function StudioChatLane(index) {
|
|
|
18020
18303
|
function StudioChatView() {
|
|
18021
18304
|
const lanes = Array.from({ length: demo.activeChatCount }, (_, index) => StudioChatLane(index)).join('');
|
|
18022
18305
|
return '<section class="vr-studio-chat ' + (demo.activeChatCount > 1 ? 'is-split' : '') + (demo.dropActive ? ' is-drop-preview' : '') + '" data-chat-count="' + String(demo.activeChatCount) + '" aria-label="Production mission chat workspace">' +
|
|
18023
|
-
CliConnectPanel() +
|
|
18024
18306
|
'<div class="vr-chat-lanes" data-chat-drop="true">' + lanes + '</div>' +
|
|
18025
18307
|
'</section>';
|
|
18026
18308
|
}
|
|
18027
18309
|
|
|
18028
18310
|
function StudioTerminalView() {
|
|
18029
|
-
const
|
|
18311
|
+
const chat = chatContext(demo.pickerChatIndex || 0);
|
|
18312
|
+
const agent = cliAgents.find((item) => item.id === chat.cliId) || cliAgents[0];
|
|
18030
18313
|
return '<section class="vr-studio-terminal" aria-label="Connected agent terminal">' +
|
|
18031
18314
|
'<header><strong>' + escapeHtml(agent.label) + '</strong><span>' + (demo.cliConnected ? 'connected to ' + escapeHtml(projectName()) : 'ready to connect') + '</span></header>' +
|
|
18032
18315
|
'<pre><code>$ npx -y viberaven studio\\nVibeRaven Studio connected to ' + escapeHtml(projectName()) + '\\nagent: ' + escapeHtml(agent.label) + '\\nmission: fix selected launch gap only\\n\\n' + (demo.agentFixing ? '> applying scoped fix...\\n> updating provider evidence\\n> running verification checks' : demo.verified ? '> verification passed\\n> launch flow clear\\n> review git diff before release' : '> waiting for Apply Fix') + '</code></pre>' +
|
|
18316
|
+
'<div class="vr-terminal-compose"><textarea data-terminal-input rows="2" placeholder="Ask the connected CLI to inspect something safely...">' + escapeHtml(chat.draft || '') + '</textarea><button type="button" data-action="terminal-send">' + Icon('arrowUp') + 'Send to chat</button></div>' +
|
|
18033
18317
|
'<footer><button type="button" data-action="show-diff">Show Diff</button><button type="button" data-action="verify-now">Run Verify</button><button type="button" data-action="stop-agent">Stop Agent</button></footer>' +
|
|
18034
18318
|
'</section>';
|
|
18035
18319
|
}
|
|
@@ -18038,7 +18322,7 @@ function StudioDiffView() {
|
|
|
18038
18322
|
return '<section class="vr-studio-diff" aria-label="Live git diff preview">' +
|
|
18039
18323
|
'<header><strong>Live Diff</strong><span>' + (demo.verified ? '+16 -2 verified' : demo.agentFixing ? '+7 -1 running' : 'No changes accepted yet') + '</span></header>' +
|
|
18040
18324
|
'<pre><code><b>src/lib/monitoring.ts</b>\\n<span class="add">+ export function captureLaunchError(error) {</span>\\n<span class="add">+ if (process.env.SENTRY_DSN) Sentry.captureException(error)</span>\\n<span class="add">+ }</span>\\n\\n<b>.env.example</b>\\n<span class="add">+ SENTRY_DSN=</span>\\n<span class="del">- # monitoring optional</span></code></pre>' +
|
|
18041
|
-
'<footer><button type="button" data-action="
|
|
18325
|
+
'<footer><button type="button" data-action="diff-to-chat">Explain in Chat</button><button type="button" data-action="verify-now">Accept & Verify</button></footer>' +
|
|
18042
18326
|
'</section>';
|
|
18043
18327
|
}
|
|
18044
18328
|
|
|
@@ -18047,7 +18331,7 @@ function StudioDock() {
|
|
|
18047
18331
|
return '<section class="vr-studio-dock ' + (demo.agentFixing ? 'is-running' : '') + (demo.verified ? ' is-verified' : '') + '" aria-label="VibeRaven Studio agent workspace">' +
|
|
18048
18332
|
'<div class="vr-studio-head">' +
|
|
18049
18333
|
'<div><h2>VibeRaven Chat</h2></div>' +
|
|
18050
|
-
'<div class="vr-studio-head-actions"><button class="vr-studio-add-chat" type="button" data-action="
|
|
18334
|
+
'<div class="vr-studio-head-actions"><button class="vr-studio-add-chat" type="button" data-action="split-chat" aria-label="Open a side-by-side chat">' + Icon('plus') + 'Split chat</button><div class="vr-studio-tabs">' + StudioTabButton('chat', 'Chat') + StudioTabButton('terminal', 'Terminal') + StudioTabButton('diff', 'Diff') + '</div></div>' +
|
|
18051
18335
|
'</div>' +
|
|
18052
18336
|
'<div class="vr-studio-body">' + view + '</div>' +
|
|
18053
18337
|
'</section>';
|
|
@@ -18138,10 +18422,14 @@ async function loadGithubStats() {
|
|
|
18138
18422
|
app.addEventListener('click', async (event) => {
|
|
18139
18423
|
const recentChatButton = event.target.closest('[data-chat-id]');
|
|
18140
18424
|
if (recentChatButton) {
|
|
18141
|
-
|
|
18425
|
+
const chatId = recentChatButton.getAttribute('data-chat-id');
|
|
18426
|
+
const recent = recentChats.find((chat) => chat.id === chatId);
|
|
18427
|
+
demo.activeRecentChatId = chatId;
|
|
18142
18428
|
demo.activeChatCount = 1;
|
|
18429
|
+
demo.chatContexts = [defaultChatContext({ ...demo.chatContexts[0], providerId: recent?.providerId || null, releaseId: recent?.releaseId || null })];
|
|
18430
|
+
demo.pickerChatIndex = 0;
|
|
18143
18431
|
demo.activeStudioTab = 'chat';
|
|
18144
|
-
demo.notice = 'Recent production chat loaded into the mission workspace.';
|
|
18432
|
+
demo.notice = recent ? recent.title + ' loaded with saved context.' : 'Recent production chat loaded into the mission workspace.';
|
|
18145
18433
|
render();
|
|
18146
18434
|
return;
|
|
18147
18435
|
}
|
|
@@ -18157,6 +18445,8 @@ app.addEventListener('click', async (event) => {
|
|
|
18157
18445
|
|
|
18158
18446
|
const cliButton = event.target.closest('[data-cli-agent]');
|
|
18159
18447
|
if (cliButton) {
|
|
18448
|
+
const chatIndex = Number(cliButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
|
|
18449
|
+
const chat = chatContext(chatIndex);
|
|
18160
18450
|
if (cliButton.getAttribute('data-connected') === 'false') {
|
|
18161
18451
|
demo.modelMenuOpen = false;
|
|
18162
18452
|
demo.reasoningMenuOpen = false;
|
|
@@ -18165,12 +18455,15 @@ app.addEventListener('click', async (event) => {
|
|
|
18165
18455
|
render();
|
|
18166
18456
|
return;
|
|
18167
18457
|
}
|
|
18168
|
-
|
|
18458
|
+
chat.cliId = cliButton.getAttribute('data-cli-agent');
|
|
18459
|
+
demo.selectedCliId = chat.cliId;
|
|
18169
18460
|
demo.cliConnected = true;
|
|
18170
|
-
demo.activeStudioTab =
|
|
18461
|
+
demo.activeStudioTab = chat.cliId === 'terminal' ? 'terminal' : 'chat';
|
|
18171
18462
|
demo.activeNavId = 'agents';
|
|
18172
|
-
const models = cliModels[
|
|
18173
|
-
|
|
18463
|
+
const models = cliModels[chat.cliId] || cliModels.codex;
|
|
18464
|
+
chat.modelId = normalizeModelId(models[0]);
|
|
18465
|
+
demo.selectedModelId = chat.modelId;
|
|
18466
|
+
demo.pickerChatIndex = chatIndex;
|
|
18174
18467
|
demo.modelMenuOpen = false;
|
|
18175
18468
|
demo.reasoningMenuOpen = false;
|
|
18176
18469
|
demo.contextMenuOpen = false;
|
|
@@ -18181,38 +18474,50 @@ app.addEventListener('click', async (event) => {
|
|
|
18181
18474
|
|
|
18182
18475
|
const modelButton = event.target.closest('[data-model]');
|
|
18183
18476
|
if (modelButton) {
|
|
18184
|
-
|
|
18185
|
-
|
|
18477
|
+
const chatIndex = Number(modelButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
|
|
18478
|
+
const chat = chatContext(chatIndex);
|
|
18479
|
+
chat.modelId = modelButton.getAttribute('data-model');
|
|
18480
|
+
demo.selectedModelId = chat.modelId;
|
|
18481
|
+
demo.selectedCliId = chat.cliId;
|
|
18186
18482
|
demo.cliConnected = true;
|
|
18187
18483
|
demo.modelMenuOpen = false;
|
|
18188
18484
|
demo.reasoningMenuOpen = false;
|
|
18189
18485
|
demo.contextMenuOpen = false;
|
|
18190
18486
|
demo.activeStudioTab = 'chat';
|
|
18191
|
-
demo.
|
|
18487
|
+
demo.pickerChatIndex = chatIndex;
|
|
18488
|
+
demo.notice = selectedModelLabel(chatIndex) + ' selected for this chat.';
|
|
18192
18489
|
render();
|
|
18193
18490
|
return;
|
|
18194
18491
|
}
|
|
18195
18492
|
|
|
18196
18493
|
const reasoningButton = event.target.closest('[data-reasoning]');
|
|
18197
18494
|
if (reasoningButton) {
|
|
18198
|
-
|
|
18495
|
+
const chatIndex = Number(reasoningButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
|
|
18496
|
+
const chat = chatContext(chatIndex);
|
|
18497
|
+
chat.reasoning = reasoningButton.getAttribute('data-reasoning');
|
|
18498
|
+
demo.selectedReasoning = chat.reasoning;
|
|
18199
18499
|
demo.reasoningMenuOpen = false;
|
|
18200
18500
|
demo.modelMenuOpen = false;
|
|
18201
18501
|
demo.contextMenuOpen = false;
|
|
18202
18502
|
demo.activeStudioTab = 'chat';
|
|
18203
|
-
demo.
|
|
18503
|
+
demo.pickerChatIndex = chatIndex;
|
|
18504
|
+
demo.notice = chat.reasoning + ' reasoning selected for this chat.';
|
|
18204
18505
|
render();
|
|
18205
18506
|
return;
|
|
18206
18507
|
}
|
|
18207
18508
|
|
|
18208
18509
|
const contextButton = event.target.closest('[data-context]');
|
|
18209
18510
|
if (contextButton) {
|
|
18210
|
-
|
|
18511
|
+
const chatIndex = Number(contextButton.getAttribute('data-chat-index') || String(demo.pickerChatIndex || 0));
|
|
18512
|
+
const chat = chatContext(chatIndex);
|
|
18513
|
+
chat.context = contextButton.getAttribute('data-context');
|
|
18514
|
+
demo.selectedContext = chat.context;
|
|
18211
18515
|
demo.contextMenuOpen = false;
|
|
18212
18516
|
demo.modelMenuOpen = false;
|
|
18213
18517
|
demo.reasoningMenuOpen = false;
|
|
18214
18518
|
demo.activeStudioTab = 'chat';
|
|
18215
|
-
demo.
|
|
18519
|
+
demo.pickerChatIndex = chatIndex;
|
|
18520
|
+
demo.notice = chat.context + ' context selected for this chat.';
|
|
18216
18521
|
render();
|
|
18217
18522
|
return;
|
|
18218
18523
|
}
|
|
@@ -18334,6 +18639,7 @@ app.addEventListener('click', async (event) => {
|
|
|
18334
18639
|
const actionButton = event.target.closest('[data-action]');
|
|
18335
18640
|
if (!actionButton) return;
|
|
18336
18641
|
const action = actionButton.getAttribute('data-action');
|
|
18642
|
+
const actionChatIndex = Math.max(0, Math.min(Number(actionButton.getAttribute('data-chat-index') || actionButton.closest('.vr-chat-lane')?.getAttribute('data-chat-index') || demo.pickerChatIndex || 0) || 0, demo.activeChatCount - 1));
|
|
18337
18643
|
if (action === 'close-modal') {
|
|
18338
18644
|
demo.activeModal = null;
|
|
18339
18645
|
render();
|
|
@@ -18410,18 +18716,22 @@ app.addEventListener('click', async (event) => {
|
|
|
18410
18716
|
return;
|
|
18411
18717
|
}
|
|
18412
18718
|
if (action === 'chat-agent-fix' || action === 'start-agent-fix') {
|
|
18719
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18413
18720
|
runChatTask('fix');
|
|
18414
18721
|
return;
|
|
18415
18722
|
}
|
|
18416
18723
|
if (action === 'verify-now') {
|
|
18724
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18417
18725
|
runChatTask('verify');
|
|
18418
18726
|
return;
|
|
18419
18727
|
}
|
|
18420
18728
|
if (action === 'recheck') {
|
|
18729
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18421
18730
|
runChatTask('verify');
|
|
18422
18731
|
return;
|
|
18423
18732
|
}
|
|
18424
18733
|
if (action === 'show-diff') {
|
|
18734
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18425
18735
|
runChatTask('diff');
|
|
18426
18736
|
return;
|
|
18427
18737
|
}
|
|
@@ -18434,13 +18744,41 @@ app.addEventListener('click', async (event) => {
|
|
|
18434
18744
|
render();
|
|
18435
18745
|
return;
|
|
18436
18746
|
}
|
|
18747
|
+
if (action === 'send-chat-message') {
|
|
18748
|
+
const chatIndex = Number(actionButton.getAttribute('data-chat-index') || '0');
|
|
18749
|
+
sendChatInput(chatIndex);
|
|
18750
|
+
return;
|
|
18751
|
+
}
|
|
18752
|
+
if (action === 'terminal-send') {
|
|
18753
|
+
const chatIndex = Math.max(0, Math.min(demo.pickerChatIndex || 0, demo.activeChatCount - 1));
|
|
18754
|
+
const terminalInput = app.querySelector('[data-terminal-input]');
|
|
18755
|
+
const value = String((terminalInput && 'value' in terminalInput ? terminalInput.value : '') || '').trim();
|
|
18756
|
+
if (!value) {
|
|
18757
|
+
demo.notice = 'Type a terminal-safe mission first, then send it to chat.';
|
|
18758
|
+
render();
|
|
18759
|
+
return;
|
|
18760
|
+
}
|
|
18761
|
+
chatContext(chatIndex).draft = value;
|
|
18762
|
+
demo.activeStudioTab = 'chat';
|
|
18763
|
+
demo.notice = 'Terminal note moved into chat. Press send when ready.';
|
|
18764
|
+
render();
|
|
18765
|
+
return;
|
|
18766
|
+
}
|
|
18767
|
+
if (action === 'diff-to-chat') {
|
|
18768
|
+
const chatIndex = Math.max(0, Math.min(demo.pickerChatIndex || 0, demo.activeChatCount - 1));
|
|
18769
|
+
chatContext(chatIndex).draft = 'Explain this diff, identify production risk, and suggest the next safe verification step.';
|
|
18770
|
+
demo.activeStudioTab = 'chat';
|
|
18771
|
+
demo.notice = 'Diff question moved into chat.';
|
|
18772
|
+
render();
|
|
18773
|
+
return;
|
|
18774
|
+
}
|
|
18437
18775
|
if (action === 'add-chat') {
|
|
18438
18776
|
demo.activeStudioTab = 'chat';
|
|
18439
18777
|
demo.activeChatCount = 1;
|
|
18440
18778
|
demo.activeRecentChatId = null;
|
|
18441
18779
|
demo.droppedProviderId = null;
|
|
18442
18780
|
demo.droppedReleaseId = null;
|
|
18443
|
-
demo.chatContexts = [{ providerId: null, releaseId: null }];
|
|
18781
|
+
demo.chatContexts = [defaultChatContext({ providerId: null, releaseId: null })];
|
|
18444
18782
|
demo.pickerChatIndex = 0;
|
|
18445
18783
|
demo.modelMenuOpen = false;
|
|
18446
18784
|
demo.reasoningMenuOpen = false;
|
|
@@ -18450,6 +18788,33 @@ app.addEventListener('click', async (event) => {
|
|
|
18450
18788
|
return;
|
|
18451
18789
|
}
|
|
18452
18790
|
if (action === 'new-chat') {
|
|
18791
|
+
demo.activeStudioTab = 'chat';
|
|
18792
|
+
demo.activeChatCount = 1;
|
|
18793
|
+
demo.activeRecentChatId = null;
|
|
18794
|
+
demo.chatContexts = [defaultChatContext({ providerId: null, releaseId: null })];
|
|
18795
|
+
demo.pickerChatIndex = 0;
|
|
18796
|
+
demo.dropActive = false;
|
|
18797
|
+
demo.dragKind = null;
|
|
18798
|
+
demo.dragProviderId = null;
|
|
18799
|
+
demo.dragReleaseId = null;
|
|
18800
|
+
demo.dragChatId = null;
|
|
18801
|
+
demo.agentFixing = false;
|
|
18802
|
+
demo.verified = false;
|
|
18803
|
+
demo.chatTaskKind = null;
|
|
18804
|
+
demo.chatTaskPhase = 'idle';
|
|
18805
|
+
demo.chatTaskPrompt = '';
|
|
18806
|
+
demo.chatTaskResponse = '';
|
|
18807
|
+
demo.chatTaskError = '';
|
|
18808
|
+
demo.chatTaskProviderId = null;
|
|
18809
|
+
demo.chatTaskReleaseId = null;
|
|
18810
|
+
demo.chatTaskChatIndex = 0;
|
|
18811
|
+
if (chatTaskTimer) window.clearTimeout(chatTaskTimer);
|
|
18812
|
+
setDragUi(null);
|
|
18813
|
+
demo.notice = 'New mission chat opened.';
|
|
18814
|
+
render();
|
|
18815
|
+
return;
|
|
18816
|
+
}
|
|
18817
|
+
if (action === 'split-chat') {
|
|
18453
18818
|
demo.activeStudioTab = 'chat';
|
|
18454
18819
|
demo.activeChatCount = Math.min(4, demo.activeChatCount + 1);
|
|
18455
18820
|
demo.activeRecentChatId = null;
|
|
@@ -18465,10 +18830,14 @@ app.addEventListener('click', async (event) => {
|
|
|
18465
18830
|
demo.chatTaskKind = null;
|
|
18466
18831
|
demo.chatTaskPhase = 'idle';
|
|
18467
18832
|
demo.chatTaskPrompt = '';
|
|
18833
|
+
demo.chatTaskResponse = '';
|
|
18834
|
+
demo.chatTaskError = '';
|
|
18468
18835
|
demo.chatTaskProviderId = null;
|
|
18836
|
+
demo.chatTaskReleaseId = null;
|
|
18837
|
+
demo.chatTaskChatIndex = 0;
|
|
18469
18838
|
if (chatTaskTimer) window.clearTimeout(chatTaskTimer);
|
|
18470
18839
|
setDragUi(null);
|
|
18471
|
-
demo.notice =
|
|
18840
|
+
demo.notice = 'New side-by-side mission chat opened. Drag a provider or version into that lane.';
|
|
18472
18841
|
render();
|
|
18473
18842
|
return;
|
|
18474
18843
|
}
|
|
@@ -18488,6 +18857,7 @@ app.addEventListener('click', async (event) => {
|
|
|
18488
18857
|
return;
|
|
18489
18858
|
}
|
|
18490
18859
|
if (action === 'guide') {
|
|
18860
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18491
18861
|
runChatTask('analyze');
|
|
18492
18862
|
return;
|
|
18493
18863
|
}
|
|
@@ -18510,10 +18880,12 @@ app.addEventListener('click', async (event) => {
|
|
|
18510
18880
|
return;
|
|
18511
18881
|
}
|
|
18512
18882
|
if (action === 'provider-proof') {
|
|
18883
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18513
18884
|
runChatTask('provider');
|
|
18514
18885
|
return;
|
|
18515
18886
|
}
|
|
18516
18887
|
if (action === 'plan') {
|
|
18888
|
+
demo.pickerChatIndex = actionChatIndex;
|
|
18517
18889
|
runChatTask('plan');
|
|
18518
18890
|
return;
|
|
18519
18891
|
}
|
|
@@ -18566,6 +18938,24 @@ app.addEventListener('pointerdown', (event) => {
|
|
|
18566
18938
|
}
|
|
18567
18939
|
});
|
|
18568
18940
|
|
|
18941
|
+
app.addEventListener('input', (event) => {
|
|
18942
|
+
const input = event.target && event.target.closest ? event.target.closest('.vr-chat-input') : null;
|
|
18943
|
+
if (input) {
|
|
18944
|
+
const chatIndex = Number(input.getAttribute('data-chat-input') || '0');
|
|
18945
|
+
chatContext(chatIndex).draft = input.value || '';
|
|
18946
|
+
return;
|
|
18947
|
+
}
|
|
18948
|
+
const terminalInput = event.target && event.target.closest ? event.target.closest('[data-terminal-input]') : null;
|
|
18949
|
+
if (terminalInput) chatContext(demo.pickerChatIndex || 0).draft = terminalInput.value || '';
|
|
18950
|
+
});
|
|
18951
|
+
|
|
18952
|
+
app.addEventListener('keydown', (event) => {
|
|
18953
|
+
const input = event.target && event.target.closest ? event.target.closest('.vr-chat-input') : null;
|
|
18954
|
+
if (!input || event.key !== 'Enter' || event.shiftKey) return;
|
|
18955
|
+
event.preventDefault();
|
|
18956
|
+
sendChatInput(input.getAttribute('data-chat-input') || '0');
|
|
18957
|
+
});
|
|
18958
|
+
|
|
18569
18959
|
app.addEventListener('dragstart', (event) => {
|
|
18570
18960
|
const providerButton = event.target.closest('[data-provider]');
|
|
18571
18961
|
const releaseButton = event.target.closest('[data-release]');
|
|
@@ -18589,7 +18979,7 @@ app.addEventListener('dragstart', (event) => {
|
|
|
18589
18979
|
provider ? '<img src="' + escapeHtml(providerMarkAssets[provider.id] || providerAssets[provider.id]) + '" alt="" />' : ''
|
|
18590
18980
|
);
|
|
18591
18981
|
providerButton.classList.add('is-being-dragged');
|
|
18592
|
-
demo.notice = 'Dragging provider context. Drop it into chat or
|
|
18982
|
+
demo.notice = 'Dragging provider context. Drop it into a chat composer or Split chat.';
|
|
18593
18983
|
setDragUi('provider');
|
|
18594
18984
|
return;
|
|
18595
18985
|
}
|
|
@@ -18627,7 +19017,7 @@ app.addEventListener('dragstart', (event) => {
|
|
|
18627
19017
|
});
|
|
18628
19018
|
|
|
18629
19019
|
app.addEventListener('dragover', (event) => {
|
|
18630
|
-
const dropTarget = event.target.closest('[data-chat-drop], [data-action="
|
|
19020
|
+
const dropTarget = event.target.closest('[data-chat-drop], [data-action="split-chat"]');
|
|
18631
19021
|
if (!dropTarget) return;
|
|
18632
19022
|
event.preventDefault();
|
|
18633
19023
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';
|
|
@@ -18636,21 +19026,23 @@ app.addEventListener('dragover', (event) => {
|
|
|
18636
19026
|
});
|
|
18637
19027
|
|
|
18638
19028
|
app.addEventListener('dragleave', (event) => {
|
|
18639
|
-
const dropTarget = event.target.closest('[data-chat-drop], [data-action="
|
|
19029
|
+
const dropTarget = event.target.closest('[data-chat-drop], [data-action="split-chat"]');
|
|
18640
19030
|
if (!dropTarget) return;
|
|
18641
19031
|
dropTarget.classList.remove('is-drop-active');
|
|
18642
19032
|
demo.dropActive = false;
|
|
18643
19033
|
});
|
|
18644
19034
|
|
|
18645
19035
|
app.addEventListener('drop', (event) => {
|
|
18646
|
-
const newChatTarget = event.target.closest('[data-action="
|
|
19036
|
+
const newChatTarget = event.target.closest('[data-action="split-chat"]');
|
|
18647
19037
|
const dropTarget = event.target.closest('[data-chat-drop]');
|
|
18648
19038
|
if (!newChatTarget && !dropTarget) return;
|
|
18649
19039
|
event.preventDefault();
|
|
18650
19040
|
(newChatTarget || dropTarget).classList.remove('is-drop-active');
|
|
18651
19041
|
const targetLane = event.target.closest('.vr-chat-lane');
|
|
19042
|
+
const chatId = event.dataTransfer?.getData('text/plain').replace(/^chat:/, '') || (demo.dragKind === 'chat' ? demo.dragChatId : '');
|
|
19043
|
+
const isRecentChatDrop = Boolean(chatId && recentChats.some((chat) => chat.id === chatId));
|
|
18652
19044
|
let newChatIndex = null;
|
|
18653
|
-
if (newChatTarget) {
|
|
19045
|
+
if (newChatTarget || isRecentChatDrop) {
|
|
18654
19046
|
demo.activeChatCount = Math.min(4, demo.activeChatCount + 1);
|
|
18655
19047
|
newChatIndex = demo.activeChatCount - 1;
|
|
18656
19048
|
chatContext(newChatIndex);
|
|
@@ -18660,13 +19052,12 @@ app.addEventListener('drop', (event) => {
|
|
|
18660
19052
|
const context = chatContext(chatIndex);
|
|
18661
19053
|
const providerId = event.dataTransfer?.getData('application/x-viberaven-provider') || (demo.dragKind === 'provider' ? demo.dragProviderId : '');
|
|
18662
19054
|
const releaseId = event.dataTransfer?.getData('application/x-viberaven-release') || (demo.dragKind === 'release' ? demo.dragReleaseId : '');
|
|
18663
|
-
|
|
18664
|
-
|
|
19055
|
+
if (isRecentChatDrop) {
|
|
19056
|
+
const recent = recentChats.find((chat) => chat.id === chatId);
|
|
18665
19057
|
demo.activeRecentChatId = chatId;
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
demo.notice = 'Recent production chat opened as the active mission.';
|
|
19058
|
+
context.providerId = recent?.providerId || null;
|
|
19059
|
+
context.releaseId = recent?.releaseId || null;
|
|
19060
|
+
demo.notice = recent ? recent.title + ' opened beside the active mission.' : 'Recent production chat opened beside the active mission.';
|
|
18670
19061
|
}
|
|
18671
19062
|
if (providerId) {
|
|
18672
19063
|
demo.selectedProviderId = providerId;
|
|
@@ -19933,6 +20324,16 @@ body:has(.vr-app.is-dragging) {
|
|
|
19933
20324
|
overflow: auto;
|
|
19934
20325
|
scrollbar-width: thin;
|
|
19935
20326
|
}
|
|
20327
|
+
.vr-recent-empty {
|
|
20328
|
+
margin: 0;
|
|
20329
|
+
border: 1px dashed rgba(148, 163, 184, 0.18);
|
|
20330
|
+
border-radius: 10px;
|
|
20331
|
+
background: rgba(255, 255, 255, 0.025);
|
|
20332
|
+
color: #94a3b8;
|
|
20333
|
+
padding: 12px;
|
|
20334
|
+
font-size: 12px;
|
|
20335
|
+
line-height: 1.45;
|
|
20336
|
+
}
|
|
19936
20337
|
.vr-recent-chat {
|
|
19937
20338
|
min-width: 0;
|
|
19938
20339
|
min-height: 60px;
|
|
@@ -20304,7 +20705,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
20304
20705
|
overflow: hidden;
|
|
20305
20706
|
}
|
|
20306
20707
|
.vr-studio-chat {
|
|
20307
|
-
grid-template-rows:
|
|
20708
|
+
grid-template-rows: minmax(0, 1fr);
|
|
20308
20709
|
gap: 10px;
|
|
20309
20710
|
padding: 12px;
|
|
20310
20711
|
}
|
|
@@ -20321,6 +20722,9 @@ body:has(.vr-app.is-dragging) {
|
|
|
20321
20722
|
.vr-studio-diff {
|
|
20322
20723
|
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
20323
20724
|
}
|
|
20725
|
+
.vr-studio-terminal {
|
|
20726
|
+
grid-template-rows: auto minmax(0, 1fr) auto auto;
|
|
20727
|
+
}
|
|
20324
20728
|
.vr-studio-terminal header,
|
|
20325
20729
|
.vr-studio-diff header,
|
|
20326
20730
|
.vr-studio-terminal footer,
|
|
@@ -20346,6 +20750,47 @@ body:has(.vr-app.is-dragging) {
|
|
|
20346
20750
|
color: #bfdbfe;
|
|
20347
20751
|
font: 13px/1.55 "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
|
|
20348
20752
|
}
|
|
20753
|
+
.vr-terminal-compose {
|
|
20754
|
+
display: grid;
|
|
20755
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
20756
|
+
align-items: end;
|
|
20757
|
+
gap: 10px;
|
|
20758
|
+
border-top: 1px solid rgba(96, 122, 177, 0.18);
|
|
20759
|
+
padding: 10px 12px;
|
|
20760
|
+
}
|
|
20761
|
+
.vr-terminal-compose textarea {
|
|
20762
|
+
min-height: 44px;
|
|
20763
|
+
resize: none;
|
|
20764
|
+
border: 1px solid rgba(148, 163, 184, 0.16);
|
|
20765
|
+
border-radius: 10px;
|
|
20766
|
+
background: rgba(255, 255, 255, 0.035);
|
|
20767
|
+
color: #e5e7eb;
|
|
20768
|
+
padding: 9px 10px;
|
|
20769
|
+
font: 13px/1.4 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
20770
|
+
outline: none;
|
|
20771
|
+
}
|
|
20772
|
+
.vr-terminal-compose textarea:focus {
|
|
20773
|
+
border-color: rgba(168, 85, 247, 0.45);
|
|
20774
|
+
}
|
|
20775
|
+
.vr-terminal-compose button {
|
|
20776
|
+
min-height: 38px;
|
|
20777
|
+
display: inline-flex;
|
|
20778
|
+
align-items: center;
|
|
20779
|
+
gap: 7px;
|
|
20780
|
+
border: 1px solid rgba(168, 85, 247, 0.45);
|
|
20781
|
+
border-radius: 10px;
|
|
20782
|
+
background: rgba(124, 58, 237, 0.2);
|
|
20783
|
+
color: #fff;
|
|
20784
|
+
padding: 0 12px;
|
|
20785
|
+
font-weight: 800;
|
|
20786
|
+
}
|
|
20787
|
+
.vr-terminal-compose svg {
|
|
20788
|
+
width: 15px;
|
|
20789
|
+
height: 15px;
|
|
20790
|
+
fill: none;
|
|
20791
|
+
stroke: currentColor;
|
|
20792
|
+
stroke-width: 2;
|
|
20793
|
+
}
|
|
20349
20794
|
.vr-studio-diff .add { color: #86efac; }
|
|
20350
20795
|
.vr-studio-diff .del { color: #fca5a5; }
|
|
20351
20796
|
|
|
@@ -20448,7 +20893,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
20448
20893
|
min-height: 100%;
|
|
20449
20894
|
min-height: 0;
|
|
20450
20895
|
display: grid;
|
|
20451
|
-
grid-template-rows: minmax(0, 1fr) auto;
|
|
20896
|
+
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
20452
20897
|
border: 0;
|
|
20453
20898
|
border-radius: 0;
|
|
20454
20899
|
background: transparent;
|
|
@@ -20515,6 +20960,9 @@ body:has(.vr-app.is-dragging) {
|
|
|
20515
20960
|
.vr-studio-chat.is-split .vr-chat-command-bar > .vr-chat-composer {
|
|
20516
20961
|
grid-template-columns: minmax(0, 1fr) 38px;
|
|
20517
20962
|
}
|
|
20963
|
+
.vr-studio-chat.is-split .vr-chat-input {
|
|
20964
|
+
grid-column: 1;
|
|
20965
|
+
}
|
|
20518
20966
|
.vr-studio-chat.is-split .vr-model-picker {
|
|
20519
20967
|
grid-column: 1 / -1;
|
|
20520
20968
|
justify-self: start;
|
|
@@ -20532,7 +20980,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
20532
20980
|
max-width: none;
|
|
20533
20981
|
}
|
|
20534
20982
|
.vr-studio-chat:not(.is-split) .vr-chat-transcript {
|
|
20535
|
-
padding: 18px 18px
|
|
20983
|
+
padding: 18px 18px 10px;
|
|
20536
20984
|
}
|
|
20537
20985
|
.vr-studio-chat:not(.is-split) .vr-chat-message,
|
|
20538
20986
|
.vr-studio-chat:not(.is-split) .vr-chat-mission-summary {
|
|
@@ -20542,11 +20990,11 @@ body:has(.vr-app.is-dragging) {
|
|
|
20542
20990
|
max-width: 720px;
|
|
20543
20991
|
}
|
|
20544
20992
|
.vr-studio-chat:not(.is-split) .vr-chat-message.is-user {
|
|
20545
|
-
max-width:
|
|
20993
|
+
max-width: min(620px, 74%);
|
|
20546
20994
|
justify-self: end;
|
|
20547
20995
|
}
|
|
20548
20996
|
.vr-studio-chat:not(.is-split) .vr-chat-message.is-user > p {
|
|
20549
|
-
max-width:
|
|
20997
|
+
max-width: 560px;
|
|
20550
20998
|
}
|
|
20551
20999
|
.vr-studio-chat:not(.is-split) .vr-chat-message p {
|
|
20552
21000
|
font-size: 13.5px;
|
|
@@ -20581,19 +21029,16 @@ body:has(.vr-app.is-dragging) {
|
|
|
20581
21029
|
}
|
|
20582
21030
|
.vr-studio-chat:not(.is-split) .vr-chat-command-bar {
|
|
20583
21031
|
padding: 0;
|
|
21032
|
+
align-self: end;
|
|
20584
21033
|
}
|
|
20585
21034
|
.vr-studio-chat:not(.is-split) .vr-chat-command-bar > .vr-chat-composer {
|
|
20586
|
-
min-height:
|
|
21035
|
+
min-height: 92px;
|
|
20587
21036
|
border-color: rgba(226, 232, 240, 0.16);
|
|
20588
21037
|
border-radius: 14px;
|
|
20589
21038
|
background: #202124;
|
|
20590
21039
|
color: #f4f4f5;
|
|
20591
21040
|
padding: 10px 14px;
|
|
20592
21041
|
}
|
|
20593
|
-
.vr-studio-chat:not(.is-split) .vr-chat-command-bar > .vr-chat-composer > span {
|
|
20594
|
-
color: #9ca3af;
|
|
20595
|
-
font-size: 13px;
|
|
20596
|
-
}
|
|
20597
21042
|
.vr-studio-chat:not(.is-split) .vr-provider-drop-zone > span {
|
|
20598
21043
|
border-color: rgba(226, 232, 240, 0.14);
|
|
20599
21044
|
background: rgba(255, 255, 255, 0.04);
|
|
@@ -20606,10 +21051,10 @@ body:has(.vr-app.is-dragging) {
|
|
|
20606
21051
|
padding-top: 18px;
|
|
20607
21052
|
}
|
|
20608
21053
|
.vr-studio-chat:not(.is-split) .vr-chat-message.is-user {
|
|
20609
|
-
position:
|
|
20610
|
-
top:
|
|
20611
|
-
right:
|
|
20612
|
-
z-index:
|
|
21054
|
+
position: relative;
|
|
21055
|
+
top: auto;
|
|
21056
|
+
right: auto;
|
|
21057
|
+
z-index: auto;
|
|
20613
21058
|
}
|
|
20614
21059
|
.vr-studio-chat:not(.is-split) .vr-chat-message.is-agent,
|
|
20615
21060
|
.vr-studio-chat:not(.is-split) .vr-chat-mission-summary {
|
|
@@ -20705,7 +21150,7 @@ body:has(.vr-app.is-dragging) {
|
|
|
20705
21150
|
min-height: 0;
|
|
20706
21151
|
display: grid;
|
|
20707
21152
|
align-content: start;
|
|
20708
|
-
gap:
|
|
21153
|
+
gap: 14px;
|
|
20709
21154
|
overflow: auto;
|
|
20710
21155
|
scrollbar-width: thin;
|
|
20711
21156
|
padding: 20px 24px 12px;
|
|
@@ -20719,37 +21164,78 @@ body:has(.vr-app.is-dragging) {
|
|
|
20719
21164
|
max-width: 560px;
|
|
20720
21165
|
justify-self: end;
|
|
20721
21166
|
justify-items: end;
|
|
21167
|
+
margin-top: 4px;
|
|
20722
21168
|
}
|
|
20723
21169
|
.vr-chat-message.is-user > p {
|
|
20724
21170
|
width: fit-content;
|
|
20725
21171
|
border: 1px solid rgba(148, 163, 184, 0.14);
|
|
20726
|
-
border-radius:
|
|
20727
|
-
background:
|
|
20728
|
-
|
|
21172
|
+
border-radius: 13px 13px 4px 13px;
|
|
21173
|
+
background: #f8fafc;
|
|
21174
|
+
color: #111827;
|
|
21175
|
+
padding: 9px 12px;
|
|
20729
21176
|
text-align: left;
|
|
20730
21177
|
}
|
|
20731
21178
|
.vr-chat-message.is-user > p {
|
|
20732
21179
|
padding-left: 12px;
|
|
20733
21180
|
}
|
|
20734
|
-
.vr-
|
|
21181
|
+
.vr-sent-context {
|
|
21182
|
+
max-width: 560px;
|
|
21183
|
+
display: flex;
|
|
21184
|
+
flex-wrap: wrap;
|
|
21185
|
+
justify-content: flex-end;
|
|
21186
|
+
gap: 7px;
|
|
21187
|
+
}
|
|
21188
|
+
.vr-sent-context span {
|
|
21189
|
+
min-height: 30px;
|
|
21190
|
+
max-width: min(360px, 100%);
|
|
21191
|
+
display: inline-flex;
|
|
21192
|
+
align-items: center;
|
|
21193
|
+
gap: 8px;
|
|
21194
|
+
border: 1px solid rgba(148, 163, 184, 0.16);
|
|
21195
|
+
border-radius: 10px;
|
|
21196
|
+
background: rgba(255, 255, 255, 0.055);
|
|
21197
|
+
color: #cbd5e1;
|
|
21198
|
+
padding: 4px 9px;
|
|
21199
|
+
font-size: 12px;
|
|
21200
|
+
}
|
|
21201
|
+
.vr-sent-context img,
|
|
21202
|
+
.vr-sent-context i {
|
|
21203
|
+
width: 22px;
|
|
21204
|
+
height: 22px;
|
|
21205
|
+
flex: 0 0 auto;
|
|
21206
|
+
display: grid;
|
|
20735
21207
|
place-items: center;
|
|
20736
|
-
|
|
21208
|
+
overflow: hidden;
|
|
21209
|
+
border: 1px solid rgba(148, 163, 184, 0.16);
|
|
21210
|
+
border-radius: 8px;
|
|
21211
|
+
background: rgba(15, 23, 42, 0.7);
|
|
21212
|
+
object-fit: contain;
|
|
21213
|
+
font-style: normal;
|
|
20737
21214
|
}
|
|
20738
|
-
.vr-
|
|
20739
|
-
|
|
20740
|
-
|
|
20741
|
-
|
|
20742
|
-
|
|
20743
|
-
|
|
21215
|
+
.vr-sent-context b {
|
|
21216
|
+
border: 0;
|
|
21217
|
+
background: transparent;
|
|
21218
|
+
color: #94a3b8;
|
|
21219
|
+
padding: 0;
|
|
21220
|
+
font-size: 10px;
|
|
21221
|
+
font-weight: 720;
|
|
21222
|
+
text-transform: uppercase;
|
|
21223
|
+
letter-spacing: 0;
|
|
21224
|
+
}
|
|
21225
|
+
.vr-sent-context em {
|
|
21226
|
+
overflow: hidden;
|
|
21227
|
+
text-overflow: ellipsis;
|
|
21228
|
+
white-space: nowrap;
|
|
21229
|
+
margin: 0;
|
|
21230
|
+
color: #f8fafc;
|
|
21231
|
+
font-style: normal;
|
|
21232
|
+
font-weight: 760;
|
|
20744
21233
|
}
|
|
20745
21234
|
.vr-chat-message > div {
|
|
20746
21235
|
display: flex;
|
|
20747
21236
|
align-items: center;
|
|
20748
21237
|
gap: 8px;
|
|
20749
21238
|
}
|
|
20750
|
-
.vr-chat-message.is-user > div {
|
|
20751
|
-
justify-self: end;
|
|
20752
|
-
}
|
|
20753
21239
|
.vr-chat-message > div > span {
|
|
20754
21240
|
width: 28px;
|
|
20755
21241
|
height: 28px;
|
|
@@ -20797,6 +21283,61 @@ body:has(.vr-app.is-dragging) {
|
|
|
20797
21283
|
color: #aeb9ca;
|
|
20798
21284
|
font-style: normal;
|
|
20799
21285
|
}
|
|
21286
|
+
.vr-chat-message > .vr-sent-context,
|
|
21287
|
+
.vr-chat-message > .vr-agent-response-meta,
|
|
21288
|
+
.vr-chat-message > .vr-agent-context-line {
|
|
21289
|
+
width: auto;
|
|
21290
|
+
height: auto;
|
|
21291
|
+
display: flex;
|
|
21292
|
+
flex-wrap: wrap;
|
|
21293
|
+
align-items: center;
|
|
21294
|
+
overflow: visible;
|
|
21295
|
+
}
|
|
21296
|
+
.vr-chat-message > .vr-sent-context > span,
|
|
21297
|
+
.vr-chat-message > .vr-agent-response-meta > span,
|
|
21298
|
+
.vr-chat-message > .vr-agent-context-line > span {
|
|
21299
|
+
width: auto;
|
|
21300
|
+
height: auto;
|
|
21301
|
+
min-width: 0;
|
|
21302
|
+
display: inline-flex;
|
|
21303
|
+
align-items: center;
|
|
21304
|
+
justify-content: flex-start;
|
|
21305
|
+
place-items: initial;
|
|
21306
|
+
overflow: hidden;
|
|
21307
|
+
border-radius: 10px;
|
|
21308
|
+
}
|
|
21309
|
+
.vr-chat-message > .vr-sent-context img,
|
|
21310
|
+
.vr-chat-message > .vr-sent-context i,
|
|
21311
|
+
.vr-chat-message > .vr-agent-response-meta img,
|
|
21312
|
+
.vr-chat-message > .vr-agent-response-meta i,
|
|
21313
|
+
.vr-chat-message > .vr-agent-context-line img,
|
|
21314
|
+
.vr-chat-message > .vr-agent-context-line i {
|
|
21315
|
+
transform: none;
|
|
21316
|
+
}
|
|
21317
|
+
.vr-chat-message > .vr-sent-context b,
|
|
21318
|
+
.vr-chat-message > .vr-agent-response-meta b,
|
|
21319
|
+
.vr-chat-message > .vr-agent-context-line b {
|
|
21320
|
+
border: 0;
|
|
21321
|
+
background: transparent;
|
|
21322
|
+
color: #94a3b8;
|
|
21323
|
+
padding: 0;
|
|
21324
|
+
font-size: 10px;
|
|
21325
|
+
font-weight: 720;
|
|
21326
|
+
text-transform: uppercase;
|
|
21327
|
+
}
|
|
21328
|
+
.vr-chat-message > .vr-sent-context em,
|
|
21329
|
+
.vr-chat-message > .vr-agent-response-meta em,
|
|
21330
|
+
.vr-chat-message > .vr-agent-context-line em {
|
|
21331
|
+
min-width: 0;
|
|
21332
|
+
overflow: hidden;
|
|
21333
|
+
text-overflow: ellipsis;
|
|
21334
|
+
white-space: nowrap;
|
|
21335
|
+
margin: 0;
|
|
21336
|
+
color: #f8fafc;
|
|
21337
|
+
font-size: 12px;
|
|
21338
|
+
font-style: normal;
|
|
21339
|
+
font-weight: 720;
|
|
21340
|
+
}
|
|
20800
21341
|
.vr-chat-copy {
|
|
20801
21342
|
max-width: 720px;
|
|
20802
21343
|
margin: 0;
|
|
@@ -21174,6 +21715,134 @@ body:has(.vr-app.is-dragging) {
|
|
|
21174
21715
|
font-size: 12px;
|
|
21175
21716
|
line-height: 1.35;
|
|
21176
21717
|
}
|
|
21718
|
+
.vr-chat-agent-response {
|
|
21719
|
+
max-width: min(920px, 82%);
|
|
21720
|
+
display: grid;
|
|
21721
|
+
gap: 7px;
|
|
21722
|
+
animation: vrTaskEnter 220ms cubic-bezier(0.2, 0, 0, 1) both;
|
|
21723
|
+
}
|
|
21724
|
+
.vr-agent-response-meta {
|
|
21725
|
+
margin-left: 48px;
|
|
21726
|
+
max-width: min(640px, calc(100% - 48px));
|
|
21727
|
+
display: flex;
|
|
21728
|
+
flex-wrap: wrap;
|
|
21729
|
+
align-items: center;
|
|
21730
|
+
gap: 8px;
|
|
21731
|
+
}
|
|
21732
|
+
.vr-agent-thinking-label {
|
|
21733
|
+
min-height: 24px;
|
|
21734
|
+
display: inline-flex;
|
|
21735
|
+
align-items: center;
|
|
21736
|
+
gap: 7px;
|
|
21737
|
+
border: 1px solid rgba(245, 158, 11, 0.16);
|
|
21738
|
+
border-radius: 999px;
|
|
21739
|
+
background: rgba(245, 158, 11, 0.055);
|
|
21740
|
+
color: #f6b35c;
|
|
21741
|
+
padding: 3px 9px;
|
|
21742
|
+
font-size: 11px;
|
|
21743
|
+
font-weight: 680;
|
|
21744
|
+
}
|
|
21745
|
+
.vr-agent-thinking-label::before {
|
|
21746
|
+
content: "";
|
|
21747
|
+
width: 7px;
|
|
21748
|
+
height: 7px;
|
|
21749
|
+
flex: 0 0 auto;
|
|
21750
|
+
border-radius: 999px;
|
|
21751
|
+
background: #f97316;
|
|
21752
|
+
box-shadow: 0 0 12px rgba(249, 115, 22, 0.4);
|
|
21753
|
+
}
|
|
21754
|
+
.vr-agent-context-line {
|
|
21755
|
+
margin-left: 48px;
|
|
21756
|
+
max-width: min(640px, calc(100% - 48px));
|
|
21757
|
+
display: flex;
|
|
21758
|
+
flex-wrap: wrap;
|
|
21759
|
+
gap: 8px;
|
|
21760
|
+
}
|
|
21761
|
+
.vr-agent-context-line span {
|
|
21762
|
+
min-width: 0;
|
|
21763
|
+
min-height: 32px;
|
|
21764
|
+
display: inline-flex;
|
|
21765
|
+
align-items: center;
|
|
21766
|
+
gap: 8px;
|
|
21767
|
+
border: 1px solid rgba(148, 163, 184, 0.16);
|
|
21768
|
+
border-radius: 10px;
|
|
21769
|
+
background: rgba(255, 255, 255, 0.045);
|
|
21770
|
+
padding: 4px 10px 4px 5px;
|
|
21771
|
+
}
|
|
21772
|
+
.vr-agent-context-line img,
|
|
21773
|
+
.vr-agent-context-line i {
|
|
21774
|
+
width: 24px;
|
|
21775
|
+
height: 24px;
|
|
21776
|
+
flex: 0 0 auto;
|
|
21777
|
+
display: grid;
|
|
21778
|
+
place-items: center;
|
|
21779
|
+
overflow: hidden;
|
|
21780
|
+
border-radius: 8px;
|
|
21781
|
+
background: rgba(15, 23, 42, 0.72);
|
|
21782
|
+
object-fit: contain;
|
|
21783
|
+
transform: none;
|
|
21784
|
+
font-style: normal;
|
|
21785
|
+
}
|
|
21786
|
+
.vr-agent-context-line b {
|
|
21787
|
+
margin: 0;
|
|
21788
|
+
color: #94a3b8;
|
|
21789
|
+
font-size: 10px;
|
|
21790
|
+
font-weight: 720;
|
|
21791
|
+
text-transform: uppercase;
|
|
21792
|
+
letter-spacing: 0;
|
|
21793
|
+
}
|
|
21794
|
+
.vr-agent-context-line em {
|
|
21795
|
+
min-width: 0;
|
|
21796
|
+
overflow: hidden;
|
|
21797
|
+
text-overflow: ellipsis;
|
|
21798
|
+
white-space: nowrap;
|
|
21799
|
+
margin: 0;
|
|
21800
|
+
color: #f8fafc;
|
|
21801
|
+
font-size: 12px;
|
|
21802
|
+
font-style: normal;
|
|
21803
|
+
font-weight: 720;
|
|
21804
|
+
}
|
|
21805
|
+
.vr-agent-answer-text {
|
|
21806
|
+
max-width: min(860px, calc(100% - 48px));
|
|
21807
|
+
overflow: visible;
|
|
21808
|
+
white-space: pre-wrap;
|
|
21809
|
+
color: #e5e7eb;
|
|
21810
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
21811
|
+
font-size: 13.5px;
|
|
21812
|
+
line-height: 1.58;
|
|
21813
|
+
}
|
|
21814
|
+
.vr-chat-response-actions {
|
|
21815
|
+
padding-left: 48px;
|
|
21816
|
+
display: flex;
|
|
21817
|
+
flex-wrap: wrap;
|
|
21818
|
+
gap: 8px;
|
|
21819
|
+
}
|
|
21820
|
+
.vr-chat-response-actions button {
|
|
21821
|
+
min-height: 30px;
|
|
21822
|
+
display: inline-flex;
|
|
21823
|
+
align-items: center;
|
|
21824
|
+
gap: 7px;
|
|
21825
|
+
border: 1px solid rgba(148, 163, 184, 0.16);
|
|
21826
|
+
border-radius: 8px;
|
|
21827
|
+
background: rgba(255, 255, 255, 0.035);
|
|
21828
|
+
color: #f8fafc;
|
|
21829
|
+
padding: 0 10px;
|
|
21830
|
+
font-size: 12px;
|
|
21831
|
+
font-weight: 740;
|
|
21832
|
+
}
|
|
21833
|
+
.vr-chat-response-actions button:hover {
|
|
21834
|
+
border-color: rgba(168, 85, 247, 0.34);
|
|
21835
|
+
background: rgba(168, 85, 247, 0.12);
|
|
21836
|
+
}
|
|
21837
|
+
.vr-chat-response-actions svg {
|
|
21838
|
+
width: 14px;
|
|
21839
|
+
height: 14px;
|
|
21840
|
+
fill: none;
|
|
21841
|
+
stroke: currentColor;
|
|
21842
|
+
stroke-width: 1.9;
|
|
21843
|
+
stroke-linecap: round;
|
|
21844
|
+
stroke-linejoin: round;
|
|
21845
|
+
}
|
|
21177
21846
|
.vr-chat-card header {
|
|
21178
21847
|
display: flex;
|
|
21179
21848
|
align-items: center;
|
|
@@ -21375,6 +22044,31 @@ body:has(.vr-app.is-dragging) {
|
|
|
21375
22044
|
color: #f8fafc;
|
|
21376
22045
|
padding: 12px 14px;
|
|
21377
22046
|
}
|
|
22047
|
+
.vr-chat-input {
|
|
22048
|
+
grid-column: 1 / 3;
|
|
22049
|
+
grid-row: 1;
|
|
22050
|
+
align-self: stretch;
|
|
22051
|
+
width: 100%;
|
|
22052
|
+
min-width: 0;
|
|
22053
|
+
min-height: 38px;
|
|
22054
|
+
border: 0;
|
|
22055
|
+
outline: 0;
|
|
22056
|
+
resize: none;
|
|
22057
|
+
background: transparent;
|
|
22058
|
+
color: #f8fafc;
|
|
22059
|
+
padding: 0;
|
|
22060
|
+
font: inherit;
|
|
22061
|
+
font-size: 13.5px;
|
|
22062
|
+
font-weight: 520;
|
|
22063
|
+
line-height: 1.45;
|
|
22064
|
+
caret-color: #f8fafc;
|
|
22065
|
+
}
|
|
22066
|
+
.vr-chat-input::placeholder {
|
|
22067
|
+
color: #a1a8b3;
|
|
22068
|
+
}
|
|
22069
|
+
.vr-chat-input:focus {
|
|
22070
|
+
outline: 0;
|
|
22071
|
+
}
|
|
21378
22072
|
.vr-chat-command-bar > .vr-chat-composer > span {
|
|
21379
22073
|
align-self: start;
|
|
21380
22074
|
overflow: hidden;
|
|
@@ -24475,6 +25169,11 @@ body:has(.vr-app.is-dragging) {
|
|
|
24475
25169
|
min-width: 0;
|
|
24476
25170
|
min-height: 92px;
|
|
24477
25171
|
}
|
|
25172
|
+
.vr-chat-input {
|
|
25173
|
+
grid-column: 1;
|
|
25174
|
+
min-width: 0;
|
|
25175
|
+
overflow-wrap: anywhere;
|
|
25176
|
+
}
|
|
24478
25177
|
.vr-chat-command-bar > .vr-chat-composer > span {
|
|
24479
25178
|
min-width: 0;
|
|
24480
25179
|
overflow-wrap: anywhere;
|
|
@@ -24546,19 +25245,173 @@ async function defaultScanRunner(flags, positional) {
|
|
|
24546
25245
|
const cli = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
24547
25246
|
return cli.runScanCommand(flags, positional);
|
|
24548
25247
|
}
|
|
24549
|
-
async function
|
|
25248
|
+
async function readPackageJson2(cwd) {
|
|
24550
25249
|
try {
|
|
24551
25250
|
const raw = await (0, import_promises24.readFile)((0, import_node_path31.join)(cwd, "package.json"), "utf8");
|
|
24552
|
-
const parsed = JSON.parse(raw);
|
|
24553
|
-
|
|
24554
|
-
return {
|
|
24555
|
-
name: typeof parsed.name === "string" && parsed.name.trim() ? parsed.name.trim() : void 0,
|
|
24556
|
-
version: typeof parsed.version === "string" && parsed.version.trim() ? parsed.version.trim() : void 0
|
|
24557
|
-
};
|
|
25251
|
+
const parsed = JSON.parse(raw.replace(/^\uFEFF/, ""));
|
|
25252
|
+
return isRecord7(parsed) ? parsed : {};
|
|
24558
25253
|
} catch {
|
|
24559
25254
|
return {};
|
|
24560
25255
|
}
|
|
24561
25256
|
}
|
|
25257
|
+
function dependencyNames(packageJson) {
|
|
25258
|
+
const names = /* @__PURE__ */ new Set();
|
|
25259
|
+
for (const key of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
25260
|
+
const value = packageJson[key];
|
|
25261
|
+
if (!isRecord7(value)) continue;
|
|
25262
|
+
Object.keys(value).forEach((name) => names.add(name.toLowerCase()));
|
|
25263
|
+
}
|
|
25264
|
+
return names;
|
|
25265
|
+
}
|
|
25266
|
+
async function listProjectFiles(cwd, maxFiles = 1800) {
|
|
25267
|
+
const skipped = /* @__PURE__ */ new Set([".git", "node_modules", ".next", "dist", "build", "coverage", ".turbo", ".viberaven"]);
|
|
25268
|
+
const files = [];
|
|
25269
|
+
async function walk(dir, prefix = "") {
|
|
25270
|
+
if (files.length >= maxFiles) return;
|
|
25271
|
+
let entries;
|
|
25272
|
+
try {
|
|
25273
|
+
entries = await (0, import_promises24.readdir)(dir, { withFileTypes: true });
|
|
25274
|
+
} catch {
|
|
25275
|
+
return;
|
|
25276
|
+
}
|
|
25277
|
+
for (const entry of entries) {
|
|
25278
|
+
if (files.length >= maxFiles) return;
|
|
25279
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
25280
|
+
if (entry.isDirectory()) {
|
|
25281
|
+
if (!skipped.has(entry.name)) await walk((0, import_node_path31.join)(dir, entry.name), rel);
|
|
25282
|
+
continue;
|
|
25283
|
+
}
|
|
25284
|
+
if (entry.isFile()) files.push(rel.toLowerCase());
|
|
25285
|
+
}
|
|
25286
|
+
}
|
|
25287
|
+
await walk(cwd);
|
|
25288
|
+
return files;
|
|
25289
|
+
}
|
|
25290
|
+
function hasDependency(deps, needles) {
|
|
25291
|
+
return needles.some((needle) => deps.has(needle) || Array.from(deps).some((dep) => dep.includes(needle)));
|
|
25292
|
+
}
|
|
25293
|
+
function hasFile(files, needles) {
|
|
25294
|
+
return needles.some((needle) => files.some((file) => file.includes(needle)));
|
|
25295
|
+
}
|
|
25296
|
+
function providerDetected(providerId, deps, files) {
|
|
25297
|
+
switch (providerId) {
|
|
25298
|
+
case "supabase":
|
|
25299
|
+
return hasDependency(deps, ["@supabase/supabase-js", "supabase"]) || hasFile(files, ["supabase/", "supabase\\", "supabase.ts"]);
|
|
25300
|
+
case "vercel":
|
|
25301
|
+
return hasFile(files, ["vercel.json", ".vercel/project.json"]) || hasDependency(deps, ["@vercel/"]);
|
|
25302
|
+
case "stripe":
|
|
25303
|
+
return hasDependency(deps, ["stripe", "@stripe/stripe-js"]) || hasFile(files, ["stripe", "webhook"]);
|
|
25304
|
+
case "github":
|
|
25305
|
+
return hasFile(files, [".github/workflows", ".github/dependabot.yml"]) || files.includes("readme.md");
|
|
25306
|
+
case "sentry":
|
|
25307
|
+
return hasDependency(deps, ["@sentry/"]) || hasFile(files, ["sentry.", "instrumentation.ts", "instrumentation.js"]);
|
|
25308
|
+
case "posthog":
|
|
25309
|
+
return hasDependency(deps, ["posthog", "posthog-js"]) || hasFile(files, ["posthog"]);
|
|
25310
|
+
case "clerk":
|
|
25311
|
+
return hasDependency(deps, ["@clerk/"]) || hasFile(files, ["clerk", "middleware.ts", "middleware.js"]);
|
|
25312
|
+
case "authjs":
|
|
25313
|
+
return hasDependency(deps, ["next-auth", "@auth/"]) || hasFile(files, ["auth.ts", "auth.js", "nextauth"]);
|
|
25314
|
+
case "resend":
|
|
25315
|
+
return hasDependency(deps, ["resend"]) || hasFile(files, ["resend", "email", "mail"]);
|
|
25316
|
+
case "upstash":
|
|
25317
|
+
return hasDependency(deps, ["@upstash/", "upstash"]) || hasFile(files, ["upstash", "ratelimit", "rate-limit", "redis"]);
|
|
25318
|
+
default:
|
|
25319
|
+
return false;
|
|
25320
|
+
}
|
|
25321
|
+
}
|
|
25322
|
+
function collapseAuthProviders(providers) {
|
|
25323
|
+
const authProviders = providers.filter((provider2) => provider2.id === "clerk" || provider2.id === "authjs");
|
|
25324
|
+
if (authProviders.length <= 1) return providers;
|
|
25325
|
+
const detectedAuth = authProviders.find((provider2) => provider2.state !== "not_detected");
|
|
25326
|
+
const visibleAuth = detectedAuth ?? authProviders.find((provider2) => provider2.id === "clerk") ?? authProviders[0];
|
|
25327
|
+
return providers.filter((provider2) => provider2.id !== "clerk" && provider2.id !== "authjs").concat(visibleAuth);
|
|
25328
|
+
}
|
|
25329
|
+
function providerDetail(provider2, detected) {
|
|
25330
|
+
if (detected) {
|
|
25331
|
+
return `${provider2.area} evidence was found in this project. Drag this slot into chat to ask the connected CLI for the next production step.`;
|
|
25332
|
+
}
|
|
25333
|
+
return `${provider2.area} is available as a production slot. Add it when this project depends on ${provider2.name}.`;
|
|
25334
|
+
}
|
|
25335
|
+
function applyProviderDetection(state, deps, files) {
|
|
25336
|
+
const providers = collapseAuthProviders(state.providers.map((provider2) => {
|
|
25337
|
+
const detected = providerDetected(provider2.id, deps, files);
|
|
25338
|
+
const providerState2 = detected ? provider2.state === "not_detected" ? "repo_evidence_found" : provider2.state : "not_detected";
|
|
25339
|
+
return {
|
|
25340
|
+
...provider2,
|
|
25341
|
+
state: providerState2,
|
|
25342
|
+
statusText: detected ? "Detected in repo" : "Add when needed",
|
|
25343
|
+
connectLabel: detected ? "Open slot" : "Add provider",
|
|
25344
|
+
launchPath: provider2.launchPath.map((item4, index) => ({
|
|
25345
|
+
...item4,
|
|
25346
|
+
state: detected && item4.source === "repo" && index < 2 ? "ready" : "not_checked",
|
|
25347
|
+
shortReason: detected ? "Repo evidence detected" : "No local evidence yet"
|
|
25348
|
+
})),
|
|
25349
|
+
selectedItemId: provider2.launchPath[0]?.id,
|
|
25350
|
+
nextFix: provider2.nextFix ? {
|
|
25351
|
+
...provider2.nextFix,
|
|
25352
|
+
title: detected ? `Review ${provider2.name} production proof` : `Add ${provider2.name} when needed`,
|
|
25353
|
+
whyItMatters: providerDetail(provider2, detected),
|
|
25354
|
+
whatToChange: detected ? `Ask VibeRaven Chat to inspect ${provider2.name} evidence and identify missing production proof.` : `Use Add Provider when this project starts using ${provider2.name}.`,
|
|
25355
|
+
verifyInstruction: "Use the connected CLI chat to inspect local evidence before claiming live provider proof."
|
|
25356
|
+
} : provider2.nextFix
|
|
25357
|
+
};
|
|
25358
|
+
}));
|
|
25359
|
+
const firstDetected = providers.find((provider2) => provider2.state !== "not_detected");
|
|
25360
|
+
return {
|
|
25361
|
+
...state,
|
|
25362
|
+
providers,
|
|
25363
|
+
selectedProviderId: firstDetected?.id ?? providers[0]?.id ?? state.selectedProviderId
|
|
25364
|
+
};
|
|
25365
|
+
}
|
|
25366
|
+
function runGit(cwd, args, timeoutMs = 1500) {
|
|
25367
|
+
return new Promise((resolveGit) => {
|
|
25368
|
+
const child = (0, import_node_child_process4.spawn)("git", args, {
|
|
25369
|
+
cwd,
|
|
25370
|
+
windowsHide: true,
|
|
25371
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
25372
|
+
});
|
|
25373
|
+
let stdout = "";
|
|
25374
|
+
const timer = setTimeout(() => child.kill(), timeoutMs);
|
|
25375
|
+
child.stdout?.on("data", (chunk) => {
|
|
25376
|
+
stdout += chunk.toString("utf8");
|
|
25377
|
+
});
|
|
25378
|
+
child.once("error", () => {
|
|
25379
|
+
clearTimeout(timer);
|
|
25380
|
+
resolveGit("");
|
|
25381
|
+
});
|
|
25382
|
+
child.once("close", () => {
|
|
25383
|
+
clearTimeout(timer);
|
|
25384
|
+
resolveGit(stdout.trim());
|
|
25385
|
+
});
|
|
25386
|
+
});
|
|
25387
|
+
}
|
|
25388
|
+
async function detectReleases(cwd, version) {
|
|
25389
|
+
const branch = await runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]) || "local";
|
|
25390
|
+
const tagsRaw = await runGit(cwd, ["tag", "--sort=-creatordate"]);
|
|
25391
|
+
const tags = tagsRaw.split(/\r?\n/).map((tag) => tag.trim()).filter(Boolean).slice(0, 5);
|
|
25392
|
+
if (tags.length > 0) {
|
|
25393
|
+
return tags.map((tag, index) => ({
|
|
25394
|
+
id: tag,
|
|
25395
|
+
label: tag,
|
|
25396
|
+
meta: index === 0 ? "latest tag" : "git tag",
|
|
25397
|
+
branch,
|
|
25398
|
+
tone: index === 0 ? "current" : "prod",
|
|
25399
|
+
summary: index === 0 ? "Latest git tag detected locally." : "Git tag detected locally."
|
|
25400
|
+
}));
|
|
25401
|
+
}
|
|
25402
|
+
const shortSha = await runGit(cwd, ["rev-parse", "--short", "HEAD"]) || "";
|
|
25403
|
+
const current = version ? `v${version}` : shortSha ? `commit ${shortSha}` : "Workspace";
|
|
25404
|
+
return [
|
|
25405
|
+
{
|
|
25406
|
+
id: current.toLowerCase().replace(/[^a-z0-9._-]+/g, "-"),
|
|
25407
|
+
label: current,
|
|
25408
|
+
meta: shortSha ? "current commit" : "not released",
|
|
25409
|
+
branch,
|
|
25410
|
+
tone: "current",
|
|
25411
|
+
summary: shortSha ? "Current git commit detected locally." : "No git release was detected yet."
|
|
25412
|
+
}
|
|
25413
|
+
];
|
|
25414
|
+
}
|
|
24562
25415
|
function cliModelDefaults(id) {
|
|
24563
25416
|
switch (id) {
|
|
24564
25417
|
case "claude":
|
|
@@ -24622,14 +25475,23 @@ function isPlaceholderProjectName(value) {
|
|
|
24622
25475
|
return normalized === "" || normalized === "project" || normalized === "npx-open-source-check" || normalized.startsWith("viberaven-local-ui");
|
|
24623
25476
|
}
|
|
24624
25477
|
async function enrichProjectMetadata(state, cwd) {
|
|
24625
|
-
const
|
|
24626
|
-
|
|
25478
|
+
const packageJson = await readPackageJson2(cwd);
|
|
25479
|
+
const metadata = {
|
|
25480
|
+
name: typeof packageJson.name === "string" && packageJson.name.trim() ? packageJson.name.trim() : void 0,
|
|
25481
|
+
version: typeof packageJson.version === "string" && packageJson.version.trim() ? packageJson.version.trim() : void 0
|
|
25482
|
+
};
|
|
25483
|
+
const files = await listProjectFiles(cwd);
|
|
25484
|
+
const deps = dependencyNames(packageJson);
|
|
25485
|
+
const detectedState = state.empty ? applyProviderDetection(state, deps, files) : state;
|
|
25486
|
+
const releases = await detectReleases(cwd, metadata.version);
|
|
24627
25487
|
return {
|
|
24628
|
-
...
|
|
25488
|
+
...detectedState,
|
|
25489
|
+
releases,
|
|
25490
|
+
selectedProviderId: detectedState.providers.find((provider2) => provider2.id === detectedState.selectedProviderId) ? detectedState.selectedProviderId : detectedState.providers[0]?.id ?? detectedState.selectedProviderId,
|
|
24629
25491
|
project: {
|
|
24630
|
-
...
|
|
24631
|
-
name: metadata.name && !isPlaceholderProjectName(metadata.name) ? metadata.name :
|
|
24632
|
-
version: metadata.version ??
|
|
25492
|
+
...detectedState.project,
|
|
25493
|
+
name: metadata.name && !isPlaceholderProjectName(metadata.name) ? metadata.name : detectedState.project.name,
|
|
25494
|
+
version: metadata.version ?? detectedState.project.version
|
|
24633
25495
|
}
|
|
24634
25496
|
};
|
|
24635
25497
|
}
|
|
@@ -24689,6 +25551,172 @@ function localActionIntent(value) {
|
|
|
24689
25551
|
if (!isRecord7(value) || typeof value.intent !== "string") return null;
|
|
24690
25552
|
return ["audit_vercel_supabase", "cleanup_plan", "preview_rehearsal", "heal_plan", "heal_prompt", "heal_apply"].includes(value.intent) ? value.intent : null;
|
|
24691
25553
|
}
|
|
25554
|
+
function stringField(value, max = 2e3) {
|
|
25555
|
+
if (typeof value !== "string") return void 0;
|
|
25556
|
+
const trimmed = value.trim();
|
|
25557
|
+
return trimmed ? trimmed.slice(0, max) : void 0;
|
|
25558
|
+
}
|
|
25559
|
+
function parseAgentChatRequest(value) {
|
|
25560
|
+
if (!isRecord7(value)) return { error: "Invalid agent chat request" };
|
|
25561
|
+
const rawCliId = stringField(value.cliId, 40);
|
|
25562
|
+
if (rawCliId === "terminal") return { error: "Terminal chat execution is not supported. Use an explicit terminal command surface." };
|
|
25563
|
+
if (rawCliId !== "codex" && rawCliId !== "claude" && rawCliId !== "gemini") return { error: "Unsupported coding CLI" };
|
|
25564
|
+
const prompt = stringField(value.prompt, 12e3);
|
|
25565
|
+
if (!prompt) return { error: "Agent chat prompt is required" };
|
|
25566
|
+
const provider2 = isRecord7(value.provider) ? { area: stringField(value.provider.area, 120), name: stringField(value.provider.name, 120) } : void 0;
|
|
25567
|
+
const release = isRecord7(value.release) ? { label: stringField(value.release.label, 120) } : void 0;
|
|
25568
|
+
return {
|
|
25569
|
+
cliId: rawCliId,
|
|
25570
|
+
modelId: stringField(value.modelId, 120),
|
|
25571
|
+
reasoning: stringField(value.reasoning, 80),
|
|
25572
|
+
context: stringField(value.context, 80),
|
|
25573
|
+
prompt,
|
|
25574
|
+
provider: provider2,
|
|
25575
|
+
release
|
|
25576
|
+
};
|
|
25577
|
+
}
|
|
25578
|
+
function buildAgentChatPrompt(request, cwd) {
|
|
25579
|
+
const lines = [
|
|
25580
|
+
"You are VibeRaven Studio, a production-readiness coding agent for an open-source local runner.",
|
|
25581
|
+
`Project folder: ${cwd}`,
|
|
25582
|
+
request.modelId ? `Selected model label: ${request.modelId}` : void 0,
|
|
25583
|
+
request.reasoning ? `Reasoning: ${request.reasoning}` : void 0,
|
|
25584
|
+
request.context ? `Context: ${request.context}` : void 0,
|
|
25585
|
+
request.provider?.name ? `Provider context: ${request.provider.area ?? "Provider"} / ${request.provider.name}` : void 0,
|
|
25586
|
+
request.release?.label ? `Release context: ${request.release.label}` : void 0,
|
|
25587
|
+
"",
|
|
25588
|
+
"Safety rules:",
|
|
25589
|
+
"- Stay scoped to this project folder.",
|
|
25590
|
+
"- Explain risky or destructive changes before making them.",
|
|
25591
|
+
"- Do not claim provider dashboard setup is complete from repo edits alone.",
|
|
25592
|
+
"- Keep the answer focused on production readiness.",
|
|
25593
|
+
"- Return only the final user-facing answer. Do not echo this prompt, session metadata, logs, or command transcripts.",
|
|
25594
|
+
"- Prefer short sections with concrete next actions and verification buttons can handle follow-up actions.",
|
|
25595
|
+
"",
|
|
25596
|
+
"User mission:",
|
|
25597
|
+
request.prompt
|
|
25598
|
+
];
|
|
25599
|
+
return lines.filter((line) => typeof line === "string").join("\n");
|
|
25600
|
+
}
|
|
25601
|
+
function commandForAgentChat(request, prompt, cwd, outputPath) {
|
|
25602
|
+
const command = process.platform === "win32" ? `${request.cliId}.cmd` : request.cliId;
|
|
25603
|
+
const promptArg = prompt.replace(/\s*\r?\n\s*/g, " ");
|
|
25604
|
+
if (request.cliId === "gemini") return { command, args: ["-p", promptArg, "--output-format", "text", "--skip-trust"] };
|
|
25605
|
+
if (request.cliId === "claude") return { command, args: ["-p", promptArg] };
|
|
25606
|
+
const codexArgs = ["--cd", cwd, "--sandbox", "workspace-write", "--ask-for-approval", "never", "exec", "--color", "never"];
|
|
25607
|
+
if (outputPath) codexArgs.push("--output-last-message", outputPath);
|
|
25608
|
+
codexArgs.push("-");
|
|
25609
|
+
return {
|
|
25610
|
+
command,
|
|
25611
|
+
args: codexArgs,
|
|
25612
|
+
stdin: prompt
|
|
25613
|
+
};
|
|
25614
|
+
}
|
|
25615
|
+
function quoteWindowsCmdArg(value) {
|
|
25616
|
+
if (/^[A-Za-z0-9._/@:=+-]+$/.test(value)) return value;
|
|
25617
|
+
return `"${value.replace(/%/g, "%%").replace(/"/g, '""')}"`;
|
|
25618
|
+
}
|
|
25619
|
+
async function resolveWindowsNodeShim(command, cwd) {
|
|
25620
|
+
if (process.platform !== "win32" || !command.endsWith(".cmd")) return void 0;
|
|
25621
|
+
const shimPath = await new Promise((resolvePath) => {
|
|
25622
|
+
const child = (0, import_node_child_process4.spawn)("where.exe", [command], {
|
|
25623
|
+
cwd,
|
|
25624
|
+
windowsHide: true,
|
|
25625
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
25626
|
+
});
|
|
25627
|
+
let stdout = "";
|
|
25628
|
+
child.stdout?.on("data", (chunk) => {
|
|
25629
|
+
stdout += chunk.toString("utf8");
|
|
25630
|
+
});
|
|
25631
|
+
child.once("error", () => resolvePath(void 0));
|
|
25632
|
+
child.once("close", (code) => {
|
|
25633
|
+
if (code !== 0) {
|
|
25634
|
+
resolvePath(void 0);
|
|
25635
|
+
return;
|
|
25636
|
+
}
|
|
25637
|
+
resolvePath(stdout.split(/\r?\n/).map((line) => line.trim()).find(Boolean));
|
|
25638
|
+
});
|
|
25639
|
+
});
|
|
25640
|
+
if (!shimPath) return void 0;
|
|
25641
|
+
try {
|
|
25642
|
+
const content = await (0, import_promises24.readFile)(shimPath, "utf8");
|
|
25643
|
+
const match = content.match(/"%dp0%\\([^"]+\.js)"/i);
|
|
25644
|
+
if (!match?.[1]) return void 0;
|
|
25645
|
+
return { command: process.execPath, args: [(0, import_node_path31.join)((0, import_node_path31.dirname)(shimPath), match[1])] };
|
|
25646
|
+
} catch {
|
|
25647
|
+
return void 0;
|
|
25648
|
+
}
|
|
25649
|
+
}
|
|
25650
|
+
async function runAgentCommand(command, args, cwd, stdin) {
|
|
25651
|
+
const nodeShim = await resolveWindowsNodeShim(command, cwd);
|
|
25652
|
+
const useCmdShim = process.platform === "win32" && command.endsWith(".cmd") && !nodeShim;
|
|
25653
|
+
const spawnCommand = nodeShim?.command ?? (useCmdShim ? process.env.ComSpec || "cmd.exe" : command);
|
|
25654
|
+
const spawnArgs = nodeShim ? [...nodeShim.args, ...args] : useCmdShim ? ["/d", "/s", "/c", [command, ...args.map(quoteWindowsCmdArg)].join(" ")] : args;
|
|
25655
|
+
return new Promise((resolveRun) => {
|
|
25656
|
+
const child = (0, import_node_child_process4.spawn)(spawnCommand, spawnArgs, {
|
|
25657
|
+
cwd,
|
|
25658
|
+
windowsHide: true,
|
|
25659
|
+
stdio: [stdin ? "pipe" : "ignore", "pipe", "pipe"]
|
|
25660
|
+
});
|
|
25661
|
+
let stdout = "";
|
|
25662
|
+
let stderr = "";
|
|
25663
|
+
let timedOut = false;
|
|
25664
|
+
const append = (current, chunk) => {
|
|
25665
|
+
const next = current + chunk.toString("utf8");
|
|
25666
|
+
return next.length > 48e3 ? next.slice(0, 48e3) : next;
|
|
25667
|
+
};
|
|
25668
|
+
const timer = setTimeout(() => {
|
|
25669
|
+
timedOut = true;
|
|
25670
|
+
child.kill();
|
|
25671
|
+
}, 12e4);
|
|
25672
|
+
child.stdout?.on("data", (chunk) => {
|
|
25673
|
+
stdout = append(stdout, chunk);
|
|
25674
|
+
});
|
|
25675
|
+
child.stderr?.on("data", (chunk) => {
|
|
25676
|
+
stderr = append(stderr, chunk);
|
|
25677
|
+
});
|
|
25678
|
+
if (stdin && child.stdin) {
|
|
25679
|
+
child.stdin.end(stdin);
|
|
25680
|
+
}
|
|
25681
|
+
child.once("error", (error) => {
|
|
25682
|
+
clearTimeout(timer);
|
|
25683
|
+
resolveRun({
|
|
25684
|
+
command,
|
|
25685
|
+
args,
|
|
25686
|
+
exitCode: null,
|
|
25687
|
+
output: "",
|
|
25688
|
+
stderr: error.message,
|
|
25689
|
+
timedOut
|
|
25690
|
+
});
|
|
25691
|
+
});
|
|
25692
|
+
child.once("close", (code) => {
|
|
25693
|
+
clearTimeout(timer);
|
|
25694
|
+
resolveRun({
|
|
25695
|
+
command,
|
|
25696
|
+
args,
|
|
25697
|
+
exitCode: code,
|
|
25698
|
+
output: stdout.trim(),
|
|
25699
|
+
stderr: stderr.trim(),
|
|
25700
|
+
timedOut
|
|
25701
|
+
});
|
|
25702
|
+
});
|
|
25703
|
+
});
|
|
25704
|
+
}
|
|
25705
|
+
async function runAgentChat(cwd, request) {
|
|
25706
|
+
const prompt = buildAgentChatPrompt(request, cwd);
|
|
25707
|
+
const outputPath = request.cliId === "codex" ? (0, import_node_path31.join)(cwd, ".viberaven", `studio-agent-${Date.now()}-${Math.random().toString(36).slice(2)}.md`) : void 0;
|
|
25708
|
+
if (outputPath) await (0, import_promises24.mkdir)((0, import_node_path31.dirname)(outputPath), { recursive: true });
|
|
25709
|
+
const { command, args, stdin } = commandForAgentChat(request, prompt, cwd, outputPath);
|
|
25710
|
+
const result = await runAgentCommand(command, args, cwd, stdin);
|
|
25711
|
+
if (outputPath) {
|
|
25712
|
+
try {
|
|
25713
|
+
const finalMessage = (await (0, import_promises24.readFile)(outputPath, "utf8")).trim();
|
|
25714
|
+
if (finalMessage) return { ...result, output: finalMessage };
|
|
25715
|
+
} catch {
|
|
25716
|
+
}
|
|
25717
|
+
}
|
|
25718
|
+
return result;
|
|
25719
|
+
}
|
|
24692
25720
|
function firstGapId(state) {
|
|
24693
25721
|
if (state.empty) return void 0;
|
|
24694
25722
|
return state.providers.find((provider2) => provider2.nextFix?.id)?.nextFix?.id;
|
|
@@ -24984,6 +26012,23 @@ async function handleRequest(request, response, options) {
|
|
|
24984
26012
|
sendJson(response, await detectLocalCliAgents(options.cwd));
|
|
24985
26013
|
return;
|
|
24986
26014
|
}
|
|
26015
|
+
if (request.method === "POST" && url.pathname === "/api/agent-chat") {
|
|
26016
|
+
let body;
|
|
26017
|
+
try {
|
|
26018
|
+
body = await readJsonBody(request);
|
|
26019
|
+
} catch {
|
|
26020
|
+
sendText(response, 400, "Invalid JSON");
|
|
26021
|
+
return;
|
|
26022
|
+
}
|
|
26023
|
+
const parsed = parseAgentChatRequest(body);
|
|
26024
|
+
if ("error" in parsed) {
|
|
26025
|
+
sendText(response, 400, parsed.error);
|
|
26026
|
+
return;
|
|
26027
|
+
}
|
|
26028
|
+
const agentRun = await runAgentChat(options.cwd, parsed);
|
|
26029
|
+
sendJson(response, { agentRun });
|
|
26030
|
+
return;
|
|
26031
|
+
}
|
|
24987
26032
|
if (request.method === "POST" && url.pathname === "/api/shutdown") {
|
|
24988
26033
|
sendJson(response, { ok: true });
|
|
24989
26034
|
setTimeout(() => process.kill(process.pid, "SIGINT"), 0);
|
|
@@ -25486,6 +26531,9 @@ function resolveDefaultEntrypointMode(options) {
|
|
|
25486
26531
|
if (options.env.VIBERAVEN_AGENT === "1") return "agent-scan";
|
|
25487
26532
|
return "local-ui";
|
|
25488
26533
|
}
|
|
26534
|
+
function resolvePositionalCwd(positional) {
|
|
26535
|
+
return positional[0] ? (0, import_node_path33.resolve)(process.cwd(), positional[0]) : process.cwd();
|
|
26536
|
+
}
|
|
25489
26537
|
function formatScanJsonStdout(artifact) {
|
|
25490
26538
|
return JSON.stringify(sanitizeArtifactForDisk(artifact), null, 2);
|
|
25491
26539
|
}
|
|
@@ -25526,7 +26574,7 @@ async function cmdStatus(flags, positional) {
|
|
|
25526
26574
|
console.log("Not signed in. Run: viberaven login");
|
|
25527
26575
|
return 1;
|
|
25528
26576
|
}
|
|
25529
|
-
const startDir =
|
|
26577
|
+
const startDir = resolvePositionalCwd(positional);
|
|
25530
26578
|
let artifact;
|
|
25531
26579
|
try {
|
|
25532
26580
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -25680,7 +26728,7 @@ async function cmdWatch(flags) {
|
|
|
25680
26728
|
}
|
|
25681
26729
|
}
|
|
25682
26730
|
async function runScanCommand(flags, positional, options) {
|
|
25683
|
-
const workspacePath = positional[0] ? (
|
|
26731
|
+
const workspacePath = positional[0] ? resolvePositionalCwd(positional) : await resolveWorkspaceRoot(process.cwd());
|
|
25684
26732
|
const apiBaseUrl = resolveApiBaseUrl(typeof flags["api-url"] === "string" ? flags["api-url"] : void 0);
|
|
25685
26733
|
let accessToken;
|
|
25686
26734
|
try {
|
|
@@ -25764,7 +26812,7 @@ async function runScanCommand(flags, positional, options) {
|
|
|
25764
26812
|
return { exitCode: 0, artifacts: paths };
|
|
25765
26813
|
}
|
|
25766
26814
|
async function cmdReport(flags, positional) {
|
|
25767
|
-
const startDir =
|
|
26815
|
+
const startDir = resolvePositionalCwd(positional);
|
|
25768
26816
|
try {
|
|
25769
26817
|
const paths = await refreshReportFromDisk(startDir);
|
|
25770
26818
|
console.log(`Report refreshed: ${paths.reportPath}`);
|
|
@@ -25786,7 +26834,7 @@ async function cmdReport(flags, positional) {
|
|
|
25786
26834
|
}
|
|
25787
26835
|
}
|
|
25788
26836
|
async function cmdPrompt(flags, positional) {
|
|
25789
|
-
const startDir =
|
|
26837
|
+
const startDir = resolvePositionalCwd(positional);
|
|
25790
26838
|
let artifact;
|
|
25791
26839
|
try {
|
|
25792
26840
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -25883,7 +26931,7 @@ async function main() {
|
|
|
25883
26931
|
const wantsJsonl = hasFlag(flags, "jsonl");
|
|
25884
26932
|
const wantsStrict = hasFlag(flags, "strict");
|
|
25885
26933
|
if (flags.condense) {
|
|
25886
|
-
const cwd =
|
|
26934
|
+
const cwd = resolvePositionalCwd(positional);
|
|
25887
26935
|
const result = await runCondenseCommand({ cwd });
|
|
25888
26936
|
console.log(`VibeRaven context map refreshed: ${result.contextMapPath}`);
|
|
25889
26937
|
return 0;
|
|
@@ -25903,7 +26951,7 @@ async function main() {
|
|
|
25903
26951
|
}
|
|
25904
26952
|
if (!command && flags.verify === true && typeof flags.action === "string") {
|
|
25905
26953
|
return runVerifyActionCommand({
|
|
25906
|
-
cwd:
|
|
26954
|
+
cwd: resolvePositionalCwd(positional),
|
|
25907
26955
|
actionId: flags.action
|
|
25908
26956
|
});
|
|
25909
26957
|
}
|
|
@@ -25940,7 +26988,7 @@ async function main() {
|
|
|
25940
26988
|
env: process.env
|
|
25941
26989
|
});
|
|
25942
26990
|
if (mode === "local-ui") {
|
|
25943
|
-
const cwd =
|
|
26991
|
+
const cwd = resolvePositionalCwd(positional);
|
|
25944
26992
|
const handle = await startLocalUiServer({ cwd });
|
|
25945
26993
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
25946
26994
|
await waitForServerShutdown();
|
|
@@ -25960,7 +27008,7 @@ async function main() {
|
|
|
25960
27008
|
await runInteractiveSession();
|
|
25961
27009
|
return 0;
|
|
25962
27010
|
case "ui": {
|
|
25963
|
-
const cwd =
|
|
27011
|
+
const cwd = resolvePositionalCwd(positional);
|
|
25964
27012
|
const handle = await startLocalUiServer({ cwd });
|
|
25965
27013
|
console.log(`VibeRaven local UI: ${handle.url}`);
|
|
25966
27014
|
await waitForServerShutdown();
|
|
@@ -25977,19 +27025,19 @@ async function main() {
|
|
|
25977
27025
|
return cmdStatus(flags, positional);
|
|
25978
27026
|
case "actions":
|
|
25979
27027
|
return runActionsCommand({
|
|
25980
|
-
cwd:
|
|
27028
|
+
cwd: resolvePositionalCwd(positional),
|
|
25981
27029
|
json: Boolean(flags.json)
|
|
25982
27030
|
});
|
|
25983
27031
|
case "preview":
|
|
25984
27032
|
return runPreviewCommand({
|
|
25985
|
-
cwd:
|
|
27033
|
+
cwd: resolvePositionalCwd(positional),
|
|
25986
27034
|
agentMode: flags["agent-mode"] === true,
|
|
25987
27035
|
json: Boolean(flags.json)
|
|
25988
27036
|
});
|
|
25989
27037
|
case "next":
|
|
25990
27038
|
return runNextCommand({
|
|
25991
27039
|
json: Boolean(flags.json),
|
|
25992
|
-
cwd:
|
|
27040
|
+
cwd: resolvePositionalCwd(positional)
|
|
25993
27041
|
});
|
|
25994
27042
|
case "guide": {
|
|
25995
27043
|
const provider2 = positional[0];
|
|
@@ -26027,7 +27075,7 @@ async function main() {
|
|
|
26027
27075
|
case "provider-verify":
|
|
26028
27076
|
return cmdProviderVerify(flags, positional);
|
|
26029
27077
|
case "init": {
|
|
26030
|
-
const cwd =
|
|
27078
|
+
const cwd = resolvePositionalCwd(positional);
|
|
26031
27079
|
const agents = typeof flags.agents === "string" ? flags.agents : void 0;
|
|
26032
27080
|
return runInitCommand({
|
|
26033
27081
|
cwd,
|
|
@@ -26041,7 +27089,7 @@ async function main() {
|
|
|
26041
27089
|
return 1;
|
|
26042
27090
|
}
|
|
26043
27091
|
return runDoctorAgentsCommand({
|
|
26044
|
-
cwd:
|
|
27092
|
+
cwd: resolvePositionalCwd(positional)
|
|
26045
27093
|
});
|
|
26046
27094
|
case "validate-npm-package":
|
|
26047
27095
|
return runValidateNpmPackageCommand({
|
|
@@ -26054,7 +27102,7 @@ async function main() {
|
|
|
26054
27102
|
return 1;
|
|
26055
27103
|
}
|
|
26056
27104
|
return runAuditCommand({
|
|
26057
|
-
cwd:
|
|
27105
|
+
cwd: resolvePositionalCwd(positional),
|
|
26058
27106
|
json: Boolean(flags.json)
|
|
26059
27107
|
});
|
|
26060
27108
|
default:
|