groove-dev 0.25.16 → 0.25.18
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/daemon/src/api.js +31 -0
- package/node_modules/@groove-dev/daemon/src/router.js +10 -3
- package/node_modules/@groove-dev/gui/dist/assets/{index-BjUplOVu.js → index-Ca4wKXQ9.js} +19 -19
- package/node_modules/@groove-dev/gui/dist/index.html +1 -1
- package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +26 -3
- package/package.json +1 -1
- package/packages/daemon/src/api.js +31 -0
- package/packages/daemon/src/router.js +10 -3
- package/packages/gui/dist/assets/{index-BjUplOVu.js → index-Ca4wKXQ9.js} +19 -19
- package/packages/gui/dist/index.html +1 -1
- package/packages/gui/src/components/agents/agent-feed.jsx +26 -3
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
7
7
|
<title>Groove GUI</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Ca4wKXQ9.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/vendor-C0HXlhrU.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/reactflow-BQPfi37R.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/codemirror-BBL3i_JW.js">
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { useGrooveStore } from '../../stores/groove';
|
|
10
10
|
import { cn } from '../../lib/cn';
|
|
11
11
|
import { timeAgo } from '../../lib/format';
|
|
12
|
+
import { api } from '../../lib/api';
|
|
12
13
|
|
|
13
14
|
const EMPTY = [];
|
|
14
15
|
|
|
@@ -532,11 +533,33 @@ export function AgentFeed({ agent }) {
|
|
|
532
533
|
}
|
|
533
534
|
}, [timeline.length]);
|
|
534
535
|
|
|
535
|
-
function handleFileSelect(e) {
|
|
536
|
+
async function handleFileSelect(e) {
|
|
536
537
|
const files = Array.from(e.target.files || []);
|
|
537
538
|
if (files.length === 0) return;
|
|
538
|
-
const
|
|
539
|
-
|
|
539
|
+
const addToast = useGrooveStore.getState().addToast;
|
|
540
|
+
|
|
541
|
+
const uploaded = [];
|
|
542
|
+
for (const file of files) {
|
|
543
|
+
try {
|
|
544
|
+
const base64 = await new Promise((resolve, reject) => {
|
|
545
|
+
const reader = new FileReader();
|
|
546
|
+
reader.onload = () => resolve(reader.result.split(',')[1]); // strip data:...;base64,
|
|
547
|
+
reader.onerror = reject;
|
|
548
|
+
reader.readAsDataURL(file);
|
|
549
|
+
});
|
|
550
|
+
await api.post(`/agents/${agent.id}/upload`, { filename: file.name, content: base64 });
|
|
551
|
+
uploaded.push(file.name);
|
|
552
|
+
} catch (err) {
|
|
553
|
+
addToast('error', `Upload failed: ${file.name}`, err.message);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (uploaded.length > 0) {
|
|
558
|
+
const names = uploaded.join(', ');
|
|
559
|
+
setInput((prev) => (prev ? prev + '\n' : '') + `[Uploaded: ${names}] — I've uploaded these files to your working directory. Read them and use their content.`);
|
|
560
|
+
addToast('success', `Uploaded ${uploaded.length} file${uploaded.length > 1 ? 's' : ''}`);
|
|
561
|
+
}
|
|
562
|
+
|
|
540
563
|
e.target.value = '';
|
|
541
564
|
inputRef.current?.focus();
|
|
542
565
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groove-dev",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.18",
|
|
4
4
|
"description": "Open-source agent orchestration layer — the AI company OS. MCP integrations (Slack, Gmail, Stripe, 15+), agent scheduling (cron), business roles (CMO, CFO, EA). GUI dashboard, multi-agent coordination, zero cold-start, infinite sessions. Works with Claude Code, Codex, Gemini CLI, Ollama.",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"author": "Groove Dev <hello@groovedev.ai> (https://groovedev.ai)",
|
|
@@ -420,6 +420,37 @@ export function createApi(app, daemon) {
|
|
|
420
420
|
}
|
|
421
421
|
});
|
|
422
422
|
|
|
423
|
+
// Upload file to agent's working directory
|
|
424
|
+
app.post('/api/agents/:id/upload', (req, res) => {
|
|
425
|
+
const agent = daemon.registry.get(req.params.id);
|
|
426
|
+
if (!agent) return res.status(404).json({ error: 'Agent not found' });
|
|
427
|
+
|
|
428
|
+
const { filename, content } = req.body;
|
|
429
|
+
if (!filename || !content) return res.status(400).json({ error: 'filename and content required' });
|
|
430
|
+
|
|
431
|
+
// Sanitize filename — no path traversal
|
|
432
|
+
const safeName = String(filename).replace(/[/\\]/g, '_').replace(/\.\./g, '');
|
|
433
|
+
if (!safeName) return res.status(400).json({ error: 'Invalid filename' });
|
|
434
|
+
|
|
435
|
+
const dir = agent.workingDir || daemon.projectDir;
|
|
436
|
+
const filePath = resolve(dir, safeName);
|
|
437
|
+
|
|
438
|
+
// Ensure file stays within working directory
|
|
439
|
+
if (!filePath.startsWith(dir)) {
|
|
440
|
+
return res.status(400).json({ error: 'Path traversal detected' });
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
try {
|
|
444
|
+
mkdirSync(dir, { recursive: true });
|
|
445
|
+
const buffer = Buffer.from(content, 'base64');
|
|
446
|
+
writeFileSync(filePath, buffer);
|
|
447
|
+
daemon.audit.log('file.upload', { agentId: agent.id, filename: safeName, size: buffer.length });
|
|
448
|
+
res.json({ ok: true, path: safeName, size: buffer.length });
|
|
449
|
+
} catch (err) {
|
|
450
|
+
res.status(500).json({ error: `Upload failed: ${err.message}` });
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
423
454
|
// List MD files for an agent (from its working directory + .groove)
|
|
424
455
|
app.get('/api/agents/:id/mdfiles', (req, res) => {
|
|
425
456
|
const agent = daemon.registry.get(req.params.id);
|
|
@@ -15,12 +15,19 @@ const MODES = {
|
|
|
15
15
|
// Role-based tier hints for new agents with no classifier data yet
|
|
16
16
|
const ROLE_HINTS = {
|
|
17
17
|
planner: 'heavy', // Planning is foundational — needs deep reasoning
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
fullstack: 'heavy', // End-to-end work needs full capability
|
|
19
|
+
slides: 'heavy', // Design quality needs top-tier model
|
|
20
|
+
creative: 'heavy', // Writing quality needs top-tier model
|
|
21
|
+
security: 'heavy', // Security audits need deep reasoning
|
|
20
22
|
backend: 'medium',
|
|
21
23
|
frontend: 'medium',
|
|
24
|
+
testing: 'medium',
|
|
22
25
|
devops: 'medium',
|
|
23
|
-
|
|
26
|
+
database: 'medium',
|
|
27
|
+
analyst: 'medium',
|
|
28
|
+
docs: 'light',
|
|
29
|
+
support: 'light',
|
|
30
|
+
ea: 'light',
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
export class ModelRouter {
|