groove-dev 0.26.13 → 0.26.15
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/GROOVE_AI_PITCH_DECK_OUTLINE.docx +0 -0
- package/node_modules/@groove-dev/daemon/src/api.js +9 -0
- package/node_modules/@groove-dev/daemon/src/process.js +3 -1
- package/node_modules/@groove-dev/daemon/src/skills.js +46 -1
- package/node_modules/@groove-dev/daemon/src/terminal-pty.js +2 -2
- package/node_modules/@groove-dev/gui/dist/assets/index-CBlL5EFb.js +638 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-C4cVCdfw.css → index-E07lphaH.css} +1 -1
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/src/views/editor.jsx +58 -2
- package/node_modules/@groove-dev/gui/src/views/marketplace.jsx +92 -7
- package/package.json +1 -1
- package/packages/daemon/src/api.js +9 -0
- package/packages/daemon/src/process.js +3 -1
- package/packages/daemon/src/skills.js +46 -1
- package/packages/daemon/src/terminal-pty.js +2 -2
- package/packages/gui/dist/assets/index-CBlL5EFb.js +638 -0
- package/packages/gui/dist/assets/{index-C4cVCdfw.css → index-E07lphaH.css} +1 -1
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/src/views/editor.jsx +58 -2
- package/packages/gui/src/views/marketplace.jsx +92 -7
- package/pitch_deck/index.html +718 -0
- package/pitch_deck/slides.json +197 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-BluxaN32.js +0 -633
- package/packages/gui/dist/assets/index-BluxaN32.js +0 -633
|
@@ -19,7 +19,7 @@ import { fmtNum, timeAgo } from '../lib/format';
|
|
|
19
19
|
import { useGrooveStore } from '../stores/groove';
|
|
20
20
|
import {
|
|
21
21
|
ChevronLeft, ChevronDown, Sparkles, Plug, LogIn, LogOut,
|
|
22
|
-
User, Upload, Package, Download, ShoppingBag,
|
|
22
|
+
User, Upload, Package, Download, ShoppingBag, RefreshCw, Trash2,
|
|
23
23
|
} from 'lucide-react';
|
|
24
24
|
|
|
25
25
|
// ── Skill Detail ─────────────────────────────────────────
|
|
@@ -28,6 +28,8 @@ function SkillDetail({ skill, onBack }) {
|
|
|
28
28
|
const [content, setContent] = useState('');
|
|
29
29
|
const [requiresPurchase, setRequiresPurchase] = useState(false);
|
|
30
30
|
const [installing, setInstalling] = useState(false);
|
|
31
|
+
const [updating, setUpdating] = useState(false);
|
|
32
|
+
const [uninstalling, setUninstalling] = useState(false);
|
|
31
33
|
const [installed, setInstalled] = useState(skill.installed);
|
|
32
34
|
const [loadingContent, setLoadingContent] = useState(true);
|
|
33
35
|
|
|
@@ -52,6 +54,28 @@ function SkillDetail({ skill, onBack }) {
|
|
|
52
54
|
setInstalling(false);
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
async function handleUpdate() {
|
|
58
|
+
setUpdating(true);
|
|
59
|
+
try {
|
|
60
|
+
await api.post(`/skills/${skill.id}/update`);
|
|
61
|
+
toast.success(`${skill.name} updated to latest`);
|
|
62
|
+
// Refresh content preview
|
|
63
|
+
const d = await api.get(`/skills/${skill.id}/content`);
|
|
64
|
+
if (d.content) setContent(d.content);
|
|
65
|
+
} catch (err) { toast.error('Update failed', err.message); }
|
|
66
|
+
setUpdating(false);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function handleUninstall() {
|
|
70
|
+
setUninstalling(true);
|
|
71
|
+
try {
|
|
72
|
+
await api.delete(`/skills/${skill.id}`);
|
|
73
|
+
setInstalled(false);
|
|
74
|
+
toast.success(`${skill.name} uninstalled`);
|
|
75
|
+
} catch (err) { toast.error('Uninstall failed', err.message); }
|
|
76
|
+
setUninstalling(false);
|
|
77
|
+
}
|
|
78
|
+
|
|
55
79
|
async function handleBuy() {
|
|
56
80
|
const { marketplaceAuthenticated, marketplaceLogin, marketplaceCheckout } = useGrooveStore.getState();
|
|
57
81
|
if (!marketplaceAuthenticated) {
|
|
@@ -133,13 +157,32 @@ function SkillDetail({ skill, onBack }) {
|
|
|
133
157
|
>
|
|
134
158
|
Buy ${(skill.price || 0).toFixed(2)}
|
|
135
159
|
</button>
|
|
160
|
+
) : installed ? (
|
|
161
|
+
<div className="mt-3 flex flex-col gap-1.5">
|
|
162
|
+
<button
|
|
163
|
+
onClick={handleUpdate}
|
|
164
|
+
disabled={updating}
|
|
165
|
+
className="w-full py-2 px-3 text-xs font-sans font-semibold rounded cursor-pointer transition-all hover:opacity-85 disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-2 border bg-accent/15 text-accent border-accent/20 hover:bg-accent/25"
|
|
166
|
+
>
|
|
167
|
+
<RefreshCw size={12} className={updating ? 'animate-spin' : ''} />
|
|
168
|
+
{updating ? 'Updating...' : 'Pull Latest'}
|
|
169
|
+
</button>
|
|
170
|
+
<button
|
|
171
|
+
onClick={handleUninstall}
|
|
172
|
+
disabled={uninstalling}
|
|
173
|
+
className="w-full py-2 px-3 text-xs font-sans font-semibold rounded cursor-pointer transition-all hover:opacity-85 disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-2 border bg-error/10 text-error border-error/20 hover:bg-error/15"
|
|
174
|
+
>
|
|
175
|
+
<Trash2 size={12} />
|
|
176
|
+
{uninstalling ? 'Removing...' : 'Uninstall'}
|
|
177
|
+
</button>
|
|
178
|
+
</div>
|
|
136
179
|
) : (
|
|
137
180
|
<button
|
|
138
181
|
onClick={handleInstall}
|
|
139
|
-
disabled={installing
|
|
140
|
-
className=
|
|
182
|
+
disabled={installing}
|
|
183
|
+
className="w-full mt-3 py-2 px-3 text-xs font-sans font-semibold rounded cursor-pointer transition-all hover:opacity-85 disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-2 border bg-accent/15 text-accent border-accent/20 hover:bg-accent/25"
|
|
141
184
|
>
|
|
142
|
-
{installing ? 'Installing...' :
|
|
185
|
+
{installing ? 'Installing...' : 'Install'}
|
|
143
186
|
</button>
|
|
144
187
|
)}
|
|
145
188
|
|
|
@@ -278,9 +321,15 @@ function MyLibrary() {
|
|
|
278
321
|
const [purchases, setPurchases] = useState([]);
|
|
279
322
|
const [installed, setInstalled] = useState([]);
|
|
280
323
|
const [loading, setLoading] = useState(true);
|
|
324
|
+
const [busyId, setBusyId] = useState(null);
|
|
281
325
|
const toast = useToast();
|
|
282
326
|
const fileRef = useRef(null);
|
|
283
327
|
|
|
328
|
+
const refreshInstalled = async () => {
|
|
329
|
+
const data = await api.get('/skills/installed');
|
|
330
|
+
setInstalled(Array.isArray(data) ? data : data.skills || []);
|
|
331
|
+
};
|
|
332
|
+
|
|
284
333
|
useEffect(() => {
|
|
285
334
|
setLoading(true);
|
|
286
335
|
Promise.all([
|
|
@@ -292,6 +341,26 @@ function MyLibrary() {
|
|
|
292
341
|
}).finally(() => setLoading(false));
|
|
293
342
|
}, [authenticated]);
|
|
294
343
|
|
|
344
|
+
async function handleUpdate(s) {
|
|
345
|
+
setBusyId(s.id);
|
|
346
|
+
try {
|
|
347
|
+
await api.post(`/skills/${s.id}/update`);
|
|
348
|
+
toast.success(`${s.name || s.id} updated`);
|
|
349
|
+
await refreshInstalled();
|
|
350
|
+
} catch (err) { toast.error('Update failed', err.message); }
|
|
351
|
+
setBusyId(null);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function handleUninstall(s) {
|
|
355
|
+
setBusyId(s.id);
|
|
356
|
+
try {
|
|
357
|
+
await api.delete(`/skills/${s.id}`);
|
|
358
|
+
toast.success(`${s.name || s.id} uninstalled`);
|
|
359
|
+
await refreshInstalled();
|
|
360
|
+
} catch (err) { toast.error('Uninstall failed', err.message); }
|
|
361
|
+
setBusyId(null);
|
|
362
|
+
}
|
|
363
|
+
|
|
295
364
|
async function handleImport(e) {
|
|
296
365
|
const file = e.target.files?.[0];
|
|
297
366
|
if (!file) return;
|
|
@@ -300,9 +369,7 @@ function MyLibrary() {
|
|
|
300
369
|
const name = file.name.replace(/\.md$/i, '');
|
|
301
370
|
await api.post('/skills/import', { name, content });
|
|
302
371
|
toast.success(`Imported "${name}"`);
|
|
303
|
-
|
|
304
|
-
const data = await api.get('/skills/installed');
|
|
305
|
-
setInstalled(Array.isArray(data) ? data : data.skills || []);
|
|
372
|
+
await refreshInstalled();
|
|
306
373
|
} catch (err) {
|
|
307
374
|
toast.error('Import failed', err.message);
|
|
308
375
|
}
|
|
@@ -398,6 +465,24 @@ function MyLibrary() {
|
|
|
398
465
|
<div className="text-xs font-semibold text-text-0 font-sans truncate">{s.name || s.id}</div>
|
|
399
466
|
<div className="text-2xs text-text-3 font-sans truncate">{s.description || s.category || 'local skill'}</div>
|
|
400
467
|
</div>
|
|
468
|
+
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
469
|
+
<button
|
|
470
|
+
onClick={() => handleUpdate(s)}
|
|
471
|
+
disabled={busyId === s.id}
|
|
472
|
+
title="Pull latest version"
|
|
473
|
+
className="p-1.5 rounded text-text-3 hover:text-accent hover:bg-accent/10 cursor-pointer transition-colors disabled:opacity-50"
|
|
474
|
+
>
|
|
475
|
+
<RefreshCw size={12} className={busyId === s.id ? 'animate-spin' : ''} />
|
|
476
|
+
</button>
|
|
477
|
+
<button
|
|
478
|
+
onClick={() => handleUninstall(s)}
|
|
479
|
+
disabled={busyId === s.id}
|
|
480
|
+
title="Uninstall"
|
|
481
|
+
className="p-1.5 rounded text-text-3 hover:text-error hover:bg-error/10 cursor-pointer transition-colors disabled:opacity-50"
|
|
482
|
+
>
|
|
483
|
+
<Trash2 size={12} />
|
|
484
|
+
</button>
|
|
485
|
+
</div>
|
|
401
486
|
<Badge variant="accent" className="text-2xs flex-shrink-0">Installed</Badge>
|
|
402
487
|
</div>
|
|
403
488
|
))}
|