@drocketxx/pm2me 1.1.4 → 1.1.6

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.
@@ -59,7 +59,7 @@ router.get('/pm2/version-check', async (req, res) => {
59
59
  // Get latest version from npm registry
60
60
  let latestVersion = null;
61
61
  try {
62
- const { stdout } = await execAsync('npm view pm2 version');
62
+ const { stdout } = await execAsync('npm view pm2 version', { windowsHide: true });
63
63
  latestVersion = stdout.trim();
64
64
  } catch {
65
65
  latestVersion = null;
@@ -78,7 +78,7 @@ router.get('/pm2/version-check', async (req, res) => {
78
78
  router.post('/pm2/install-update', async (req, res) => {
79
79
  try {
80
80
  res.writeHead(200, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked' });
81
- const child = exec('npm install -g pm2@latest');
81
+ const child = exec('npm install -g pm2@latest', { windowsHide: true });
82
82
  child.stdout.on('data', (d) => res.write(d));
83
83
  child.stderr.on('data', (d) => res.write(d));
84
84
  child.on('close', (code) => {
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
- // ── Handle Service Commands ───────────────────────────────────────────────────
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: '${SERVICE_NAME}' is now running in the background.`);
46
- console.log(`[pm2me] To make it start automatically on Windows restart, we recommend using 'pm2-windows-startup':`);
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
- console.log(`[pm2me] Done! If you see a command above, please copy and run it to finalize startup.`);
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 (action === 'uninstall') {
66
- console.log('[pm2me] Uninstalling background service...');
67
- try {
68
- execSync(`pm2 delete ${SERVICE_NAME}`, { stdio: 'inherit', windowsHide: true });
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
- } else if (action === 'stop') {
86
- console.log(`[pm2me] Stopping service '${SERVICE_NAME}'...`);
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
- execSync(`pm2 restart ${SERVICE_NAME}`, { stdio: 'inherit', windowsHide: true });
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 restart service:`, err.message);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drocketxx/pm2me",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "PM2 Deployment and Management System — Web UI for PM2 process management",
5
5
  "type": "module",
6
6
  "main": "backend/app.js",