groove-dev 0.27.123 → 0.27.124

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/cli",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
4
4
  "description": "GROOVE CLI — manage AI coding agents from your terminal",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/daemon",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -347,8 +347,36 @@ export class TunnelManager {
347
347
  failCount: 0,
348
348
  });
349
349
 
350
- const skipUpgrade = testResult.daemonRunning && testResult.remoteVersion && testResult.remoteVersion === getLocalVersion();
351
- if (!preConnectHandled && !skipUpgrade) {
350
+ // Verify the remote daemon is actually reachable through the tunnel.
351
+ // The cached test result (line 270) assumes daemonRunning=true based on
352
+ // lastConnected, but the daemon may have stopped since then.
353
+ let remoteAlive = false;
354
+ try {
355
+ const probe = await fetch(`http://localhost:${localPort}/api/health`, {
356
+ signal: AbortSignal.timeout(5000),
357
+ });
358
+ remoteAlive = probe.ok;
359
+ } catch { /* not reachable */ }
360
+
361
+ if (!remoteAlive && config.autoStart) {
362
+ this.daemon.broadcast({ type: 'tunnel.status', data: { id, step: 'starting' } });
363
+ await this.autoStart(id);
364
+ // Give the daemon a moment to accept connections through the tunnel
365
+ for (let i = 0; i < 5; i++) {
366
+ await new Promise(r => setTimeout(r, 1000));
367
+ try {
368
+ const retry = await fetch(`http://localhost:${localPort}/api/health`, {
369
+ signal: AbortSignal.timeout(3000),
370
+ });
371
+ if (retry.ok) { remoteAlive = true; break; }
372
+ } catch { /* retry */ }
373
+ }
374
+ } else if (!remoteAlive && !config.autoStart) {
375
+ this.daemon.broadcast({ type: 'tunnel.status', data: { id, step: 'waiting', message: 'Remote daemon not running. Start it manually or enable auto-start.' } });
376
+ }
377
+
378
+ const skipUpgrade = remoteAlive && testResult.remoteVersion && testResult.remoteVersion === getLocalVersion();
379
+ if (remoteAlive && !preConnectHandled && !skipUpgrade) {
352
380
  await this._checkAndUpgradeRunning(id, config, localPort);
353
381
  }
354
382
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/gui",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
4
4
  "description": "GROOVE GUI — visual agent control plane",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groove-dev",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
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)",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/cli",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
4
4
  "description": "GROOVE CLI — manage AI coding agents from your terminal",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/daemon",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -347,8 +347,36 @@ export class TunnelManager {
347
347
  failCount: 0,
348
348
  });
349
349
 
350
- const skipUpgrade = testResult.daemonRunning && testResult.remoteVersion && testResult.remoteVersion === getLocalVersion();
351
- if (!preConnectHandled && !skipUpgrade) {
350
+ // Verify the remote daemon is actually reachable through the tunnel.
351
+ // The cached test result (line 270) assumes daemonRunning=true based on
352
+ // lastConnected, but the daemon may have stopped since then.
353
+ let remoteAlive = false;
354
+ try {
355
+ const probe = await fetch(`http://localhost:${localPort}/api/health`, {
356
+ signal: AbortSignal.timeout(5000),
357
+ });
358
+ remoteAlive = probe.ok;
359
+ } catch { /* not reachable */ }
360
+
361
+ if (!remoteAlive && config.autoStart) {
362
+ this.daemon.broadcast({ type: 'tunnel.status', data: { id, step: 'starting' } });
363
+ await this.autoStart(id);
364
+ // Give the daemon a moment to accept connections through the tunnel
365
+ for (let i = 0; i < 5; i++) {
366
+ await new Promise(r => setTimeout(r, 1000));
367
+ try {
368
+ const retry = await fetch(`http://localhost:${localPort}/api/health`, {
369
+ signal: AbortSignal.timeout(3000),
370
+ });
371
+ if (retry.ok) { remoteAlive = true; break; }
372
+ } catch { /* retry */ }
373
+ }
374
+ } else if (!remoteAlive && !config.autoStart) {
375
+ this.daemon.broadcast({ type: 'tunnel.status', data: { id, step: 'waiting', message: 'Remote daemon not running. Start it manually or enable auto-start.' } });
376
+ }
377
+
378
+ const skipUpgrade = remoteAlive && testResult.remoteVersion && testResult.remoteVersion === getLocalVersion();
379
+ if (remoteAlive && !preConnectHandled && !skipUpgrade) {
352
380
  await this._checkAndUpgradeRunning(id, config, localPort);
353
381
  }
354
382
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/gui",
3
- "version": "0.27.123",
3
+ "version": "0.27.124",
4
4
  "description": "GROOVE GUI — visual agent control plane",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",