groove-dev 0.12.0 → 0.12.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.
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { existsSync, writeFileSync, readFileSync } from 'fs';
5
5
  import { resolve } from 'path';
6
+ import { networkInterfaces } from 'os';
6
7
  import { listProviders } from './providers/index.js';
7
8
 
8
9
  const DEFAULT_CONFIG = {
@@ -53,32 +54,57 @@ export function printWelcome(port, host = '127.0.0.1') {
53
54
 
54
55
  console.log('');
55
56
  const isRemote = host !== '127.0.0.1';
56
- const isSSH = !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT);
57
+
58
+ // Detect headless/server environment: no graphical display available
59
+ // Works even through sudo (which strips SSH_* env vars)
60
+ const hasDisplay = !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
61
+ const isSSH = !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY);
62
+ const isHeadless = !hasDisplay && !process.env.TERM_PROGRAM;
63
+ const isServer = isSSH || isHeadless;
57
64
 
58
65
  if (isRemote) {
59
66
  // Bound to network interface (Tailscale/LAN)
60
67
  console.log(` GUI: http://${host}:${port}`);
61
68
  console.log(` Host: ${host} (network-accessible)`);
62
- } else if (isSSH) {
63
- // Running on a VPS via SSH print remote access instructions
64
- const sshUser = process.env.USER || 'user';
69
+ } else if (isServer) {
70
+ // VPS / headless serverdead simple instructions
71
+ const sshUser = process.env.SUDO_USER || process.env.USER || 'user';
72
+
73
+ // Get server IP: try SSH_CONNECTION first, fall back to network interfaces
74
+ let serverIp = '';
65
75
  const sshConn = process.env.SSH_CONNECTION || '';
66
- const serverIp = sshConn.split(' ')[2] || '<this-server-ip>';
76
+ if (sshConn) {
77
+ serverIp = sshConn.split(' ')[2] || '';
78
+ }
79
+ if (!serverIp) {
80
+ const nets = networkInterfaces();
81
+ for (const addrs of Object.values(nets)) {
82
+ for (const addr of addrs) {
83
+ if (addr.family === 'IPv4' && !addr.internal) {
84
+ serverIp = addr.address;
85
+ break;
86
+ }
87
+ }
88
+ if (serverIp) break;
89
+ }
90
+ }
91
+ serverIp = serverIp || '<your-server-ip>';
67
92
 
68
- console.log(` GUI: http://localhost:${port} (this server only)`);
93
+ console.log(` Daemon running on port ${port}`);
94
+ console.log('');
95
+ console.log(' To open the GUI, run this on your local machine:');
69
96
  console.log('');
70
- console.log(' ► Connect from your laptop:');
71
97
  console.log(` groove connect ${sshUser}@${serverIp}`);
72
98
  console.log('');
73
- console.log(' Or manually:');
74
- console.log(` ssh -L ${port + 1}:localhost:${port} ${sshUser}@${serverIp}`);
75
- console.log(` Then open http://localhost:${port + 1}`);
99
+ console.log(` Don't have groove locally? Install it first:`);
100
+ console.log(` npm i -g groove-dev`);
76
101
  } else {
77
- // Local machine
102
+ // Local machine with display
78
103
  console.log(` GUI: http://localhost:${port}`);
79
104
  }
80
105
 
81
- console.log(' Docs: https://docs.groovedev.ai');
106
+ console.log('');
107
+ console.log(' Docs: https://docs.groovedev.ai');
82
108
  console.log(' GitHub: https://github.com/grooveai-dev/groove');
83
109
  console.log('');
84
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groove-dev",
3
- "version": "0.12.0",
3
+ "version": "0.12.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)",
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { existsSync, writeFileSync, readFileSync } from 'fs';
5
5
  import { resolve } from 'path';
6
+ import { networkInterfaces } from 'os';
6
7
  import { listProviders } from './providers/index.js';
7
8
 
8
9
  const DEFAULT_CONFIG = {
@@ -53,32 +54,57 @@ export function printWelcome(port, host = '127.0.0.1') {
53
54
 
54
55
  console.log('');
55
56
  const isRemote = host !== '127.0.0.1';
56
- const isSSH = !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT);
57
+
58
+ // Detect headless/server environment: no graphical display available
59
+ // Works even through sudo (which strips SSH_* env vars)
60
+ const hasDisplay = !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
61
+ const isSSH = !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY);
62
+ const isHeadless = !hasDisplay && !process.env.TERM_PROGRAM;
63
+ const isServer = isSSH || isHeadless;
57
64
 
58
65
  if (isRemote) {
59
66
  // Bound to network interface (Tailscale/LAN)
60
67
  console.log(` GUI: http://${host}:${port}`);
61
68
  console.log(` Host: ${host} (network-accessible)`);
62
- } else if (isSSH) {
63
- // Running on a VPS via SSH print remote access instructions
64
- const sshUser = process.env.USER || 'user';
69
+ } else if (isServer) {
70
+ // VPS / headless serverdead simple instructions
71
+ const sshUser = process.env.SUDO_USER || process.env.USER || 'user';
72
+
73
+ // Get server IP: try SSH_CONNECTION first, fall back to network interfaces
74
+ let serverIp = '';
65
75
  const sshConn = process.env.SSH_CONNECTION || '';
66
- const serverIp = sshConn.split(' ')[2] || '<this-server-ip>';
76
+ if (sshConn) {
77
+ serverIp = sshConn.split(' ')[2] || '';
78
+ }
79
+ if (!serverIp) {
80
+ const nets = networkInterfaces();
81
+ for (const addrs of Object.values(nets)) {
82
+ for (const addr of addrs) {
83
+ if (addr.family === 'IPv4' && !addr.internal) {
84
+ serverIp = addr.address;
85
+ break;
86
+ }
87
+ }
88
+ if (serverIp) break;
89
+ }
90
+ }
91
+ serverIp = serverIp || '<your-server-ip>';
67
92
 
68
- console.log(` GUI: http://localhost:${port} (this server only)`);
93
+ console.log(` Daemon running on port ${port}`);
94
+ console.log('');
95
+ console.log(' To open the GUI, run this on your local machine:');
69
96
  console.log('');
70
- console.log(' ► Connect from your laptop:');
71
97
  console.log(` groove connect ${sshUser}@${serverIp}`);
72
98
  console.log('');
73
- console.log(' Or manually:');
74
- console.log(` ssh -L ${port + 1}:localhost:${port} ${sshUser}@${serverIp}`);
75
- console.log(` Then open http://localhost:${port + 1}`);
99
+ console.log(` Don't have groove locally? Install it first:`);
100
+ console.log(` npm i -g groove-dev`);
76
101
  } else {
77
- // Local machine
102
+ // Local machine with display
78
103
  console.log(` GUI: http://localhost:${port}`);
79
104
  }
80
105
 
81
- console.log(' Docs: https://docs.groovedev.ai');
106
+ console.log('');
107
+ console.log(' Docs: https://docs.groovedev.ai');
82
108
  console.log(' GitHub: https://github.com/grooveai-dev/groove');
83
109
  console.log('');
84
110
  }