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.
- package/bin/nterminal.js +1 -0
- package/dist/client/assets/{MarkdownPreview-Dqb1LX21.js → MarkdownPreview-DCfGMtwX.js} +1 -1
- package/dist/client/assets/{index-Bzw1v9JR.css → index-f-1XNznv.css} +1 -1
- package/dist/client/assets/{index-7jUpdsER.js → index-ljxLHcWv.js} +22 -26
- package/dist/client/index.html +2 -2
- package/dist/scripts/onboarding.js +78 -17
- package/dist/scripts/onboarding.js.map +1 -1
- package/dist/server/agent/agentRoutes.js +11 -0
- package/dist/server/agent/agentRoutes.js.map +1 -1
- package/dist/server/config.d.ts +1 -0
- package/dist/server/config.js +12 -0
- package/dist/server/config.js.map +1 -1
- package/dist/server/index.js +44 -35
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/updateRoutes.js +11 -1
- package/dist/server/routes/updateRoutes.js.map +1 -1
- package/dist/server/runtimeState.d.ts +4 -0
- package/dist/server/runtimeState.js +13 -0
- package/dist/server/runtimeState.js.map +1 -0
- package/dist/server/storage/fileStore.d.ts +11 -1
- package/dist/server/storage/fileStore.js +20 -1
- package/dist/server/storage/fileStore.js.map +1 -1
- package/dist/server/terminal/transcriptHistory.js +6 -6
- package/dist/server/terminal/transcriptHistory.js.map +1 -1
- package/dist/server/update/packageUpdate.js +1 -1
- package/dist/server/update/packageUpdate.js.map +1 -1
- package/dist/server/update/stateCheckpoint.d.ts +3 -0
- package/dist/server/update/stateCheckpoint.js +34 -0
- package/dist/server/update/stateCheckpoint.js.map +1 -0
- package/dist/shared/manualUpdate.js +1 -1
- package/dist/shared/manualUpdate.js.map +1 -1
- package/docs/configuration.md +1 -0
- package/docs/features.md +2 -2
- package/docs/onboarding.md +1 -1
- package/docs/operations.md +4 -2
- package/package.json +1 -1
- package/scripts/nterminalctl +58 -39
package/scripts/nterminalctl
CHANGED
|
@@ -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
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
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 "$@" ;;
|