groove-dev 0.19.2 → 0.19.3

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.
Files changed (23) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/node_modules/@groove-dev/cli/bin/groove.js +1 -1
  3. package/node_modules/@groove-dev/daemon/src/api.js +52 -0
  4. package/node_modules/@groove-dev/daemon/src/providers/ollama.js +127 -26
  5. package/node_modules/@groove-dev/gui/.groove/codebase-index.json +1 -1
  6. package/node_modules/@groove-dev/gui/.groove/daemon.host +1 -0
  7. package/node_modules/@groove-dev/gui/.groove/daemon.pid +1 -0
  8. package/node_modules/@groove-dev/gui/.groove/timeline.json +168 -0
  9. package/node_modules/@groove-dev/gui/AGENTS_REGISTRY.md +9 -0
  10. package/node_modules/@groove-dev/gui/dist/assets/{index-DbujgqhS.js → index-CBSgTE0t.js} +123 -123
  11. package/node_modules/@groove-dev/gui/dist/assets/{index-DCakRxDE.css → index-DgIS4D-j.css} +1 -1
  12. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  13. package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +9 -3
  14. package/node_modules/@groove-dev/gui/src/components/agents/ollama-setup.jsx +322 -0
  15. package/package.json +1 -1
  16. package/packages/cli/bin/groove.js +1 -1
  17. package/packages/daemon/src/api.js +52 -0
  18. package/packages/daemon/src/providers/ollama.js +127 -26
  19. package/packages/gui/dist/assets/{index-DbujgqhS.js → index-CBSgTE0t.js} +123 -123
  20. package/packages/gui/dist/assets/{index-DCakRxDE.css → index-DgIS4D-j.css} +1 -1
  21. package/packages/gui/dist/index.html +2 -2
  22. package/packages/gui/src/components/agents/agent-config.jsx +9 -3
  23. package/packages/gui/src/components/agents/ollama-setup.jsx +322 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.19.3 — Ollama setup experience: hardware detection, model catalog, one-click pull (2026-04-08)
4
+
5
+ - **Ollama model catalog** — 22 models across Code and General categories with RAM requirements and download sizes
6
+ - **Hardware detection** — auto-detects RAM, CPU, GPU (Apple Silicon unified memory, NVIDIA), recommends best models for your system
7
+ - **Model management** — pull models from GUI with progress via WebSocket, delete installed models, category tabs (Code/General)
8
+ - **Install flow** — platform-specific install command (brew on macOS, curl on Linux), copy button, hardware readiness check, "Recheck" button
9
+ - **5 new API endpoints** — `/api/providers/ollama/hardware`, `/models`, `/pull`, `/check`, `DELETE /models/:model`
10
+
3
11
  ## v0.19.2 — Config tab cleanup, remove restart, fix Ollama key prompt (2026-04-08)
4
12
 
5
13
  - **Remove restart button** — sending a chat message resumes with context, restart was redundant
@@ -24,7 +24,7 @@ import { federationPair, federationUnpair, federationList, federationStatus } fr
24
24
  program
25
25
  .name('groove')
26
26
  .description('Agent orchestration layer for AI coding tools')
27
- .version('0.19.2');
27
+ .version('0.19.3');
28
28
 
29
29
  program
30
30
  .command('start')
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'url';
7
7
  import { existsSync, readFileSync, readdirSync, statSync, writeFileSync, mkdirSync, unlinkSync, renameSync, rmSync, createReadStream } from 'fs';
8
8
  import { lookup as mimeLookup } from './mimetypes.js';
9
9
  import { listProviders, getProvider } from './providers/index.js';
10
+ import { OllamaProvider } from './providers/ollama.js';
10
11
  import { validateAgentConfig } from './validate.js';
11
12
 
12
13
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -126,6 +127,57 @@ export function createApi(app, daemon) {
126
127
  res.json(providers);
127
128
  });
128
129
 
130
+ // --- Ollama ---
131
+
132
+ app.get('/api/providers/ollama/hardware', (req, res) => {
133
+ res.json(OllamaProvider.getSystemHardware());
134
+ });
135
+
136
+ app.get('/api/providers/ollama/models', (req, res) => {
137
+ const installed = OllamaProvider.isInstalled() ? OllamaProvider.getInstalledModels() : [];
138
+ const catalog = OllamaProvider.catalog;
139
+ const hardware = OllamaProvider.getSystemHardware();
140
+ res.json({ installed, catalog, hardware });
141
+ });
142
+
143
+ app.post('/api/providers/ollama/pull', async (req, res) => {
144
+ const { model } = req.body;
145
+ if (!model) return res.status(400).json({ error: 'model is required' });
146
+ if (!OllamaProvider.isInstalled()) return res.status(400).json({ error: 'Ollama is not installed' });
147
+ const broadcast = daemon.broadcast || (() => {});
148
+ try {
149
+ broadcast({ type: 'ollama:pull:start', model });
150
+ await OllamaProvider.pullModel(model, (progress) => {
151
+ broadcast({ type: 'ollama:pull:progress', model, progress: progress.trim() });
152
+ });
153
+ broadcast({ type: 'ollama:pull:complete', model });
154
+ daemon.audit.log('ollama.pull', { model });
155
+ res.json({ ok: true, model });
156
+ } catch (err) {
157
+ broadcast({ type: 'ollama:pull:error', model, error: err.message });
158
+ res.status(500).json({ error: `Pull failed: ${err.message}` });
159
+ }
160
+ });
161
+
162
+ app.delete('/api/providers/ollama/models/:model', (req, res) => {
163
+ if (!OllamaProvider.isInstalled()) return res.status(400).json({ error: 'Ollama is not installed' });
164
+ const success = OllamaProvider.deleteModel(req.params.model);
165
+ if (success) {
166
+ daemon.audit.log('ollama.delete', { model: req.params.model });
167
+ res.json({ ok: true });
168
+ } else {
169
+ res.status(500).json({ error: 'Failed to delete model' });
170
+ }
171
+ });
172
+
173
+ app.post('/api/providers/ollama/check', (req, res) => {
174
+ const installed = OllamaProvider.isInstalled();
175
+ const install = OllamaProvider.installCommand();
176
+ const hardware = OllamaProvider.getSystemHardware();
177
+ const requirements = OllamaProvider.hardwareRequirements();
178
+ res.json({ installed, install, hardware, requirements });
179
+ });
180
+
129
181
  // --- Credentials ---
130
182
 
131
183
  app.get('/api/credentials', (req, res) => {
@@ -2,19 +2,54 @@
2
2
  // FSL-1.1-Apache-2.0 — see LICENSE
3
3
 
4
4
  import { execSync } from 'child_process';
5
+ import { execFile } from 'child_process';
6
+ import os from 'os';
5
7
  import { Provider } from './base.js';
6
8
 
9
+ // Comprehensive model catalog with RAM requirements
10
+ const MODEL_CATALOG = [
11
+ // ── Code-Focused ──────────────────────────────────────────
12
+ { id: 'qwen2.5-coder:0.5b', name: 'Qwen 2.5 Coder 0.5B', category: 'code', tier: 'light', ramGb: 1, sizeGb: 0.4, description: 'Ultra-light code completion' },
13
+ { id: 'qwen2.5-coder:1.5b', name: 'Qwen 2.5 Coder 1.5B', category: 'code', tier: 'light', ramGb: 2, sizeGb: 1.0, description: 'Fast code assistant' },
14
+ { id: 'qwen2.5-coder:3b', name: 'Qwen 2.5 Coder 3B', category: 'code', tier: 'light', ramGb: 4, sizeGb: 1.9, description: 'Balanced speed and quality' },
15
+ { id: 'qwen2.5-coder:7b', name: 'Qwen 2.5 Coder 7B', category: 'code', tier: 'medium', ramGb: 8, sizeGb: 4.7, description: 'Strong general coding' },
16
+ { id: 'qwen2.5-coder:14b', name: 'Qwen 2.5 Coder 14B', category: 'code', tier: 'medium', ramGb: 16, sizeGb: 9.0, description: 'Advanced code reasoning' },
17
+ { id: 'qwen2.5-coder:32b', name: 'Qwen 2.5 Coder 32B', category: 'code', tier: 'heavy', ramGb: 24, sizeGb: 20, description: 'Best-in-class code generation' },
18
+ { id: 'codellama:7b', name: 'Code Llama 7B', category: 'code', tier: 'medium', ramGb: 8, sizeGb: 3.8, description: 'Meta code model, solid baseline' },
19
+ { id: 'codellama:13b', name: 'Code Llama 13B', category: 'code', tier: 'medium', ramGb: 16, sizeGb: 7.4, description: 'Stronger code reasoning' },
20
+ { id: 'codellama:34b', name: 'Code Llama 34B', category: 'code', tier: 'heavy', ramGb: 24, sizeGb: 19, description: 'Largest Code Llama' },
21
+ { id: 'deepseek-coder-v2:16b', name: 'DeepSeek Coder V2 16B', category: 'code', tier: 'medium', ramGb: 16, sizeGb: 8.9, description: 'Strong multi-language coding' },
22
+ { id: 'starcoder2:3b', name: 'StarCoder2 3B', category: 'code', tier: 'light', ramGb: 4, sizeGb: 1.7, description: 'Code completion specialist' },
23
+ { id: 'starcoder2:7b', name: 'StarCoder2 7B', category: 'code', tier: 'medium', ramGb: 8, sizeGb: 4.0, description: 'Solid code generation' },
24
+ { id: 'starcoder2:15b', name: 'StarCoder2 15B', category: 'code', tier: 'medium', ramGb: 16, sizeGb: 9.0, description: 'Best StarCoder variant' },
25
+
26
+ // ── General (Strong at Code) ──────────────────────────────
27
+ { id: 'llama3.1:8b', name: 'Llama 3.1 8B', category: 'general', tier: 'medium', ramGb: 8, sizeGb: 4.7, description: 'Meta flagship, great all-rounder' },
28
+ { id: 'llama3.1:70b', name: 'Llama 3.1 70B', category: 'general', tier: 'heavy', ramGb: 48, sizeGb: 40, description: 'Frontier-class open model' },
29
+ { id: 'mistral:7b', name: 'Mistral 7B', category: 'general', tier: 'medium', ramGb: 8, sizeGb: 4.1, description: 'Fast and efficient' },
30
+ { id: 'mixtral:8x7b', name: 'Mixtral 8x7B', category: 'general', tier: 'heavy', ramGb: 32, sizeGb: 26, description: 'MoE architecture, expert routing' },
31
+ { id: 'gemma2:2b', name: 'Gemma 2 2B', category: 'general', tier: 'light', ramGb: 2, sizeGb: 1.6, description: 'Google lightweight model' },
32
+ { id: 'gemma2:9b', name: 'Gemma 2 9B', category: 'general', tier: 'medium', ramGb: 8, sizeGb: 5.4, description: 'Google mid-range model' },
33
+ { id: 'gemma2:27b', name: 'Gemma 2 27B', category: 'general', tier: 'heavy', ramGb: 20, sizeGb: 16, description: 'Google large model' },
34
+ { id: 'phi3:mini', name: 'Phi-3 Mini 3.8B', category: 'general', tier: 'light', ramGb: 4, sizeGb: 2.3, description: 'Microsoft small but capable' },
35
+ { id: 'phi3:medium', name: 'Phi-3 Medium 14B', category: 'general', tier: 'medium', ramGb: 16, sizeGb: 7.9, description: 'Microsoft mid-range' },
36
+ ];
37
+
7
38
  export class OllamaProvider extends Provider {
8
39
  static name = 'ollama';
9
40
  static displayName = 'Ollama (Local)';
10
41
  static command = 'ollama';
11
42
  static authType = 'local';
12
- static models = [
13
- { id: 'qwen2.5-coder:32b', name: 'Qwen 2.5 Coder 32B', tier: 'heavy' },
14
- { id: 'qwen2.5-coder:7b', name: 'Qwen 2.5 Coder 7B', tier: 'medium' },
15
- { id: 'codellama:13b', name: 'Code Llama 13B', tier: 'medium' },
16
- { id: 'deepseek-coder-v2:16b', name: 'DeepSeek Coder V2', tier: 'medium' },
17
- ];
43
+
44
+ // Models exposed to the spawn wizard / provider listing
45
+ static get models() {
46
+ return MODEL_CATALOG.map(({ id, name, tier }) => ({ id, name, tier }));
47
+ }
48
+
49
+ // Full catalog with RAM/size/description for the setup UI
50
+ static get catalog() {
51
+ return MODEL_CATALOG;
52
+ }
18
53
 
19
54
  static isInstalled() {
20
55
  try {
@@ -26,53 +61,119 @@ export class OllamaProvider extends Provider {
26
61
  }
27
62
 
28
63
  static installCommand() {
29
- return 'curl -fsSL https://ollama.ai/install.sh | sh';
64
+ const platform = process.platform;
65
+ if (platform === 'darwin') {
66
+ return { command: 'brew install ollama', alt: 'Or download from https://ollama.ai/download', platform: 'macOS' };
67
+ }
68
+ if (platform === 'linux') {
69
+ return { command: 'curl -fsSL https://ollama.ai/install.sh | sh', platform: 'Linux' };
70
+ }
71
+ return { command: 'Download from https://ollama.ai/download', platform: 'other' };
30
72
  }
31
73
 
32
74
  static hardwareRequirements() {
33
75
  return {
34
- minRAM: 8,
76
+ minRAM: 4,
35
77
  recommendedRAM: 16,
36
78
  gpuRecommended: true,
37
- note: '7B models need ~8GB RAM, 32B models need ~24GB RAM',
79
+ note: 'Apple Silicon Macs use unified memory — all RAM is GPU RAM. NVIDIA GPUs recommended on Linux.',
80
+ };
81
+ }
82
+
83
+ static getSystemHardware() {
84
+ const totalRamGb = Math.round(os.totalmem() / (1024 ** 3));
85
+ const cpus = os.cpus();
86
+ const cpuModel = cpus[0]?.model || 'Unknown';
87
+ const cores = cpus.length;
88
+ const platform = process.platform;
89
+ const arch = os.arch();
90
+ const isAppleSilicon = platform === 'darwin' && arch === 'arm64';
91
+
92
+ let gpu = null;
93
+ if (isAppleSilicon) {
94
+ gpu = { type: 'apple-silicon', name: cpuModel.replace(/Apple /g, ''), vram: totalRamGb, note: 'Unified memory — all RAM available to GPU' };
95
+ } else if (platform === 'linux') {
96
+ try {
97
+ const out = execSync('nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits', { encoding: 'utf8', timeout: 5000 });
98
+ const [name, vram] = out.trim().split(', ');
99
+ gpu = { type: 'nvidia', name, vram: Math.round(parseInt(vram, 10) / 1024) };
100
+ } catch {
101
+ gpu = null;
102
+ }
103
+ }
104
+
105
+ // Recommend models based on available RAM
106
+ const recommended = MODEL_CATALOG
107
+ .filter((m) => m.ramGb <= totalRamGb)
108
+ .sort((a, b) => b.ramGb - a.ramGb);
109
+
110
+ const bestCodeModel = recommended.find((m) => m.category === 'code');
111
+ const bestGeneralModel = recommended.find((m) => m.category === 'general');
112
+
113
+ return {
114
+ totalRamGb,
115
+ cpuModel,
116
+ cores,
117
+ platform,
118
+ arch,
119
+ isAppleSilicon,
120
+ gpu,
121
+ recommended: { code: bestCodeModel?.id || null, general: bestGeneralModel?.id || null },
122
+ maxModelRam: totalRamGb,
38
123
  };
39
124
  }
40
125
 
41
126
  static getInstalledModels() {
42
127
  try {
43
- const output = execSync('ollama list', { encoding: 'utf8' });
128
+ const output = execSync('ollama list', { encoding: 'utf8', timeout: 10000 });
44
129
  const lines = output.split('\n').slice(1).filter(Boolean);
45
130
  return lines.map((line) => {
46
131
  const parts = line.split(/\s+/);
47
- return { name: parts[0], size: parts[1] };
132
+ const name = parts[0];
133
+ const size = parts[2] || parts[1] || '';
134
+ // Match against catalog for metadata
135
+ const catalogEntry = MODEL_CATALOG.find((m) => name.startsWith(m.id.split(':')[0]));
136
+ return { id: name, name, size, category: catalogEntry?.category || 'other', tier: catalogEntry?.tier || 'medium' };
48
137
  });
49
138
  } catch {
50
139
  return [];
51
140
  }
52
141
  }
53
142
 
54
- buildSpawnCommand(agent) {
55
- const model = agent.model || 'qwen2.5-coder:7b';
56
- const args = ['run', model];
143
+ static pullModel(modelId, onProgress) {
144
+ return new Promise((resolve, reject) => {
145
+ const child = execFile('ollama', ['pull', modelId], { timeout: 600000 }, (err) => {
146
+ if (err) reject(err);
147
+ else resolve({ success: true, model: modelId });
148
+ });
149
+ if (child.stderr && onProgress) {
150
+ child.stderr.on('data', (data) => onProgress(data.toString()));
151
+ }
152
+ if (child.stdout && onProgress) {
153
+ child.stdout.on('data', (data) => onProgress(data.toString()));
154
+ }
155
+ });
156
+ }
57
157
 
58
- if (agent.prompt) {
59
- args.push(agent.prompt);
158
+ static deleteModel(modelId) {
159
+ try {
160
+ execSync(`ollama rm ${modelId}`, { encoding: 'utf8', timeout: 30000 });
161
+ return true;
162
+ } catch {
163
+ return false;
60
164
  }
165
+ }
61
166
 
62
- return {
63
- command: 'ollama',
64
- args,
65
- env: { OLLAMA_API_BASE: 'http://localhost:11434' },
66
- };
167
+ buildSpawnCommand(agent) {
168
+ const model = agent.model || 'qwen2.5-coder:7b';
169
+ const args = ['run', model];
170
+ if (agent.prompt) args.push(agent.prompt);
171
+ return { command: 'ollama', args, env: { OLLAMA_API_BASE: 'http://localhost:11434' } };
67
172
  }
68
173
 
69
174
  buildHeadlessCommand(prompt, model) {
70
175
  const m = model || 'qwen2.5-coder:7b';
71
- return {
72
- command: 'ollama',
73
- args: ['run', m, prompt],
74
- env: {},
75
- };
176
+ return { command: 'ollama', args: ['run', m, prompt], env: {} };
76
177
  }
77
178
 
78
179
  switchModel(agent, newModel) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "projectName": "gui",
3
- "scannedAt": "2026-04-09T05:20:41.239Z",
3
+ "scannedAt": "2026-04-09T05:29:41.298Z",
4
4
  "stats": {
5
5
  "totalFiles": 84,
6
6
  "totalDirs": 14,
@@ -0,0 +1 @@
1
+ 127.0.0.1
@@ -5983,6 +5983,174 @@
5983
5983
  "agents": 1,
5984
5984
  "running": 0,
5985
5985
  "cacheHitRate": 0.8360697165954649
5986
+ },
5987
+ {
5988
+ "t": 1775712463147,
5989
+ "tokens": 3005468,
5990
+ "costUsd": 0.42406725000000006,
5991
+ "agents": 1,
5992
+ "running": 0,
5993
+ "cacheHitRate": 0.8360697165954649
5994
+ },
5995
+ {
5996
+ "t": 1775712493148,
5997
+ "tokens": 3005468,
5998
+ "costUsd": 0.42406725000000006,
5999
+ "agents": 1,
6000
+ "running": 0,
6001
+ "cacheHitRate": 0.8360697165954649
6002
+ },
6003
+ {
6004
+ "t": 1775712523147,
6005
+ "tokens": 3005468,
6006
+ "costUsd": 0.42406725000000006,
6007
+ "agents": 1,
6008
+ "running": 0,
6009
+ "cacheHitRate": 0.8360697165954649
6010
+ },
6011
+ {
6012
+ "t": 1775712553147,
6013
+ "tokens": 3005468,
6014
+ "costUsd": 0.42406725000000006,
6015
+ "agents": 1,
6016
+ "running": 0,
6017
+ "cacheHitRate": 0.8360697165954649
6018
+ },
6019
+ {
6020
+ "t": 1775712581292,
6021
+ "tokens": 3005468,
6022
+ "costUsd": 0.42406725000000006,
6023
+ "agents": 1,
6024
+ "running": 0,
6025
+ "cacheHitRate": 0.8360697165954649
6026
+ },
6027
+ {
6028
+ "t": 1775712611295,
6029
+ "tokens": 3005468,
6030
+ "costUsd": 0.42406725000000006,
6031
+ "agents": 1,
6032
+ "running": 0,
6033
+ "cacheHitRate": 0.8360697165954649
6034
+ },
6035
+ {
6036
+ "t": 1775712641294,
6037
+ "tokens": 3005468,
6038
+ "costUsd": 0.42406725000000006,
6039
+ "agents": 1,
6040
+ "running": 0,
6041
+ "cacheHitRate": 0.8360697165954649
6042
+ },
6043
+ {
6044
+ "t": 1775712671294,
6045
+ "tokens": 3005468,
6046
+ "costUsd": 0.42406725000000006,
6047
+ "agents": 1,
6048
+ "running": 0,
6049
+ "cacheHitRate": 0.8360697165954649
6050
+ },
6051
+ {
6052
+ "t": 1775712701294,
6053
+ "tokens": 3005468,
6054
+ "costUsd": 0.42406725000000006,
6055
+ "agents": 1,
6056
+ "running": 0,
6057
+ "cacheHitRate": 0.8360697165954649
6058
+ },
6059
+ {
6060
+ "t": 1775712731295,
6061
+ "tokens": 3005468,
6062
+ "costUsd": 0.42406725000000006,
6063
+ "agents": 1,
6064
+ "running": 0,
6065
+ "cacheHitRate": 0.8360697165954649
6066
+ },
6067
+ {
6068
+ "t": 1775712761294,
6069
+ "tokens": 3005468,
6070
+ "costUsd": 0.42406725000000006,
6071
+ "agents": 1,
6072
+ "running": 0,
6073
+ "cacheHitRate": 0.8360697165954649
6074
+ },
6075
+ {
6076
+ "t": 1775712791294,
6077
+ "tokens": 3005468,
6078
+ "costUsd": 0.42406725000000006,
6079
+ "agents": 1,
6080
+ "running": 0,
6081
+ "cacheHitRate": 0.8360697165954649
6082
+ },
6083
+ {
6084
+ "t": 1775712821294,
6085
+ "tokens": 3005468,
6086
+ "costUsd": 0.42406725000000006,
6087
+ "agents": 1,
6088
+ "running": 0,
6089
+ "cacheHitRate": 0.8360697165954649
6090
+ },
6091
+ {
6092
+ "t": 1775712851295,
6093
+ "tokens": 3005468,
6094
+ "costUsd": 0.42406725000000006,
6095
+ "agents": 1,
6096
+ "running": 0,
6097
+ "cacheHitRate": 0.8360697165954649
6098
+ },
6099
+ {
6100
+ "t": 1775712881294,
6101
+ "tokens": 3005468,
6102
+ "costUsd": 0.42406725000000006,
6103
+ "agents": 1,
6104
+ "running": 0,
6105
+ "cacheHitRate": 0.8360697165954649
6106
+ },
6107
+ {
6108
+ "t": 1775712911295,
6109
+ "tokens": 3005468,
6110
+ "costUsd": 0.42406725000000006,
6111
+ "agents": 1,
6112
+ "running": 0,
6113
+ "cacheHitRate": 0.8360697165954649
6114
+ },
6115
+ {
6116
+ "t": 1775712941294,
6117
+ "tokens": 3005468,
6118
+ "costUsd": 0.42406725000000006,
6119
+ "agents": 1,
6120
+ "running": 0,
6121
+ "cacheHitRate": 0.8360697165954649
6122
+ },
6123
+ {
6124
+ "t": 1775712971295,
6125
+ "tokens": 3005468,
6126
+ "costUsd": 0.42406725000000006,
6127
+ "agents": 1,
6128
+ "running": 0,
6129
+ "cacheHitRate": 0.8360697165954649
6130
+ },
6131
+ {
6132
+ "t": 1775713001295,
6133
+ "tokens": 3005468,
6134
+ "costUsd": 0.42406725000000006,
6135
+ "agents": 1,
6136
+ "running": 0,
6137
+ "cacheHitRate": 0.8360697165954649
6138
+ },
6139
+ {
6140
+ "t": 1775713031294,
6141
+ "tokens": 3005468,
6142
+ "costUsd": 0.42406725000000006,
6143
+ "agents": 1,
6144
+ "running": 0,
6145
+ "cacheHitRate": 0.8360697165954649
6146
+ },
6147
+ {
6148
+ "t": 1775713061296,
6149
+ "tokens": 3005468,
6150
+ "costUsd": 0.42406725000000006,
6151
+ "agents": 1,
6152
+ "running": 0,
6153
+ "cacheHitRate": 0.8360697165954649
5986
6154
  }
5987
6155
  ],
5988
6156
  "events": [
@@ -0,0 +1,9 @@
1
+ # AGENTS REGISTRY
2
+
3
+ *Auto-generated by GROOVE. Do not edit manually.*
4
+
5
+ | ID | Name | Role | Provider | Directory | Scope | Status |
6
+ |----|------|------|----------|-----------|-------|--------|
7
+ | 15f1e784 | planner-1 | planner | claude-code | /Users/rok/Desktop/groove/packages/gui | - | stopped |
8
+
9
+ *Updated: 2026-04-09T05:32:30.004Z*