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.
@@ -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-fyGUwOq4.js"></script>
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/gui",
3
- "version": "0.27.188",
3
+ "version": "0.27.190",
4
4
  "description": "GROOVE GUI — visual agent control plane",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -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">Connecting...</p>
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
+ }