groove-dev 0.8.1 → 0.8.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/cli",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
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.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -1,7 +1,8 @@
1
1
  // GROOVE Daemon — Entry Point
2
2
  // FSL-1.1-Apache-2.0 — see LICENSE
3
3
 
4
- import { createServer } from 'http';
4
+ import { createServer as createHttpServer } from 'http';
5
+ import { createServer as createNetServer } from 'net';
5
6
  import { resolve } from 'path';
6
7
  import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync } from 'fs';
7
8
  import express from 'express';
@@ -71,7 +72,7 @@ export class Daemon {
71
72
 
72
73
  // HTTP + WebSocket server
73
74
  this.app = express();
74
- this.server = createServer(this.app);
75
+ this.server = createHttpServer(this.app);
75
76
  this.wss = new WebSocketServer({
76
77
  server: this.server,
77
78
  maxPayload: 1024 * 1024, // 1MB max message
@@ -123,17 +124,35 @@ export class Daemon {
123
124
  }
124
125
 
125
126
  async start() {
126
- // Check for existing daemon
127
+ // Kill any existing daemon on our port
127
128
  if (existsSync(this.pidFile)) {
128
129
  const existingPid = parseInt(readFileSync(this.pidFile, 'utf8'), 10);
129
130
  try {
130
131
  process.kill(existingPid, 0); // Signal 0 = check if alive
131
- console.error(`GROOVE daemon already running (PID ${existingPid})`);
132
- process.exit(1);
132
+ console.log(` Stopping previous daemon (PID ${existingPid})...`);
133
+ process.kill(existingPid, 'SIGTERM');
134
+ // Wait briefly for clean shutdown
135
+ await new Promise((r) => setTimeout(r, 1000));
136
+ try { process.kill(existingPid, 'SIGKILL'); } catch { /* already dead */ }
133
137
  } catch {
134
- // PID file is stale — previous daemon crashed
135
- unlinkSync(this.pidFile);
138
+ // PID file is stale
136
139
  }
140
+ try { unlinkSync(this.pidFile); } catch { /* ignore */ }
141
+ }
142
+
143
+ // Check if port is in use by something else
144
+ const portFree = await new Promise((res) => {
145
+ const tester = createNetServer();
146
+ tester.once('error', () => res(false));
147
+ tester.once('listening', () => { tester.close(); res(true); });
148
+ tester.listen(this.port, '127.0.0.1');
149
+ }).catch(() => false);
150
+
151
+ if (!portFree) {
152
+ console.error(`\n Port ${this.port} is in use by another application.`);
153
+ console.error(` Try a different port: groove start --port 31416`);
154
+ console.error(` Or stop whatever is using port ${this.port}\n`);
155
+ process.exit(1);
137
156
  }
138
157
 
139
158
  // Restore persisted state