groove-dev 0.27.140 → 0.27.142
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/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/daemon/integrations-registry.json +12 -44
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/api.js +100 -23
- package/node_modules/@groove-dev/daemon/src/integrations.js +10 -0
- package/node_modules/@groove-dev/daemon/src/introducer.js +1 -1
- package/node_modules/@groove-dev/daemon/src/journalist.js +171 -1
- package/node_modules/@groove-dev/daemon/src/keeper.js +2 -2
- package/node_modules/@groove-dev/daemon/src/memory.js +8 -5
- package/node_modules/@groove-dev/daemon/src/model-lab.js +11 -0
- package/node_modules/@groove-dev/daemon/src/process.js +65 -0
- package/node_modules/@groove-dev/daemon/src/rotator.js +25 -8
- package/node_modules/@groove-dev/daemon/src/validate.js +8 -0
- package/node_modules/@groove-dev/gui/dist/assets/{codemirror-BQqYnZfL.js → codemirror-BYKpdS2W.js} +10 -10
- package/node_modules/@groove-dev/gui/dist/assets/index-Bjd91ufV.js +984 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-BqdwIFn4.css +1 -0
- package/node_modules/@groove-dev/gui/dist/index.html +3 -3
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/app.jsx +0 -2
- package/node_modules/@groove-dev/gui/src/components/agents/agent-chat.jsx +3 -4
- package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +8 -2
- package/node_modules/@groove-dev/gui/src/components/agents/agent-file-tree.jsx +12 -8
- package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +79 -5
- package/node_modules/@groove-dev/gui/src/components/agents/code-review.jsx +5 -4
- package/node_modules/@groove-dev/gui/src/components/agents/workspace-mode.jsx +109 -12
- package/node_modules/@groove-dev/gui/src/components/dashboard/context-gauges.jsx +111 -0
- package/node_modules/@groove-dev/gui/src/components/dashboard/routing-chart.jsx +70 -33
- package/node_modules/@groove-dev/gui/src/components/editor/ai-panel.jsx +77 -6
- package/node_modules/@groove-dev/gui/src/components/editor/code-editor.jsx +2 -68
- package/node_modules/@groove-dev/gui/src/components/editor/file-tree.jsx +2 -49
- package/node_modules/@groove-dev/gui/src/components/editor/terminal.jsx +15 -4
- package/node_modules/@groove-dev/gui/src/components/keeper/global-modals.jsx +10 -10
- package/node_modules/@groove-dev/gui/src/components/layout/activity-bar.jsx +1 -2
- package/node_modules/@groove-dev/gui/src/components/layout/terminal-panel.jsx +151 -3
- package/node_modules/@groove-dev/gui/src/components/marketplace/integration-wizard.jsx +223 -18
- package/node_modules/@groove-dev/gui/src/stores/groove.js +107 -29
- package/node_modules/@groove-dev/gui/src/views/agents.jsx +114 -56
- package/node_modules/@groove-dev/gui/src/views/dashboard.jsx +2 -0
- package/node_modules/@groove-dev/gui/src/views/marketplace.jsx +3 -71
- package/node_modules/@groove-dev/gui/src/views/memory.jsx +9 -9
- package/node_modules/@groove-dev/gui/src/views/model-lab.jsx +1 -6
- package/node_modules/@groove-dev/gui/src/views/models.jsx +658 -565
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/integrations-registry.json +12 -44
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/api.js +100 -23
- package/packages/daemon/src/integrations.js +10 -0
- package/packages/daemon/src/introducer.js +1 -1
- package/packages/daemon/src/journalist.js +171 -1
- package/packages/daemon/src/keeper.js +2 -2
- package/packages/daemon/src/memory.js +8 -5
- package/packages/daemon/src/model-lab.js +11 -0
- package/packages/daemon/src/process.js +65 -0
- package/packages/daemon/src/rotator.js +25 -8
- package/packages/daemon/src/validate.js +8 -0
- package/packages/gui/dist/assets/{codemirror-BQqYnZfL.js → codemirror-BYKpdS2W.js} +10 -10
- package/packages/gui/dist/assets/index-Bjd91ufV.js +984 -0
- package/packages/gui/dist/assets/index-BqdwIFn4.css +1 -0
- package/packages/gui/dist/index.html +3 -3
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/app.jsx +0 -2
- package/packages/gui/src/components/agents/agent-chat.jsx +3 -4
- package/packages/gui/src/components/agents/agent-feed.jsx +8 -2
- package/packages/gui/src/components/agents/agent-file-tree.jsx +12 -8
- package/packages/gui/src/components/agents/agent-panel.jsx +79 -5
- package/packages/gui/src/components/agents/code-review.jsx +5 -4
- package/packages/gui/src/components/agents/workspace-mode.jsx +109 -12
- package/packages/gui/src/components/dashboard/context-gauges.jsx +111 -0
- package/packages/gui/src/components/dashboard/routing-chart.jsx +70 -33
- package/packages/gui/src/components/editor/ai-panel.jsx +77 -6
- package/packages/gui/src/components/editor/code-editor.jsx +2 -68
- package/packages/gui/src/components/editor/file-tree.jsx +2 -49
- package/packages/gui/src/components/editor/terminal.jsx +15 -4
- package/packages/gui/src/components/keeper/global-modals.jsx +10 -10
- package/packages/gui/src/components/layout/activity-bar.jsx +1 -2
- package/packages/gui/src/components/layout/terminal-panel.jsx +151 -3
- package/packages/gui/src/components/marketplace/integration-wizard.jsx +223 -18
- package/packages/gui/src/stores/groove.js +107 -29
- package/packages/gui/src/views/agents.jsx +114 -56
- package/packages/gui/src/views/dashboard.jsx +2 -0
- package/packages/gui/src/views/marketplace.jsx +3 -71
- package/packages/gui/src/views/memory.jsx +9 -9
- package/packages/gui/src/views/model-lab.jsx +1 -6
- package/packages/gui/src/views/models.jsx +658 -565
- package/plan_files/keeper-manual.md +53 -42
- package/node_modules/@groove-dev/gui/dist/assets/index-BV9CAiw1.css +0 -1
- package/node_modules/@groove-dev/gui/dist/assets/index-DK6UIz0n.js +0 -8698
- package/node_modules/@groove-dev/gui/src/components/toys/toy-card.jsx +0 -78
- package/node_modules/@groove-dev/gui/src/components/toys/toy-creator.jsx +0 -144
- package/node_modules/@groove-dev/gui/src/components/toys/toy-launcher.jsx +0 -187
- package/node_modules/@groove-dev/gui/src/views/toys.jsx +0 -162
- package/packages/gui/dist/assets/index-BV9CAiw1.css +0 -1
- package/packages/gui/dist/assets/index-DK6UIz0n.js +0 -8698
- package/packages/gui/src/components/toys/toy-card.jsx +0 -78
- package/packages/gui/src/components/toys/toy-creator.jsx +0 -144
- package/packages/gui/src/components/toys/toy-launcher.jsx +0 -187
- package/packages/gui/src/views/toys.jsx +0 -162
|
@@ -10,7 +10,7 @@ import { RootNode } from '../components/agents/root-node';
|
|
|
10
10
|
import { cn } from '../lib/cn';
|
|
11
11
|
import { Button } from '../components/ui/button';
|
|
12
12
|
import { Badge } from '../components/ui/badge';
|
|
13
|
-
import { Plus, Users, UserPlus, Zap, X, Check, Rocket, Server, Monitor, Code2, TestTube, Shield, Pencil, Copy, Trash2, ChevronDown, ChevronLeft, ChevronRight, FolderOpen, Eye, Settings2, Search, GripVertical, Cloud, FileText, Database, Megaphone, Calculator, UserCheck, Headphones, BarChart3, Pen, Presentation, Globe, MessageCircle, Save, Layers,
|
|
13
|
+
import { Plus, Users, UserPlus, Zap, X, Check, Rocket, Server, Monitor, Code2, TestTube, Shield, Pencil, Copy, Trash2, ChevronDown, ChevronLeft, ChevronRight, FolderOpen, Eye, Settings2, Search, GripVertical, Cloud, FileText, Database, Megaphone, Calculator, UserCheck, Headphones, BarChart3, Pen, Presentation, Globe, MessageCircle, Save, Layers, LayoutGrid, Activity, Gauge, Cpu } from 'lucide-react';
|
|
14
14
|
import { PreviewWorkspace } from '../components/preview/preview-workspace';
|
|
15
15
|
import { WorkspaceMode } from '../components/agents/workspace-mode';
|
|
16
16
|
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSeparator } from '../components/ui/context-menu';
|
|
@@ -1258,7 +1258,7 @@ function RecommendedTeamCard() {
|
|
|
1258
1258
|
const [tsModel, setTsModel] = useState(teamLaunchConfig?.model || '');
|
|
1259
1259
|
const [tsReasoning, setTsReasoning] = useState(teamLaunchConfig?.reasoningEffort ?? 50);
|
|
1260
1260
|
const [tsTemp, setTsTemp] = useState(teamLaunchConfig?.temperature ?? 0.5);
|
|
1261
|
-
const [
|
|
1261
|
+
const [expandedAgent, setExpandedAgent] = useState(null);
|
|
1262
1262
|
|
|
1263
1263
|
useEffect(() => {
|
|
1264
1264
|
fetchProviders().then((list) => {
|
|
@@ -1283,6 +1283,15 @@ function RecommendedTeamCard() {
|
|
|
1283
1283
|
setEditedAgents(next);
|
|
1284
1284
|
}
|
|
1285
1285
|
|
|
1286
|
+
function handleAgentField(i, updates) {
|
|
1287
|
+
if (typeof updates === 'string') {
|
|
1288
|
+
const [field, value] = [updates, arguments[2]];
|
|
1289
|
+
setEditedAgents((prev) => (prev ?? agentEdits).map((a, idx) => idx === i ? { ...a, [field]: value } : a));
|
|
1290
|
+
} else {
|
|
1291
|
+
setEditedAgents((prev) => (prev ?? agentEdits).map((a, idx) => idx === i ? { ...a, ...updates } : a));
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1286
1295
|
function handleTsProviderChange(id) {
|
|
1287
1296
|
setTsProvider(id);
|
|
1288
1297
|
const p = providers.find((x) => x.id === id);
|
|
@@ -1298,7 +1307,6 @@ function RecommendedTeamCard() {
|
|
|
1298
1307
|
...(tsProvider && { provider: tsProvider, model: tsModel }),
|
|
1299
1308
|
reasoningEffort: tsReasoning,
|
|
1300
1309
|
...(showTemp && { temperature: tsTemp }),
|
|
1301
|
-
mode: tsMode,
|
|
1302
1310
|
},
|
|
1303
1311
|
});
|
|
1304
1312
|
try {
|
|
@@ -1376,41 +1384,6 @@ function RecommendedTeamCard() {
|
|
|
1376
1384
|
formatValue={(v) => v.toFixed(2)}
|
|
1377
1385
|
/>
|
|
1378
1386
|
)}
|
|
1379
|
-
{/* Build Mode */}
|
|
1380
|
-
<div className="space-y-1">
|
|
1381
|
-
<label className="text-2xs text-text-3 font-sans">Build Mode</label>
|
|
1382
|
-
<div className="flex rounded-md bg-surface-4 border border-border-subtle p-0.5">
|
|
1383
|
-
<button
|
|
1384
|
-
onClick={() => setTsMode('sandbox')}
|
|
1385
|
-
className={cn(
|
|
1386
|
-
'flex-1 flex items-center justify-center gap-1.5 rounded px-2 py-1.5 text-xs font-sans transition-all cursor-pointer',
|
|
1387
|
-
tsMode === 'sandbox'
|
|
1388
|
-
? 'bg-surface-2 text-text-0 font-semibold shadow-sm'
|
|
1389
|
-
: 'text-text-3 hover:text-text-1',
|
|
1390
|
-
)}
|
|
1391
|
-
>
|
|
1392
|
-
<Box size={11} />
|
|
1393
|
-
Sandbox
|
|
1394
|
-
</button>
|
|
1395
|
-
<button
|
|
1396
|
-
onClick={() => setTsMode('production')}
|
|
1397
|
-
className={cn(
|
|
1398
|
-
'flex-1 flex items-center justify-center gap-1.5 rounded px-2 py-1.5 text-xs font-sans transition-all cursor-pointer',
|
|
1399
|
-
tsMode === 'production'
|
|
1400
|
-
? 'bg-surface-2 text-text-0 font-semibold shadow-sm'
|
|
1401
|
-
: 'text-text-3 hover:text-text-1',
|
|
1402
|
-
)}
|
|
1403
|
-
>
|
|
1404
|
-
<HardDrive size={11} />
|
|
1405
|
-
Production
|
|
1406
|
-
</button>
|
|
1407
|
-
</div>
|
|
1408
|
-
<p className="text-2xs text-text-4 font-sans">
|
|
1409
|
-
{tsMode === 'sandbox'
|
|
1410
|
-
? 'Files live in a team directory, removable with the team'
|
|
1411
|
-
: 'Files live in the project directory, persist forever'}
|
|
1412
|
-
</p>
|
|
1413
|
-
</div>
|
|
1414
1387
|
</div>
|
|
1415
1388
|
)}
|
|
1416
1389
|
</div>
|
|
@@ -1419,31 +1392,116 @@ function RecommendedTeamCard() {
|
|
|
1419
1392
|
{agentEdits.map((a, i) => {
|
|
1420
1393
|
const Icon = ROLE_ICONS[a.role] || Code2;
|
|
1421
1394
|
const nameValid = !a.name || NAME_RE.test(a.name);
|
|
1395
|
+
const isExpanded = expandedAgent === i;
|
|
1396
|
+
const agentProvider = providers.find((p) => p.id === (a.provider || tsProvider));
|
|
1397
|
+
const agentModels = (agentProvider?.models || []).filter((m) => m.type !== 'image' && !m.disabled);
|
|
1422
1398
|
return (
|
|
1423
|
-
<div key={i} className="
|
|
1424
|
-
<
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1399
|
+
<div key={i} className="rounded-md bg-surface-4 border border-border-subtle overflow-hidden">
|
|
1400
|
+
<div
|
|
1401
|
+
className="flex items-center gap-2 px-2.5 py-1.5 cursor-pointer hover:bg-surface-5/50 transition-colors"
|
|
1402
|
+
onClick={() => setExpandedAgent(isExpanded ? null : i)}
|
|
1403
|
+
>
|
|
1404
|
+
<Icon size={12} className="text-text-2 shrink-0" />
|
|
1405
|
+
<input
|
|
1406
|
+
type="text"
|
|
1407
|
+
value={a.name}
|
|
1408
|
+
onChange={(e) => handleNameChange(i, e.target.value)}
|
|
1409
|
+
onClick={(e) => e.stopPropagation()}
|
|
1410
|
+
placeholder={a.role}
|
|
1411
|
+
className={cn(
|
|
1412
|
+
'flex-1 min-w-0 bg-transparent text-xs font-mono text-text-0 outline-none placeholder:text-text-4',
|
|
1413
|
+
!nameValid && 'text-red-400',
|
|
1414
|
+
)}
|
|
1415
|
+
maxLength={64}
|
|
1416
|
+
spellCheck={false}
|
|
1417
|
+
/>
|
|
1418
|
+
{a.provider && a.provider !== tsProvider && (
|
|
1419
|
+
<span className="text-2xs text-accent font-mono shrink-0">{a.provider}</span>
|
|
1433
1420
|
)}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1421
|
+
{a.scope?.length > 0 && (
|
|
1422
|
+
<span className="text-2xs text-text-4 font-mono shrink-0 truncate max-w-[120px]">
|
|
1423
|
+
{a.scope[0]}{a.scope.length > 1 ? ` +${a.scope.length - 1}` : ''}
|
|
1424
|
+
</span>
|
|
1425
|
+
)}
|
|
1426
|
+
<ChevronDown size={10} className={cn('text-text-4 shrink-0 transition-transform duration-200', !isExpanded && '-rotate-90')} />
|
|
1427
|
+
</div>
|
|
1428
|
+
{isExpanded && (
|
|
1429
|
+
<div className="px-2.5 pb-2.5 pt-1 space-y-2.5 border-t border-border-subtle">
|
|
1430
|
+
<div className="flex gap-2">
|
|
1431
|
+
<div className="flex-1 space-y-1">
|
|
1432
|
+
<label className="flex items-center gap-1 text-2xs text-text-3 font-sans"><Cpu size={10} />Provider</label>
|
|
1433
|
+
<Select value={a.provider || ''} onValueChange={(id) => {
|
|
1434
|
+
const p = providers.find((x) => x.id === id);
|
|
1435
|
+
const pModels = (p?.models || []).filter((m) => m.type !== 'image' && !m.disabled);
|
|
1436
|
+
handleAgentField(i, { provider: id, model: pModels[0]?.id || '' });
|
|
1437
|
+
}}>
|
|
1438
|
+
<SelectTrigger placeholder="Team default" className="bg-surface-3 h-7 text-xs" />
|
|
1439
|
+
<SelectContent>
|
|
1440
|
+
<SelectItem value="">Team default</SelectItem>
|
|
1441
|
+
{providers.map((p) => (
|
|
1442
|
+
<SelectItem key={p.id} value={p.id}>{p.displayName || p.name || p.id}</SelectItem>
|
|
1443
|
+
))}
|
|
1444
|
+
</SelectContent>
|
|
1445
|
+
</Select>
|
|
1446
|
+
</div>
|
|
1447
|
+
<div className="flex-1 space-y-1">
|
|
1448
|
+
<label className="text-2xs text-text-3 font-sans">Model</label>
|
|
1449
|
+
<Select value={a.model || ''} onValueChange={(v) => handleAgentField(i, 'model', v)}>
|
|
1450
|
+
<SelectTrigger placeholder="Auto" className="bg-surface-3 h-7 text-xs" />
|
|
1451
|
+
<SelectContent>
|
|
1452
|
+
<SelectItem value="">Auto</SelectItem>
|
|
1453
|
+
{agentModels.map((m) => (
|
|
1454
|
+
<SelectItem key={m.id} value={m.id}>{m.name || m.id}</SelectItem>
|
|
1455
|
+
))}
|
|
1456
|
+
</SelectContent>
|
|
1457
|
+
</Select>
|
|
1458
|
+
</div>
|
|
1459
|
+
</div>
|
|
1460
|
+
<div className="space-y-1">
|
|
1461
|
+
<label className="flex items-center gap-1 text-2xs text-text-3 font-sans"><Activity size={10} />Model Routing</label>
|
|
1462
|
+
<div className="flex bg-surface-3 rounded-md p-0.5 border border-border-subtle">
|
|
1463
|
+
{[{ value: 'fixed', label: 'Fixed' }, { value: 'auto', label: 'Auto' }, { value: 'auto-floor', label: 'Auto + Floor' }].map((opt) => (
|
|
1464
|
+
<button
|
|
1465
|
+
key={opt.value}
|
|
1466
|
+
onClick={() => handleAgentField(i, 'routingMode', opt.value)}
|
|
1467
|
+
className={cn(
|
|
1468
|
+
'flex-1 px-2 py-1 text-2xs font-semibold font-sans rounded transition-all cursor-pointer',
|
|
1469
|
+
(a.routingMode || 'auto') === opt.value
|
|
1470
|
+
? 'bg-accent/15 text-accent shadow-sm'
|
|
1471
|
+
: 'text-text-3 hover:text-text-1',
|
|
1472
|
+
)}
|
|
1473
|
+
>
|
|
1474
|
+
{opt.label}
|
|
1475
|
+
</button>
|
|
1476
|
+
))}
|
|
1477
|
+
</div>
|
|
1478
|
+
</div>
|
|
1479
|
+
<div className="space-y-1">
|
|
1480
|
+
<label className="flex items-center gap-1 text-2xs text-text-3 font-sans"><Gauge size={10} />Effort Level</label>
|
|
1481
|
+
<div className="flex bg-surface-3 rounded-md p-0.5 border border-border-subtle">
|
|
1482
|
+
{[{ value: 'min', label: 'Min' }, { value: 'low', label: 'Low' }, { value: 'default', label: 'Default' }, { value: 'high', label: 'High' }, { value: 'max', label: 'Max' }].map((opt) => (
|
|
1483
|
+
<button
|
|
1484
|
+
key={opt.value}
|
|
1485
|
+
onClick={() => handleAgentField(i, 'effort', opt.value)}
|
|
1486
|
+
className={cn(
|
|
1487
|
+
'flex-1 px-1.5 py-1 text-2xs font-semibold font-sans rounded transition-all cursor-pointer',
|
|
1488
|
+
(a.effort || 'default') === opt.value
|
|
1489
|
+
? 'bg-accent/15 text-accent shadow-sm'
|
|
1490
|
+
: 'text-text-3 hover:text-text-1',
|
|
1491
|
+
)}
|
|
1492
|
+
>
|
|
1493
|
+
{opt.label}
|
|
1494
|
+
</button>
|
|
1495
|
+
))}
|
|
1496
|
+
</div>
|
|
1497
|
+
</div>
|
|
1498
|
+
</div>
|
|
1441
1499
|
)}
|
|
1442
1500
|
</div>
|
|
1443
1501
|
);
|
|
1444
1502
|
})}
|
|
1445
1503
|
|
|
1446
|
-
{recommendedTeam.projectDir &&
|
|
1504
|
+
{recommendedTeam.projectDir && (
|
|
1447
1505
|
<div className="flex items-center gap-1.5 text-2xs text-text-2 font-mono pt-0.5">
|
|
1448
1506
|
<span className="text-text-4">Project:</span>
|
|
1449
1507
|
<span className="text-accent">{recommendedTeam.projectDir}/</span>
|
|
@@ -4,6 +4,7 @@ import { useGrooveStore } from '../stores/groove';
|
|
|
4
4
|
import { DashboardHeader } from '../components/dashboard/header-bar';
|
|
5
5
|
import { KpiStrip } from '../components/dashboard/kpi-card';
|
|
6
6
|
import { FleetPanel } from '../components/dashboard/fleet-panel';
|
|
7
|
+
import { ContextGauges } from '../components/dashboard/context-gauges';
|
|
7
8
|
import { TokenChart } from '../components/dashboard/token-chart';
|
|
8
9
|
import { CacheRing } from '../components/dashboard/cache-ring';
|
|
9
10
|
import { RoutingChart } from '../components/dashboard/routing-chart';
|
|
@@ -142,6 +143,7 @@ export default function DashboardView() {
|
|
|
142
143
|
<div className="px-3 pt-2.5 pb-1 flex-shrink-0">
|
|
143
144
|
<span className="text-2xs font-mono text-text-3 uppercase tracking-widest">Agent Fleet</span>
|
|
144
145
|
</div>
|
|
146
|
+
<ContextGauges agentBreakdown={agentBreakdown} />
|
|
145
147
|
<FleetPanel agentBreakdown={agentBreakdown} rotating={rotating} teams={teams} />
|
|
146
148
|
</div>
|
|
147
149
|
|
|
@@ -4,15 +4,13 @@ import { ScrollArea } from '../components/ui/scroll-area';
|
|
|
4
4
|
import { Badge } from '../components/ui/badge';
|
|
5
5
|
import { Button } from '../components/ui/button';
|
|
6
6
|
import { Skeleton } from '../components/ui/skeleton';
|
|
7
|
-
import {
|
|
7
|
+
import { SkillCardSkeleton } from '../components/marketplace/skill-card';
|
|
8
8
|
import { MarketplaceCard } from '../components/marketplace/marketplace-card';
|
|
9
9
|
import { SearchBar } from '../components/marketplace/search-bar';
|
|
10
|
-
import { CategoryBar } from '../components/marketplace/category-bar';
|
|
11
10
|
import { MarketplaceBadge } from '../components/marketplace/marketplace-badge';
|
|
12
11
|
import { StarRating } from '../components/marketplace/star-rating';
|
|
13
12
|
import { PriceBadge } from '../components/marketplace/price-badge';
|
|
14
13
|
import { VerifiedShield } from '../components/marketplace/verified-shield';
|
|
15
|
-
import { markFavorites } from '../components/marketplace/favorites';
|
|
16
14
|
import { api } from '../lib/api';
|
|
17
15
|
import { useToast } from '../lib/hooks/use-toast';
|
|
18
16
|
import { fmtNum, timeAgo } from '../lib/format';
|
|
@@ -22,7 +20,7 @@ import { RepoImport } from '../components/marketplace/repo-import';
|
|
|
22
20
|
import { RepoCard } from '../components/marketplace/repo-card';
|
|
23
21
|
import { RepoNukeDialog } from '../components/marketplace/repo-nuke-dialog';
|
|
24
22
|
import {
|
|
25
|
-
ChevronLeft,
|
|
23
|
+
ChevronLeft, Plug, LogIn,
|
|
26
24
|
Upload, Package, Download, ShoppingBag, RefreshCw, Trash2,
|
|
27
25
|
GitBranch,
|
|
28
26
|
} from 'lucide-react';
|
|
@@ -214,70 +212,6 @@ function SkillDetail({ skill, onBack }) {
|
|
|
214
212
|
}
|
|
215
213
|
|
|
216
214
|
// ── Skills Browse ────────────────────────────────────────
|
|
217
|
-
function SkillsBrowse() {
|
|
218
|
-
const [skills, setSkills] = useState([]);
|
|
219
|
-
const [loading, setLoading] = useState(true);
|
|
220
|
-
const [search, setSearch] = useState('');
|
|
221
|
-
const [category, setCategory] = useState('');
|
|
222
|
-
const [sort, setSort] = useState('popular');
|
|
223
|
-
const [selectedSkill, setSelectedSkill] = useState(null);
|
|
224
|
-
|
|
225
|
-
useEffect(() => {
|
|
226
|
-
setLoading(true);
|
|
227
|
-
const params = new URLSearchParams();
|
|
228
|
-
if (search) params.set('search', search);
|
|
229
|
-
if (category) params.set('category', category);
|
|
230
|
-
if (sort) params.set('sort', sort);
|
|
231
|
-
api.get(`/skills/registry?${params}`)
|
|
232
|
-
.then((d) => setSkills(markFavorites(d.skills || d.items || (Array.isArray(d) ? d : []))))
|
|
233
|
-
.catch(() => setSkills([]))
|
|
234
|
-
.finally(() => setLoading(false));
|
|
235
|
-
}, [search, category, sort]);
|
|
236
|
-
|
|
237
|
-
if (selectedSkill) {
|
|
238
|
-
return <SkillDetail skill={selectedSkill} onBack={() => setSelectedSkill(null)} />;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return (
|
|
242
|
-
<ScrollArea className="h-full">
|
|
243
|
-
<div className="px-5 py-4">
|
|
244
|
-
<div className="flex items-center gap-3">
|
|
245
|
-
<div className="w-72">
|
|
246
|
-
<SearchBar value={search} onChange={setSearch} />
|
|
247
|
-
</div>
|
|
248
|
-
<CategoryBar selected={category} onSelect={setCategory} />
|
|
249
|
-
<div className="flex-1" />
|
|
250
|
-
<div className="relative flex-shrink-0">
|
|
251
|
-
<select
|
|
252
|
-
value={sort}
|
|
253
|
-
onChange={(e) => setSort(e.target.value)}
|
|
254
|
-
className="appearance-none font-sans cursor-pointer pr-7 py-2 pl-3 text-xs bg-surface-0 border border-border-subtle rounded text-text-1 focus:outline-none"
|
|
255
|
-
>
|
|
256
|
-
<option value="popular">Popular</option>
|
|
257
|
-
<option value="rating">Top Rated</option>
|
|
258
|
-
<option value="newest">Newest</option>
|
|
259
|
-
<option value="name">A-Z</option>
|
|
260
|
-
</select>
|
|
261
|
-
<ChevronDown size={12} className="absolute right-2 top-1/2 -translate-y-1/2 text-text-4 pointer-events-none" />
|
|
262
|
-
</div>
|
|
263
|
-
<span className="text-2xs text-text-4 font-mono flex-shrink-0">{skills.length}</span>
|
|
264
|
-
</div>
|
|
265
|
-
|
|
266
|
-
<div className="mt-4 grid gap-3" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))' }}>
|
|
267
|
-
{loading
|
|
268
|
-
? Array.from({ length: 8 }).map((_, i) => <SkillCardSkeleton key={i} />)
|
|
269
|
-
: skills.map((s) => <SkillCard key={s.id} skill={s} onClick={setSelectedSkill} />)
|
|
270
|
-
}
|
|
271
|
-
</div>
|
|
272
|
-
|
|
273
|
-
{!loading && skills.length === 0 && (
|
|
274
|
-
<div className="text-center py-16 text-text-4 font-sans text-sm">No skills found.</div>
|
|
275
|
-
)}
|
|
276
|
-
</div>
|
|
277
|
-
</ScrollArea>
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
215
|
// ── Integrations Browse ──────────────────────────────────
|
|
282
216
|
const GOOGLE_IDS = new Set(['gmail', 'google-calendar', 'google-drive', 'google-docs', 'google-sheets', 'google-slides']);
|
|
283
217
|
|
|
@@ -666,10 +600,9 @@ function GitHubBrowse() {
|
|
|
666
600
|
|
|
667
601
|
// ── Main ─────────────────────────────────────────────────
|
|
668
602
|
export default function MarketplaceView() {
|
|
669
|
-
const [tab, setTab] = useState('
|
|
603
|
+
const [tab, setTab] = useState('integrations');
|
|
670
604
|
|
|
671
605
|
const tabs = [
|
|
672
|
-
{ id: 'skills', label: 'Skills', icon: Sparkles },
|
|
673
606
|
{ id: 'integrations', label: 'Integrations', icon: Plug },
|
|
674
607
|
{ id: 'github', label: 'GitHub', icon: GitBranch },
|
|
675
608
|
{ id: 'library', label: 'My Library', icon: Package },
|
|
@@ -701,7 +634,6 @@ export default function MarketplaceView() {
|
|
|
701
634
|
|
|
702
635
|
{/* Content */}
|
|
703
636
|
<div className="flex-1 min-h-0">
|
|
704
|
-
{tab === 'skills' && <SkillsBrowse />}
|
|
705
637
|
{tab === 'integrations' && <IntegrationsBrowse />}
|
|
706
638
|
{tab === 'github' && <GitHubBrowse />}
|
|
707
639
|
{tab === 'library' && <MyLibrary />}
|
|
@@ -7,15 +7,15 @@ import { Dialog, DialogContent } from '../components/ui/dialog';
|
|
|
7
7
|
import { BookOpen, Plus, Search, Trash2, Pencil, ChevronRight, Hash, FolderOpen, Clock, Save, Link2, FileText, Sparkles, HelpCircle } from 'lucide-react';
|
|
8
8
|
|
|
9
9
|
const COMMANDS = [
|
|
10
|
-
{ cmd: '
|
|
11
|
-
{ cmd: '
|
|
12
|
-
{ cmd: '
|
|
13
|
-
{ cmd: '
|
|
14
|
-
{ cmd: '
|
|
15
|
-
{ cmd: '
|
|
16
|
-
{ cmd: '
|
|
17
|
-
{ cmd: '
|
|
18
|
-
{ cmd: '[instruct]', args: '',
|
|
10
|
+
{ cmd: 'save', args: '#tag', desc: 'Save the message and send it to the agent' },
|
|
11
|
+
{ cmd: 'append', args: '#tag', desc: 'Add to an existing memory and send to agent' },
|
|
12
|
+
{ cmd: 'update', args: '#tag', desc: 'Open the editor to modify a memory in place' },
|
|
13
|
+
{ cmd: 'delete', args: '#tag', desc: 'Remove a memory permanently' },
|
|
14
|
+
{ cmd: 'view', args: '#tag', desc: 'Read a memory in the viewer' },
|
|
15
|
+
{ cmd: 'read', args: '#tag1 #tag2 ...', desc: 'Send memory content to the agent — chat stays clean' },
|
|
16
|
+
{ cmd: 'doc', args: '#tag', desc: 'AI synthesizes the full conversation into a document' },
|
|
17
|
+
{ cmd: 'link', args: '#tag path/to/doc', desc: 'Link a memory to a NORTHSTAR or external document' },
|
|
18
|
+
{ cmd: '[instruct]', args: '', desc: 'Show this command reference' },
|
|
19
19
|
];
|
|
20
20
|
|
|
21
21
|
function formatRelative(iso) {
|
|
@@ -171,17 +171,12 @@ export default function ModelLabView() {
|
|
|
171
171
|
<PanelToggle collapsed={false} onClick={() => setLeftCollapsed(true)} side="left" />
|
|
172
172
|
</div>
|
|
173
173
|
<ScrollArea className="flex-1 min-h-0">
|
|
174
|
-
<div className="px-4 pb-4 space-y-5">
|
|
174
|
+
<div className="px-4 pb-4 space-y-5 divide-y divide-border-subtle [&>*]:pt-5 [&>*:first-child]:pt-0">
|
|
175
175
|
<LaunchModel />
|
|
176
|
-
<div className="h-px bg-border-subtle" />
|
|
177
176
|
<RuntimeConfig />
|
|
178
|
-
<div className="h-px bg-border-subtle" />
|
|
179
177
|
<ModelSelector />
|
|
180
|
-
<div className="h-px bg-border-subtle" />
|
|
181
178
|
<ParameterPanel />
|
|
182
|
-
<div className="h-px bg-border-subtle" />
|
|
183
179
|
<PresetManager />
|
|
184
|
-
<div className="h-px bg-border-subtle" />
|
|
185
180
|
<SystemPromptEditor />
|
|
186
181
|
</div>
|
|
187
182
|
</ScrollArea>
|