groove-dev 0.10.0 → 0.10.2
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/cli/package.json +1 -1
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/process.js +9 -0
- package/node_modules/@groove-dev/daemon/src/providers/codex.js +3 -0
- package/node_modules/@groove-dev/daemon/src/providers/gemini.js +3 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-iBqV1c12.js → index-C9USf6W_.js} +13 -13
- package/node_modules/@groove-dev/gui/dist/index.html +1 -1
- package/node_modules/@groove-dev/gui/package.json +1 -1
- package/node_modules/@groove-dev/gui/src/views/CommandCenter.jsx +23 -36
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/process.js +9 -0
- package/packages/daemon/src/providers/codex.js +3 -0
- package/packages/daemon/src/providers/gemini.js +3 -0
- package/packages/gui/dist/assets/{index-iBqV1c12.js → index-C9USf6W_.js} +13 -13
- package/packages/gui/dist/index.html +1 -1
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/views/CommandCenter.jsx +23 -36
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>GROOVE</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-C9USf6W_.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-CPzm9ZE9.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -62,30 +62,13 @@ export default function CommandCenter() {
|
|
|
62
62
|
return (
|
|
63
63
|
<div style={s.root}>
|
|
64
64
|
|
|
65
|
-
{/* ROW 1 — Stat
|
|
66
|
-
<div style={s.
|
|
67
|
-
<StatCard
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
/>
|
|
72
|
-
<StatCard
|
|
73
|
-
label="Estimated Savings"
|
|
74
|
-
value={estDollarSaved > 0 ? `$${estDollarSaved.toFixed(2)}` : '$0.00'}
|
|
75
|
-
sub={`${fmtNum(tokens.savings.total)} tokens saved`}
|
|
76
|
-
color={GREEN}
|
|
77
|
-
/>
|
|
78
|
-
<StatCard
|
|
79
|
-
label="Efficiency"
|
|
80
|
-
value={`${tokens.savings.percentage || 0}%`}
|
|
81
|
-
sub="vs uncoordinated"
|
|
82
|
-
color={tokens.savings.percentage > 0 ? GREEN : undefined}
|
|
83
|
-
/>
|
|
84
|
-
<StatCard
|
|
85
|
-
label="Rotations"
|
|
86
|
-
value={rotation.totalRotations}
|
|
87
|
-
sub={fmtUptime(uptime)}
|
|
88
|
-
/>
|
|
65
|
+
{/* ROW 1 — Connected Stat Bar */}
|
|
66
|
+
<div style={s.statBar}>
|
|
67
|
+
<StatCard label="Total Tokens" value={fmtNum(tokens.totalTokens)} sub={`${data.agents.total} agent${data.agents.total !== 1 ? 's' : ''}`} />
|
|
68
|
+
<StatCard label="Tokens Saved" value={fmtNum(tokens.savings.total)} sub={`${tokens.savings.percentage || 0}% efficiency`} color={GREEN} />
|
|
69
|
+
<StatCard label="Est. Savings" value={estDollarSaved > 0 ? `$${estDollarSaved.toFixed(2)}` : '$0.00'} sub="based on token costs" color={GREEN} />
|
|
70
|
+
<StatCard label="Rotations" value={rotation.totalRotations} sub={`${fmtNum(rotation.totalTokensSaved)} tok recovered`} />
|
|
71
|
+
<StatCard label="Uptime" value={fmtUptime(uptime)} sub={`${data.agents.running} running`} />
|
|
89
72
|
</div>
|
|
90
73
|
|
|
91
74
|
{/* ROW 2 — Area Chart + Donut */}
|
|
@@ -119,13 +102,16 @@ export default function CommandCenter() {
|
|
|
119
102
|
<HorizBar label="Conflict Prevention" value={tokens.savings.fromConflictPrevention} max={tokens.savings.total || 1} color={AMBER} />
|
|
120
103
|
<HorizBar label="Cold-Start Skip" value={tokens.savings.fromColdStartSkip} max={tokens.savings.total || 1} color={GREEN} />
|
|
121
104
|
<div style={s.divider} />
|
|
122
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: '#
|
|
105
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: '#8b929e', padding: '4px 0' }}>
|
|
123
106
|
<span>Without Groove</span>
|
|
124
|
-
<span style={{ color: RED }}>{fmtNum(tokens.savings.estimatedWithoutGroove)}</span>
|
|
107
|
+
<span style={{ color: RED, fontWeight: 600 }}>{fmtNum(tokens.savings.estimatedWithoutGroove)}</span>
|
|
125
108
|
</div>
|
|
126
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: '#
|
|
109
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: '#8b929e', padding: '4px 0' }}>
|
|
127
110
|
<span>With Groove</span>
|
|
128
|
-
<span style={{ color: GREEN }}>{fmtNum(tokens.totalTokens)}</span>
|
|
111
|
+
<span style={{ color: GREEN, fontWeight: 600 }}>{fmtNum(tokens.totalTokens)}</span>
|
|
112
|
+
</div>
|
|
113
|
+
<div style={{ fontSize: 8, color: '#5c6370', marginTop: 4, lineHeight: 1.4 }}>
|
|
114
|
+
Calculated from: rotation recovery (30% of degraded context), cold-start prevention (2K tokens/skip), conflict avoidance (500 tokens/conflict).
|
|
129
115
|
</div>
|
|
130
116
|
{journalist.lastSummary && (
|
|
131
117
|
<>
|
|
@@ -176,9 +162,9 @@ export default function CommandCenter() {
|
|
|
176
162
|
function StatCard({ label, value, sub, color }) {
|
|
177
163
|
return (
|
|
178
164
|
<div style={s.statCard}>
|
|
179
|
-
<div style={{ fontSize:
|
|
180
|
-
<div style={{ fontSize:
|
|
181
|
-
{sub && <div style={{ fontSize: 9, color: '#
|
|
165
|
+
<div style={{ fontSize: 10, color: '#8b929e', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 6 }}>{label}</div>
|
|
166
|
+
<div style={{ fontSize: 20, fontWeight: 700, color: color || '#e6e6e6', lineHeight: 1 }}>{value}</div>
|
|
167
|
+
{sub && <div style={{ fontSize: 9, color: '#6b7280', marginTop: 4 }}>{sub}</div>}
|
|
182
168
|
</div>
|
|
183
169
|
);
|
|
184
170
|
}
|
|
@@ -437,13 +423,14 @@ const s = {
|
|
|
437
423
|
loadingBar: { width: 120, height: 2, background: '#282c34', borderRadius: 1, overflow: 'hidden' },
|
|
438
424
|
loadingFill: { width: '40%', height: '100%', background: ACCENT, animation: 'pulse 1.5s infinite' },
|
|
439
425
|
|
|
440
|
-
// Stat
|
|
441
|
-
|
|
442
|
-
display: '
|
|
443
|
-
|
|
426
|
+
// Stat bar — connected, no gaps
|
|
427
|
+
statBar: {
|
|
428
|
+
display: 'flex', flexShrink: 0,
|
|
429
|
+
background: '#282c34', borderRadius: 12, overflow: 'hidden',
|
|
444
430
|
},
|
|
445
431
|
statCard: {
|
|
446
|
-
|
|
432
|
+
flex: 1, padding: '14px 16px',
|
|
433
|
+
borderRight: '1px solid #1e222a',
|
|
447
434
|
display: 'flex', flexDirection: 'column',
|
|
448
435
|
},
|
|
449
436
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groove-dev",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Open-source agent orchestration layer for AI coding tools. GUI dashboard, multi-agent coordination, zero cold-start (Journalist), infinite sessions (adaptive context rotation), AI Project Manager, Quick Launch. 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)",
|
|
@@ -165,6 +165,15 @@ For normal file edits within your scope, proceed without review.
|
|
|
165
165
|
const spawnLine = `[${new Date().toISOString()}] GROOVE spawning: ${command} [${safeArgs.length} args]\n`;
|
|
166
166
|
logStream.write(spawnLine);
|
|
167
167
|
|
|
168
|
+
// Inject API key from credential store if the provider needs one
|
|
169
|
+
const providerMeta = getProvider(agent.provider);
|
|
170
|
+
if (providerMeta?.constructor?.envKey) {
|
|
171
|
+
const storedKey = this.daemon.credentials.getKey(agent.provider);
|
|
172
|
+
if (storedKey) {
|
|
173
|
+
env[providerMeta.constructor.envKey] = storedKey;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
168
177
|
// Spawn the process
|
|
169
178
|
const proc = cpSpawn(command, args, {
|
|
170
179
|
cwd: agent.workingDir || this.daemon.projectDir,
|
|
@@ -11,6 +11,9 @@ export class CodexProvider extends Provider {
|
|
|
11
11
|
static authType = 'api-key';
|
|
12
12
|
static envKey = 'OPENAI_API_KEY';
|
|
13
13
|
static models = [
|
|
14
|
+
{ id: 'gpt-5.4', name: 'GPT-5.4', tier: 'heavy' },
|
|
15
|
+
{ id: 'gpt-5.4-mini', name: 'GPT-5.4 Mini', tier: 'medium' },
|
|
16
|
+
{ id: 'gpt-5.4-nano', name: 'GPT-5.4 Nano', tier: 'light' },
|
|
14
17
|
{ id: 'o3', name: 'o3', tier: 'heavy' },
|
|
15
18
|
{ id: 'o4-mini', name: 'o4-mini', tier: 'medium' },
|
|
16
19
|
];
|
|
@@ -11,6 +11,9 @@ export class GeminiProvider extends Provider {
|
|
|
11
11
|
static authType = 'api-key';
|
|
12
12
|
static envKey = 'GEMINI_API_KEY';
|
|
13
13
|
static models = [
|
|
14
|
+
{ id: 'gemini-3.0-pro', name: 'Gemini 3.0 Pro', tier: 'heavy' },
|
|
15
|
+
{ id: 'gemini-3.0-flash', name: 'Gemini 3.0 Flash', tier: 'medium' },
|
|
16
|
+
{ id: 'gemini-3.0-flash-lite', name: 'Gemini 3.0 Flash Lite', tier: 'light' },
|
|
14
17
|
{ id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro', tier: 'heavy' },
|
|
15
18
|
{ id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash', tier: 'medium' },
|
|
16
19
|
];
|