groove-dev 0.27.107 → 0.27.108
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/TRAINING_DATA.md +9 -0
- package/moe-training/client/envelope-builder.js +5 -0
- package/moe-training/client/scrubber.js +1 -1
- package/moe-training/client/step-classifier.js +22 -6
- package/moe-training/client/trajectory-capture.js +15 -4
- package/moe-training/shared/constants.js +2 -0
- package/moe-training/shared/envelope-schema.js +1 -1
- package/moe-training/test/client/envelope-builder.test.js +32 -0
- package/moe-training/test/client/scrubber.test.js +13 -0
- package/moe-training/test/client/step-classifier.test.js +96 -7
- package/moe-training/test/client/trajectory-capture.test.js +53 -6
- 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 +29 -2
- package/node_modules/@groove-dev/daemon/src/process.js +5 -5
- package/node_modules/@groove-dev/gui/dist/assets/{index-DkAGIluW.js → index-CEgtSfbG.js} +1748 -1745
- package/node_modules/@groove-dev/gui/dist/assets/{index-QwgLRN8B.css → index-_3cJS_UG.css} +1 -1
- 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/components/layout/command-palette.jsx +2 -1
- package/node_modules/@groove-dev/gui/src/components/layout/status-bar.jsx +9 -3
- package/node_modules/@groove-dev/gui/src/components/settings/federation-panel.jsx +2 -2
- package/node_modules/@groove-dev/gui/src/components/settings/federation-peers.jsx +14 -2
- package/node_modules/@groove-dev/gui/src/components/settings/quick-connect.jsx +9 -0
- package/node_modules/@groove-dev/gui/src/stores/groove.js +10 -0
- package/node_modules/@groove-dev/gui/src/views/federation.jsx +56 -15
- package/node_modules/moe-training/client/envelope-builder.js +5 -0
- package/node_modules/moe-training/client/scrubber.js +1 -1
- package/node_modules/moe-training/client/step-classifier.js +22 -6
- package/node_modules/moe-training/client/trajectory-capture.js +15 -4
- package/node_modules/moe-training/shared/constants.js +2 -0
- package/node_modules/moe-training/shared/envelope-schema.js +1 -1
- package/node_modules/moe-training/test/client/envelope-builder.test.js +32 -0
- package/node_modules/moe-training/test/client/scrubber.test.js +13 -0
- package/node_modules/moe-training/test/client/step-classifier.test.js +96 -7
- package/node_modules/moe-training/test/client/trajectory-capture.test.js +53 -6
- 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 +29 -2
- package/packages/daemon/src/process.js +5 -5
- package/packages/gui/dist/assets/{index-DkAGIluW.js → index-CEgtSfbG.js} +1748 -1745
- package/packages/gui/dist/assets/{index-QwgLRN8B.css → index-_3cJS_UG.css} +1 -1
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/components/layout/command-palette.jsx +2 -1
- package/packages/gui/src/components/layout/status-bar.jsx +9 -3
- package/packages/gui/src/components/settings/federation-panel.jsx +2 -2
- package/packages/gui/src/components/settings/federation-peers.jsx +14 -2
- package/packages/gui/src/components/settings/quick-connect.jsx +9 -0
- package/packages/gui/src/stores/groove.js +10 -0
- package/packages/gui/src/views/federation.jsx +56 -15
- package/ssh/main.js +2253 -0
|
@@ -4,7 +4,7 @@ import { useGrooveStore } from '../../stores/groove';
|
|
|
4
4
|
import {
|
|
5
5
|
Network, Code2, ChartSpline, Puzzle, Users, Plus,
|
|
6
6
|
RotateCw, Skull, MessageSquare, Terminal, Newspaper,
|
|
7
|
-
Search, Radio, ExternalLink, FolderOpen, Globe,
|
|
7
|
+
Search, Radio, ExternalLink, FolderOpen, Globe, Shield,
|
|
8
8
|
} from 'lucide-react';
|
|
9
9
|
import { cn } from '../../lib/cn';
|
|
10
10
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
@@ -16,6 +16,7 @@ const STATIC_COMMANDS = [
|
|
|
16
16
|
{ id: 'nav:marketplace', label: 'Go to Marketplace', icon: Puzzle, category: 'Navigation', action: (s) => { s.setActiveView('marketplace'); } },
|
|
17
17
|
{ id: 'nav:teams', label: 'Go to Teams', icon: Users, category: 'Navigation', action: (s) => { s.setActiveView('teams'); } },
|
|
18
18
|
{ id: 'nav:federation', label: 'Go to Federation', icon: Globe, category: 'Navigation', action: (s) => { s.setActiveView('federation'); } },
|
|
19
|
+
{ id: 'action:whitelist', label: 'Add to Federation Whitelist', icon: Shield, category: 'Federation', action: (s) => { s.setActiveView('federation'); } },
|
|
19
20
|
{ id: 'action:spawn', label: 'Spawn Agent', icon: Plus, category: 'Actions', action: (s) => { s.openDetail({ type: 'spawn' }); } },
|
|
20
21
|
{ id: 'action:terminal', label: 'Toggle Terminal', icon: Terminal, category: 'Actions', action: (s) => { s.setTerminalVisible(!s.terminalVisible); }, shortcut: 'Cmd+J' },
|
|
21
22
|
{ id: 'action:journalist', label: 'Toggle Journalist', icon: Newspaper, category: 'Actions', action: (s) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
-
import { Terminal, BookOpen, Radio, Plug, Globe, ArrowUpCircle, X, Unplug } from 'lucide-react';
|
|
2
|
+
import { Terminal, BookOpen, Radio, Plug, Globe, ArrowUpCircle, X, Unplug, Shield } from 'lucide-react';
|
|
3
3
|
import { cn } from '../../lib/cn';
|
|
4
4
|
import { StatusDot } from '../ui/status-dot';
|
|
5
5
|
import { Badge } from '../ui/badge';
|
|
@@ -22,7 +22,6 @@ export function StatusBar({
|
|
|
22
22
|
const updateReady = useGrooveStore((s) => s.updateReady);
|
|
23
23
|
const updateProgress = useGrooveStore((s) => s.updateProgress);
|
|
24
24
|
const setUpdateModalOpen = useGrooveStore((s) => s.setUpdateModalOpen);
|
|
25
|
-
const subscription = useGrooveStore((s) => s.subscription);
|
|
26
25
|
const navigate = useGrooveStore((s) => s.setActiveView);
|
|
27
26
|
const activeTunnel = savedTunnels.find((t) => t.active);
|
|
28
27
|
const electron = isElectron();
|
|
@@ -71,6 +70,13 @@ export function StatusBar({
|
|
|
71
70
|
<span className="text-text-4">{activeTunnel.latencyMs}ms</span>
|
|
72
71
|
)}
|
|
73
72
|
</button>
|
|
73
|
+
<button
|
|
74
|
+
onClick={() => useGrooveStore.getState().addToWhitelist(activeTunnel.host)}
|
|
75
|
+
className="p-0.5 text-text-4 hover:text-accent cursor-pointer transition-colors rounded"
|
|
76
|
+
title="Add to Federation Whitelist"
|
|
77
|
+
>
|
|
78
|
+
<Shield size={10} />
|
|
79
|
+
</button>
|
|
74
80
|
<button
|
|
75
81
|
onClick={() => useGrooveStore.getState().disconnectTunnel(activeTunnel.id)}
|
|
76
82
|
className="p-0.5 text-text-4 hover:text-danger cursor-pointer transition-colors rounded"
|
|
@@ -98,7 +104,7 @@ export function StatusBar({
|
|
|
98
104
|
<span>Connect</span>
|
|
99
105
|
</button>
|
|
100
106
|
)}
|
|
101
|
-
{
|
|
107
|
+
{connected && (
|
|
102
108
|
<button
|
|
103
109
|
onClick={() => navigate('federation')}
|
|
104
110
|
className="flex items-center gap-1.5 text-text-4 hover:text-text-1 cursor-pointer transition-colors"
|
|
@@ -22,7 +22,7 @@ function statusBadge(status) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function WhitelistTab() {
|
|
25
|
+
export function WhitelistTab() {
|
|
26
26
|
const whitelist = useGrooveStore((s) => s.federation.whitelist);
|
|
27
27
|
const addToWhitelist = useGrooveStore((s) => s.addToWhitelist);
|
|
28
28
|
const removeFromWhitelist = useGrooveStore((s) => s.removeFromWhitelist);
|
|
@@ -198,7 +198,7 @@ function WhitelistTab() {
|
|
|
198
198
|
);
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
function AmbassadorsTab() {
|
|
201
|
+
export function AmbassadorsTab() {
|
|
202
202
|
const ambassadors = useGrooveStore((s) => s.federation.ambassadors);
|
|
203
203
|
|
|
204
204
|
return (
|
|
@@ -22,6 +22,8 @@ export function FederationPeers({ onOpenWizard }) {
|
|
|
22
22
|
const connections = useGrooveStore((s) => s.federation.connections);
|
|
23
23
|
const peers = useGrooveStore((s) => s.federation.peers);
|
|
24
24
|
const sendPouch = useGrooveStore((s) => s.sendPouch);
|
|
25
|
+
const disconnectPeer = useGrooveStore((s) => s.disconnectPeer);
|
|
26
|
+
const addToast = useGrooveStore((s) => s.addToast);
|
|
25
27
|
const [sendingTo, setSendingTo] = useState(null);
|
|
26
28
|
|
|
27
29
|
const allPeers = peers.length > 0 ? peers : connections;
|
|
@@ -97,7 +99,12 @@ export function FederationPeers({ onOpenWizard }) {
|
|
|
97
99
|
</div>
|
|
98
100
|
|
|
99
101
|
<div className="flex items-center gap-1.5 mt-3 pt-2.5 border-t border-border-subtle">
|
|
100
|
-
<Button
|
|
102
|
+
<Button
|
|
103
|
+
size="sm"
|
|
104
|
+
variant="ghost"
|
|
105
|
+
className="h-6 text-2xs gap-1 text-text-2"
|
|
106
|
+
onClick={() => addToast('info', name, `ID: ${id}\nIP: ${ip}${peer.port ? `:${peer.port}` : ''}\nLatency: ${latency != null ? `${latency}ms` : 'N/A'}\nState: ${state}`)}
|
|
107
|
+
>
|
|
101
108
|
<Eye size={10} />
|
|
102
109
|
Details
|
|
103
110
|
</Button>
|
|
@@ -111,7 +118,12 @@ export function FederationPeers({ onOpenWizard }) {
|
|
|
111
118
|
<Send size={10} />
|
|
112
119
|
Send Pouch
|
|
113
120
|
</Button>
|
|
114
|
-
<Button
|
|
121
|
+
<Button
|
|
122
|
+
size="sm"
|
|
123
|
+
variant="ghost"
|
|
124
|
+
className="h-6 text-2xs gap-1 text-danger/70 hover:text-danger ml-auto"
|
|
125
|
+
onClick={() => disconnectPeer(id)}
|
|
126
|
+
>
|
|
115
127
|
<Unplug size={10} />
|
|
116
128
|
Disconnect
|
|
117
129
|
</Button>
|
|
@@ -25,6 +25,15 @@ export function QuickConnect() {
|
|
|
25
25
|
setConnectingId(id);
|
|
26
26
|
try {
|
|
27
27
|
await useGrooveStore.getState().connectTunnel(id);
|
|
28
|
+
const tunnel = savedTunnels.find((t) => t.id === id);
|
|
29
|
+
if (tunnel?.host) {
|
|
30
|
+
addToast('info', `Add ${tunnel.host} to Federation Whitelist?`, '', {
|
|
31
|
+
action: {
|
|
32
|
+
label: 'Add',
|
|
33
|
+
onClick: () => useGrooveStore.getState().addToWhitelist(tunnel.host),
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
28
37
|
toggle();
|
|
29
38
|
} catch (err) {
|
|
30
39
|
let detail = err?.message || 'Unknown error';
|
|
@@ -2660,6 +2660,16 @@ export const useGrooveStore = create((set, get) => ({
|
|
|
2660
2660
|
}
|
|
2661
2661
|
},
|
|
2662
2662
|
|
|
2663
|
+
async disconnectPeer(peerId) {
|
|
2664
|
+
try {
|
|
2665
|
+
await api.delete(`/federation/peers/${encodeURIComponent(peerId)}`);
|
|
2666
|
+
get().addToast('info', 'Peer disconnected');
|
|
2667
|
+
get().fetchFederationStatus();
|
|
2668
|
+
} catch (err) {
|
|
2669
|
+
get().addToast('error', 'Disconnect failed', err.message);
|
|
2670
|
+
}
|
|
2671
|
+
},
|
|
2672
|
+
|
|
2663
2673
|
// ── Training Data ─────────────────────────────────────────
|
|
2664
2674
|
|
|
2665
2675
|
async setTrainingOptIn(enabled) {
|
|
@@ -1,37 +1,78 @@
|
|
|
1
1
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
2
|
-
import { useEffect } from 'react';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
3
|
import { useGrooveStore } from '../stores/groove';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { FederationPeers } from '../components/settings/federation-peers';
|
|
5
|
+
import { FederationActivity } from '../components/settings/federation-activity';
|
|
6
|
+
import { FederationWizard } from '../components/settings/federation-wizard';
|
|
7
|
+
import { WhitelistTab, AmbassadorsTab } from '../components/settings/federation-panel';
|
|
8
|
+
import { Button } from '../components/ui/button';
|
|
6
9
|
import { ScrollArea } from '../components/ui/scroll-area';
|
|
7
|
-
import { Globe } from 'lucide-react';
|
|
10
|
+
import { Globe, Plus } from 'lucide-react';
|
|
8
11
|
|
|
9
12
|
export default function FederationView() {
|
|
10
13
|
const fetchFederationStatus = useGrooveStore((s) => s.fetchFederationStatus);
|
|
14
|
+
const fetchPouchLog = useGrooveStore((s) => s.fetchPouchLog);
|
|
15
|
+
const peers = useGrooveStore((s) => s.federation.peers);
|
|
16
|
+
const connections = useGrooveStore((s) => s.federation.connections);
|
|
17
|
+
const whitelist = useGrooveStore((s) => s.federation.whitelist);
|
|
18
|
+
const [wizardOpen, setWizardOpen] = useState(false);
|
|
19
|
+
|
|
20
|
+
const peerCount = (peers.length > 0 ? peers : connections).length;
|
|
11
21
|
|
|
12
22
|
useEffect(() => {
|
|
13
23
|
fetchFederationStatus();
|
|
24
|
+
fetchPouchLog();
|
|
14
25
|
}, []);
|
|
15
26
|
|
|
16
27
|
return (
|
|
17
28
|
<div className="flex flex-col h-full bg-surface-0">
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
29
|
+
{/* Hero strip */}
|
|
30
|
+
<div className="flex items-center justify-between px-6 py-4 border-b border-border">
|
|
31
|
+
<div className="flex items-center gap-3">
|
|
32
|
+
<div className="w-8 h-8 rounded-md bg-accent/10 flex items-center justify-center">
|
|
33
|
+
<Globe size={16} className="text-accent" />
|
|
34
|
+
</div>
|
|
35
|
+
<div>
|
|
36
|
+
<h1 className="text-sm font-semibold text-text-0 font-sans">Federation</h1>
|
|
37
|
+
<p className="text-2xs text-text-3 font-sans">
|
|
38
|
+
{peerCount} peer{peerCount !== 1 ? 's' : ''} · {whitelist.length} whitelisted
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
25
41
|
</div>
|
|
42
|
+
<Button size="sm" variant="primary" onClick={() => setWizardOpen(true)} className="h-8 text-xs gap-1.5">
|
|
43
|
+
<Plus size={12} />
|
|
44
|
+
Add Peer
|
|
45
|
+
</Button>
|
|
26
46
|
</div>
|
|
27
47
|
|
|
48
|
+
{/* Content */}
|
|
28
49
|
<ScrollArea className="flex-1">
|
|
29
|
-
<div className="
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
50
|
+
<div className="p-6">
|
|
51
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
|
52
|
+
{/* Left: Peers + Activity (stacked) */}
|
|
53
|
+
<div className="lg:col-span-2 space-y-4">
|
|
54
|
+
<div className="rounded-lg border border-border-subtle bg-surface-1 p-4">
|
|
55
|
+
<FederationPeers onOpenWizard={() => setWizardOpen(true)} />
|
|
56
|
+
</div>
|
|
57
|
+
<div className="rounded-lg border border-border-subtle bg-surface-1 p-4">
|
|
58
|
+
<FederationActivity />
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
{/* Right: Whitelist + Ambassadors (stacked) */}
|
|
63
|
+
<div className="space-y-4">
|
|
64
|
+
<div className="rounded-lg border border-border-subtle bg-surface-1 p-4">
|
|
65
|
+
<WhitelistTab />
|
|
66
|
+
</div>
|
|
67
|
+
<div className="rounded-lg border border-border-subtle bg-surface-1 p-4">
|
|
68
|
+
<AmbassadorsTab />
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
33
72
|
</div>
|
|
34
73
|
</ScrollArea>
|
|
74
|
+
|
|
75
|
+
<FederationWizard open={wizardOpen} onOpenChange={setWizardOpen} />
|
|
35
76
|
</div>
|
|
36
77
|
);
|
|
37
78
|
}
|