nterminal 1.2.16 → 1.2.17

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.
@@ -12,7 +12,7 @@
12
12
  <link rel="icon" type="image/png" sizes="64x64" href="/icons/favicon-64.png" />
13
13
  <link rel="icon" type="image/png" sizes="96x96" href="/icons/favicon-96.png" />
14
14
  <title>NTerminal</title>
15
- <script type="module" crossorigin src="/assets/index-2oIP_yU8.js"></script>
15
+ <script type="module" crossorigin src="/assets/index-CzfRb88C.js"></script>
16
16
  <link rel="stylesheet" crossorigin href="/assets/index-B3-WG4Tf.css">
17
17
  </head>
18
18
  <body>
@@ -101,7 +101,7 @@ export function getVersionInfo(cwd = appDir(), manualUpdate = null) {
101
101
  export function checkPackageUpdate(cwd = appDir()) {
102
102
  const currentVersion = runningPackageVersion(cwd);
103
103
  const packageName = readPackageName(cwd);
104
- const latest = npm(['view', `${packageName}@latest`, 'version'], cwd);
104
+ const latest = npm(['view', `${packageName}@latest`, 'version', '--prefer-online'], cwd);
105
105
  if (!latest.ok) {
106
106
  return {
107
107
  currentVersion,
@@ -134,7 +134,7 @@ export function runUpdate(cwd = appDir()) {
134
134
  const packageName = readPackageName(cwd);
135
135
  const installedVersion = readPackageVersion(cwd);
136
136
  if (!check.latestVersion || installedVersion !== check.latestVersion) {
137
- const install = npm(['install', '-g', `${packageName}@latest`], cwd, packageUpdateTimeoutMs);
137
+ const install = npm(['install', '-g', `${packageName}@latest`, '--prefer-online'], cwd, packageUpdateTimeoutMs);
138
138
  if (!install.ok) {
139
139
  releaseUpdateLock(cwd);
140
140
  const output = install.stderr || install.stdout || 'npm install -g failed';
@@ -1 +1 @@
1
- {"version":3,"file":"packageUpdate.js","sourceRoot":"","sources":["../../../src/server/update/packageUpdate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"packageUpdate.js","sourceRoot":"","sources":["../../../src/server/update/packageUpdate.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ export function createManualUpdateInfo(packageName = 'nterminal', detectedAt = n
3
3
  return {
4
4
  reason: 'permission',
5
5
  message: manualUpdateMessage,
6
- command: `sudo npm i -g ${packageName}@latest && nterminal restart`,
6
+ command: `sudo npm i -g ${packageName}@latest --prefer-online && nterminal restart`,
7
7
  detectedAt: detectedAt.toISOString()
8
8
  };
9
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manualUpdate.js","sourceRoot":"","sources":["../../src/shared/manualUpdate.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAC9B,8GAA8G,CAAC;AAEjH,MAAM,UAAU,sBAAsB,CAAC,WAAW,GAAG,WAAW,EAAE,UAAU,GAAG,IAAI,IAAI,EAAE;IACvF,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,mBAAmB;QAC5B,OAAO,EAAE,iBAAiB,WAAW,8BAA8B;QACnE,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,OAAO,qKAAqK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5L,CAAC"}
1
+ {"version":3,"file":"manualUpdate.js","sourceRoot":"","sources":["../../src/shared/manualUpdate.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAC9B,8GAA8G,CAAC;AAEjH,MAAM,UAAU,sBAAsB,CAAC,WAAW,GAAG,WAAW,EAAE,UAAU,GAAG,IAAI,IAAI,EAAE;IACvF,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,mBAAmB;QAC5B,OAAO,EAAE,iBAAiB,WAAW,8CAA8C;QACnF,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,OAAO,qKAAqK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5L,CAAC"}
@@ -38,6 +38,7 @@ Onboarding writes `.env` for you, including an absolute `NTERMINAL_STATE_PATH` s
38
38
  | `NTERMINAL_FILE_TEXT_MAX_BYTES` | `1048576` | Maximum bytes loaded for text or Markdown view/edit. |
39
39
  | `NTERMINAL_FILE_PREVIEW_MAX_BYTES` | `52428800` | Maximum bytes served for browser file previews. |
40
40
  | `NTERMINAL_PID_PATH` | `~/.nterminal/nterminal.pid` | PID file for the control script. |
41
+ | `NTERMINAL_MONITOR_PID_PATH` | `~/.nterminal/nterminal.monitor.pid` | PID file for the lightweight restart supervisor. |
41
42
  | `NTERMINAL_LOG_PATH` | `~/.nterminal/nterminal.log` | Log file for the control script. |
42
43
  | `NTERMINAL_HEALTH_TIMEOUT_SECONDS` | `15` | Startup health-check timeout for the control script. |
43
44
  | `NTERMINAL_STOP_TIMEOUT_SECONDS` | `20` | Graceful stop timeout for the control script. |
@@ -7,7 +7,7 @@ npm install -g nterminal
7
7
  nterminal onboarding
8
8
  ```
9
9
 
10
- NTerminal stores `.env`, state, pid, and log files under `~/.nterminal`. Install with a user-writable npm global prefix so in-app updates can run `npm install -g nterminal@latest` without sudo.
10
+ NTerminal stores `.env`, state, pid, and log files under `~/.nterminal`. Install with a user-writable npm global prefix so in-app updates can run `npm install -g nterminal@latest --prefer-online` without sudo.
11
11
 
12
12
  ## Main Server
13
13
 
@@ -13,7 +13,7 @@ nterminal restart
13
13
  nterminal stop
14
14
  ```
15
15
 
16
- The script starts the built server in the background, writes a PID file, appends logs, waits for the local health endpoint, and stops the real Node PID so PTY cleanup can run.
16
+ The script starts a lightweight supervisor in the background. The supervisor runs the built server, writes PID files, appends logs, waits for the local health endpoint, and restarts the Node process if it exits unexpectedly. `nterminal stop` stops both the supervisor and the real Node PID so PTY cleanup can run.
17
17
 
18
18
  Runtime files are kept under `~/.nterminal`.
19
19
 
@@ -34,7 +34,7 @@ Each server updates itself as an npm package install.
34
34
  The **updates** panel in the main server sidebar footer can manage the fleet:
35
35
 
36
36
  - **Check for updates** checks the npm registry.
37
- - **Update** runs `npm install -g nterminal@latest` plus restart.
37
+ - **Update** runs `npm install -g nterminal@latest --prefer-online` plus restart.
38
38
  - **Update all** updates secondary servers in parallel first and the main server last.
39
39
 
40
40
  Notes:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nterminal",
3
- "version": "1.2.16",
3
+ "version": "1.2.17",
4
4
  "license": "GPL-3.0-only",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.7",
@@ -68,6 +68,7 @@ load_env_file
68
68
 
69
69
  DEFAULT_STATE_PATH="$DEFAULT_RUNTIME_DIR/state.json"
70
70
  DEFAULT_PID_PATH="$DEFAULT_RUNTIME_DIR/nterminal.pid"
71
+ DEFAULT_MONITOR_PID_PATH="$DEFAULT_RUNTIME_DIR/nterminal.monitor.pid"
71
72
  DEFAULT_LOG_PATH="$DEFAULT_RUNTIME_DIR/nterminal.log"
72
73
 
73
74
  HOST="${NTERMINAL_HOST:-127.0.0.1}"
@@ -75,6 +76,7 @@ PORT="${NTERMINAL_PORT:-3107}"
75
76
  NODE_BIN="${NTERMINAL_NODE_BIN:-node}"
76
77
  NPM_BIN="${NTERMINAL_NPM_BIN:-npm}"
77
78
  PID_PATH="$(resolve_path "${NTERMINAL_PID_PATH:-${NTERMINAL_RUNTIME_PID_PATH:-$DEFAULT_PID_PATH}}")"
79
+ MONITOR_PID_PATH="$(resolve_path "${NTERMINAL_MONITOR_PID_PATH:-${NTERMINAL_RUNTIME_MONITOR_PID_PATH:-$DEFAULT_MONITOR_PID_PATH}}")"
78
80
  LOG_PATH="$(resolve_path "${NTERMINAL_LOG_PATH:-${NTERMINAL_RUNTIME_LOG_PATH:-$DEFAULT_LOG_PATH}}")"
79
81
  STATE_PATH="$(resolve_path "${NTERMINAL_STATE_PATH:-${NTERMINAL_RUNTIME_STATE_PATH:-$DEFAULT_STATE_PATH}}")"
80
82
  HEALTH_TIMEOUT_SECONDS="${NTERMINAL_HEALTH_TIMEOUT_SECONDS:-15}"
@@ -100,6 +102,7 @@ export NTERMINAL_APP_DIR="$APP_DIR"
100
102
  export NTERMINAL_ENV_FILE="$ENV_FILE"
101
103
  export NTERMINAL_STATE_PATH="$STATE_PATH"
102
104
  export NTERMINAL_PID_PATH="$PID_PATH"
105
+ export NTERMINAL_MONITOR_PID_PATH="$MONITOR_PID_PATH"
103
106
  export NTERMINAL_LOG_PATH="$LOG_PATH"
104
107
 
105
108
  health_url() {
@@ -130,7 +133,7 @@ ensure_runtime() {
130
133
  }
131
134
 
132
135
  ensure_directories() {
133
- mkdir -p "$(dirname "$PID_PATH")" "$(dirname "$LOG_PATH")"
136
+ mkdir -p "$(dirname "$PID_PATH")" "$(dirname "$MONITOR_PID_PATH")" "$(dirname "$LOG_PATH")"
134
137
  : >> "$LOG_PATH"
135
138
  chmod 600 "$LOG_PATH" 2>/dev/null || true
136
139
  }
@@ -152,6 +155,11 @@ read_pid() {
152
155
  read_pid_file "$PID_PATH"
153
156
  }
154
157
 
158
+ read_monitor_pid() {
159
+ [[ -f "$MONITOR_PID_PATH" ]] || return 1
160
+ read_pid_file "$MONITOR_PID_PATH"
161
+ }
162
+
155
163
  read_pid_file() {
156
164
  local pid_path="$1"
157
165
  [[ -f "$pid_path" ]] || return 1
@@ -166,6 +174,19 @@ is_running() {
166
174
  kill -0 "$pid" 2>/dev/null
167
175
  }
168
176
 
177
+ parent_pid() {
178
+ local pid="$1"
179
+ if [[ -r "/proc/$pid/status" ]]; then
180
+ awk '/^PPid:/ { print $2; exit }' "/proc/$pid/status" 2>/dev/null
181
+ return
182
+ fi
183
+ if command -v ps >/dev/null 2>&1; then
184
+ ps -o ppid= -p "$pid" 2>/dev/null | tr -d '[:space:]'
185
+ return
186
+ fi
187
+ return 1
188
+ }
189
+
169
190
  pid_controls_app() {
170
191
  local pid="$1"
171
192
  is_running "$pid" || return 1
@@ -193,6 +214,26 @@ pid_controls_app() {
193
214
  return 1
194
215
  }
195
216
 
217
+ monitor_controls_app() {
218
+ local pid="$1"
219
+ is_running "$pid" || return 1
220
+
221
+ local cmdline=""
222
+ if [[ -r "/proc/$pid/cmdline" ]]; then
223
+ cmdline="$(tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null || true)"
224
+ [[ "$cmdline" == *"$SCRIPT_DIR/nterminalctl"* && "$cmdline" == *" supervise"* ]]
225
+ return
226
+ fi
227
+
228
+ if command -v ps >/dev/null 2>&1; then
229
+ cmdline="$(ps -p "$pid" -o command= 2>/dev/null || true)"
230
+ [[ "$cmdline" == *"$SCRIPT_DIR/nterminalctl"* && "$cmdline" == *" supervise"* ]]
231
+ return
232
+ fi
233
+
234
+ return 1
235
+ }
236
+
196
237
  current_pid() {
197
238
  local pid
198
239
  pid="$(read_pid || true)"
@@ -200,6 +241,35 @@ current_pid() {
200
241
  printf '%s' "$pid"
201
242
  return 0
202
243
  fi
244
+
245
+ # npm can replace the package directory while the old Node process is still
246
+ # listening. If the pid file is missing, recover by recognizing the port owner
247
+ # as this package runtime before deciding the app is stopped.
248
+ pid="$(port_owner_pid || true)"
249
+ if [[ -n "$pid" && "$(pid_controls_app "$pid" && echo yes || echo no)" == yes ]]; then
250
+ printf '%s' "$pid"
251
+ return 0
252
+ fi
253
+ return 1
254
+ }
255
+
256
+ current_monitor_pid() {
257
+ local pid
258
+ pid="$(read_monitor_pid || true)"
259
+ if [[ -n "$pid" && "$(monitor_controls_app "$pid" && echo yes || echo no)" == yes ]]; then
260
+ printf '%s' "$pid"
261
+ return 0
262
+ fi
263
+
264
+ local child_pid parent
265
+ child_pid="$(current_pid || true)"
266
+ if [[ -n "$child_pid" ]]; then
267
+ parent="$(parent_pid "$child_pid" || true)"
268
+ if [[ -n "$parent" && "$(monitor_controls_app "$parent" && echo yes || echo no)" == yes ]]; then
269
+ printf '%s' "$parent"
270
+ return 0
271
+ fi
272
+ fi
203
273
  return 1
204
274
  }
205
275
 
@@ -258,6 +328,14 @@ remove_stale_pid() {
258
328
  fi
259
329
  }
260
330
 
331
+ remove_stale_monitor_pid() {
332
+ local pid
333
+ pid="$(read_monitor_pid || true)"
334
+ if [[ -n "$pid" && ! "$(monitor_controls_app "$pid" && echo yes || echo no)" == yes ]]; then
335
+ rm -f "$MONITOR_PID_PATH"
336
+ fi
337
+ }
338
+
261
339
  node_health_check() {
262
340
  "$NODE_BIN" -e '
263
341
  const http = require("node:http");
@@ -272,15 +350,90 @@ request.on("error", () => process.exit(1));
272
350
  }
273
351
 
274
352
  start_daemon() {
275
- cd "$APP_DIR"
276
353
  if command -v setsid >/dev/null 2>&1; then
277
- nohup setsid "$NODE_BIN" "$RUNTIME_ENTRY" >> "$LOG_PATH" 2>&1 &
354
+ nohup setsid bash "$SCRIPT_DIR/nterminalctl" supervise >> "$LOG_PATH" 2>&1 &
278
355
  else
279
- nohup "$NODE_BIN" "$RUNTIME_ENTRY" >> "$LOG_PATH" 2>&1 &
356
+ nohup bash "$SCRIPT_DIR/nterminalctl" supervise >> "$LOG_PATH" 2>&1 &
280
357
  fi
281
- local pid="$!"
282
- disown "$pid" 2>/dev/null || true
283
- echo "$pid" > "$PID_PATH"
358
+ local monitor_pid="$!"
359
+ disown "$monitor_pid" 2>/dev/null || true
360
+ echo "$monitor_pid" > "$MONITOR_PID_PATH"
361
+ chmod 600 "$MONITOR_PID_PATH" 2>/dev/null || true
362
+
363
+ local pid=""
364
+ local deadline=$((SECONDS + HEALTH_TIMEOUT_SECONDS))
365
+ while (( SECONDS <= deadline )); do
366
+ if ! is_running "$monitor_pid"; then
367
+ return 1
368
+ fi
369
+ pid="$(current_pid || true)"
370
+ [[ -n "$pid" ]] && return 0
371
+ sleep 0.25
372
+ done
373
+ return 1
374
+ }
375
+
376
+ stop_supervised_child() {
377
+ local pid="$1"
378
+ [[ -n "$pid" ]] || return 0
379
+ if ! is_running "$pid"; then
380
+ rm -f "$PID_PATH"
381
+ return 0
382
+ fi
383
+ kill -TERM "$pid" 2>/dev/null || true
384
+ local deadline=$((SECONDS + STOP_TIMEOUT_SECONDS))
385
+ while (( SECONDS <= deadline )); do
386
+ if ! is_running "$pid"; then
387
+ rm -f "$PID_PATH"
388
+ return 0
389
+ fi
390
+ sleep 0.25
391
+ done
392
+ kill -KILL "$pid" 2>/dev/null || true
393
+ rm -f "$PID_PATH"
394
+ }
395
+
396
+ cmd_supervise() {
397
+ ensure_app_dir
398
+ ensure_env_file
399
+ ensure_runtime
400
+ validate_required_env || die "generate real secrets before starting"
401
+ ensure_directories
402
+ echo "$$" > "$MONITOR_PID_PATH"
403
+ chmod 600 "$MONITOR_PID_PATH" 2>/dev/null || true
404
+
405
+ local child_pid=""
406
+ local stop_requested=0
407
+ supervisor_shutdown() {
408
+ stop_requested=1
409
+ trap - TERM INT
410
+ stop_supervised_child "$child_pid"
411
+ rm -f "$MONITOR_PID_PATH"
412
+ exit 0
413
+ }
414
+ trap supervisor_shutdown TERM INT
415
+
416
+ while true; do
417
+ cd "$APP_DIR"
418
+ "$NODE_BIN" "$RUNTIME_ENTRY" >> "$LOG_PATH" 2>&1 &
419
+ child_pid="$!"
420
+ echo "$child_pid" > "$PID_PATH"
421
+ chmod 600 "$PID_PATH" 2>/dev/null || true
422
+
423
+ set +e
424
+ wait "$child_pid"
425
+ local status="$?"
426
+ set -e
427
+
428
+ rm -f "$PID_PATH"
429
+ if (( stop_requested == 1 )); then
430
+ rm -f "$MONITOR_PID_PATH"
431
+ exit 0
432
+ fi
433
+
434
+ printf '[%s] NTerminal process exited status=%s; restarting in 2s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$status" >> "$LOG_PATH"
435
+ sleep 2
436
+ done
284
437
  }
285
438
 
286
439
  start_launchd() {
@@ -320,8 +473,15 @@ wait_for_health() {
320
473
  }
321
474
 
322
475
  port_owner_pid() {
323
- command -v lsof >/dev/null 2>&1 || return 1
324
- lsof -nP -iTCP:"$PORT" -sTCP:LISTEN -t 2>/dev/null | head -n 1
476
+ if command -v lsof >/dev/null 2>&1; then
477
+ lsof -nP -iTCP:"$PORT" -sTCP:LISTEN -t 2>/dev/null | head -n 1
478
+ return
479
+ fi
480
+ if command -v ss >/dev/null 2>&1; then
481
+ ss -ltnp "sport = :$PORT" 2>/dev/null | sed -n 's/.*pid=\([0-9]\+\).*/\1/p' | head -n 1
482
+ return
483
+ fi
484
+ return 1
325
485
  }
326
486
 
327
487
  assert_port_available() {
@@ -336,12 +496,19 @@ assert_port_available() {
336
496
 
337
497
  cmd_status() {
338
498
  remove_stale_pid
499
+ remove_stale_monitor_pid
339
500
  local pid
340
501
  pid="$(current_pid || true)"
341
502
  if [[ -n "$pid" ]]; then
342
503
  info "NTerminal running pid=$pid url=$(public_url) log=$LOG_PATH"
343
504
  return 0
344
505
  fi
506
+ local monitor_pid
507
+ monitor_pid="$(current_monitor_pid || true)"
508
+ if [[ -n "$monitor_pid" ]]; then
509
+ info "NTerminal supervisor running pid=$monitor_pid; server is restarting url=$(public_url) log=$LOG_PATH"
510
+ return 4
511
+ fi
345
512
  info "NTerminal stopped pid_file=$PID_PATH"
346
513
  return 3
347
514
  }
@@ -353,6 +520,7 @@ cmd_start() {
353
520
  validate_required_env || die "generate real secrets before starting"
354
521
  ensure_directories
355
522
  remove_stale_pid
523
+ remove_stale_monitor_pid
356
524
 
357
525
  local pid
358
526
  pid="$(current_pid || true)"
@@ -360,6 +528,12 @@ cmd_start() {
360
528
  info "NTerminal already running pid=$pid url=$(public_url)"
361
529
  return 0
362
530
  fi
531
+ local monitor_pid
532
+ monitor_pid="$(current_monitor_pid || true)"
533
+ if [[ -n "$monitor_pid" ]]; then
534
+ info "NTerminal supervisor already running pid=$monitor_pid url=$(public_url)"
535
+ return 0
536
+ fi
363
537
 
364
538
  if launchd_controls_app; then
365
539
  start_launchd
@@ -367,12 +541,28 @@ cmd_start() {
367
541
  fi
368
542
 
369
543
  assert_port_available
370
- start_daemon
544
+ if ! start_daemon; then
545
+ rm -f "$MONITOR_PID_PATH"
546
+ echo "NTerminal failed to start supervisor. Last log lines:" >&2
547
+ tail -n 40 "$LOG_PATH" >&2 || true
548
+ return 1
549
+ fi
371
550
  chmod 600 "$PID_PATH" 2>/dev/null || true
372
- pid="$(read_pid)"
551
+ pid="$(current_pid || true)"
552
+ if [[ -z "$pid" ]]; then
553
+ rm -f "$MONITOR_PID_PATH"
554
+ echo "NTerminal failed to start supervisor. Last log lines:" >&2
555
+ tail -n 40 "$LOG_PATH" >&2 || true
556
+ return 1
557
+ fi
373
558
 
374
559
  if wait_for_health "$pid"; then
375
- info "NTerminal started pid=$pid url=$(public_url) log=$LOG_PATH"
560
+ monitor_pid="$(current_monitor_pid || true)"
561
+ if [[ -n "$monitor_pid" ]]; then
562
+ info "NTerminal started pid=$pid supervisor=$monitor_pid url=$(public_url) log=$LOG_PATH"
563
+ else
564
+ info "NTerminal started pid=$pid url=$(public_url) log=$LOG_PATH"
565
+ fi
376
566
  return 0
377
567
  fi
378
568
 
@@ -380,7 +570,11 @@ cmd_start() {
380
570
  if ! is_running "$pid"; then
381
571
  exit_hint="process exited during startup"
382
572
  fi
383
- rm -f "$PID_PATH"
573
+ monitor_pid="$(current_monitor_pid || true)"
574
+ if [[ -n "$monitor_pid" ]]; then
575
+ kill -TERM "$monitor_pid" 2>/dev/null || true
576
+ fi
577
+ rm -f "$PID_PATH" "$MONITOR_PID_PATH"
384
578
  echo "NTerminal $exit_hint. Last log lines:" >&2
385
579
  tail -n 40 "$LOG_PATH" >&2 || true
386
580
  return 1
@@ -388,13 +582,44 @@ cmd_start() {
388
582
 
389
583
  cmd_stop() {
390
584
  remove_stale_pid
585
+ remove_stale_monitor_pid
391
586
  local pid
392
587
  pid="$(current_pid || true)"
393
- if [[ -z "$pid" ]]; then
588
+ local monitor_pid
589
+ monitor_pid="$(current_monitor_pid || true)"
590
+ if [[ -z "$pid" && -z "$monitor_pid" ]]; then
394
591
  info "NTerminal already stopped"
395
592
  return 0
396
593
  fi
397
594
 
595
+ if [[ -n "$monitor_pid" ]]; then
596
+ kill -TERM "$monitor_pid" 2>/dev/null || true
597
+ local monitor_deadline=$((SECONDS + STOP_TIMEOUT_SECONDS))
598
+ while (( SECONDS <= monitor_deadline )); do
599
+ if ! is_running "$monitor_pid"; then
600
+ rm -f "$MONITOR_PID_PATH"
601
+ break
602
+ fi
603
+ sleep 0.25
604
+ done
605
+ if is_running "$monitor_pid"; then
606
+ kill -KILL "$monitor_pid" 2>/dev/null || true
607
+ rm -f "$MONITOR_PID_PATH"
608
+ fi
609
+
610
+ if [[ -n "$pid" && "$(is_running "$pid" && echo yes || echo no)" == yes ]]; then
611
+ stop_supervised_child "$pid"
612
+ fi
613
+
614
+ rm -f "$PID_PATH" "$MONITOR_PID_PATH"
615
+ if [[ -n "$pid" ]]; then
616
+ info "NTerminal stopped pid=$pid supervisor=$monitor_pid"
617
+ else
618
+ info "NTerminal stopped supervisor=$monitor_pid"
619
+ fi
620
+ return 0
621
+ fi
622
+
398
623
  kill -TERM "$pid" 2>/dev/null || true
399
624
  local deadline=$((SECONDS + STOP_TIMEOUT_SECONDS))
400
625
  while (( SECONDS <= deadline )); do
@@ -452,43 +677,17 @@ cmd_logs() {
452
677
  fi
453
678
  }
454
679
 
455
- stop_pid_file() {
456
- local pid_path="$1"
457
- local pid
458
- pid="$(read_pid_file "$pid_path" || true)"
459
- if [[ -z "$pid" ]]; then
460
- return 0
461
- fi
462
- if ! is_running "$pid"; then
463
- rm -f "$pid_path"
464
- return 0
465
- fi
466
- if ! pid_controls_app "$pid"; then
467
- rm -f "$pid_path"
468
- return 0
469
- fi
470
-
471
- kill -TERM "$pid" 2>/dev/null || true
472
- local deadline=$((SECONDS + STOP_TIMEOUT_SECONDS))
473
- while (( SECONDS <= deadline )); do
474
- if ! is_running "$pid"; then
475
- rm -f "$pid_path"
476
- return 0
477
- fi
478
- sleep 0.25
479
- done
480
-
481
- kill -KILL "$pid" 2>/dev/null || true
482
- rm -f "$pid_path"
483
- }
484
-
485
680
  clean_state_paths() {
486
681
  local state_path="$1"
487
682
  local pid_path="$2"
488
683
  local log_path="$3"
684
+ local monitor_pid_path="${4:-}"
489
685
  local state_dir
490
686
  state_dir="$(dirname "$state_path")"
491
687
  rm -f "$state_path" "$pid_path" "$log_path" "$state_dir/update.lock"
688
+ if [[ -n "$monitor_pid_path" ]]; then
689
+ rm -f "$monitor_pid_path"
690
+ fi
492
691
  rm -rf "$state_dir/notification-assets"
493
692
  }
494
693
 
@@ -518,7 +717,7 @@ cmd_clean() {
518
717
 
519
718
  local state_dir
520
719
  state_dir="$(dirname "$STATE_PATH")"
521
- clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH"
720
+ clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH" "$MONITOR_PID_PATH"
522
721
  if (( remove_env == 1 )); then
523
722
  rm -f "$ENV_FILE"
524
723
  fi
@@ -544,11 +743,11 @@ cmd_uninstall() {
544
743
 
545
744
  ensure_app_dir
546
745
  unload_launchd_if_controlled
547
- stop_pid_file "$PID_PATH"
746
+ cmd_stop >/dev/null
548
747
  if (( kill_tmux == 1 )) && command -v tmux >/dev/null 2>&1; then
549
748
  tmux -L nterminal kill-server >/dev/null 2>&1 || true
550
749
  fi
551
- clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH"
750
+ clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH" "$MONITOR_PID_PATH"
552
751
  rm -f "$ENV_FILE"
553
752
  remove_owned_launchd_plist
554
753
 
@@ -609,10 +808,10 @@ cmd_doctor() {
609
808
  fi
610
809
 
611
810
  ensure_directories
612
- if [[ -w "$(dirname "$PID_PATH")" && -w "$(dirname "$LOG_PATH")" ]]; then
613
- echo "ok writable: pid/log directories"
811
+ if [[ -w "$(dirname "$PID_PATH")" && -w "$(dirname "$MONITOR_PID_PATH")" && -w "$(dirname "$LOG_PATH")" ]]; then
812
+ echo "ok writable: pid/monitor/log directories"
614
813
  else
615
- echo "fail writable: pid/log directories"
814
+ echo "fail writable: pid/monitor/log directories"
616
815
  failed=1
617
816
  fi
618
817
 
@@ -634,9 +833,9 @@ cmd_help() {
634
833
  Usage: nterminal <command>
635
834
 
636
835
  Commands:
637
- status Show process status. Exit 0 when running, 3 when stopped.
836
+ status Show process status. Exit 0 when running, 3 when stopped, 4 when the supervisor is restarting it.
638
837
  start Start the built server in the background.
639
- stop Stop the managed server with SIGTERM, then SIGKILL after timeout.
838
+ stop Stop the managed server and supervisor with SIGTERM, then SIGKILL after timeout.
640
839
  restart Stop and start the server.
641
840
  build No-op for package installs; verifies the bundled runtime exists.
642
841
  deploy Restart the installed package using the bundled runtime.
@@ -657,6 +856,7 @@ Environment:
657
856
  NTERMINAL_ENV_FILE Override .env path.
658
857
  NTERMINAL_STATE_PATH Default ~/.nterminal/state.json.
659
858
  NTERMINAL_PID_PATH Default ~/.nterminal/nterminal.pid.
859
+ NTERMINAL_MONITOR_PID_PATH Default ~/.nterminal/nterminal.monitor.pid.
660
860
  NTERMINAL_LOG_PATH Default ~/.nterminal/nterminal.log.
661
861
  NTERMINAL_HEALTH_TIMEOUT_SECONDS Default 15.
662
862
  NTERMINAL_STOP_TIMEOUT_SECONDS Default 20.
@@ -667,6 +867,7 @@ EOF
667
867
  case "$COMMAND" in
668
868
  status) cmd_status "$@" ;;
669
869
  start) cmd_start "$@" ;;
870
+ supervise) cmd_supervise "$@" ;;
670
871
  stop) cmd_stop "$@" ;;
671
872
  restart|reload) cmd_restart "$@" ;;
672
873
  build) cmd_build "$@" ;;