@drocketxx/pm2me 1.1.3 → 1.1.5
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.
- package/backend/services/systemService.js +3 -3
- package/bin/pm2me.js +37 -65
- package/package.json +1 -1
|
@@ -32,7 +32,7 @@ export const getSystemStats = async () => {
|
|
|
32
32
|
const promises = [];
|
|
33
33
|
|
|
34
34
|
// 1. CPU Usage (Every time)
|
|
35
|
-
const cpuPromise = execPromise('powershell -Command "(Get-Counter \'\\Processor(_Total)\\% Processor Time\' -ErrorAction SilentlyContinue).CounterSamples.CookedValue"')
|
|
35
|
+
const cpuPromise = execPromise('powershell -Command "(Get-Counter \'\\Processor(_Total)\\% Processor Time\' -ErrorAction SilentlyContinue).CounterSamples.CookedValue"', { windowsHide: true })
|
|
36
36
|
.then(({ stdout }) => {
|
|
37
37
|
const realCpu = parseFloat(stdout.trim());
|
|
38
38
|
if (!isNaN(realCpu)) cpuUsage = realCpu;
|
|
@@ -41,7 +41,7 @@ export const getSystemStats = async () => {
|
|
|
41
41
|
promises.push(cpuPromise);
|
|
42
42
|
|
|
43
43
|
// 2. Network Stats (Every time)
|
|
44
|
-
const netPromise = execPromise('powershell -Command "Get-NetAdapterStatistics | Select-Object ReceivedBytes, SentBytes | ConvertTo-Json"')
|
|
44
|
+
const netPromise = execPromise('powershell -Command "Get-NetAdapterStatistics | Select-Object ReceivedBytes, SentBytes | ConvertTo-Json"', { windowsHide: true })
|
|
45
45
|
.then(({ stdout }) => {
|
|
46
46
|
const netData = JSON.parse(stdout);
|
|
47
47
|
let totalRx = 0;
|
|
@@ -67,7 +67,7 @@ export const getSystemStats = async () => {
|
|
|
67
67
|
|
|
68
68
|
// 3. Disk Stats (Cached)
|
|
69
69
|
if (now - cachedDiskStats.lastFetch > DISK_CACHE_TTL) {
|
|
70
|
-
const diskPromise = execPromise('powershell -Command "Get-Volume -DriveLetter C | Select-Object Size, SizeRemaining | ConvertTo-Json"')
|
|
70
|
+
const diskPromise = execPromise('powershell -Command "Get-Volume -DriveLetter C | Select-Object Size, SizeRemaining | ConvertTo-Json"', { windowsHide: true })
|
|
71
71
|
.then(({ stdout }) => {
|
|
72
72
|
const data = JSON.parse(stdout);
|
|
73
73
|
if (data.Size > 0) {
|
package/bin/pm2me.js
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* pm2me — CLI entry point
|
|
4
|
-
* Usage:
|
|
5
|
-
* pm2me (Run in foreground)
|
|
6
|
-
* pm2me service install (Run in background via PM2 + set boot startup)
|
|
7
|
-
* pm2me service uninstall (Remove from PM2 background)
|
|
8
|
-
* pm2me service start (Start background service)
|
|
9
|
-
* pm2me service stop (Stop background service)
|
|
10
|
-
* pm2me service restart (Restart background service)
|
|
11
4
|
*/
|
|
12
5
|
import path from 'path';
|
|
13
6
|
import { fileURLToPath } from 'url';
|
|
@@ -19,13 +12,25 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
19
12
|
const pkgDir = path.resolve(__dirname, '..'); // root of the package
|
|
20
13
|
const backendDir = path.join(pkgDir, 'backend');
|
|
21
14
|
|
|
22
|
-
// ── Parse CLI args ────────────────────────────────────────────────────────────
|
|
23
15
|
const args = process.argv.slice(2);
|
|
16
|
+
const SERVICE_NAME = 'pm2me-server';
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Check if a PM2 process exists by name
|
|
20
|
+
*/
|
|
21
|
+
function processExists(name) {
|
|
22
|
+
try {
|
|
23
|
+
const output = execSync(`pm2 jlist`, { windowsHide: true }).toString();
|
|
24
|
+
const list = JSON.parse(output);
|
|
25
|
+
return list.some(p => p.name === name);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ── Service Commands ──────────────────────────────────────────────────────────
|
|
26
32
|
if (args[0] === 'service') {
|
|
27
33
|
const action = args[1];
|
|
28
|
-
const SERVICE_NAME = 'pm2me-server';
|
|
29
34
|
|
|
30
35
|
if (action === 'install') {
|
|
31
36
|
console.log('[pm2me] Installing background service...');
|
|
@@ -35,6 +40,12 @@ if (args[0] === 'service') {
|
|
|
35
40
|
const homeDir = path.join(os.homedir(), '.pm2me');
|
|
36
41
|
const dbPath = path.join(homeDir, 'database.json');
|
|
37
42
|
|
|
43
|
+
// Clean up existing service if it exists (allows updates)
|
|
44
|
+
if (processExists(SERVICE_NAME)) {
|
|
45
|
+
console.log(`[pm2me] Existing service found. Removing for clean update...`);
|
|
46
|
+
execSync(`pm2 delete ${SERVICE_NAME}`, { stdio: 'inherit', windowsHide: true });
|
|
47
|
+
}
|
|
48
|
+
|
|
38
49
|
console.log(`[pm2me] Starting via PM2 as '${SERVICE_NAME}'...`);
|
|
39
50
|
execSync(`pm2 start "${appPath}" --name ${SERVICE_NAME} --env PM2ME_DB_PATH="${dbPath}"`, { stdio: 'inherit', windowsHide: true });
|
|
40
51
|
|
|
@@ -42,62 +53,37 @@ if (args[0] === 'service') {
|
|
|
42
53
|
execSync(`pm2 save`, { stdio: 'inherit', windowsHide: true });
|
|
43
54
|
|
|
44
55
|
if (isWindows) {
|
|
45
|
-
console.log(`\n[pm2me] 💡 Windows Info:
|
|
46
|
-
console.log(`[pm2me] To make it start automatically on Windows restart
|
|
47
|
-
console.log(` npm install -g pm2-windows-startup`);
|
|
48
|
-
console.log(` pm2-startup install`);
|
|
56
|
+
console.log(`\n[pm2me] 💡 Windows Info: Service is now running silently.`);
|
|
57
|
+
console.log(`[pm2me] To make it start automatically on Windows restart:`);
|
|
58
|
+
console.log(` 1. npm install -g pm2-windows-startup`);
|
|
59
|
+
console.log(` 2. pm2-startup install`);
|
|
49
60
|
} else {
|
|
50
61
|
console.log(`[pm2me] Setting up boot startup...`);
|
|
51
62
|
try {
|
|
52
63
|
execSync(`pm2 startup`, { stdio: 'inherit', windowsHide: true });
|
|
53
|
-
|
|
54
|
-
} catch (e) {
|
|
55
|
-
console.log(`[pm2me] 'pm2 startup' might need manual execution. Check instructions above.`);
|
|
56
|
-
}
|
|
64
|
+
} catch (e) { }
|
|
57
65
|
}
|
|
58
|
-
|
|
59
|
-
console.log(`\n[pm2me] Service installed successfully. Access your UI at http://localhost:12345`);
|
|
66
|
+
console.log(`\n[pm2me] Service installed successfully. http://localhost:12345`);
|
|
60
67
|
process.exit(0);
|
|
61
68
|
} catch (err) {
|
|
62
69
|
console.error(`[pm2me] Failed to install service:`, err.message);
|
|
63
70
|
process.exit(1);
|
|
64
71
|
}
|
|
65
|
-
} else if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
execSync(`pm2 save`, { stdio: 'inherit', windowsHide: true });
|
|
70
|
-
console.log(`[pm2me] Service uninstalled successfully.`);
|
|
71
|
-
process.exit(0);
|
|
72
|
-
} catch (err) {
|
|
73
|
-
console.error(`[pm2me] Failed to uninstall service:`, err.message);
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
} else if (action === 'start') {
|
|
77
|
-
console.log(`[pm2me] Starting service '${SERVICE_NAME}'...`);
|
|
78
|
-
try {
|
|
79
|
-
execSync(`pm2 start ${SERVICE_NAME}`, { stdio: 'inherit', windowsHide: true });
|
|
80
|
-
process.exit(0);
|
|
81
|
-
} catch (err) {
|
|
82
|
-
console.error(`[pm2me] Failed to start service:`, err.message);
|
|
72
|
+
} else if (['start', 'stop', 'restart', 'uninstall'].includes(action)) {
|
|
73
|
+
if (!processExists(SERVICE_NAME)) {
|
|
74
|
+
console.error(`[pm2me] Error: Service '${SERVICE_NAME}' is not installed.`);
|
|
75
|
+
console.log(`[pm2me] Please run 'pm2me service install' first.`);
|
|
83
76
|
process.exit(1);
|
|
84
77
|
}
|
|
85
|
-
|
|
86
|
-
console.log(`[pm2me]
|
|
87
|
-
try {
|
|
88
|
-
execSync(`pm2 stop ${SERVICE_NAME}`, { stdio: 'inherit', windowsHide: true });
|
|
89
|
-
process.exit(0);
|
|
90
|
-
} catch (err) {
|
|
91
|
-
console.error(`[pm2me] Failed to stop service:`, err.message);
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
} else if (action === 'restart') {
|
|
95
|
-
console.log(`[pm2me] Restarting service '${SERVICE_NAME}'...`);
|
|
78
|
+
|
|
79
|
+
console.log(`[pm2me] ${action.charAt(0).toUpperCase() + action.slice(1)}ing service '${SERVICE_NAME}'...`);
|
|
96
80
|
try {
|
|
97
|
-
|
|
81
|
+
const cmd = action === 'uninstall' ? 'delete' : action;
|
|
82
|
+
execSync(`pm2 ${cmd} ${SERVICE_NAME}`, { stdio: 'inherit', windowsHide: true });
|
|
83
|
+
if (action === 'uninstall') execSync(`pm2 save`, { stdio: 'inherit', windowsHide: true });
|
|
98
84
|
process.exit(0);
|
|
99
85
|
} catch (err) {
|
|
100
|
-
console.error(`[pm2me] Failed to
|
|
86
|
+
console.error(`[pm2me] Failed to ${action} service:`, err.message);
|
|
101
87
|
process.exit(1);
|
|
102
88
|
}
|
|
103
89
|
} else {
|
|
@@ -110,16 +96,13 @@ if (args[0] === 'service') {
|
|
|
110
96
|
const portArg = args.indexOf('--port');
|
|
111
97
|
const PORT = portArg !== -1 ? args[portArg + 1] : (process.env.PORT || 12345);
|
|
112
98
|
|
|
113
|
-
// ── Ensure .pm2me home directory exists ───────────────────────────────────────
|
|
114
99
|
const homeDir = path.join(os.homedir(), '.pm2me');
|
|
115
100
|
const defaultAppsDir = path.join(homeDir, 'apps');
|
|
116
101
|
const dbPath = path.join(homeDir, 'database.json');
|
|
117
102
|
|
|
118
103
|
fs.mkdirSync(defaultAppsDir, { recursive: true });
|
|
119
104
|
|
|
120
|
-
// ── Ensure database.json exists (first run bootstrap) ────────────────────────
|
|
121
105
|
if (!fs.existsSync(dbPath)) {
|
|
122
|
-
// Write empty DB — backend will handle setup wizard redirect
|
|
123
106
|
fs.writeFileSync(dbPath, JSON.stringify({
|
|
124
107
|
apps: [],
|
|
125
108
|
settings: {
|
|
@@ -134,14 +117,9 @@ if (!fs.existsSync(dbPath)) {
|
|
|
134
117
|
admin: { passwordHash: '' },
|
|
135
118
|
setupComplete: false,
|
|
136
119
|
}, null, 2));
|
|
137
|
-
console.log('[pm2me] First run — database initialized at', dbPath);
|
|
138
|
-
console.log('[pm2me] Apps directory:', defaultAppsDir);
|
|
139
120
|
}
|
|
140
121
|
|
|
141
|
-
// ── Launch backend server ─────────────────────────────────────────────────────
|
|
142
122
|
console.log(`[pm2me] Starting server on http://localhost:${PORT}`);
|
|
143
|
-
console.log(`[pm2me] Using database: ${dbPath}`);
|
|
144
|
-
|
|
145
123
|
const server = spawn('node', ['app.js'], {
|
|
146
124
|
cwd: backendDir,
|
|
147
125
|
stdio: 'inherit',
|
|
@@ -153,16 +131,10 @@ const server = spawn('node', ['app.js'], {
|
|
|
153
131
|
},
|
|
154
132
|
});
|
|
155
133
|
|
|
156
|
-
server.on('error', (err) => {
|
|
157
|
-
console.error('[pm2me] Failed to start server:', err.message);
|
|
158
|
-
process.exit(1);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
134
|
server.on('close', (code) => {
|
|
162
135
|
process.exit(code ?? 0);
|
|
163
136
|
});
|
|
164
137
|
|
|
165
|
-
// Forward signals
|
|
166
138
|
for (const sig of ['SIGINT', 'SIGTERM']) {
|
|
167
139
|
process.on(sig, () => server.kill(sig));
|
|
168
140
|
}
|