groove-dev 0.25.19 → 0.25.21

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.
@@ -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-Ca4wKXQ9.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-B1FkEzF0.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">
@@ -3,7 +3,7 @@ import { useState, useEffect } from 'react';
3
3
  import { useGrooveStore } from '../../stores/groove';
4
4
  import { Sheet, SheetContent } from '../ui/sheet';
5
5
  import { Button } from '../ui/button';
6
- import { Input, Textarea } from '../ui/input';
6
+ import { Input } from '../ui/input';
7
7
  import { Badge } from '../ui/badge';
8
8
  import { cn } from '../../lib/cn';
9
9
  import { roleColor } from '../../lib/status';
@@ -190,8 +190,10 @@ export function SpawnWizard() {
190
190
  className="w-full h-8 px-3 pr-8 text-sm rounded-md bg-surface-1 border border-border text-text-0 font-sans appearance-none cursor-pointer focus:outline-none focus:ring-1 focus:ring-accent"
191
191
  >
192
192
  <option value="">Auto</option>
193
- {installedProviders.map((p) => (
194
- <option key={p.id} value={p.id}>{p.name}</option>
193
+ {providers.map((p) => (
194
+ <option key={p.id} value={p.id} disabled={!p.installed}>
195
+ {p.name}{!p.installed ? ' (not installed)' : ''}
196
+ </option>
195
197
  ))}
196
198
  </select>
197
199
  <ChevronDown size={14} className="absolute right-2 top-1/2 -translate-y-1/2 text-text-3 pointer-events-none" />
@@ -220,10 +222,12 @@ export function SpawnWizard() {
220
222
  {/* Provider status hints */}
221
223
  {provider && selectedProvider && (
222
224
  <div className="text-2xs text-text-3 font-sans flex items-center gap-2">
223
- {selectedProvider.hasKey ? (
224
- <Badge variant="success">API key set</Badge>
225
+ {selectedProvider.authType === 'local' ? (
226
+ <Badge variant="success">Local</Badge>
225
227
  ) : selectedProvider.authType === 'subscription' ? (
226
228
  <Badge variant="accent">Subscription</Badge>
229
+ ) : selectedProvider.hasKey ? (
230
+ <Badge variant="success">API key set</Badge>
227
231
  ) : (
228
232
  <Badge variant="warning">No API key — set with: groove set-key {provider} YOUR_KEY</Badge>
229
233
  )}
@@ -324,13 +328,6 @@ export function SpawnWizard() {
324
328
  </DialogContent>
325
329
  </Dialog>
326
330
 
327
- <Textarea
328
- label="Prompt (optional)"
329
- value={prompt}
330
- onChange={(e) => setPrompt(e.target.value)}
331
- placeholder="What should this agent work on?"
332
- rows={3}
333
- />
334
331
  </div>
335
332
  )}
336
333
  </div>
@@ -197,13 +197,17 @@ export const useGrooveStore = create((set, get) => ({
197
197
  case 'agent:exit': {
198
198
  const agent = get().agents.find((a) => a.id === msg.agentId);
199
199
  const name = agent?.name || msg.agentId;
200
- // Exit 143 = SIGTERM (kill), exit 137 = SIGKILL — treat as intentional kill
201
200
  const isKill = msg.status === 'killed' || msg.code === 143 || msg.code === 137;
202
201
  const text = msg.status === 'completed' ? `${name} completed`
203
202
  : isKill ? `${name} stopped`
204
203
  : `${name} crashed (exit ${msg.code})`;
205
204
  const type = msg.status === 'completed' ? 'success' : isKill ? 'info' : 'warning';
206
- get().addToast(type, text);
205
+ get().addToast(type, text, msg.error ? msg.error.slice(0, 200) : undefined);
206
+
207
+ // Log crash error to agent chat so user can see what happened
208
+ if (msg.error && msg.agentId) {
209
+ get().addChatMessage(msg.agentId, 'system', `Crashed: ${msg.error}`);
210
+ }
207
211
  // Check for recommended team when planner completes
208
212
  if (agent?.role === 'planner' && msg.status === 'completed') {
209
213
  setTimeout(() => get().checkRecommendedTeam(), 1000);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groove-dev",
3
- "version": "0.25.19",
3
+ "version": "0.25.21",
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)",
@@ -437,9 +437,14 @@ For normal file edits within your scope, proceed without review.
437
437
  }
438
438
  });
439
439
 
440
- // Capture stderr
440
+ // Capture stderr — collect for crash reporting
441
+ const stderrBuf = [];
441
442
  proc.stderr.on('data', (chunk) => {
442
- logStream.write(`[stderr] ${chunk}`);
443
+ const text = chunk.toString();
444
+ logStream.write(`[stderr] ${text}`);
445
+ stderrBuf.push(text);
446
+ // Keep last 2KB of stderr for crash reporting
447
+ while (stderrBuf.join('').length > 2048) stderrBuf.shift();
443
448
  });
444
449
 
445
450
  // Handle process exit
@@ -456,6 +461,9 @@ For normal file edits within your scope, proceed without review.
456
461
  ? 'completed'
457
462
  : 'crashed';
458
463
 
464
+ // Capture crash error from stderr for UI display
465
+ const crashError = finalStatus === 'crashed' ? stderrBuf.join('').trim().slice(-500) : null;
466
+
459
467
  registry.update(agent.id, { status: finalStatus, pid: null });
460
468
 
461
469
  // Record lifecycle event for timeline
@@ -474,6 +482,7 @@ For normal file edits within your scope, proceed without review.
474
482
  code,
475
483
  signal,
476
484
  status: finalStatus,
485
+ error: crashError || undefined,
477
486
  });
478
487
 
479
488
  // Refresh MCP config — remove integrations no longer needed by running agents
@@ -497,6 +506,14 @@ For normal file edits within your scope, proceed without review.
497
506
 
498
507
  this.handles.delete(agent.id);
499
508
  registry.update(agent.id, { status: 'crashed', pid: null });
509
+ this.daemon.broadcast({
510
+ type: 'agent:exit',
511
+ agentId: agent.id,
512
+ code: null,
513
+ signal: null,
514
+ status: 'crashed',
515
+ error: err.message,
516
+ });
500
517
  });
501
518
 
502
519
  return agent;