voyageai-cli 1.24.0 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli.js +2 -0
- package/src/commands/about.js +1 -1
- package/src/commands/bug.js +1 -1
- package/src/commands/playground.js +31 -0
- package/src/commands/scaffold.js +23 -1
- package/src/commands/workflow.js +336 -0
- package/src/lib/explanations.js +53 -0
- package/src/lib/scaffold-structure.js +8 -9
- package/src/lib/telemetry.js +1 -1
- package/src/lib/template-engine.js +240 -0
- package/src/lib/templates/nextjs/README.md.tpl +78 -55
- package/src/lib/templates/nextjs/favicon.svg.tpl +11 -0
- package/src/lib/templates/nextjs/footer.jsx.tpl +49 -0
- package/src/lib/templates/nextjs/layout.jsx.tpl +16 -10
- package/src/lib/templates/nextjs/lib-mongo.js.tpl +5 -5
- package/src/lib/templates/nextjs/lib-voyage.js.tpl +13 -8
- package/src/lib/templates/nextjs/navbar.jsx.tpl +98 -0
- package/src/lib/templates/nextjs/page-home.jsx.tpl +201 -0
- package/src/lib/templates/nextjs/page-search.jsx.tpl +184 -82
- package/src/lib/templates/nextjs/theme-registry.jsx.tpl +51 -0
- package/src/lib/templates/nextjs/theme.js.tpl +138 -65
- package/src/lib/templates/nextjs/vai-logo-256.png +0 -0
- package/src/lib/workflow-utils.js +65 -0
- package/src/lib/workflow.js +1259 -0
- package/src/mcp/tools/management.js +1 -60
- package/src/playground/icons/dark/128.png +0 -0
- package/src/playground/icons/dark/16.png +0 -0
- package/src/playground/icons/dark/256.png +0 -0
- package/src/playground/icons/dark/32.png +0 -0
- package/src/playground/icons/dark/64.png +0 -0
- package/src/playground/icons/light/128.png +0 -0
- package/src/playground/icons/light/16.png +0 -0
- package/src/playground/icons/light/256.png +0 -0
- package/src/playground/icons/light/32.png +0 -0
- package/src/playground/icons/light/64.png +0 -0
- package/src/playground/icons/watermark.png +0 -0
- package/src/playground/index.html +125 -73
- package/src/workflows/consistency-check.json +64 -0
- package/src/workflows/cost-analysis.json +69 -0
- package/src/workflows/multi-collection-search.json +80 -0
- package/src/workflows/research-and-summarize.json +46 -0
- package/src/workflows/smart-ingest.json +63 -0
|
@@ -2,66 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { MODEL_CATALOG } = require('../../lib/catalog');
|
|
4
4
|
const { loadProject } = require('../../lib/project');
|
|
5
|
-
const {
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Introspect MongoDB collections — list collections with vector index info.
|
|
9
|
-
* @param {string} dbName
|
|
10
|
-
* @returns {Promise<Array<{ name: string, documentCount: number, hasVectorIndex: boolean, embeddingField?: string, dimensions?: number }>>}
|
|
11
|
-
*/
|
|
12
|
-
async function introspectCollections(dbName) {
|
|
13
|
-
const { MongoClient } = require('mongodb');
|
|
14
|
-
const uri = requireMongoUri();
|
|
15
|
-
const client = new MongoClient(uri);
|
|
16
|
-
await client.connect();
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
const db = client.db(dbName);
|
|
20
|
-
const collections = await db.listCollections().toArray();
|
|
21
|
-
const results = [];
|
|
22
|
-
|
|
23
|
-
for (const collInfo of collections) {
|
|
24
|
-
if (collInfo.name.startsWith('system.')) continue;
|
|
25
|
-
const coll = db.collection(collInfo.name);
|
|
26
|
-
const documentCount = await coll.estimatedDocumentCount();
|
|
27
|
-
|
|
28
|
-
let hasVectorIndex = false;
|
|
29
|
-
let embeddingField;
|
|
30
|
-
let dimensions;
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
const indexes = await coll.listSearchIndexes().toArray();
|
|
34
|
-
for (const idx of indexes) {
|
|
35
|
-
// Atlas Search index definitions vary; look for vector type
|
|
36
|
-
const fields = idx.latestDefinition?.fields || [];
|
|
37
|
-
for (const f of fields) {
|
|
38
|
-
if (f.type === 'vector') {
|
|
39
|
-
hasVectorIndex = true;
|
|
40
|
-
embeddingField = f.path;
|
|
41
|
-
dimensions = f.numDimensions;
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (hasVectorIndex) break;
|
|
46
|
-
}
|
|
47
|
-
} catch {
|
|
48
|
-
// listSearchIndexes may not be available on non-Atlas deployments
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
results.push({
|
|
52
|
-
name: collInfo.name,
|
|
53
|
-
documentCount,
|
|
54
|
-
hasVectorIndex,
|
|
55
|
-
...(embeddingField && { embeddingField }),
|
|
56
|
-
...(dimensions && { dimensions }),
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return results;
|
|
61
|
-
} finally {
|
|
62
|
-
await client.close();
|
|
63
|
-
}
|
|
64
|
-
}
|
|
5
|
+
const { introspectCollections } = require('../../lib/workflow-utils');
|
|
65
6
|
|
|
66
7
|
/**
|
|
67
8
|
* Register management tools: vai_collections, vai_models
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -10,56 +10,56 @@
|
|
|
10
10
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
11
11
|
|
|
12
12
|
:root {
|
|
13
|
-
/*
|
|
13
|
+
/* Vai Dark Mode Palette (default) — Teal/Cyan brand */
|
|
14
14
|
--bg: #001E2B; /* MDB Black */
|
|
15
15
|
--bg-surface: #112733; /* Gray Dark 4 */
|
|
16
16
|
--bg-card: #1C2D38; /* Gray Dark 3 */
|
|
17
17
|
--bg-input: #112733; /* Gray Dark 4 */
|
|
18
|
-
--accent: #
|
|
18
|
+
--accent: #00D4AA; /* Teal — interactive elements */
|
|
19
19
|
--accent-text: #FFFFFF; /* Bright white — headings/labels in dark mode */
|
|
20
|
-
--accent-dim: #
|
|
21
|
-
--accent-glow: rgba(0,
|
|
20
|
+
--accent-dim: #009E80; /* Teal Dark */
|
|
21
|
+
--accent-glow: rgba(0, 212, 170, 0.10);
|
|
22
22
|
--text: #E8EDEB; /* Gray Light 2 */
|
|
23
23
|
--text-dim: #C1C7C6; /* Gray Light 1 */
|
|
24
24
|
--text-muted: #889397; /* Gray Base */
|
|
25
25
|
--border: #3D4F58; /* Gray Dark 2 */
|
|
26
26
|
--error: #FF6960; /* Red Light 1 */
|
|
27
27
|
--warning: #FFC010; /* Yellow Base */
|
|
28
|
-
--success: #
|
|
28
|
+
--success: #00D4AA; /* Teal */
|
|
29
29
|
--red: #FF6960; /* Red Light 1 */
|
|
30
30
|
--yellow: #FFC010; /* Yellow Base */
|
|
31
|
-
--green: #
|
|
32
|
-
--blue: #
|
|
31
|
+
--green: #00D4AA; /* Teal */
|
|
32
|
+
--blue: #40E0FF; /* Cyan (links) */
|
|
33
33
|
--purple: #B45AF2; /* Purple Base */
|
|
34
|
-
--green-dark: #
|
|
34
|
+
--green-dark: #00241E; /* Teal Dark 3 */
|
|
35
35
|
--radius: 8px;
|
|
36
36
|
--font: 'Euclid Circular A', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
|
37
37
|
--mono: 'Source Code Pro', 'SF Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
/*
|
|
40
|
+
/* Vai Light Mode Palette — Teal/Cyan brand */
|
|
41
41
|
[data-theme="light"] {
|
|
42
42
|
--bg: #FFFFFF; /* White */
|
|
43
43
|
--bg-surface: #F9FBFA; /* Gray Light 3 */
|
|
44
44
|
--bg-card: #FFFFFF; /* White */
|
|
45
45
|
--bg-input: #F9FBFA; /* Gray Light 3 */
|
|
46
|
-
--accent: #
|
|
46
|
+
--accent: #009E80; /* Teal Dark — interactive elements */
|
|
47
47
|
--accent-text: #001E2B; /* MDB Black — headings/labels in light mode */
|
|
48
|
-
--accent-dim: #
|
|
49
|
-
--accent-glow: rgba(0,
|
|
48
|
+
--accent-dim: #007A63; /* Teal Darker */
|
|
49
|
+
--accent-glow: rgba(0, 158, 128, 0.08);
|
|
50
50
|
--text: #001E2B; /* MDB Black */
|
|
51
51
|
--text-dim: #5C6C75; /* Gray Dark 1 */
|
|
52
52
|
--text-muted: #889397; /* Gray Base */
|
|
53
53
|
--border: #E8EDEB; /* Gray Light 2 */
|
|
54
54
|
--error: #DB3030; /* Red Base */
|
|
55
55
|
--warning: #944F01; /* Yellow Dark 2 */
|
|
56
|
-
--success: #
|
|
56
|
+
--success: #009E80; /* Teal Dark */
|
|
57
57
|
--red: #DB3030; /* Red Base */
|
|
58
58
|
--yellow: #944F01; /* Yellow Dark 2 */
|
|
59
|
-
--green: #
|
|
60
|
-
--blue: #
|
|
59
|
+
--green: #009E80; /* Teal Dark */
|
|
60
|
+
--blue: #0088CC; /* Cyan Dark (links) */
|
|
61
61
|
--purple: #5E0C9E; /* Purple Dark 2 */
|
|
62
|
-
--green-dark: #
|
|
62
|
+
--green-dark: #00241E; /* Teal Dark 3 */
|
|
63
63
|
}
|
|
64
64
|
/* Light mode shadow + card adjustments */
|
|
65
65
|
[data-theme="light"] .explore-card,
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
box-shadow: 0 1px 4px rgba(0, 30, 43, 0.08);
|
|
70
70
|
}
|
|
71
71
|
[data-theme="light"] .explore-card:hover {
|
|
72
|
-
box-shadow: 0 4px 16px rgba(0,
|
|
72
|
+
box-shadow: 0 4px 16px rgba(0, 158, 128, 0.12);
|
|
73
73
|
}
|
|
74
74
|
[data-theme="light"] .cost-modal,
|
|
75
75
|
[data-theme="light"] .explore-modal {
|
|
@@ -83,14 +83,14 @@
|
|
|
83
83
|
box-shadow: 1px 0 3px rgba(0, 30, 43, 0.06);
|
|
84
84
|
}
|
|
85
85
|
/* Light mode gradient overrides */
|
|
86
|
-
[data-theme="light"] .quant-bar-fill.storage { background: linear-gradient(90deg, #
|
|
87
|
-
[data-theme="light"] .quant-bar-fill.latency { background: linear-gradient(90deg, #
|
|
88
|
-
[data-theme="light"] .quant-meter-fill.perfect { background: linear-gradient(90deg, #
|
|
86
|
+
[data-theme="light"] .quant-bar-fill.storage { background: linear-gradient(90deg, #009E80, #00D4AA); }
|
|
87
|
+
[data-theme="light"] .quant-bar-fill.latency { background: linear-gradient(90deg, #0088CC, #40E0FF); }
|
|
88
|
+
[data-theme="light"] .quant-meter-fill.perfect { background: linear-gradient(90deg, #009E80, #00D4AA); }
|
|
89
89
|
[data-theme="light"] .quant-meter-fill.good { background: linear-gradient(90deg, #944F01, #FFC010); }
|
|
90
90
|
[data-theme="light"] .quant-meter-fill.degraded { background: linear-gradient(90deg, #DB3030, #FF6960); }
|
|
91
91
|
/* Light mode button text */
|
|
92
92
|
[data-theme="light"] .btn { color: #FFFFFF; }
|
|
93
|
-
[data-theme="light"] .btn:hover { background: #
|
|
93
|
+
[data-theme="light"] .btn:hover { background: #007A63; }
|
|
94
94
|
|
|
95
95
|
html, body { height: 100%; }
|
|
96
96
|
|
|
@@ -108,8 +108,8 @@ body {
|
|
|
108
108
|
align-items: center;
|
|
109
109
|
gap: 10px;
|
|
110
110
|
padding: 8px 16px;
|
|
111
|
-
background: linear-gradient(135deg, rgba(0,
|
|
112
|
-
border-bottom: 1px solid rgba(0,
|
|
111
|
+
background: linear-gradient(135deg, rgba(0,158,128,0.12), rgba(4,152,236,0.12));
|
|
112
|
+
border-bottom: 1px solid rgba(0,212,170,0.2);
|
|
113
113
|
font-size: 13px;
|
|
114
114
|
color: var(--text);
|
|
115
115
|
flex-shrink: 0;
|
|
@@ -178,7 +178,7 @@ body {
|
|
|
178
178
|
padding: 24px 28px 20px;
|
|
179
179
|
width: 380px;
|
|
180
180
|
max-width: 90vw;
|
|
181
|
-
box-shadow: 0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px rgba(0,
|
|
181
|
+
box-shadow: 0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px rgba(0,212,170,0.15);
|
|
182
182
|
transition: all 0.4s cubic-bezier(0.4,0,0.2,1);
|
|
183
183
|
opacity: 0;
|
|
184
184
|
transform: translateY(10px);
|
|
@@ -296,7 +296,7 @@ body {
|
|
|
296
296
|
width: 460px;
|
|
297
297
|
max-width: 90vw;
|
|
298
298
|
text-align: center;
|
|
299
|
-
box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 80px rgba(0,
|
|
299
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 80px rgba(0,212,170,0.08);
|
|
300
300
|
pointer-events: auto;
|
|
301
301
|
opacity: 0;
|
|
302
302
|
transform: scale(0.95);
|
|
@@ -324,10 +324,10 @@ body {
|
|
|
324
324
|
margin-bottom: 28px;
|
|
325
325
|
}
|
|
326
326
|
[data-theme="light"] .onboarding-tooltip {
|
|
327
|
-
box-shadow: 0 12px 40px rgba(0,30,43,0.15), 0 0 0 1px rgba(0,
|
|
327
|
+
box-shadow: 0 12px 40px rgba(0,30,43,0.15), 0 0 0 1px rgba(0,158,128,0.2);
|
|
328
328
|
}
|
|
329
329
|
[data-theme="light"] .onboarding-welcome-card {
|
|
330
|
-
box-shadow: 0 20px 60px rgba(0,30,43,0.18), 0 0 80px rgba(0,
|
|
330
|
+
box-shadow: 0 20px 60px rgba(0,30,43,0.18), 0 0 80px rgba(0,158,128,0.06);
|
|
331
331
|
}
|
|
332
332
|
[data-theme="light"] .onboarding-backdrop {
|
|
333
333
|
background: rgba(0,30,43,0.45);
|
|
@@ -480,7 +480,7 @@ body:not(.is-electron) .sidebar-drag-region {
|
|
|
480
480
|
height: 16px;
|
|
481
481
|
}
|
|
482
482
|
[data-theme="light"] .tab-btn:hover { background: rgba(0,30,43,0.04); }
|
|
483
|
-
[data-theme="light"] .tab-btn.active { background: rgba(0,
|
|
483
|
+
[data-theme="light"] .tab-btn.active { background: rgba(0,158,128,0.08); }
|
|
484
484
|
|
|
485
485
|
.sidebar-footer {
|
|
486
486
|
padding: 12px 16px;
|
|
@@ -558,6 +558,27 @@ body:not(.is-electron) .sidebar-drag-region {
|
|
|
558
558
|
overflow-y: auto;
|
|
559
559
|
display: flex;
|
|
560
560
|
flex-direction: column;
|
|
561
|
+
position: relative;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.content-area::after {
|
|
565
|
+
content: '';
|
|
566
|
+
position: fixed;
|
|
567
|
+
bottom: 2rem;
|
|
568
|
+
right: 2rem;
|
|
569
|
+
width: 200px;
|
|
570
|
+
height: 200px;
|
|
571
|
+
background-image: url('/icons/watermark.png');
|
|
572
|
+
background-size: contain;
|
|
573
|
+
background-repeat: no-repeat;
|
|
574
|
+
opacity: 0.05;
|
|
575
|
+
pointer-events: none;
|
|
576
|
+
z-index: 0;
|
|
577
|
+
filter: invert(1);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
[data-theme="light"] .content-area::after {
|
|
581
|
+
filter: none;
|
|
561
582
|
}
|
|
562
583
|
|
|
563
584
|
.content-drag-region {
|
|
@@ -644,7 +665,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
644
665
|
align-items: center;
|
|
645
666
|
gap: 8px;
|
|
646
667
|
}
|
|
647
|
-
.btn:hover { background: #
|
|
668
|
+
.btn:hover { background: #5CE8CC; transform: translateY(-1px); }
|
|
648
669
|
.btn:active { transform: translateY(0); }
|
|
649
670
|
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
|
|
650
671
|
|
|
@@ -689,7 +710,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
689
710
|
}
|
|
690
711
|
.subtab:hover {
|
|
691
712
|
color: var(--text);
|
|
692
|
-
background: rgba(0,
|
|
713
|
+
background: rgba(0, 212, 170, 0.05);
|
|
693
714
|
}
|
|
694
715
|
.subtab.active {
|
|
695
716
|
background: var(--accent);
|
|
@@ -964,7 +985,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
964
985
|
.explore-card:hover {
|
|
965
986
|
border-color: var(--accent);
|
|
966
987
|
transform: translateY(-2px);
|
|
967
|
-
box-shadow: 0 4px 20px rgba(0,
|
|
988
|
+
box-shadow: 0 4px 20px rgba(0, 212, 170, 0.1);
|
|
968
989
|
}
|
|
969
990
|
.explore-card.expanded {
|
|
970
991
|
border-color: var(--accent);
|
|
@@ -1252,8 +1273,8 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1252
1273
|
font-family: var(--mono); font-size: 12px; font-weight: 600;
|
|
1253
1274
|
color: var(--green-dark); white-space: nowrap; min-width: fit-content;
|
|
1254
1275
|
}
|
|
1255
|
-
.quant-bar-fill.storage { background: linear-gradient(90deg, #
|
|
1256
|
-
.quant-bar-fill.latency { background: linear-gradient(90deg, #
|
|
1276
|
+
.quant-bar-fill.storage { background: linear-gradient(90deg, #00D4AA, #5CE8CC); }
|
|
1277
|
+
.quant-bar-fill.latency { background: linear-gradient(90deg, #40E0FF, #0088CC); }
|
|
1257
1278
|
.quant-bar-badge {
|
|
1258
1279
|
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
|
|
1259
1280
|
font-size: 12px; color: var(--text-dim); font-family: var(--mono);
|
|
@@ -1278,7 +1299,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1278
1299
|
height: 100%; border-radius: 5px;
|
|
1279
1300
|
transition: width 0.8s cubic-bezier(0.22, 1, 0.36, 1);
|
|
1280
1301
|
}
|
|
1281
|
-
.quant-meter-fill.perfect { background: linear-gradient(90deg, #
|
|
1302
|
+
.quant-meter-fill.perfect { background: linear-gradient(90deg, #00D4AA, #5CE8CC); }
|
|
1282
1303
|
.quant-meter-fill.good { background: linear-gradient(90deg, #FFC010, #FFEC9E); }
|
|
1283
1304
|
.quant-meter-fill.degraded { background: linear-gradient(90deg, #FF6960, #FFCDC7); }
|
|
1284
1305
|
.quant-meter-detail { font-size: 11px; color: var(--text-muted); margin-top: 4px; font-family: var(--mono); }
|
|
@@ -1374,7 +1395,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1374
1395
|
font-weight: 600;
|
|
1375
1396
|
}
|
|
1376
1397
|
.cost-mode-btn:hover:not(.active) {
|
|
1377
|
-
background: rgba(0,
|
|
1398
|
+
background: rgba(0, 212, 170, 0.1);
|
|
1378
1399
|
color: var(--text);
|
|
1379
1400
|
}
|
|
1380
1401
|
.cost-select {
|
|
@@ -1514,7 +1535,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1514
1535
|
border-bottom: 1px solid rgba(42, 53, 80, 0.3);
|
|
1515
1536
|
font-family: var(--mono);
|
|
1516
1537
|
}
|
|
1517
|
-
.cost-table tr:hover { background: rgba(0,
|
|
1538
|
+
.cost-table tr:hover { background: rgba(0, 212, 170, 0.03); }
|
|
1518
1539
|
.cost-highlight {
|
|
1519
1540
|
color: var(--accent-text);
|
|
1520
1541
|
font-weight: 600;
|
|
@@ -1541,7 +1562,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1541
1562
|
.cost-tip {
|
|
1542
1563
|
font-size: 12px;
|
|
1543
1564
|
color: var(--text-muted);
|
|
1544
|
-
background: rgba(0,
|
|
1565
|
+
background: rgba(0, 212, 170, 0.05);
|
|
1545
1566
|
border-left: 3px solid var(--accent);
|
|
1546
1567
|
padding: 10px 14px;
|
|
1547
1568
|
border-radius: 0 6px 6px 0;
|
|
@@ -1661,7 +1682,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1661
1682
|
}
|
|
1662
1683
|
.cost-modal .formula .accent { color: var(--accent); font-weight: 600; }
|
|
1663
1684
|
.cost-modal .example {
|
|
1664
|
-
background: rgba(0,
|
|
1685
|
+
background: rgba(0, 212, 170, 0.05);
|
|
1665
1686
|
border-left: 3px solid var(--accent);
|
|
1666
1687
|
border-radius: 0 8px 8px 0;
|
|
1667
1688
|
padding: 12px 16px;
|
|
@@ -1843,8 +1864,8 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1843
1864
|
line-height: 1.5;
|
|
1844
1865
|
}
|
|
1845
1866
|
.settings-api-banner.success {
|
|
1846
|
-
background: rgba(0,
|
|
1847
|
-
border-color: rgba(0,
|
|
1867
|
+
background: rgba(0,212,170,0.06);
|
|
1868
|
+
border-color: rgba(0,212,170,0.2);
|
|
1848
1869
|
color: var(--success);
|
|
1849
1870
|
}
|
|
1850
1871
|
[data-theme="light"] .settings-api-banner {
|
|
@@ -1932,8 +1953,8 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1932
1953
|
font-size: 13px;
|
|
1933
1954
|
font-weight: 600;
|
|
1934
1955
|
color: var(--accent);
|
|
1935
|
-
background: rgba(0,
|
|
1936
|
-
border: 1px solid rgba(0,
|
|
1956
|
+
background: rgba(0,212,170,0.08);
|
|
1957
|
+
border: 1px solid rgba(0,212,170,0.2);
|
|
1937
1958
|
border-radius: 6px;
|
|
1938
1959
|
padding: 4px 12px;
|
|
1939
1960
|
letter-spacing: 0.3px;
|
|
@@ -1941,7 +1962,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
1941
1962
|
[data-theme="light"] .version-badge {
|
|
1942
1963
|
background: rgba(0,104,74,0.06);
|
|
1943
1964
|
border-color: rgba(0,104,74,0.2);
|
|
1944
|
-
color: #
|
|
1965
|
+
color: #007A63;
|
|
1945
1966
|
}
|
|
1946
1967
|
.settings-api-field .save-btn {
|
|
1947
1968
|
color: var(--accent);
|
|
@@ -2174,7 +2195,7 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
2174
2195
|
}
|
|
2175
2196
|
[data-theme="light"] .settings-origin.origin-env {
|
|
2176
2197
|
background: rgba(4,120,190,0.10);
|
|
2177
|
-
color: #
|
|
2198
|
+
color: #0088CC;
|
|
2178
2199
|
}
|
|
2179
2200
|
.settings-origin.origin-config {
|
|
2180
2201
|
background: rgba(180,90,242,0.12);
|
|
@@ -2185,12 +2206,12 @@ select:focus { outline: none; border-color: var(--accent); }
|
|
|
2185
2206
|
color: #7B3DB5;
|
|
2186
2207
|
}
|
|
2187
2208
|
.settings-origin.origin-project {
|
|
2188
|
-
background: rgba(0,
|
|
2209
|
+
background: rgba(0,212,170,0.12);
|
|
2189
2210
|
color: var(--accent);
|
|
2190
2211
|
}
|
|
2191
2212
|
[data-theme="light"] .settings-origin.origin-project {
|
|
2192
|
-
background: rgba(0,
|
|
2193
|
-
color: #
|
|
2213
|
+
background: rgba(0,158,128,0.10);
|
|
2214
|
+
color: #009E80;
|
|
2194
2215
|
}
|
|
2195
2216
|
.settings-origin.origin-default {
|
|
2196
2217
|
background: rgba(136,147,151,0.12);
|
|
@@ -4280,7 +4301,7 @@ let lastEmbedding = null;
|
|
|
4280
4301
|
|
|
4281
4302
|
// ── Init ──
|
|
4282
4303
|
// ── Anonymous Telemetry ──
|
|
4283
|
-
const TELEMETRY_URL = 'https://
|
|
4304
|
+
const TELEMETRY_URL = 'https://vaicli.com/api/telemetry';
|
|
4284
4305
|
const TELEMETRY_KEY = 'vai-telemetry-enabled';
|
|
4285
4306
|
|
|
4286
4307
|
function isTelemetryEnabled() {
|
|
@@ -5318,8 +5339,8 @@ const BENCH_SAMPLE_TEXTS = [
|
|
|
5318
5339
|
];
|
|
5319
5340
|
|
|
5320
5341
|
const MODEL_COLORS = [
|
|
5321
|
-
'#
|
|
5322
|
-
'#FF6960', '#B45AF2', '#FFC010', '#
|
|
5342
|
+
'#00D4AA', '#5CE8CC', '#40E0FF', '#B45AF2', '#FFC010',
|
|
5343
|
+
'#FF6960', '#B45AF2', '#FFC010', '#0088CC', '#A8F0E0',
|
|
5323
5344
|
];
|
|
5324
5345
|
|
|
5325
5346
|
window.doBenchLatency = async function() {
|
|
@@ -5660,7 +5681,7 @@ window.doBenchQuantization = async function() {
|
|
|
5660
5681
|
const baseline = completed.find(r => r.dtype === 'float') || completed[0];
|
|
5661
5682
|
const maxBytes = Math.max(...completed.map(r => r.bytesPerVec));
|
|
5662
5683
|
const maxLatency = Math.max(...completed.map(r => r.latency));
|
|
5663
|
-
const DTYPE_COLORS = { float: '#
|
|
5684
|
+
const DTYPE_COLORS = { float: '#00D4AA', int8: '#5CE8CC', uint8: '#40E0FF', ubinary: '#FFC010', binary: '#FF6960' };
|
|
5664
5685
|
|
|
5665
5686
|
// ── Storage Bar Chart ──
|
|
5666
5687
|
let storageHTML = '';
|
|
@@ -5671,7 +5692,7 @@ window.doBenchQuantization = async function() {
|
|
|
5671
5692
|
const savings = r.bytesPerVec < baseline.bytesPerVec
|
|
5672
5693
|
? `${(baseline.bytesPerVec / r.bytesPerVec).toFixed(0)}× smaller`
|
|
5673
5694
|
: 'baseline';
|
|
5674
|
-
const color = DTYPE_COLORS[r.dtype] || '#
|
|
5695
|
+
const color = DTYPE_COLORS[r.dtype] || '#40E0FF';
|
|
5675
5696
|
storageHTML += `<div class="quant-bar-group">
|
|
5676
5697
|
<div class="quant-bar-label">
|
|
5677
5698
|
<span class="dtype-name">${r.dtype}</span>
|
|
@@ -5689,7 +5710,7 @@ window.doBenchQuantization = async function() {
|
|
|
5689
5710
|
const minLatency = Math.min(...completed.map(r => r.latency));
|
|
5690
5711
|
for (const r of completed) {
|
|
5691
5712
|
const pct = Math.max(8, (r.latency / maxLatency) * 100);
|
|
5692
|
-
const color = DTYPE_COLORS[r.dtype] || '#
|
|
5713
|
+
const color = DTYPE_COLORS[r.dtype] || '#40E0FF';
|
|
5693
5714
|
const badge = r.latency === minLatency ? ' ⚡' : '';
|
|
5694
5715
|
latencyHTML += `<div class="quant-bar-group">
|
|
5695
5716
|
<div class="quant-bar-label">
|
|
@@ -7229,7 +7250,22 @@ init = async function() {
|
|
|
7229
7250
|
// ── Start ──
|
|
7230
7251
|
init();
|
|
7231
7252
|
|
|
7232
|
-
// ── Vector Space Invaders (Easter Egg) ──
|
|
7253
|
+
// ── Vector Space Invaders (Easter Egg) ──
|
|
7254
|
+
|
|
7255
|
+
// VSI Telemetry helper
|
|
7256
|
+
function sendVSITelemetry(event, extra) {
|
|
7257
|
+
try {
|
|
7258
|
+
fetch('https://vaicli.com/api/telemetry', {
|
|
7259
|
+
method: 'POST',
|
|
7260
|
+
headers: { 'Content-Type': 'application/json' },
|
|
7261
|
+
body: JSON.stringify({ event, ...extra, sentAt: new Date().toISOString() }),
|
|
7262
|
+
}).catch(() => {});
|
|
7263
|
+
} catch (_) {}
|
|
7264
|
+
}
|
|
7265
|
+
|
|
7266
|
+
let _vsiGameStartTime = 0;
|
|
7267
|
+
let _vsiGameTrigger = 'unknown';
|
|
7268
|
+
|
|
7233
7269
|
(function initEasterEgg() {
|
|
7234
7270
|
const KONAMI = ['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
|
7235
7271
|
let konamiIdx = 0;
|
|
@@ -7237,7 +7273,7 @@ init();
|
|
|
7237
7273
|
|
|
7238
7274
|
document.addEventListener('keydown', (e) => {
|
|
7239
7275
|
if (document.getElementById('vsiOverlay')?.style.display === 'flex') return;
|
|
7240
|
-
if (e.key === KONAMI[konamiIdx]) { konamiIdx++; if (konamiIdx === KONAMI.length) { konamiIdx = 0; launchVSI(); } }
|
|
7276
|
+
if (e.key === KONAMI[konamiIdx]) { konamiIdx++; if (konamiIdx === KONAMI.length) { konamiIdx = 0; _vsiGameTrigger = 'konami'; launchVSI(); } }
|
|
7241
7277
|
else { konamiIdx = 0; }
|
|
7242
7278
|
});
|
|
7243
7279
|
|
|
@@ -7247,7 +7283,7 @@ init();
|
|
|
7247
7283
|
const now = Date.now();
|
|
7248
7284
|
logoClicks.push(now);
|
|
7249
7285
|
logoClicks = logoClicks.filter(t => now - t < 2000);
|
|
7250
|
-
if (logoClicks.length >= 7) { logoClicks = []; launchVSI(); }
|
|
7286
|
+
if (logoClicks.length >= 7) { logoClicks = []; _vsiGameTrigger = 'logo_click'; launchVSI(); }
|
|
7251
7287
|
});
|
|
7252
7288
|
}
|
|
7253
7289
|
|
|
@@ -7256,6 +7292,22 @@ init();
|
|
|
7256
7292
|
const canvas = document.getElementById('vsiCanvas');
|
|
7257
7293
|
if (!overlay || !canvas) return;
|
|
7258
7294
|
overlay.style.display = 'flex';
|
|
7295
|
+
_vsiGameStartTime = Date.now();
|
|
7296
|
+
|
|
7297
|
+
// Detect version from page
|
|
7298
|
+
const versionEl = document.querySelector('.version-label, [data-version]');
|
|
7299
|
+
const version = versionEl ? (versionEl.dataset?.version || versionEl.textContent?.trim()) : 'unknown';
|
|
7300
|
+
const ua = navigator.userAgent;
|
|
7301
|
+
const platform = /Mac/.test(ua) ? 'macOS' : /Win/.test(ua) ? 'Windows' : /Linux/.test(ua) ? 'Linux' : /Android/.test(ua) ? 'Android' : /iPhone|iPad/.test(ua) ? 'iOS' : 'unknown';
|
|
7302
|
+
|
|
7303
|
+
sendVSITelemetry('vsi_game_start', {
|
|
7304
|
+
version,
|
|
7305
|
+
context: 'playground',
|
|
7306
|
+
platform,
|
|
7307
|
+
locale: navigator.language || 'unknown',
|
|
7308
|
+
trigger: _vsiGameTrigger,
|
|
7309
|
+
});
|
|
7310
|
+
|
|
7259
7311
|
startVSI(canvas, () => { overlay.style.display = 'none'; });
|
|
7260
7312
|
}
|
|
7261
7313
|
})();
|
|
@@ -7277,7 +7329,7 @@ function startVSI(canvas, onExit) {
|
|
|
7277
7329
|
ctx.quadraticCurveTo(x - size * 0.6, y - size * 0.3, x, y - size);
|
|
7278
7330
|
ctx.fill();
|
|
7279
7331
|
// Central vein
|
|
7280
|
-
ctx.strokeStyle = color === '#
|
|
7332
|
+
ctx.strokeStyle = color === '#00D4AA' ? '#009E80' : color;
|
|
7281
7333
|
ctx.lineWidth = 1;
|
|
7282
7334
|
ctx.beginPath();
|
|
7283
7335
|
ctx.moveTo(x, y - size);
|
|
@@ -7312,7 +7364,7 @@ function startVSI(canvas, onExit) {
|
|
|
7312
7364
|
let waveQueued = false;
|
|
7313
7365
|
|
|
7314
7366
|
const keys = {};
|
|
7315
|
-
const keyDown = (e) => { keys[e.key] = true; if (['ArrowLeft','ArrowRight',' ','Escape'].includes(e.key)) e.preventDefault(); if (e.key === 'Escape') { cleanup(); onExit(); } };
|
|
7367
|
+
const keyDown = (e) => { keys[e.key] = true; if (['ArrowLeft','ArrowRight',' ','Escape'].includes(e.key)) e.preventDefault(); if (e.key === 'Escape') { sendVSITelemetry('vsi_game_over', { score, wave, durationMs: Date.now() - _vsiGameStartTime, livesRemaining: lives, exitReason: 'esc' }); cleanup(); onExit(); } };
|
|
7316
7368
|
const keyUp = (e) => { keys[e.key] = false; };
|
|
7317
7369
|
document.addEventListener('keydown', keyDown);
|
|
7318
7370
|
document.addEventListener('keyup', keyUp);
|
|
@@ -7353,7 +7405,7 @@ function startVSI(canvas, onExit) {
|
|
|
7353
7405
|
}
|
|
7354
7406
|
|
|
7355
7407
|
function addExplosion(x, y, sim) {
|
|
7356
|
-
const color = sim > 0.7 ? '#
|
|
7408
|
+
const color = sim > 0.7 ? '#00D4AA' : sim > 0.4 ? '#FFC010' : '#FF6960';
|
|
7357
7409
|
for (let i = 0; i < 8; i++) {
|
|
7358
7410
|
const angle = (Math.PI * 2 / 8) * i + Math.random() * 0.5;
|
|
7359
7411
|
const speed = 1.5 + Math.random() * 2;
|
|
@@ -7445,7 +7497,7 @@ function startVSI(canvas, onExit) {
|
|
|
7445
7497
|
if (enemies[i].y > H - 50) {
|
|
7446
7498
|
enemies.splice(i, 1);
|
|
7447
7499
|
lives--;
|
|
7448
|
-
if (lives <= 0) gameOver = true;
|
|
7500
|
+
if (lives <= 0) { gameOver = true; sendVSITelemetry('vsi_game_over', { score, wave, durationMs: Date.now() - _vsiGameStartTime, livesRemaining: 0, exitReason: 'death' }); }
|
|
7449
7501
|
}
|
|
7450
7502
|
}
|
|
7451
7503
|
|
|
@@ -7482,16 +7534,16 @@ function startVSI(canvas, onExit) {
|
|
|
7482
7534
|
}
|
|
7483
7535
|
|
|
7484
7536
|
// Ship (Voyage AI leaf)
|
|
7485
|
-
drawLeaf(ctx, ship.x, H - 32, 12, '#
|
|
7537
|
+
drawLeaf(ctx, ship.x, H - 32, 12, '#00D4AA');
|
|
7486
7538
|
// Ship label
|
|
7487
|
-
ctx.fillStyle = '#
|
|
7539
|
+
ctx.fillStyle = '#00D4AA';
|
|
7488
7540
|
ctx.font = '9px monospace';
|
|
7489
7541
|
ctx.textAlign = 'center';
|
|
7490
7542
|
ctx.fillText('voyage', ship.x, H - 14);
|
|
7491
7543
|
|
|
7492
7544
|
// Bullets (small leaf shapes)
|
|
7493
7545
|
for (const b of bullets) {
|
|
7494
|
-
drawLeaf(ctx, b.x, b.y, 3, '#
|
|
7546
|
+
drawLeaf(ctx, b.x, b.y, 3, '#00D4AA');
|
|
7495
7547
|
}
|
|
7496
7548
|
|
|
7497
7549
|
// Boss
|
|
@@ -7516,7 +7568,7 @@ function startVSI(canvas, onExit) {
|
|
|
7516
7568
|
for (const e of enemies) {
|
|
7517
7569
|
ctx.fillStyle = 'rgba(61,79,88,0.6)';
|
|
7518
7570
|
ctx.fillRect(e.x - e.w / 2, e.y - e.h / 2, e.w, e.h);
|
|
7519
|
-
ctx.strokeStyle = '#
|
|
7571
|
+
ctx.strokeStyle = '#40E0FF';
|
|
7520
7572
|
ctx.lineWidth = 1;
|
|
7521
7573
|
ctx.strokeRect(e.x - e.w / 2, e.y - e.h / 2, e.w, e.h);
|
|
7522
7574
|
ctx.fillStyle = '#E8EDEB';
|
|
@@ -7556,19 +7608,19 @@ function startVSI(canvas, onExit) {
|
|
|
7556
7608
|
|
|
7557
7609
|
// Lives (leaf icons)
|
|
7558
7610
|
for (let i = 0; i < lives; i++) {
|
|
7559
|
-
drawLeaf(ctx, W - 20 - (i * 18), 15, 6, '#
|
|
7611
|
+
drawLeaf(ctx, W - 20 - (i * 18), 15, 6, '#00D4AA');
|
|
7560
7612
|
}
|
|
7561
7613
|
|
|
7562
7614
|
// Title with Voyage AI branding
|
|
7563
|
-
ctx.fillStyle = '#
|
|
7615
|
+
ctx.fillStyle = '#00D4AA';
|
|
7564
7616
|
ctx.font = 'bold 10px monospace';
|
|
7565
7617
|
ctx.textAlign = 'center';
|
|
7566
7618
|
ctx.fillText('VECTOR SPACE INVADERS', W / 2, H - 4);
|
|
7567
7619
|
|
|
7568
7620
|
// Voyage AI watermark (top right corner)
|
|
7569
7621
|
ctx.globalAlpha = 0.3;
|
|
7570
|
-
drawLeaf(ctx, W - 25, 25, 8, '#
|
|
7571
|
-
ctx.fillStyle = '#
|
|
7622
|
+
drawLeaf(ctx, W - 25, 25, 8, '#00D4AA');
|
|
7623
|
+
ctx.fillStyle = '#00D4AA';
|
|
7572
7624
|
ctx.font = 'bold 9px monospace';
|
|
7573
7625
|
ctx.textAlign = 'right';
|
|
7574
7626
|
ctx.fillText('VOYAGE AI', W - 38, 28);
|
|
@@ -7578,7 +7630,7 @@ function startVSI(canvas, onExit) {
|
|
|
7578
7630
|
if (gameOver) {
|
|
7579
7631
|
ctx.fillStyle = 'rgba(0,30,43,0.8)';
|
|
7580
7632
|
ctx.fillRect(0, 0, W, H);
|
|
7581
|
-
ctx.fillStyle = '#
|
|
7633
|
+
ctx.fillStyle = '#00D4AA';
|
|
7582
7634
|
ctx.font = 'bold 28px monospace';
|
|
7583
7635
|
ctx.textAlign = 'center';
|
|
7584
7636
|
ctx.fillText('GAME OVER', W / 2, H / 2 - 30);
|
|
@@ -8141,13 +8193,13 @@ init();
|
|
|
8141
8193
|
.bug-error{padding:10px 12px;background:rgba(255,107,107,0.15);border:1px solid rgba(255,107,107,0.3);border-radius:8px;color:var(--error);font-size:13px;margin-bottom:16px}
|
|
8142
8194
|
.bug-actions{display:flex;gap:12px}
|
|
8143
8195
|
.bug-actions button{flex:1;padding:12px 16px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;border:none}
|
|
8144
|
-
.bug-actions .primary{background:linear-gradient(135deg,var(--accent),#
|
|
8145
|
-
.bug-actions .primary:hover{box-shadow:0 4px 12px rgba(0,
|
|
8196
|
+
.bug-actions .primary{background:linear-gradient(135deg,var(--accent),#5CE8CC);color:#000}
|
|
8197
|
+
.bug-actions .primary:hover{box-shadow:0 4px 12px rgba(0,212,170,0.4)}
|
|
8146
8198
|
.bug-actions .primary:disabled{opacity:0.6;cursor:not-allowed}
|
|
8147
8199
|
.bug-actions .secondary{background:rgba(255,255,255,0.1);color:var(--text);border:1px solid var(--border)}
|
|
8148
8200
|
.bug-actions .secondary:hover{background:rgba(255,255,255,0.15)}
|
|
8149
8201
|
.bug-success{padding:40px 20px;text-align:center}
|
|
8150
|
-
.bug-success .icon{width:60px;height:60px;border-radius:50%;background:linear-gradient(135deg,var(--accent),#
|
|
8202
|
+
.bug-success .icon{width:60px;height:60px;border-radius:50%;background:linear-gradient(135deg,var(--accent),#5CE8CC);color:#000;font-size:32px;display:flex;align-items:center;justify-content:center;margin:0 auto 20px}
|
|
8151
8203
|
.bug-success h3{margin:0 0 12px;color:var(--accent-text);font-size:20px}
|
|
8152
8204
|
.bug-success p{margin:8px 0;color:var(--text-muted)}
|
|
8153
8205
|
.bug-success code{background:rgba(255,255,255,0.1);padding:4px 8px;border-radius:4px;font-size:12px;color:var(--accent)}
|
|
@@ -8203,7 +8255,7 @@ init();
|
|
|
8203
8255
|
|
|
8204
8256
|
<script>
|
|
8205
8257
|
(function() {
|
|
8206
|
-
const BUG_API = 'https://
|
|
8258
|
+
const BUG_API = 'https://vaicli.com/api/bugs';
|
|
8207
8259
|
const GITHUB_URL = 'https://github.com/mrlynn/voyageai-cli/issues/new';
|
|
8208
8260
|
|
|
8209
8261
|
function getEnv() {
|