@woopsy/mcpanel 2.1.1 → 2.1.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.
@@ -0,0 +1,52 @@
1
+ <svg width="1200" height="320" viewBox="0 0 1200 320" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="MCPANEL - Terminal Minecraft Server Manager">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#0d1117"/>
5
+ <stop offset="1" stop-color="#10231a"/>
6
+ </linearGradient>
7
+ <linearGradient id="title" x1="0" y1="0" x2="1" y2="0">
8
+ <stop offset="0" stop-color="#5eead4"/>
9
+ <stop offset="0.5" stop-color="#34d399"/>
10
+ <stop offset="1" stop-color="#22c55e"/>
11
+ </linearGradient>
12
+ </defs>
13
+
14
+ <!-- backdrop -->
15
+ <rect width="1200" height="320" rx="18" fill="url(#bg)"/>
16
+ <rect x="1" y="1" width="1198" height="318" rx="17" fill="none" stroke="#1f6f4d" stroke-opacity="0.5"/>
17
+
18
+ <!-- terminal traffic lights -->
19
+ <circle cx="42" cy="40" r="8" fill="#ff5f56"/>
20
+ <circle cx="68" cy="40" r="8" fill="#ffbd2e"/>
21
+ <circle cx="94" cy="40" r="8" fill="#27c93f"/>
22
+ <text x="120" y="46" font-family="'JetBrains Mono','Fira Code',Consolas,monospace" font-size="16" fill="#7d8590">mcpanel — minecraft server manager</text>
23
+
24
+ <!-- creeper face accent -->
25
+ <g transform="translate(70,110)">
26
+ <rect width="150" height="150" rx="8" fill="#22c55e"/>
27
+ <rect width="150" height="150" rx="8" fill="#000000" opacity="0.08"/>
28
+ <rect x="28" y="36" width="34" height="34" fill="#0d1117"/>
29
+ <rect x="88" y="36" width="34" height="34" fill="#0d1117"/>
30
+ <rect x="58" y="74" width="34" height="40" fill="#0d1117"/>
31
+ <rect x="28" y="100" width="30" height="34" fill="#0d1117"/>
32
+ <rect x="92" y="100" width="30" height="34" fill="#0d1117"/>
33
+ </g>
34
+
35
+ <!-- title -->
36
+ <text x="270" y="170" font-family="'Segoe UI',Arial,sans-serif" font-size="96" font-weight="800" letter-spacing="6" fill="url(#title)">MCPANEL</text>
37
+ <text x="274" y="212" font-family="'JetBrains Mono','Fira Code',Consolas,monospace" font-size="24" fill="#9ca3af">Terminal Minecraft Server Manager</text>
38
+
39
+ <!-- prompt line -->
40
+ <text x="274" y="262" font-family="'JetBrains Mono','Fira Code',Consolas,monospace" font-size="22" fill="#34d399">mcpanel&gt; <tspan fill="#e5e7eb">/start</tspan> <tspan fill="#6b7280">·</tspan> <tspan fill="#e5e7eb">/log</tspan> <tspan fill="#6b7280">·</tspan> <tspan fill="#e5e7eb">/backup</tspan> <tspan fill="#6b7280">·</tspan> <tspan fill="#e5e7eb">/tunnel</tspan></text>
41
+
42
+ <!-- neofetch palette strip -->
43
+ <g transform="translate(274,286)">
44
+ <rect x="0" y="0" width="34" height="16" fill="#ef4444"/>
45
+ <rect x="34" y="0" width="34" height="16" fill="#eab308"/>
46
+ <rect x="68" y="0" width="34" height="16" fill="#22c55e"/>
47
+ <rect x="102" y="0" width="34" height="16" fill="#06b6d4"/>
48
+ <rect x="136" y="0" width="34" height="16" fill="#3b82f6"/>
49
+ <rect x="170" y="0" width="34" height="16" fill="#a855f7"/>
50
+ <rect x="204" y="0" width="34" height="16" fill="#e5e7eb"/>
51
+ </g>
52
+ </svg>
Binary file
Binary file
@@ -134,6 +134,10 @@ class TrayManager {
134
134
  systray = null;
135
135
  activeHandle = null;
136
136
  isInitialized = false;
137
+ // The tray runs a separate native helper over a stdin pipe. If that helper
138
+ // dies, writes to its pipe raise an async EPIPE. The tray is best-effort, so
139
+ // this flag lets us stop writing and degrade to CLI-only instead of crashing.
140
+ trayAlive = false;
137
141
  // Menu item state tracking
138
142
  itemShow = { title: 'Open Console', tooltip: 'Restore terminal window', enabled: true };
139
143
  itemHide = { title: 'Hide Console', tooltip: 'Hide terminal window from taskbar', enabled: true };
@@ -154,12 +158,22 @@ class TrayManager {
154
158
  if (this.isInitialized)
155
159
  return true;
156
160
  const osType = (0, helpers_1.detectOS)();
157
- const iconFile = osType === 'Windows' || osType === 'WSL'
161
+ const iconCandidate = osType === 'Windows' || osType === 'WSL'
158
162
  ? path.join(configManager_1.APP_ROOT, 'assets', 'logo.ico')
159
163
  : path.join(configManager_1.APP_ROOT, 'assets', 'logo.png');
164
+ // systray2 only base64-encodes the icon if the file exists; otherwise it
165
+ // ships the raw path, which the native helper can't decode and then exits.
166
+ // Omit a missing icon so the helper stays alive (CLI works without one).
167
+ const iconFile = fs.existsSync(iconCandidate) ? iconCandidate : undefined;
168
+ if (!iconFile) {
169
+ logger_1.logger.warn(`Tray icon not found at ${iconCandidate}; starting tray without an icon.`);
170
+ }
160
171
  try {
161
172
  this.systray = new WSLSysTray({
162
173
  menu: {
174
+ // May be undefined when the icon file is absent; systray2 tolerates
175
+ // this at runtime (it pathExists-checks before encoding) — the cast
176
+ // just satisfies the `Conf` type, which declares icon as required.
163
177
  icon: iconFile,
164
178
  title: 'MCPANEL',
165
179
  tooltip: 'MCPANEL Server Manager',
@@ -185,6 +199,8 @@ class TrayManager {
185
199
  });
186
200
  await this.systray.ready();
187
201
  this.isInitialized = true;
202
+ this.trayAlive = true;
203
+ this.attachTrayGuards();
188
204
  logger_1.logger.info('System tray initialized successfully.');
189
205
  this.updateMenu();
190
206
  return true;
@@ -196,12 +212,35 @@ class TrayManager {
196
212
  return false;
197
213
  }
198
214
  }
215
+ /**
216
+ * Attaches error/exit listeners to the native tray helper so a dead helper
217
+ * (e.g. EPIPE when writing to its closed stdin) degrades to CLI-only mode
218
+ * instead of throwing an unhandled 'error' event that crashes the process.
219
+ */
220
+ attachTrayGuards() {
221
+ const proc = this.systray?._process;
222
+ if (!proc)
223
+ return;
224
+ const onDead = (err) => {
225
+ if (this.trayAlive) {
226
+ const detail = err ? ` (${err.code || err.message})` : '';
227
+ logger_1.logger.warn(`System tray helper stopped; continuing in CLI-only mode.${detail}`);
228
+ }
229
+ this.trayAlive = false;
230
+ };
231
+ // The load-bearing handler: without an 'error' listener, an EPIPE on the
232
+ // helper's stdin is emitted as an unhandled 'error' event and crashes Node.
233
+ proc.stdin?.on('error', onDead);
234
+ proc.on('error', onDead);
235
+ proc.on('exit', () => onDead());
236
+ proc.on('close', () => onDead());
237
+ }
199
238
  /**
200
239
  * Dynamically updates the titles and states of the tray menu items
201
240
  */
202
241
  updateMenu() {
203
242
  const tray = this.systray;
204
- if (!tray || !this.isInitialized)
243
+ if (!tray || !this.isInitialized || !this.trayAlive)
205
244
  return;
206
245
  const server = this.configManager.getServer();
207
246
  const running = server ? !!this.processManager.getActiveServer(server.name) : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@woopsy/mcpanel",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "MCPANEL — a terminal-based, single-server Minecraft server manager with an Arch/neofetch-style UI, live logs, backups, plugins and Playit.gg tunnels.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "files": [
10
10
  "dist",
11
+ "assets",
11
12
  "README.md",
12
13
  "LICENSE"
13
14
  ],