groove-dev 0.27.188 → 0.27.190
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/index.js +4 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-fyGUwOq4.js → index-DXup-n8w.js} +2 -2
- 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/App.jsx +41 -2
- package/node_modules/@groove-dev/gui/src/stores/groove.js +15 -1
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/index.js +4 -0
- package/packages/gui/dist/assets/{index-fyGUwOq4.js → index-DXup-n8w.js} +2 -2
- package/packages/gui/dist/index.html +1 -1
- package/packages/gui/package.json +1 -1
- package/packages/gui/src/App.jsx +41 -2
- package/packages/gui/src/stores/groove.js +15 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
8
8
|
<title>Groove GUI</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-DXup-n8w.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-26L3JoZv.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/reactflow-DoBZjiHE.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/codemirror-BYKpdS2W.js">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// GROOVE GUI v2 — App Root
|
|
2
2
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
3
3
|
|
|
4
|
-
import React, { useEffect, useMemo } from 'react';
|
|
4
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
5
5
|
import { useGrooveStore } from './stores/groove';
|
|
6
6
|
import { AppShell } from './components/layout/app-shell';
|
|
7
7
|
import { SetupWizard } from './components/onboarding/setup-wizard';
|
|
@@ -133,10 +133,49 @@ function TunneledFolderPicker() {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
function LoadingScreen() {
|
|
136
|
+
const connected = useGrooveStore((s) => s.connected);
|
|
137
|
+
const [slow, setSlow] = useState(false);
|
|
138
|
+
const [reconnecting, setReconnecting] = useState(false);
|
|
139
|
+
|
|
140
|
+
// Reveal a manual reconnect after a while rather than pulsing forever. We do
|
|
141
|
+
// NOT auto-reconnect here: over a slow SSH tunnel the socket can take longer
|
|
142
|
+
// than this to open, and reloading mid-connect would restart the load in a
|
|
143
|
+
// loop that never finishes. Wake recovery is handled by the desktop shell's
|
|
144
|
+
// power-resume handler; this is just a user-triggered escape hatch.
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
const t = setTimeout(() => setSlow(true), 12000);
|
|
147
|
+
return () => clearTimeout(t);
|
|
148
|
+
}, []);
|
|
149
|
+
|
|
150
|
+
async function manualReconnect() {
|
|
151
|
+
if (window.groove?.reconnect) {
|
|
152
|
+
setReconnecting(true);
|
|
153
|
+
try { await window.groove.reconnect(); } catch { /* falls through to reload */ }
|
|
154
|
+
setReconnecting(false);
|
|
155
|
+
}
|
|
156
|
+
window.location.reload();
|
|
157
|
+
}
|
|
158
|
+
|
|
136
159
|
return (
|
|
137
160
|
<div className="h-screen bg-surface-0 flex flex-col items-center justify-center gap-4">
|
|
138
161
|
<img src="/favicon.png" alt="" className="w-10 h-10 opacity-60 animate-pulse" />
|
|
139
|
-
<p className="text-sm text-text-3 font-sans">
|
|
162
|
+
<p className="text-sm text-text-3 font-sans">
|
|
163
|
+
{reconnecting ? 'Re-establishing connection…' : connected ? 'Loading…' : 'Connecting to daemon…'}
|
|
164
|
+
</p>
|
|
165
|
+
{slow && (
|
|
166
|
+
<div className="flex flex-col items-center gap-2 mt-1">
|
|
167
|
+
<p className="text-xs text-text-4 font-sans max-w-xs text-center">
|
|
168
|
+
Still trying to reach the daemon. If you just woke your machine, the connection is re-establishing.
|
|
169
|
+
</p>
|
|
170
|
+
<button
|
|
171
|
+
onClick={manualReconnect}
|
|
172
|
+
disabled={reconnecting}
|
|
173
|
+
className="px-3 py-1.5 rounded-md text-xs font-medium font-sans border border-accent/40 bg-accent/10 text-accent hover:bg-accent/20 disabled:opacity-50 transition-colors cursor-pointer"
|
|
174
|
+
>
|
|
175
|
+
{reconnecting ? 'Reconnecting…' : 'Reconnect'}
|
|
176
|
+
</button>
|
|
177
|
+
</div>
|
|
178
|
+
)}
|
|
140
179
|
</div>
|
|
141
180
|
);
|
|
142
181
|
}
|
|
@@ -776,8 +776,9 @@ export const useGrooveStore = create((set, get) => ({
|
|
|
776
776
|
}
|
|
777
777
|
|
|
778
778
|
case 'auth:expired':
|
|
779
|
+
// Marketplace/subscription token lapsed — reset to the community state
|
|
780
|
+
// silently. There is no sign-in flow to nag the user toward.
|
|
779
781
|
set({ marketplaceAuthenticated: false, marketplaceUser: null });
|
|
780
|
-
get().addToast('warning', 'Session expired', 'Please sign in again');
|
|
781
782
|
break;
|
|
782
783
|
|
|
783
784
|
case 'network:node:status': {
|
|
@@ -1146,3 +1147,16 @@ export const useGrooveStore = create((set, get) => ({
|
|
|
1146
1147
|
ws.onerror = () => ws.close();
|
|
1147
1148
|
},
|
|
1148
1149
|
}));
|
|
1150
|
+
|
|
1151
|
+
// Reconnect promptly when connectivity returns — laptop wake, network back, or
|
|
1152
|
+
// the window regaining focus — instead of waiting out the periodic 2s retry.
|
|
1153
|
+
// connect() no-ops if a socket already exists, so these are safe to fire often.
|
|
1154
|
+
if (typeof window !== 'undefined') {
|
|
1155
|
+
const kick = () => {
|
|
1156
|
+
const s = useGrooveStore.getState();
|
|
1157
|
+
if (!s.ws) s.connect();
|
|
1158
|
+
};
|
|
1159
|
+
window.addEventListener('online', kick);
|
|
1160
|
+
window.addEventListener('focus', kick);
|
|
1161
|
+
document.addEventListener('visibilitychange', () => { if (!document.hidden) kick(); });
|
|
1162
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groove-dev",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.190",
|
|
4
4
|
"description": "Open-source agent orchestration layer — the AI company OS. Local model agent engine (GGUF/Ollama/llama-server), HuggingFace model browser, 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, any local model.",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"author": "Groove Dev <hello@groovedev.ai> (https://groovedev.ai)",
|
|
@@ -491,7 +491,11 @@ export class Daemon {
|
|
|
491
491
|
signal: AbortSignal.timeout(10000),
|
|
492
492
|
});
|
|
493
493
|
if (resp.status === 401) {
|
|
494
|
+
// The stored marketplace token is invalid. Clear it and stop here so
|
|
495
|
+
// we don't re-poll a dead token every cycle and re-fire this forever.
|
|
494
496
|
this.subscriptionCache = { plan: 'community', status: 'none', features: [], active: false, validatedAt: Date.now() };
|
|
497
|
+
this.authToken = null;
|
|
498
|
+
try { await this.skills.clearAuth(); } catch { /* best effort */ }
|
|
495
499
|
this.broadcast({ type: 'subscription:updated', data: this.subscriptionCache });
|
|
496
500
|
this.broadcast({ type: 'auth:expired' });
|
|
497
501
|
return;
|