groove-dev 0.27.143 → 0.27.145
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/CLAUDE.md +0 -7
- package/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/api.js +1086 -6532
- package/node_modules/@groove-dev/daemon/src/conversations.js +18 -48
- package/node_modules/@groove-dev/daemon/src/gateways/manager.js +35 -1
- package/node_modules/@groove-dev/daemon/src/index.js +3 -0
- package/node_modules/@groove-dev/daemon/src/journalist.js +23 -13
- package/node_modules/@groove-dev/daemon/src/mlx-server.js +365 -0
- package/node_modules/@groove-dev/daemon/src/model-lab.js +308 -12
- package/node_modules/@groove-dev/daemon/src/pm.js +1 -1
- package/node_modules/@groove-dev/daemon/src/process.js +2 -2
- package/node_modules/@groove-dev/daemon/src/providers/local.js +36 -8
- package/node_modules/@groove-dev/daemon/src/registry.js +21 -5
- package/node_modules/@groove-dev/daemon/src/routes/agents.js +812 -0
- package/node_modules/@groove-dev/daemon/src/routes/coordination.js +318 -0
- package/node_modules/@groove-dev/daemon/src/routes/files.js +751 -0
- package/node_modules/@groove-dev/daemon/src/routes/integrations.js +485 -0
- package/node_modules/@groove-dev/daemon/src/routes/network.js +1784 -0
- package/node_modules/@groove-dev/daemon/src/routes/providers.js +755 -0
- package/node_modules/@groove-dev/daemon/src/routes/schedules.js +110 -0
- package/node_modules/@groove-dev/daemon/src/routes/teams.js +650 -0
- package/node_modules/@groove-dev/daemon/src/scheduler.js +456 -24
- package/node_modules/@groove-dev/daemon/src/teams.js +1 -1
- package/node_modules/@groove-dev/daemon/src/validate.js +38 -1
- package/node_modules/@groove-dev/daemon/templates/mlx-setup.json +12 -0
- package/node_modules/@groove-dev/daemon/templates/tgi-setup.json +1 -1
- package/node_modules/@groove-dev/daemon/templates/vllm-setup.json +1 -1
- package/node_modules/@groove-dev/daemon/test/introducer.test.js +3 -3
- package/node_modules/@groove-dev/daemon/test/journalist.test.js +7 -10
- package/node_modules/@groove-dev/daemon/test/registry.test.js +38 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-Bxc0gU06.js +1006 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-C0pztKBn.css +1 -0
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/{app.jsx → App.jsx} +0 -2
- package/node_modules/@groove-dev/gui/src/app.css +35 -0
- package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +1 -128
- package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +210 -112
- package/node_modules/@groove-dev/gui/src/components/agents/agent-node.jsx +8 -13
- package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +2 -70
- package/node_modules/@groove-dev/gui/src/components/agents/code-review.jsx +159 -122
- package/node_modules/@groove-dev/gui/src/components/agents/diff-viewer.jsx +23 -23
- package/node_modules/@groove-dev/gui/src/components/agents/journalist-panel.jsx +1 -1
- package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +2 -135
- package/node_modules/@groove-dev/gui/src/components/automations/automation-card.jsx +274 -0
- package/node_modules/@groove-dev/gui/src/components/automations/automation-wizard.jsx +1136 -0
- package/node_modules/@groove-dev/gui/src/components/chat/chat-header.jsx +2 -0
- package/node_modules/@groove-dev/gui/src/components/chat/chat-input.jsx +68 -66
- package/node_modules/@groove-dev/gui/src/components/chat/chat-view.jsx +4 -8
- package/node_modules/@groove-dev/gui/src/components/dashboard/activity-feed.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/dashboard/cache-ring.jsx +5 -5
- package/node_modules/@groove-dev/gui/src/components/dashboard/context-gauges.jsx +6 -8
- package/node_modules/@groove-dev/gui/src/components/dashboard/fleet-panel.jsx +8 -14
- package/node_modules/@groove-dev/gui/src/components/dashboard/intel-panel.jsx +238 -656
- package/node_modules/@groove-dev/gui/src/components/dashboard/kpi-card.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/dashboard/routing-chart.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/dashboard/team-burn-panel.jsx +1 -1
- package/node_modules/@groove-dev/gui/src/components/dashboard/token-chart.jsx +4 -4
- package/node_modules/@groove-dev/gui/src/components/lab/chat-playground.jsx +39 -31
- package/node_modules/@groove-dev/gui/src/components/lab/lab-assistant.jsx +316 -82
- package/node_modules/@groove-dev/gui/src/components/lab/metrics-panel.jsx +187 -32
- package/node_modules/@groove-dev/gui/src/components/lab/parameter-panel.jsx +200 -18
- package/node_modules/@groove-dev/gui/src/components/lab/preset-manager.jsx +17 -14
- package/node_modules/@groove-dev/gui/src/components/lab/runtime-config.jsx +335 -152
- package/node_modules/@groove-dev/gui/src/components/lab/system-prompt-editor.jsx +10 -8
- package/node_modules/@groove-dev/gui/src/components/layout/activity-bar.jsx +2 -4
- package/node_modules/@groove-dev/gui/src/components/layout/terminal-panel.jsx +4 -2
- package/node_modules/@groove-dev/gui/src/components/layout/welcome-splash.jsx +137 -108
- package/node_modules/@groove-dev/gui/src/components/network/network-health.jsx +2 -2
- package/node_modules/@groove-dev/gui/src/components/network/performance-dashboard.jsx +4 -4
- package/node_modules/@groove-dev/gui/src/components/settings/ssh-wizard.jsx +81 -99
- package/node_modules/@groove-dev/gui/src/components/ui/sheet.jsx +5 -2
- package/node_modules/@groove-dev/gui/src/components/ui/slider.jsx +8 -8
- package/node_modules/@groove-dev/gui/src/lib/cron.js +64 -0
- package/node_modules/@groove-dev/gui/src/lib/status.js +25 -24
- package/node_modules/@groove-dev/gui/src/lib/theme-hex.js +1 -0
- package/node_modules/@groove-dev/gui/src/stores/groove.js +51 -3144
- package/node_modules/@groove-dev/gui/src/stores/helpers.js +10 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +459 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/automations-slice.js +96 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/chat-slice.js +226 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/editor-slice.js +285 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/marketplace-slice.js +461 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/network-slice.js +361 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/preview-slice.js +109 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/providers-slice.js +897 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/teams-slice.js +413 -0
- package/node_modules/@groove-dev/gui/src/stores/slices/ui-slice.js +98 -0
- package/node_modules/@groove-dev/gui/src/views/agents.jsx +5 -5
- package/node_modules/@groove-dev/gui/src/views/dashboard.jsx +12 -13
- package/node_modules/@groove-dev/gui/src/views/marketplace.jsx +191 -3
- package/node_modules/@groove-dev/gui/src/views/model-lab.jsx +54 -12
- package/node_modules/@groove-dev/gui/src/views/models.jsx +419 -496
- package/node_modules/@groove-dev/gui/src/views/network.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/views/settings.jsx +81 -94
- package/node_modules/@groove-dev/gui/src/views/teams.jsx +40 -483
- package/node_modules/axios/CHANGELOG.md +260 -0
- package/node_modules/axios/README.md +595 -223
- package/node_modules/axios/dist/axios.js +1460 -1090
- package/node_modules/axios/dist/axios.js.map +1 -1
- package/node_modules/axios/dist/axios.min.js +3 -3
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +1560 -1132
- package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
- package/node_modules/axios/dist/esm/axios.js +1557 -1128
- package/node_modules/axios/dist/esm/axios.js.map +1 -1
- package/node_modules/axios/dist/esm/axios.min.js +2 -2
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +1594 -1057
- package/node_modules/axios/dist/node/axios.cjs.map +1 -1
- package/node_modules/axios/index.d.cts +40 -41
- package/node_modules/axios/index.d.ts +151 -227
- package/node_modules/axios/index.js +2 -0
- package/node_modules/axios/lib/adapters/adapters.js +4 -2
- package/node_modules/axios/lib/adapters/fetch.js +147 -16
- package/node_modules/axios/lib/adapters/http.js +306 -58
- package/node_modules/axios/lib/adapters/xhr.js +6 -2
- package/node_modules/axios/lib/core/Axios.js +7 -3
- package/node_modules/axios/lib/core/AxiosError.js +120 -34
- package/node_modules/axios/lib/core/AxiosHeaders.js +27 -25
- package/node_modules/axios/lib/core/buildFullPath.js +1 -1
- package/node_modules/axios/lib/core/dispatchRequest.js +19 -7
- package/node_modules/axios/lib/core/mergeConfig.js +21 -4
- package/node_modules/axios/lib/core/settle.js +7 -11
- package/node_modules/axios/lib/defaults/index.js +14 -9
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -2
- package/node_modules/axios/lib/helpers/buildURL.js +1 -1
- package/node_modules/axios/lib/helpers/cookies.js +14 -2
- package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +28 -1
- package/node_modules/axios/lib/helpers/formDataToJSON.js +3 -1
- package/node_modules/axios/lib/helpers/formDataToStream.js +3 -2
- package/node_modules/axios/lib/helpers/parseProtocol.js +1 -1
- package/node_modules/axios/lib/helpers/progressEventReducer.js +5 -5
- package/node_modules/axios/lib/helpers/resolveConfig.js +54 -18
- package/node_modules/axios/lib/helpers/shouldBypassProxy.js +74 -2
- package/node_modules/axios/lib/helpers/toFormData.js +10 -2
- package/node_modules/axios/lib/helpers/validator.js +3 -1
- package/node_modules/axios/lib/utils.js +33 -21
- package/node_modules/axios/package.json +17 -24
- package/node_modules/follow-redirects/README.md +7 -5
- package/node_modules/follow-redirects/index.js +24 -1
- package/node_modules/follow-redirects/package.json +1 -1
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/api.js +1086 -6532
- package/packages/daemon/src/conversations.js +18 -48
- package/packages/daemon/src/gateways/manager.js +35 -1
- package/packages/daemon/src/index.js +3 -0
- package/packages/daemon/src/journalist.js +23 -13
- package/packages/daemon/src/mlx-server.js +365 -0
- package/packages/daemon/src/model-lab.js +308 -12
- package/packages/daemon/src/pm.js +1 -1
- package/packages/daemon/src/process.js +2 -2
- package/packages/daemon/src/providers/local.js +36 -8
- package/packages/daemon/src/registry.js +21 -5
- package/packages/daemon/src/routes/agents.js +812 -0
- package/packages/daemon/src/routes/coordination.js +318 -0
- package/packages/daemon/src/routes/files.js +751 -0
- package/packages/daemon/src/routes/integrations.js +485 -0
- package/packages/daemon/src/routes/network.js +1784 -0
- package/packages/daemon/src/routes/providers.js +755 -0
- package/packages/daemon/src/routes/schedules.js +110 -0
- package/packages/daemon/src/routes/teams.js +650 -0
- package/packages/daemon/src/scheduler.js +456 -24
- package/packages/daemon/src/teams.js +1 -1
- package/packages/daemon/src/validate.js +38 -1
- package/packages/daemon/templates/mlx-setup.json +12 -0
- package/packages/daemon/templates/tgi-setup.json +1 -1
- package/packages/daemon/templates/vllm-setup.json +1 -1
- package/packages/gui/dist/assets/index-Bxc0gU06.js +1006 -0
- package/packages/gui/dist/assets/index-C0pztKBn.css +1 -0
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/{app.jsx → App.jsx} +0 -2
- package/packages/gui/src/app.css +35 -0
- package/packages/gui/src/components/agents/agent-config.jsx +1 -128
- package/packages/gui/src/components/agents/agent-feed.jsx +210 -112
- package/packages/gui/src/components/agents/agent-node.jsx +8 -13
- package/packages/gui/src/components/agents/agent-panel.jsx +2 -70
- package/packages/gui/src/components/agents/code-review.jsx +159 -122
- package/packages/gui/src/components/agents/diff-viewer.jsx +23 -23
- package/packages/gui/src/components/agents/journalist-panel.jsx +1 -1
- package/packages/gui/src/components/agents/spawn-wizard.jsx +2 -135
- package/packages/gui/src/components/automations/automation-card.jsx +274 -0
- package/packages/gui/src/components/automations/automation-wizard.jsx +1136 -0
- package/packages/gui/src/components/chat/chat-header.jsx +2 -0
- package/packages/gui/src/components/chat/chat-input.jsx +68 -66
- package/packages/gui/src/components/chat/chat-view.jsx +4 -8
- package/packages/gui/src/components/dashboard/activity-feed.jsx +3 -3
- package/packages/gui/src/components/dashboard/cache-ring.jsx +5 -5
- package/packages/gui/src/components/dashboard/context-gauges.jsx +6 -8
- package/packages/gui/src/components/dashboard/fleet-panel.jsx +8 -14
- package/packages/gui/src/components/dashboard/intel-panel.jsx +238 -656
- package/packages/gui/src/components/dashboard/kpi-card.jsx +3 -3
- package/packages/gui/src/components/dashboard/routing-chart.jsx +3 -3
- package/packages/gui/src/components/dashboard/team-burn-panel.jsx +1 -1
- package/packages/gui/src/components/dashboard/token-chart.jsx +4 -4
- package/packages/gui/src/components/lab/chat-playground.jsx +39 -31
- package/packages/gui/src/components/lab/lab-assistant.jsx +316 -82
- package/packages/gui/src/components/lab/metrics-panel.jsx +187 -32
- package/packages/gui/src/components/lab/parameter-panel.jsx +200 -18
- package/packages/gui/src/components/lab/preset-manager.jsx +17 -14
- package/packages/gui/src/components/lab/runtime-config.jsx +335 -152
- package/packages/gui/src/components/lab/system-prompt-editor.jsx +10 -8
- package/packages/gui/src/components/layout/activity-bar.jsx +2 -4
- package/packages/gui/src/components/layout/terminal-panel.jsx +4 -2
- package/packages/gui/src/components/layout/welcome-splash.jsx +137 -108
- package/packages/gui/src/components/network/network-health.jsx +2 -2
- package/packages/gui/src/components/network/performance-dashboard.jsx +4 -4
- package/packages/gui/src/components/settings/ssh-wizard.jsx +81 -99
- package/packages/gui/src/components/ui/sheet.jsx +5 -2
- package/packages/gui/src/components/ui/slider.jsx +8 -8
- package/packages/gui/src/lib/cron.js +64 -0
- package/packages/gui/src/lib/status.js +25 -24
- package/packages/gui/src/lib/theme-hex.js +1 -0
- package/packages/gui/src/stores/groove.js +51 -3144
- package/packages/gui/src/stores/helpers.js +10 -0
- package/packages/gui/src/stores/slices/agents-slice.js +459 -0
- package/packages/gui/src/stores/slices/automations-slice.js +96 -0
- package/packages/gui/src/stores/slices/chat-slice.js +226 -0
- package/packages/gui/src/stores/slices/editor-slice.js +285 -0
- package/packages/gui/src/stores/slices/marketplace-slice.js +461 -0
- package/packages/gui/src/stores/slices/network-slice.js +361 -0
- package/packages/gui/src/stores/slices/preview-slice.js +109 -0
- package/packages/gui/src/stores/slices/providers-slice.js +897 -0
- package/packages/gui/src/stores/slices/teams-slice.js +413 -0
- package/packages/gui/src/stores/slices/ui-slice.js +98 -0
- package/packages/gui/src/views/agents.jsx +5 -5
- package/packages/gui/src/views/dashboard.jsx +12 -13
- package/packages/gui/src/views/marketplace.jsx +191 -3
- package/packages/gui/src/views/model-lab.jsx +54 -12
- package/packages/gui/src/views/models.jsx +419 -496
- package/packages/gui/src/views/network.jsx +3 -3
- package/packages/gui/src/views/settings.jsx +81 -94
- package/packages/gui/src/views/teams.jsx +40 -483
- package/SECURITY_SWEEP.md +0 -228
- package/TRAINING_DATA_v4.md +0 -6
- package/node_modules/@groove-dev/gui/dist/assets/index-CCVvAoQn.css +0 -1
- package/node_modules/@groove-dev/gui/dist/assets/index-DGIv_TRm.js +0 -984
- package/node_modules/@groove-dev/gui/src/components/agents/agent-chat.jsx +0 -379
- package/node_modules/@groove-dev/gui/src/views/preview.jsx +0 -6
- package/node_modules/@groove-dev/gui/src/views/subscription-panel.jsx +0 -327
- package/packages/gui/dist/assets/index-CCVvAoQn.css +0 -1
- package/packages/gui/dist/assets/index-DGIv_TRm.js +0 -984
- package/packages/gui/src/components/agents/agent-chat.jsx +0 -379
- package/packages/gui/src/views/preview.jsx +0 -6
- package/packages/gui/src/views/subscription-panel.jsx +0 -327
- package/test.py +0 -571
|
@@ -25,7 +25,7 @@ export function SystemPromptEditor() {
|
|
|
25
25
|
const systemPrompt = useGrooveStore((s) => s.labSystemPrompt);
|
|
26
26
|
const setSystemPrompt = useGrooveStore((s) => s.setLabSystemPrompt);
|
|
27
27
|
const themeKey = useGrooveStore((s) => s.editorTheme);
|
|
28
|
-
const [collapsed, setCollapsed] = useState(
|
|
28
|
+
const [collapsed, setCollapsed] = useState(true);
|
|
29
29
|
const containerRef = useRef(null);
|
|
30
30
|
const viewRef = useRef(null);
|
|
31
31
|
const themeCompartment = useRef(new Compartment());
|
|
@@ -87,20 +87,22 @@ export function SystemPromptEditor() {
|
|
|
87
87
|
}, [systemPrompt]);
|
|
88
88
|
|
|
89
89
|
return (
|
|
90
|
-
<div className="space-y-
|
|
90
|
+
<div className="space-y-3">
|
|
91
91
|
<button
|
|
92
92
|
onClick={() => setCollapsed(!collapsed)}
|
|
93
|
-
className="flex items-center gap-1.5 w-full cursor-pointer group"
|
|
93
|
+
className="flex items-center gap-1.5 w-full h-6 cursor-pointer group"
|
|
94
94
|
>
|
|
95
95
|
{collapsed ? (
|
|
96
|
-
<ChevronRight size={
|
|
96
|
+
<ChevronRight size={10} className="text-text-4 group-hover:text-text-2 transition-colors flex-shrink-0" />
|
|
97
97
|
) : (
|
|
98
|
-
<ChevronDown size={
|
|
98
|
+
<ChevronDown size={10} className="text-text-4 group-hover:text-text-2 transition-colors flex-shrink-0" />
|
|
99
99
|
)}
|
|
100
|
-
<span className="text-
|
|
100
|
+
<span className="text-[10px] font-semibold font-sans text-text-3 uppercase tracking-widest group-hover:text-text-2 transition-colors">
|
|
101
101
|
System Prompt
|
|
102
102
|
</span>
|
|
103
|
-
|
|
103
|
+
{charCount > 0 && (
|
|
104
|
+
<span className="text-[10px] font-mono text-text-4 ml-auto tabular-nums">{charCount}</span>
|
|
105
|
+
)}
|
|
104
106
|
</button>
|
|
105
107
|
|
|
106
108
|
<div className={cn(
|
|
@@ -109,7 +111,7 @@ export function SystemPromptEditor() {
|
|
|
109
111
|
)}>
|
|
110
112
|
<div
|
|
111
113
|
ref={containerRef}
|
|
112
|
-
className="h-full border border-border-subtle
|
|
114
|
+
className="h-full rounded-md bg-surface-1/50 border border-border-subtle overflow-hidden"
|
|
113
115
|
/>
|
|
114
116
|
</div>
|
|
115
117
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
-
import { Network, Code2, ChartSpline, Puzzle, Users, Box, FlaskConical, Newspaper, Settings, Globe, MessageCircle,
|
|
2
|
+
import { Network, Code2, ChartSpline, Puzzle, Users, Box, FlaskConical, Newspaper, Settings, Globe, MessageCircle, BookOpen } from 'lucide-react';
|
|
3
3
|
import { cn } from '../../lib/cn';
|
|
4
4
|
import { Tooltip } from '../ui/tooltip';
|
|
5
5
|
import { useGrooveStore } from '../../stores/groove';
|
|
@@ -18,7 +18,6 @@ const BASE_NAV_ITEMS = [
|
|
|
18
18
|
];
|
|
19
19
|
|
|
20
20
|
const NETWORK_NAV_ITEM = { id: 'network', icon: Globe, label: 'Network' };
|
|
21
|
-
const PREVIEW_NAV_ITEM = { id: 'preview', icon: Eye, label: 'Preview' };
|
|
22
21
|
|
|
23
22
|
const UTIL_ITEMS = [
|
|
24
23
|
{ id: 'journalist', icon: Newspaper, label: 'Journalist', panel: true },
|
|
@@ -28,8 +27,7 @@ const UTIL_ITEMS = [
|
|
|
28
27
|
export function ActivityBar({ activeView, detailPanel, onNavigate, onTogglePanel }) {
|
|
29
28
|
const darwinTrafficLights = isElectron() && getPlatform() === 'darwin';
|
|
30
29
|
const networkUnlocked = useGrooveStore((s) => s.networkUnlocked);
|
|
31
|
-
|
|
32
|
-
let NAV_ITEMS = previewUrl ? [...BASE_NAV_ITEMS, PREVIEW_NAV_ITEM] : BASE_NAV_ITEMS;
|
|
30
|
+
let NAV_ITEMS = BASE_NAV_ITEMS;
|
|
33
31
|
if (networkUnlocked) NAV_ITEMS = [...NAV_ITEMS, NETWORK_NAV_ITEM];
|
|
34
32
|
|
|
35
33
|
return (
|
|
@@ -107,7 +107,9 @@ export function TerminalPanel({
|
|
|
107
107
|
const startY = useRef(0);
|
|
108
108
|
const startH = useRef(0);
|
|
109
109
|
|
|
110
|
-
const
|
|
110
|
+
const detailPanel = useGrooveStore((s) => s.detailPanel);
|
|
111
|
+
const workspaceAgentId = useGrooveStore((s) => s.workspaceAgentId);
|
|
112
|
+
const activeAgent = detailPanel?.type === 'agent' ? detailPanel.agentId : workspaceAgentId || null;
|
|
111
113
|
const agents = useGrooveStore((s) => s.agents);
|
|
112
114
|
const attachSnippet = useGrooveStore((s) => s.attachSnippet);
|
|
113
115
|
|
|
@@ -141,8 +143,8 @@ export function TerminalPanel({
|
|
|
141
143
|
function sendToAgent(agentId) {
|
|
142
144
|
if (!agentId || !selectedText?.trim()) return;
|
|
143
145
|
setShowPicker(false);
|
|
144
|
-
useGrooveStore.setState({ editorSelectedAgent: agentId });
|
|
145
146
|
attachSnippet({ type: 'terminal', code: selectedText.trim() });
|
|
147
|
+
useGrooveStore.getState().selectAgent(agentId);
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
function handleSendClick() {
|
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
+
//
|
|
3
|
+
// ⚠️ AGENT CONTEXT LANDMINE — READ BEFORE MODIFYING THIS FILE
|
|
4
|
+
//
|
|
5
|
+
// This file's import chain pulls in heavy components (quick-connect → ssh-wizard
|
|
6
|
+
// at 22KB, folder-browser at 7KB, groove.js store at 41KB). Reading those files
|
|
7
|
+
// will blow your context window and cause compaction → stall → freeze.
|
|
8
|
+
//
|
|
9
|
+
// RULES FOR AI AGENTS:
|
|
10
|
+
// 1. Do NOT read groove.js — the store selectors below are the full interface
|
|
11
|
+
// 2. Do NOT read or modify quick-connect.jsx or ssh-wizard.jsx — they are
|
|
12
|
+
// standalone components rendered as-is. Restyle them in their own files.
|
|
13
|
+
// 3. Do NOT read folder-browser.jsx — it's a dialog, just pass it props
|
|
14
|
+
// 4. Do NOT spawn Explore sub-agents to "understand the codebase" — everything
|
|
15
|
+
// you need is in THIS file and app.css (for design tokens / CSS variables)
|
|
16
|
+
// 5. Redesign THIS file only. Never rewrite imported components as a side-effect.
|
|
17
|
+
//
|
|
2
18
|
import { useState, useEffect } from 'react';
|
|
3
19
|
import { useGrooveStore } from '../../stores/groove';
|
|
4
|
-
import { HEX, hexAlpha } from '../../lib/theme-hex';
|
|
5
20
|
import { cn } from '../../lib/cn';
|
|
6
21
|
import {
|
|
7
22
|
FolderOpen, Radio, X, Plus, ExternalLink, Loader2, Unplug,
|
|
23
|
+
ArrowRight, Clock, Server,
|
|
8
24
|
} from 'lucide-react';
|
|
9
|
-
import { FolderBrowser } from '../agents/folder-browser';
|
|
10
|
-
import { QuickConnect } from '../settings/quick-connect';
|
|
25
|
+
import { FolderBrowser } from '../agents/folder-browser'; // dialog — don't read source, just pass props
|
|
26
|
+
import { QuickConnect } from '../settings/quick-connect'; // self-contained — don't read or rewrite
|
|
11
27
|
import { StatusDot } from '../ui/status-dot';
|
|
12
28
|
import { ToastContainer } from '../ui/toast';
|
|
13
29
|
|
|
14
30
|
export function WelcomeSplash() {
|
|
31
|
+
// These are ALL the store selectors this component uses — no need to read groove.js
|
|
15
32
|
const recentProjects = useGrooveStore((s) => s.recentProjects);
|
|
16
33
|
const setProjectDir = useGrooveStore((s) => s.setProjectDir);
|
|
17
34
|
const removeRecentProject = useGrooveStore((s) => s.removeRecentProject);
|
|
@@ -32,7 +49,7 @@ export function WelcomeSplash() {
|
|
|
32
49
|
const visibleProjects = (recentProjects || []).slice(0, 8);
|
|
33
50
|
const hasRecent = visibleProjects.length > 0;
|
|
34
51
|
const hasTunnels = savedTunnels.length > 0;
|
|
35
|
-
const
|
|
52
|
+
const hasContent = hasRecent || hasTunnels;
|
|
36
53
|
|
|
37
54
|
async function handleTunnelClick(server) {
|
|
38
55
|
if (server.active) {
|
|
@@ -53,106 +70,96 @@ export function WelcomeSplash() {
|
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
return (
|
|
56
|
-
<div
|
|
57
|
-
className="fixed
|
|
58
|
-
style={{ background: `radial-gradient(ellipse at 50% 40%, ${hexAlpha(HEX.accent, 0.06)} 0%, transparent 70%) ${HEX.surface0}` }}
|
|
59
|
-
>
|
|
60
|
-
<div className={cn(
|
|
61
|
-
'w-full max-w-4xl px-8 flex gap-12',
|
|
62
|
-
hasRightContent ? 'items-start' : 'items-center justify-center',
|
|
63
|
-
'max-md:flex-col max-md:items-center max-md:gap-8 max-md:overflow-y-auto max-md:max-h-[100vh] max-md:py-12',
|
|
64
|
-
)}>
|
|
65
|
-
{/* ── Left Panel ─────────────────────────────────────── */}
|
|
66
|
-
<div className={cn(
|
|
67
|
-
'flex flex-col',
|
|
68
|
-
hasRightContent ? 'w-[55%] max-md:w-full' : 'w-full max-w-lg',
|
|
69
|
-
hasRightContent ? 'pt-[10vh]' : 'items-center text-center',
|
|
70
|
-
)}>
|
|
71
|
-
{/* Hero */}
|
|
72
|
-
<div className={cn('flex items-center gap-4 mb-6', !hasRightContent && 'flex-col')}>
|
|
73
|
-
<div
|
|
74
|
-
className="w-16 h-16 rounded-full flex items-center justify-center flex-shrink-0"
|
|
75
|
-
style={{
|
|
76
|
-
background: hexAlpha(HEX.accent, 0.08),
|
|
77
|
-
border: `1px solid ${hexAlpha(HEX.accent, 0.15)}`,
|
|
78
|
-
boxShadow: `0 0 40px ${hexAlpha(HEX.accent, 0.1)}`,
|
|
79
|
-
}}
|
|
80
|
-
>
|
|
81
|
-
<img src="/favicon.png" className="w-9 h-9 rounded-full" alt="Groove" />
|
|
82
|
-
</div>
|
|
83
|
-
<div>
|
|
84
|
-
<h1 className="text-2xl font-bold text-text-0 font-sans tracking-tight">Welcome to Groove</h1>
|
|
85
|
-
<p className="text-sm text-text-2 font-sans mt-0.5">Your AI coding team, ready in minutes</p>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
73
|
+
<div className="fixed inset-0 z-50 overflow-y-auto welcome-bg">
|
|
74
|
+
<div className="pointer-events-none fixed top-0 left-1/2 -translate-x-1/2 w-[800px] h-[600px] rounded-full bg-accent/[0.03] blur-[120px]" />
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
<div className="flex flex-col gap-3 mt-4 w-full">
|
|
91
|
-
<button
|
|
92
|
-
onClick={() => setBrowsing(true)}
|
|
93
|
-
className="w-full flex items-center gap-4 p-5 rounded-lg border border-accent/25 bg-gradient-to-r from-accent/8 to-accent/3 hover:from-accent/14 hover:to-accent/6 hover:border-accent/40 transition-all cursor-pointer group text-left"
|
|
94
|
-
>
|
|
95
|
-
<div className="w-11 h-11 rounded-lg bg-accent/20 flex items-center justify-center group-hover:scale-110 transition-transform flex-shrink-0">
|
|
96
|
-
<FolderOpen size={22} className="text-accent" />
|
|
97
|
-
</div>
|
|
98
|
-
<div className="flex-1 min-w-0">
|
|
99
|
-
<div className="text-base font-semibold text-text-0 font-sans">Open Project</div>
|
|
100
|
-
<div className="text-sm text-text-2 font-sans mt-0.5">Browse the filesystem to pick a project</div>
|
|
101
|
-
</div>
|
|
102
|
-
</button>
|
|
76
|
+
<div className="relative min-h-screen flex flex-col items-center px-8 pt-[14vh] pb-12 max-sm:pt-[8vh] max-sm:px-5">
|
|
103
77
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
<div className="text-sm text-text-2 font-sans mt-0.5">SSH tunnel to a server</div>
|
|
114
|
-
</div>
|
|
115
|
-
</button>
|
|
78
|
+
{/* ── Hero ──────────────────────────────────────────── */}
|
|
79
|
+
<div className="flex flex-col items-center text-center mb-14">
|
|
80
|
+
<div className="relative mb-8">
|
|
81
|
+
<div className="absolute -inset-10 rounded-full bg-accent/[0.06] blur-3xl animate-welcome-breathe" />
|
|
82
|
+
<div className="absolute -inset-4 rounded-full border border-accent/25 animate-welcome-ring" />
|
|
83
|
+
<div className="absolute -inset-4 rounded-full border border-accent/15 animate-welcome-ring-delayed" />
|
|
84
|
+
<div className="relative w-[88px] h-[88px] rounded-full bg-accent/[0.07] border border-accent/20 flex items-center justify-center welcome-logo-shadow">
|
|
85
|
+
<img src="/favicon.png" className="w-12 h-12 rounded-full" alt="Groove" />
|
|
86
|
+
</div>
|
|
116
87
|
</div>
|
|
117
88
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<
|
|
124
|
-
<span className="
|
|
125
|
-
<span className="text-text-4 mx-1">·</span>
|
|
126
|
-
<kbd className="font-mono bg-surface-4 px-1.5 py-0.5 rounded text-text-3">Cmd+J</kbd>
|
|
127
|
-
<span className="mx-1.5">terminal</span>
|
|
89
|
+
<h1 className="text-4xl font-bold text-text-0 tracking-tight mb-3 font-sans max-sm:text-3xl">
|
|
90
|
+
Welcome to Groove
|
|
91
|
+
</h1>
|
|
92
|
+
<p className="text-base text-text-2 font-sans max-w-md leading-relaxed max-sm:text-sm">
|
|
93
|
+
The most powerful agenticOS ever built.
|
|
94
|
+
<br className="max-sm:hidden" />
|
|
95
|
+
<span className="max-sm:hidden"> </span>Spawn fast. Stay aware. Never lose context.
|
|
128
96
|
</p>
|
|
129
97
|
</div>
|
|
130
98
|
|
|
131
|
-
{/* ──
|
|
132
|
-
|
|
133
|
-
<
|
|
134
|
-
{
|
|
99
|
+
{/* ── Action Cards ──────────────────────────────────── */}
|
|
100
|
+
<div className="w-full max-w-2xl grid grid-cols-2 gap-4 mb-14 max-sm:grid-cols-1 max-sm:max-w-sm">
|
|
101
|
+
<button
|
|
102
|
+
onClick={() => setBrowsing(true)}
|
|
103
|
+
className="group relative overflow-hidden rounded-xl border border-accent/20 bg-gradient-to-br from-accent/[0.08] via-accent/[0.03] to-transparent p-6 text-left hover:border-accent/40 hover:from-accent/[0.14] hover:via-accent/[0.06] transition-all duration-300 cursor-pointer"
|
|
104
|
+
>
|
|
105
|
+
<div className="w-12 h-12 rounded-xl bg-accent/15 border border-accent/20 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform duration-300">
|
|
106
|
+
<FolderOpen size={24} className="text-accent" />
|
|
107
|
+
</div>
|
|
108
|
+
<div className="text-lg font-semibold text-text-0 font-sans mb-1">Open Project</div>
|
|
109
|
+
<div className="text-sm text-text-2 font-sans">Browse the filesystem to pick a project</div>
|
|
110
|
+
<div className="flex items-center gap-1 text-xs text-accent font-sans mt-4 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
|
111
|
+
Browse files <ArrowRight size={12} />
|
|
112
|
+
</div>
|
|
113
|
+
</button>
|
|
114
|
+
|
|
115
|
+
<button
|
|
116
|
+
onClick={toggleQuickConnect}
|
|
117
|
+
className="group relative overflow-hidden rounded-xl border border-border bg-surface-1 p-6 text-left hover:border-accent/30 hover:bg-surface-2 transition-all duration-300 cursor-pointer"
|
|
118
|
+
>
|
|
119
|
+
<div className="w-12 h-12 rounded-xl bg-surface-4 border border-border-subtle flex items-center justify-center mb-4 group-hover:scale-110 group-hover:bg-accent/10 group-hover:border-accent/20 transition-all duration-300">
|
|
120
|
+
<Radio size={24} className="text-text-2 group-hover:text-accent transition-colors duration-300" />
|
|
121
|
+
</div>
|
|
122
|
+
<div className="text-lg font-semibold text-text-0 font-sans mb-1">Connect to Remote</div>
|
|
123
|
+
<div className="text-sm text-text-2 font-sans">SSH tunnel to a server running Groove</div>
|
|
124
|
+
<div className="flex items-center gap-1 text-xs text-accent font-sans mt-4 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
|
125
|
+
Setup connection <ArrowRight size={12} />
|
|
126
|
+
</div>
|
|
127
|
+
</button>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
{/* ── Content Grid ──────────────────────────────────── */}
|
|
131
|
+
{hasContent && (
|
|
132
|
+
<div className={cn(
|
|
133
|
+
'w-full max-w-4xl gap-6 mb-14 max-sm:flex max-sm:flex-col max-sm:gap-6',
|
|
134
|
+
hasRecent && hasTunnels ? 'grid grid-cols-2' : 'flex justify-center',
|
|
135
|
+
)}>
|
|
135
136
|
{hasRecent && (
|
|
136
|
-
<div>
|
|
137
|
-
<div className="
|
|
138
|
-
|
|
137
|
+
<div className={cn(!hasTunnels && 'w-full max-w-lg')}>
|
|
138
|
+
<div className="flex items-center gap-2 mb-3">
|
|
139
|
+
<Clock size={13} className="text-text-3" />
|
|
140
|
+
<h2 className="text-2xs font-mono text-text-3 uppercase tracking-widest">Recent Projects</h2>
|
|
141
|
+
</div>
|
|
142
|
+
<div className="rounded-xl border border-border-subtle bg-surface-1/50 overflow-hidden divide-y divide-border-subtle">
|
|
139
143
|
{visibleProjects.map((project) => (
|
|
140
144
|
<div
|
|
141
145
|
key={project.path}
|
|
142
|
-
className="group flex items-center gap-
|
|
146
|
+
className="group flex items-center gap-3 px-4 py-3 hover:bg-surface-2/50 transition-colors"
|
|
143
147
|
>
|
|
148
|
+
<div className="w-8 h-8 rounded-lg bg-surface-3 flex items-center justify-center flex-shrink-0 group-hover:bg-accent/10 transition-colors">
|
|
149
|
+
<FolderOpen size={14} className="text-text-3 group-hover:text-accent transition-colors" />
|
|
150
|
+
</div>
|
|
144
151
|
<button
|
|
145
152
|
onClick={() => setProjectDir(project.path)}
|
|
146
153
|
className="flex-1 min-w-0 text-left cursor-pointer"
|
|
147
154
|
>
|
|
148
|
-
<div className="text-sm font-medium text-text-1 hover:text-accent truncate transition-colors">
|
|
155
|
+
<div className="text-sm font-medium text-text-1 group-hover:text-accent truncate transition-colors font-sans">
|
|
149
156
|
{project.name}
|
|
150
157
|
</div>
|
|
151
158
|
<div className="text-2xs font-mono text-text-4 truncate">{project.path}</div>
|
|
152
159
|
</button>
|
|
153
160
|
<button
|
|
154
161
|
onClick={(e) => { e.stopPropagation(); removeRecentProject(project.path); }}
|
|
155
|
-
className="opacity-0 group-hover:opacity-100 p-
|
|
162
|
+
className="opacity-0 group-hover:opacity-100 p-1 text-text-4 hover:text-danger cursor-pointer transition-all flex-shrink-0"
|
|
156
163
|
title="Remove from recent"
|
|
157
164
|
>
|
|
158
165
|
<X size={14} />
|
|
@@ -163,45 +170,51 @@ export function WelcomeSplash() {
|
|
|
163
170
|
</div>
|
|
164
171
|
)}
|
|
165
172
|
|
|
166
|
-
{/* Divider */}
|
|
167
|
-
{hasRecent && hasTunnels && (
|
|
168
|
-
<div className="border-t border-border-subtle my-4" />
|
|
169
|
-
)}
|
|
170
|
-
|
|
171
|
-
{/* SSH Connections */}
|
|
172
173
|
{hasTunnels && (
|
|
173
|
-
<div>
|
|
174
|
-
<div className="
|
|
175
|
-
|
|
174
|
+
<div className={cn(!hasRecent && 'w-full max-w-lg')}>
|
|
175
|
+
<div className="flex items-center gap-2 mb-3">
|
|
176
|
+
<Server size={13} className="text-text-3" />
|
|
177
|
+
<h2 className="text-2xs font-mono text-text-3 uppercase tracking-widest">SSH Connections</h2>
|
|
178
|
+
</div>
|
|
179
|
+
<div className="rounded-xl border border-border-subtle bg-surface-1/50 overflow-hidden divide-y divide-border-subtle">
|
|
176
180
|
{savedTunnels.map((server) => (
|
|
177
181
|
<div
|
|
178
182
|
key={server.id}
|
|
179
183
|
className={cn(
|
|
180
|
-
'group flex items-center gap-
|
|
184
|
+
'group flex items-center gap-3 px-4 py-3 hover:bg-surface-2/50 transition-colors',
|
|
181
185
|
connectingId === server.id && 'opacity-60 pointer-events-none',
|
|
182
186
|
)}
|
|
183
187
|
>
|
|
188
|
+
<div className={cn(
|
|
189
|
+
'w-8 h-8 rounded-lg flex items-center justify-center flex-shrink-0 transition-colors',
|
|
190
|
+
server.active ? 'bg-success/10' : 'bg-surface-3 group-hover:bg-accent/10',
|
|
191
|
+
)}>
|
|
192
|
+
<Server size={14} className={cn(
|
|
193
|
+
'transition-colors',
|
|
194
|
+
server.active ? 'text-success' : 'text-text-3 group-hover:text-accent',
|
|
195
|
+
)} />
|
|
196
|
+
</div>
|
|
184
197
|
<button
|
|
185
198
|
onClick={() => handleTunnelClick(server)}
|
|
186
199
|
disabled={connectingId === server.id}
|
|
187
200
|
className="flex-1 min-w-0 text-left cursor-pointer"
|
|
188
201
|
>
|
|
189
202
|
<div className="flex items-center gap-1.5">
|
|
190
|
-
<span className="text-sm font-medium text-text-1 hover:text-accent truncate transition-colors">
|
|
203
|
+
<span className="text-sm font-medium text-text-1 group-hover:text-accent truncate transition-colors font-sans">
|
|
191
204
|
{server.name}
|
|
192
205
|
</span>
|
|
193
206
|
{server.active && <StatusDot status="running" size="sm" />}
|
|
194
207
|
</div>
|
|
195
208
|
<div className="text-2xs font-mono text-text-4 truncate">{server.user}@{server.host}</div>
|
|
196
209
|
</button>
|
|
197
|
-
<div className="flex items-center gap-1 flex-shrink-0">
|
|
210
|
+
<div className="flex items-center gap-1.5 flex-shrink-0">
|
|
198
211
|
{connectingId === server.id ? (
|
|
199
212
|
<Loader2 size={14} className="text-text-3 animate-spin" />
|
|
200
213
|
) : server.active ? (
|
|
201
214
|
<>
|
|
202
215
|
<button
|
|
203
216
|
onClick={() => handleTunnelClick(server)}
|
|
204
|
-
className="opacity-0 group-hover:opacity-100 flex items-center gap-0.5 text-2xs text-success hover:text-success/80 cursor-pointer transition-all"
|
|
217
|
+
className="opacity-0 group-hover:opacity-100 flex items-center gap-0.5 text-2xs text-success hover:text-success/80 cursor-pointer transition-all font-sans"
|
|
205
218
|
>
|
|
206
219
|
<ExternalLink size={11} /> Open
|
|
207
220
|
</button>
|
|
@@ -210,7 +223,7 @@ export function WelcomeSplash() {
|
|
|
210
223
|
await disconnectTunnel(server.id);
|
|
211
224
|
addToast('info', 'Disconnected', server.name);
|
|
212
225
|
}}
|
|
213
|
-
className="opacity-0 group-hover:opacity-100 p-
|
|
226
|
+
className="opacity-0 group-hover:opacity-100 p-1 text-text-4 hover:text-danger cursor-pointer transition-all"
|
|
214
227
|
title="Disconnect"
|
|
215
228
|
>
|
|
216
229
|
<Unplug size={12} />
|
|
@@ -219,7 +232,7 @@ export function WelcomeSplash() {
|
|
|
219
232
|
) : null}
|
|
220
233
|
<button
|
|
221
234
|
onClick={(e) => { e.stopPropagation(); deleteTunnel(server.id); }}
|
|
222
|
-
className="opacity-0 group-hover:opacity-100 p-
|
|
235
|
+
className="opacity-0 group-hover:opacity-100 p-1 text-text-4 hover:text-danger cursor-pointer transition-all flex-shrink-0"
|
|
223
236
|
title="Remove connection"
|
|
224
237
|
>
|
|
225
238
|
<X size={14} />
|
|
@@ -227,24 +240,40 @@ export function WelcomeSplash() {
|
|
|
227
240
|
</div>
|
|
228
241
|
</div>
|
|
229
242
|
))}
|
|
243
|
+
<button
|
|
244
|
+
onClick={toggleQuickConnect}
|
|
245
|
+
className="flex items-center gap-1.5 text-2xs text-accent hover:text-accent/80 font-sans font-medium cursor-pointer transition-colors w-full px-4 py-2.5 hover:bg-surface-2/30"
|
|
246
|
+
>
|
|
247
|
+
<Plus size={11} /> Add Connection
|
|
248
|
+
</button>
|
|
230
249
|
</div>
|
|
231
|
-
<button
|
|
232
|
-
onClick={toggleQuickConnect}
|
|
233
|
-
className="flex items-center gap-1 text-xs text-accent hover:underline font-sans cursor-pointer mt-2 px-2"
|
|
234
|
-
>
|
|
235
|
-
<Plus size={12} /> Add Connection
|
|
236
|
-
</button>
|
|
237
250
|
</div>
|
|
238
251
|
)}
|
|
239
|
-
|
|
240
|
-
{/* Empty state */}
|
|
241
|
-
{!hasRecent && !hasTunnels && (
|
|
242
|
-
<p className="text-sm text-text-4 italic px-2">No recent activity</p>
|
|
243
|
-
)}
|
|
244
252
|
</div>
|
|
245
253
|
)}
|
|
254
|
+
|
|
255
|
+
{/* ── Footer ──────────────────────────────────────── */}
|
|
256
|
+
<div className="mt-auto pt-8 flex flex-col items-center gap-4">
|
|
257
|
+
<div className="flex items-center gap-5 text-xs text-text-4 font-sans">
|
|
258
|
+
<span className="flex items-center gap-1.5">
|
|
259
|
+
<kbd className="font-mono bg-surface-4 px-1.5 py-0.5 rounded text-text-3 text-2xs">⌘K</kbd>
|
|
260
|
+
<span>palette</span>
|
|
261
|
+
</span>
|
|
262
|
+
<span className="text-border">·</span>
|
|
263
|
+
<span className="flex items-center gap-1.5">
|
|
264
|
+
<kbd className="font-mono bg-surface-4 px-1.5 py-0.5 rounded text-text-3 text-2xs">⌘N</kbd>
|
|
265
|
+
<span>spawn</span>
|
|
266
|
+
</span>
|
|
267
|
+
<span className="text-border">·</span>
|
|
268
|
+
<span className="flex items-center gap-1.5">
|
|
269
|
+
<kbd className="font-mono bg-surface-4 px-1.5 py-0.5 rounded text-text-3 text-2xs">⌘J</kbd>
|
|
270
|
+
<span>terminal</span>
|
|
271
|
+
</span>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
246
274
|
</div>
|
|
247
275
|
|
|
276
|
+
{/* These are self-contained components — do NOT read/rewrite their source files */}
|
|
248
277
|
<FolderBrowser
|
|
249
278
|
open={browsing}
|
|
250
279
|
onOpenChange={setBrowsing}
|
|
@@ -43,8 +43,8 @@ export const NetworkHealth = memo(function NetworkHealth() {
|
|
|
43
43
|
<span className="absolute inset-0 rounded-sm" style={{ background: signalReachable ? HEX.success : HEX.danger }} />
|
|
44
44
|
{signalReachable && (
|
|
45
45
|
<span
|
|
46
|
-
className="absolute inset-[-2px] rounded-sm"
|
|
47
|
-
style={{ background: HEX.success
|
|
46
|
+
className="absolute inset-[-2px] rounded-sm opacity-15 [animation:node-pulse-bar_2s_ease-in-out_infinite]"
|
|
47
|
+
style={{ background: HEX.success }}
|
|
48
48
|
/>
|
|
49
49
|
)}
|
|
50
50
|
</span>
|
|
@@ -156,7 +156,7 @@ const TpsChart = memo(function TpsChart() {
|
|
|
156
156
|
{latestTps > 0 ? `${latestTps.toFixed(1)} t/s` : '\u2014'}
|
|
157
157
|
</span>
|
|
158
158
|
</div>
|
|
159
|
-
<div ref={containerRef} className="relative flex-1 min-h-
|
|
159
|
+
<div ref={containerRef} className="relative flex-1 min-h-[120px]">
|
|
160
160
|
{chartData.length < 2 ? (
|
|
161
161
|
<div className="absolute inset-0 flex items-center justify-center">
|
|
162
162
|
<span className="text-xs font-mono text-text-3">Collecting performance data\u2026</span>
|
|
@@ -353,8 +353,8 @@ function GaugeBar({ value, max, peakValue, color, label, unit }) {
|
|
|
353
353
|
/>
|
|
354
354
|
{peakPct != null && (
|
|
355
355
|
<div
|
|
356
|
-
className="absolute top-0 h-full w-px"
|
|
357
|
-
style={{ left: `${peakPct}%`, background: HEX.danger
|
|
356
|
+
className="absolute top-0 h-full w-px opacity-70"
|
|
357
|
+
style={{ left: `${peakPct}%`, background: HEX.danger }}
|
|
358
358
|
title={`Peak: ${Math.round(peakValue)} ${unit || ''}`}
|
|
359
359
|
/>
|
|
360
360
|
)}
|
|
@@ -548,7 +548,7 @@ export const PerformanceDashboard = memo(function PerformanceDashboard({ active
|
|
|
548
548
|
<div className="p-4 grid grid-cols-1 lg:grid-cols-2 gap-3">
|
|
549
549
|
{/* Left column */}
|
|
550
550
|
<div className="flex flex-col gap-3">
|
|
551
|
-
<div className="rounded-md border border-border-subtle bg-surface-0 overflow-hidden"
|
|
551
|
+
<div className="rounded-md border border-border-subtle bg-surface-0 overflow-hidden min-h-[200px]">
|
|
552
552
|
<TpsChart />
|
|
553
553
|
</div>
|
|
554
554
|
|