nterminal 1.2.23 → 1.2.25

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.
Files changed (37) hide show
  1. package/bin/nterminal.js +1 -0
  2. package/dist/client/assets/{MarkdownPreview-Dqb1LX21.js → MarkdownPreview-DCfGMtwX.js} +1 -1
  3. package/dist/client/assets/{index-Bzw1v9JR.css → index-f-1XNznv.css} +1 -1
  4. package/dist/client/assets/{index-7jUpdsER.js → index-ljxLHcWv.js} +22 -26
  5. package/dist/client/index.html +2 -2
  6. package/dist/scripts/onboarding.js +78 -17
  7. package/dist/scripts/onboarding.js.map +1 -1
  8. package/dist/server/agent/agentRoutes.js +11 -0
  9. package/dist/server/agent/agentRoutes.js.map +1 -1
  10. package/dist/server/config.d.ts +1 -0
  11. package/dist/server/config.js +12 -0
  12. package/dist/server/config.js.map +1 -1
  13. package/dist/server/index.js +44 -35
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/server/routes/updateRoutes.js +11 -1
  16. package/dist/server/routes/updateRoutes.js.map +1 -1
  17. package/dist/server/runtimeState.d.ts +4 -0
  18. package/dist/server/runtimeState.js +13 -0
  19. package/dist/server/runtimeState.js.map +1 -0
  20. package/dist/server/storage/fileStore.d.ts +11 -1
  21. package/dist/server/storage/fileStore.js +20 -1
  22. package/dist/server/storage/fileStore.js.map +1 -1
  23. package/dist/server/terminal/transcriptHistory.js +6 -6
  24. package/dist/server/terminal/transcriptHistory.js.map +1 -1
  25. package/dist/server/update/packageUpdate.js +1 -1
  26. package/dist/server/update/packageUpdate.js.map +1 -1
  27. package/dist/server/update/stateCheckpoint.d.ts +3 -0
  28. package/dist/server/update/stateCheckpoint.js +34 -0
  29. package/dist/server/update/stateCheckpoint.js.map +1 -0
  30. package/dist/shared/manualUpdate.js +1 -1
  31. package/dist/shared/manualUpdate.js.map +1 -1
  32. package/docs/configuration.md +1 -0
  33. package/docs/features.md +2 -2
  34. package/docs/onboarding.md +1 -1
  35. package/docs/operations.md +4 -2
  36. package/package.json +1 -1
  37. package/scripts/nterminalctl +58 -39
@@ -81,6 +81,7 @@ LOG_PATH="$(resolve_path "${NTERMINAL_LOG_PATH:-${NTERMINAL_RUNTIME_LOG_PATH:-$D
81
81
  STATE_PATH="$(resolve_path "${NTERMINAL_STATE_PATH:-${NTERMINAL_RUNTIME_STATE_PATH:-$DEFAULT_STATE_PATH}}")"
82
82
  HEALTH_TIMEOUT_SECONDS="${NTERMINAL_HEALTH_TIMEOUT_SECONDS:-15}"
83
83
  STOP_TIMEOUT_SECONDS="${NTERMINAL_STOP_TIMEOUT_SECONDS:-20}"
84
+ FATAL_STARTUP_EXIT_CODE="${NTERMINAL_FATAL_STARTUP_EXIT_CODE:-78}"
84
85
  RUNTIME_ENTRY="$APP_DIR/dist/server/index.js"
85
86
  LAUNCHD_LABEL="${NTERMINAL_LAUNCHD_LABEL:-com.nterminal.local}"
86
87
  UPDATE_LOCK_PATH="${NTERMINAL_UPDATE_LOCK_PATH:-}"
@@ -147,9 +148,41 @@ validate_required_env() {
147
148
  missing=1
148
149
  fi
149
150
  done
151
+ if [[ "${NTERMINAL_ROLE:-}" != "main" && "${NTERMINAL_ROLE:-}" != "secondary" ]]; then
152
+ echo "missing or invalid env: NTERMINAL_ROLE (expected main or secondary)"
153
+ missing=1
154
+ fi
155
+ if [[ "${NTERMINAL_ROLE:-}" == "secondary" ]]; then
156
+ local agent_token="${NTERMINAL_AGENT_TOKEN:-}"
157
+ if (( ${#agent_token} < 32 )); then
158
+ echo "missing or too-short env: NTERMINAL_AGENT_TOKEN"
159
+ missing=1
160
+ fi
161
+ fi
150
162
  return "$missing"
151
163
  }
152
164
 
165
+ doctor_runtime_state() {
166
+ local role="${NTERMINAL_ROLE:-}"
167
+ if [[ "$role" != "main" && "$role" != "secondary" ]]; then
168
+ return 1
169
+ fi
170
+ if [[ ! -f "$STATE_PATH" ]]; then
171
+ echo "fail state: state file not found at $STATE_PATH"
172
+ return 1
173
+ fi
174
+ if [[ "$role" == "secondary" ]]; then
175
+ echo "ok state: $STATE_PATH"
176
+ return 0
177
+ fi
178
+ if "$NODE_BIN" -e 'const fs = require("node:fs"); const state = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.exit(state && typeof state.passwordCredential === "object" && state.passwordCredential ? 0 : 2);' "$STATE_PATH" >/dev/null 2>&1; then
179
+ echo "ok state: main password credential present"
180
+ return 0
181
+ fi
182
+ echo "fail state: main state has no passwordCredential at $STATE_PATH"
183
+ return 1
184
+ }
185
+
153
186
  prepare_start() {
154
187
  ensure_app_dir
155
188
  ensure_env_file
@@ -438,6 +471,11 @@ cmd_supervise() {
438
471
  rm -f "$MONITOR_PID_PATH"
439
472
  exit 0
440
473
  fi
474
+ if (( status == FATAL_STARTUP_EXIT_CODE )); then
475
+ printf '[%s] NTerminal process exited with fatal startup status=%s; supervisor will not restart it\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$status" >> "$LOG_PATH"
476
+ rm -f "$MONITOR_PID_PATH"
477
+ exit "$status"
478
+ fi
441
479
 
442
480
  printf '[%s] NTerminal process exited status=%s; restarting in 2s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$status" >> "$LOG_PATH"
443
481
  sleep 2
@@ -480,30 +518,6 @@ wait_for_health() {
480
518
  return 1
481
519
  }
482
520
 
483
- restart_supervised_child() {
484
- local monitor_pid="$1"
485
- local old_pid="${2:-}"
486
-
487
- if [[ -n "$old_pid" ]]; then
488
- stop_supervised_child "$old_pid"
489
- fi
490
-
491
- local pid=""
492
- local deadline=$((SECONDS + HEALTH_TIMEOUT_SECONDS))
493
- while (( SECONDS <= deadline )); do
494
- if ! is_running "$monitor_pid"; then
495
- return 1
496
- fi
497
- pid="$(current_pid || true)"
498
- if [[ -n "$pid" && "$pid" != "$old_pid" ]] && wait_for_health "$pid"; then
499
- info "NTerminal restarted pid=$pid supervisor=$monitor_pid url=$(public_url) log=$LOG_PATH"
500
- return 0
501
- fi
502
- sleep 0.25
503
- done
504
- return 1
505
- }
506
-
507
521
  port_owner_pid() {
508
522
  if command -v lsof >/dev/null 2>&1; then
509
523
  lsof -nP -iTCP:"$PORT" -sTCP:LISTEN -t 2>/dev/null | head -n 1
@@ -669,26 +683,27 @@ cmd_restart() {
669
683
  start_launchd
670
684
  else
671
685
  prepare_start
672
- remove_stale_pid
673
- remove_stale_monitor_pid
674
- local monitor_pid
675
- monitor_pid="$(current_monitor_pid || true)"
676
- if [[ -n "$monitor_pid" ]]; then
677
- local pid
678
- pid="$(current_pid || true)"
679
- if restart_supervised_child "$monitor_pid" "$pid"; then
680
- return 0
681
- fi
682
- echo "NTerminal failed to restart under supervisor. Last log lines:" >&2
683
- tail -n 40 "$LOG_PATH" >&2 || true
684
- return 1
685
- fi
686
- cmd_stop >/dev/null
686
+ # Replace the supervisor instead of only restarting its child. The
687
+ # supervisor keeps its original environment, so reusing it after onboarding
688
+ # or npm replacement can restart the server with stale .env values or old
689
+ # package code.
690
+ cmd_stop >/dev/null || true
687
691
  cmd_start
688
692
  fi
689
693
  info "NTerminal restarted"
690
694
  }
691
695
 
696
+ cmd_restart_after_update() {
697
+ prepare_start
698
+ if launchd_controls_app; then
699
+ start_launchd
700
+ info "NTerminal restarted after update"
701
+ return 0
702
+ fi
703
+ cmd_stop >/dev/null || true
704
+ cmd_start
705
+ }
706
+
692
707
  cmd_build() {
693
708
  ensure_app_dir
694
709
  ensure_runtime
@@ -842,6 +857,7 @@ cmd_doctor() {
842
857
  echo "fail env: .env not found at $ENV_FILE"
843
858
  failed=1
844
859
  fi
860
+ doctor_runtime_state || failed=1
845
861
 
846
862
  if [[ -f "$RUNTIME_ENTRY" ]]; then
847
863
  echo "ok runtime: dist/server/index.js"
@@ -880,6 +896,8 @@ Commands:
880
896
  start Start the built server in the background.
881
897
  stop Stop the managed server and supervisor with SIGTERM, then SIGKILL after timeout.
882
898
  restart Stop and start the server.
899
+ restart-after-update
900
+ Stop the supervisor and start again after an npm package update.
883
901
  build No-op for package installs; verifies the bundled runtime exists.
884
902
  deploy Restart the installed package using the bundled runtime.
885
903
  clean --force Stop server, kill NTerminal tmux sessions, and remove local state/log/pid files.
@@ -913,6 +931,7 @@ case "$COMMAND" in
913
931
  supervise) cmd_supervise "$@" ;;
914
932
  stop) cmd_stop "$@" ;;
915
933
  restart|reload) cmd_restart "$@" ;;
934
+ restart-after-update) cmd_restart_after_update "$@" ;;
916
935
  build) cmd_build "$@" ;;
917
936
  deploy) cmd_deploy "$@" ;;
918
937
  clean|purge) cmd_clean "$@" ;;