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
|
-
|
|
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 (
|
|
63
|
-
//
|
|
64
|
-
const sshUser = process.env.USER || 'user';
|
|
69
|
+
} else if (isServer) {
|
|
70
|
+
// VPS / headless server — dead 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
|
-
|
|
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(`
|
|
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('
|
|
74
|
-
console.log(`
|
|
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('
|
|
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.
|
|
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
|
-
|
|
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 (
|
|
63
|
-
//
|
|
64
|
-
const sshUser = process.env.USER || 'user';
|
|
69
|
+
} else if (isServer) {
|
|
70
|
+
// VPS / headless server — dead 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
|
-
|
|
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(`
|
|
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('
|
|
74
|
-
console.log(`
|
|
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('
|
|
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
|
}
|