groove-dev 0.27.119 → 0.27.121
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/moe-training/client/trajectory-capture.js +55 -0
- package/moe-training/test/client/trajectory-capture.test.js +63 -0
- package/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/cli/src/commands/start.js +2 -1
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/api.js +30 -10
- package/node_modules/@groove-dev/daemon/src/conversations.js +54 -32
- package/node_modules/@groove-dev/daemon/src/introducer.js +45 -20
- package/node_modules/@groove-dev/daemon/src/process.js +47 -1
- package/node_modules/@groove-dev/daemon/src/teams.js +33 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-DT6Jbf_q.css → index-BLd3MON8.css} +1 -1
- package/node_modules/@groove-dev/gui/dist/assets/{index-BxPCaxlC.js → index-bmkBX18f.js} +1721 -1721
- 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/agents/agent-config.jsx +3 -41
- package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +4 -43
- package/node_modules/@groove-dev/gui/src/components/layout/status-bar.jsx +8 -10
- package/node_modules/@groove-dev/gui/src/components/onboarding/setup-wizard.jsx +8 -23
- package/node_modules/@groove-dev/gui/src/components/settings/ProviderSetupWizard.jsx +54 -143
- package/node_modules/@groove-dev/gui/src/components/ui/data-sharing-modal.jsx +7 -57
- package/node_modules/@groove-dev/gui/src/stores/groove.js +13 -0
- package/node_modules/@groove-dev/gui/src/views/settings.jsx +50 -84
- package/node_modules/@groove-dev/gui/src/views/teams.jsx +61 -1
- package/node_modules/moe-training/client/trajectory-capture.js +55 -0
- package/node_modules/moe-training/test/client/trajectory-capture.test.js +63 -0
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/commands/start.js +2 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/api.js +30 -10
- package/packages/daemon/src/conversations.js +54 -32
- package/packages/daemon/src/introducer.js +45 -20
- package/packages/daemon/src/process.js +47 -1
- package/packages/daemon/src/teams.js +33 -0
- package/packages/gui/dist/assets/{index-DT6Jbf_q.css → index-BLd3MON8.css} +1 -1
- package/packages/gui/dist/assets/{index-BxPCaxlC.js → index-bmkBX18f.js} +1721 -1721
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/components/agents/agent-config.jsx +3 -41
- package/packages/gui/src/components/agents/spawn-wizard.jsx +4 -43
- package/packages/gui/src/components/layout/status-bar.jsx +8 -10
- package/packages/gui/src/components/onboarding/setup-wizard.jsx +8 -23
- package/packages/gui/src/components/settings/ProviderSetupWizard.jsx +54 -143
- package/packages/gui/src/components/ui/data-sharing-modal.jsx +7 -57
- package/packages/gui/src/stores/groove.js +13 -0
- package/packages/gui/src/views/settings.jsx +50 -84
- package/packages/gui/src/views/teams.jsx +61 -1
|
@@ -62,10 +62,8 @@ function ProviderCard({ provider, onKeyChange }) {
|
|
|
62
62
|
const [customPathOpen, setCustomPathOpen] = useState(false);
|
|
63
63
|
const [customPath, setCustomPath] = useState('');
|
|
64
64
|
const [savingPath, setSavingPath] = useState(false);
|
|
65
|
-
const [loginPending, setLoginPending] = useState(false);
|
|
66
65
|
const addToast = useGrooveStore((s) => s.addToast);
|
|
67
66
|
const installProgress = useGrooveStore((s) => s.providerInstallProgress[provider.id]);
|
|
68
|
-
const loginProvider = useGrooveStore((s) => s.loginProvider);
|
|
69
67
|
const setProviderPath = useGrooveStore((s) => s.setProviderPath);
|
|
70
68
|
const verifyProvider = useGrooveStore((s) => s.verifyProvider);
|
|
71
69
|
const installProvider = useGrooveStore((s) => s.installProvider);
|
|
@@ -100,15 +98,6 @@ function ProviderCard({ provider, onKeyChange }) {
|
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
async function handleLogin(body) {
|
|
104
|
-
try {
|
|
105
|
-
setLoginPending(true);
|
|
106
|
-
await loginProvider(provider.id, body);
|
|
107
|
-
} catch {
|
|
108
|
-
setLoginPending(false);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
101
|
async function handleSavePath() {
|
|
113
102
|
if (!customPath.trim()) return;
|
|
114
103
|
setSavingPath(true);
|
|
@@ -321,15 +310,30 @@ function ProviderCard({ provider, onKeyChange }) {
|
|
|
321
310
|
{effectivelyInstalled && !isReady && !settingKey && !isInstalling && (
|
|
322
311
|
<div className="flex flex-col gap-3 flex-1">
|
|
323
312
|
{/* ── Claude Code auth ── */}
|
|
324
|
-
{provider.id === 'claude-code' &&
|
|
313
|
+
{provider.id === 'claude-code' && (
|
|
325
314
|
<>
|
|
326
|
-
<div className="space-y-
|
|
327
|
-
<p className="text-xs text-text-1 font-sans font-medium">Sign in
|
|
328
|
-
<
|
|
315
|
+
<div className="space-y-2">
|
|
316
|
+
<p className="text-xs text-text-1 font-sans font-medium">Sign in via terminal</p>
|
|
317
|
+
<div className="space-y-1.5">
|
|
318
|
+
<div className="flex items-start gap-2">
|
|
319
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">1</span>
|
|
320
|
+
<p className="text-2xs text-text-2 font-sans flex items-center gap-1">
|
|
321
|
+
<Terminal size={10} className="text-text-3 flex-shrink-0" />
|
|
322
|
+
Open the Groove terminal below
|
|
323
|
+
</p>
|
|
324
|
+
</div>
|
|
325
|
+
<div className="flex items-start gap-2">
|
|
326
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">2</span>
|
|
327
|
+
<p className="text-2xs text-text-2 font-sans">
|
|
328
|
+
Run: <code className="font-mono text-accent bg-surface-4 px-1.5 py-0.5 rounded text-2xs">claude</code>
|
|
329
|
+
</p>
|
|
330
|
+
</div>
|
|
331
|
+
<div className="flex items-start gap-2">
|
|
332
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">3</span>
|
|
333
|
+
<p className="text-2xs text-text-2 font-sans">Follow the prompts to sign in with your Anthropic account</p>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
329
336
|
</div>
|
|
330
|
-
<Button variant="primary" size="sm" onClick={() => handleLogin()} className="w-full h-9 text-xs gap-1.5">
|
|
331
|
-
<ExternalLink size={12} /> Sign In
|
|
332
|
-
</Button>
|
|
333
337
|
<button
|
|
334
338
|
onClick={() => { setSettingKey(true); setShowKey(false); setKeyInput(''); }}
|
|
335
339
|
className="text-2xs text-text-4 hover:text-accent cursor-pointer font-sans text-center"
|
|
@@ -340,15 +344,36 @@ function ProviderCard({ provider, onKeyChange }) {
|
|
|
340
344
|
)}
|
|
341
345
|
|
|
342
346
|
{/* ── Codex auth ── */}
|
|
343
|
-
{provider.id === 'codex' &&
|
|
347
|
+
{provider.id === 'codex' && (
|
|
344
348
|
<>
|
|
345
|
-
<div className="space-y-
|
|
346
|
-
<p className="text-xs text-text-1 font-sans font-medium">Sign in
|
|
347
|
-
<
|
|
349
|
+
<div className="space-y-2">
|
|
350
|
+
<p className="text-xs text-text-1 font-sans font-medium">Sign in via terminal</p>
|
|
351
|
+
<div className="space-y-1.5">
|
|
352
|
+
<div className="flex items-start gap-2">
|
|
353
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">1</span>
|
|
354
|
+
<p className="text-2xs text-text-2 font-sans flex items-center gap-1">
|
|
355
|
+
<Terminal size={10} className="text-text-3 flex-shrink-0" />
|
|
356
|
+
Open the Groove terminal below
|
|
357
|
+
</p>
|
|
358
|
+
</div>
|
|
359
|
+
<div className="flex items-start gap-2">
|
|
360
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">2</span>
|
|
361
|
+
<p className="text-2xs text-text-2 font-sans">
|
|
362
|
+
Run: <code className="font-mono text-accent bg-surface-4 px-1.5 py-0.5 rounded text-2xs">npm i -g @openai/codex</code> (if not installed)
|
|
363
|
+
</p>
|
|
364
|
+
</div>
|
|
365
|
+
<div className="flex items-start gap-2">
|
|
366
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">3</span>
|
|
367
|
+
<p className="text-2xs text-text-2 font-sans">
|
|
368
|
+
Run: <code className="font-mono text-accent bg-surface-4 px-1.5 py-0.5 rounded text-2xs">codex login</code>
|
|
369
|
+
</p>
|
|
370
|
+
</div>
|
|
371
|
+
<div className="flex items-start gap-2">
|
|
372
|
+
<span className="text-2xs font-bold text-accent font-mono mt-0.5">4</span>
|
|
373
|
+
<p className="text-2xs text-text-2 font-sans">Follow the prompts to authenticate</p>
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
348
376
|
</div>
|
|
349
|
-
<Button variant="primary" size="sm" onClick={() => handleLogin({ method: 'chatgpt-plus' })} className="w-full h-9 text-xs gap-1.5">
|
|
350
|
-
<ExternalLink size={12} /> Sign In
|
|
351
|
-
</Button>
|
|
352
377
|
<button
|
|
353
378
|
onClick={() => { setSettingKey(true); setShowKey(false); setKeyInput(''); }}
|
|
354
379
|
className="text-2xs text-text-4 hover:text-accent cursor-pointer font-sans text-center"
|
|
@@ -442,65 +467,6 @@ function ProviderCard({ provider, onKeyChange }) {
|
|
|
442
467
|
</>
|
|
443
468
|
)}
|
|
444
469
|
|
|
445
|
-
{/* ── Any provider: login pending state ── */}
|
|
446
|
-
{(provider.id === 'claude-code' || provider.id === 'codex') && loginPending && (
|
|
447
|
-
<div className="flex flex-col gap-3">
|
|
448
|
-
<div className="flex items-center gap-2 p-3 bg-accent/5 border border-accent/15 rounded-md">
|
|
449
|
-
<Loader2 size={14} className="text-accent animate-spin" />
|
|
450
|
-
<div>
|
|
451
|
-
<p className="text-xs text-accent font-sans font-medium">Check your browser</p>
|
|
452
|
-
<p className="text-2xs text-text-3 font-sans">Complete the sign-in in the browser window that opened.</p>
|
|
453
|
-
</div>
|
|
454
|
-
</div>
|
|
455
|
-
<Button
|
|
456
|
-
variant="primary"
|
|
457
|
-
size="sm"
|
|
458
|
-
disabled={checking}
|
|
459
|
-
onClick={async () => {
|
|
460
|
-
if (provider.id === 'codex') {
|
|
461
|
-
setChecking(true);
|
|
462
|
-
try {
|
|
463
|
-
const res = await api.post(`/providers/codex/verify`);
|
|
464
|
-
if (res.authenticated) {
|
|
465
|
-
setLoginPending(false);
|
|
466
|
-
if (onKeyChange) onKeyChange();
|
|
467
|
-
} else {
|
|
468
|
-
addToast('error', 'Authentication not detected yet. Please complete sign-in in your browser and try again.');
|
|
469
|
-
}
|
|
470
|
-
} catch {
|
|
471
|
-
addToast('error', 'Authentication not detected yet. Please complete sign-in in your browser and try again.');
|
|
472
|
-
} finally {
|
|
473
|
-
setChecking(false);
|
|
474
|
-
}
|
|
475
|
-
} else {
|
|
476
|
-
setChecking(true);
|
|
477
|
-
try {
|
|
478
|
-
const res = await api.post(`/providers/claude-code/verify`);
|
|
479
|
-
if (res.authenticated) {
|
|
480
|
-
setLoginPending(false);
|
|
481
|
-
if (onKeyChange) onKeyChange();
|
|
482
|
-
} else {
|
|
483
|
-
addToast('error', 'Authentication not detected yet. Please complete sign-in in your browser and try again.');
|
|
484
|
-
}
|
|
485
|
-
} catch {
|
|
486
|
-
addToast('error', 'Authentication not detected yet. Please complete sign-in in your browser and try again.');
|
|
487
|
-
} finally {
|
|
488
|
-
setChecking(false);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}}
|
|
492
|
-
className="w-full h-8 text-xs gap-1.5"
|
|
493
|
-
>
|
|
494
|
-
{checking ? <Loader2 size={12} className="animate-spin" /> : <Check size={12} />} I've signed in
|
|
495
|
-
</Button>
|
|
496
|
-
<button
|
|
497
|
-
onClick={() => setLoginPending(false)}
|
|
498
|
-
className="text-2xs text-text-4 hover:text-text-2 cursor-pointer font-sans text-center"
|
|
499
|
-
>
|
|
500
|
-
Cancel
|
|
501
|
-
</button>
|
|
502
|
-
</div>
|
|
503
|
-
)}
|
|
504
470
|
</div>
|
|
505
471
|
)}
|
|
506
472
|
|
|
@@ -9,10 +9,11 @@ import { api } from '../lib/api';
|
|
|
9
9
|
import { useToast } from '../lib/hooks/use-toast';
|
|
10
10
|
import { fmtNum, fmtDollar, timeAgo, fmtUptime } from '../lib/format';
|
|
11
11
|
import { cn } from '../lib/cn';
|
|
12
|
+
import { Dialog, DialogContent } from '../components/ui/dialog';
|
|
12
13
|
import {
|
|
13
14
|
Clock, CheckCircle, XCircle, AlertTriangle, ShieldCheck, ShieldX,
|
|
14
15
|
Users, Folder, Cpu, Trash2, Play, Pause, LayoutDashboard, ListChecks, Calendar,
|
|
15
|
-
Archive, RotateCcw, ChevronRight,
|
|
16
|
+
Archive, RotateCcw, ChevronRight, ArrowUpCircle,
|
|
16
17
|
} from 'lucide-react';
|
|
17
18
|
import { TeamRemovalDialog, PurgeConfirmDialog } from '../components/teams/team-removal-dialog';
|
|
18
19
|
|
|
@@ -28,9 +29,11 @@ function TeamsDashboard() {
|
|
|
28
29
|
const fetchArchivedTeams = useGrooveStore((s) => s.fetchArchivedTeams);
|
|
29
30
|
const restoreTeam = useGrooveStore((s) => s.restoreTeam);
|
|
30
31
|
const purgeTeam = useGrooveStore((s) => s.purgeTeam);
|
|
32
|
+
const promoteTeam = useGrooveStore((s) => s.promoteTeam);
|
|
31
33
|
|
|
32
34
|
const [archiveConfirm, setArchiveConfirm] = useState(null);
|
|
33
35
|
const [purgeConfirm, setPurgeConfirm] = useState(null);
|
|
36
|
+
const [promoteConfirm, setPromoteConfirm] = useState(null);
|
|
34
37
|
const [archivedOpen, setArchivedOpen] = useState(false);
|
|
35
38
|
|
|
36
39
|
useEffect(() => { fetchArchivedTeams(); }, []);
|
|
@@ -84,6 +87,15 @@ function TeamsDashboard() {
|
|
|
84
87
|
</div>
|
|
85
88
|
)}
|
|
86
89
|
</div>
|
|
90
|
+
{team.mode !== 'production' && (
|
|
91
|
+
<button
|
|
92
|
+
onClick={() => setPromoteConfirm(team)}
|
|
93
|
+
className="p-1.5 text-text-4 hover:text-success rounded transition-colors cursor-pointer"
|
|
94
|
+
title="Promote to production"
|
|
95
|
+
>
|
|
96
|
+
<ArrowUpCircle size={13} />
|
|
97
|
+
</button>
|
|
98
|
+
)}
|
|
87
99
|
<button
|
|
88
100
|
onClick={() => {
|
|
89
101
|
if (teamAgents.some((a) => a.status === 'running' || a.status === 'starting')) {
|
|
@@ -195,10 +207,58 @@ function TeamsDashboard() {
|
|
|
195
207
|
onOpenChange={(open) => !open && setPurgeConfirm(null)}
|
|
196
208
|
onPurge={purgeTeam}
|
|
197
209
|
/>
|
|
210
|
+
|
|
211
|
+
<PromoteConfirmDialog
|
|
212
|
+
team={promoteConfirm}
|
|
213
|
+
open={!!promoteConfirm}
|
|
214
|
+
onOpenChange={(open) => !open && setPromoteConfirm(null)}
|
|
215
|
+
onPromote={promoteTeam}
|
|
216
|
+
/>
|
|
198
217
|
</div>
|
|
199
218
|
);
|
|
200
219
|
}
|
|
201
220
|
|
|
221
|
+
function PromoteConfirmDialog({ team, open, onOpenChange, onPromote }) {
|
|
222
|
+
const [promoting, setPromoting] = useState(false);
|
|
223
|
+
|
|
224
|
+
useEffect(() => {
|
|
225
|
+
if (!open) setPromoting(false);
|
|
226
|
+
}, [open]);
|
|
227
|
+
|
|
228
|
+
async function handleConfirm() {
|
|
229
|
+
setPromoting(true);
|
|
230
|
+
try {
|
|
231
|
+
await onPromote(team?.id);
|
|
232
|
+
onOpenChange(false);
|
|
233
|
+
} catch {
|
|
234
|
+
setPromoting(false);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
240
|
+
<DialogContent title="Promote to Production" description="Promote this team to production mode">
|
|
241
|
+
<div className="px-5 py-4 space-y-3">
|
|
242
|
+
<p className="text-sm text-text-1 font-sans">
|
|
243
|
+
Promote <span className="font-semibold text-text-0">{team?.name}</span> to production?
|
|
244
|
+
</p>
|
|
245
|
+
<p className="text-xs text-text-3 font-sans">
|
|
246
|
+
This will move files from the team directory into the project directory.
|
|
247
|
+
The team will switch to production mode and files will persist when the team is removed.
|
|
248
|
+
</p>
|
|
249
|
+
</div>
|
|
250
|
+
<div className="px-5 py-3 border-t border-border-subtle flex justify-end gap-2">
|
|
251
|
+
<Button variant="ghost" size="sm" onClick={() => onOpenChange(false)}>Cancel</Button>
|
|
252
|
+
<Button variant="primary" size="sm" disabled={promoting} onClick={handleConfirm} className="gap-1.5">
|
|
253
|
+
<ArrowUpCircle size={12} />
|
|
254
|
+
{promoting ? 'Promoting...' : 'Promote'}
|
|
255
|
+
</Button>
|
|
256
|
+
</div>
|
|
257
|
+
</DialogContent>
|
|
258
|
+
</Dialog>
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
202
262
|
function Stat({ label, value, color }) {
|
|
203
263
|
return (
|
|
204
264
|
<div className="text-center">
|