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.
- package/README.md +1 -0
- package/bin/nterminal.js +1 -0
- package/dist/client/assets/{MarkdownPreview-EXPZkKVj.js → MarkdownPreview-fAU63YUT.js} +1 -1
- package/dist/client/assets/{index-2oIP_yU8.js → index-CzfRb88C.js} +10 -10
- package/dist/client/index.html +1 -1
- package/dist/server/update/packageUpdate.js +2 -2
- package/dist/server/update/packageUpdate.js.map +1 -1
- package/dist/shared/manualUpdate.js +1 -1
- package/dist/shared/manualUpdate.js.map +1 -1
- package/docs/configuration.md +1 -0
- package/docs/onboarding.md +1 -1
- package/docs/operations.md +2 -2
- package/package.json +1 -1
- package/scripts/nterminalctl +253 -52
package/dist/client/index.html
CHANGED
|
@@ -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-
|
|
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
|
|
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":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1G,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEjG,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAuB7C,SAAS,MAAM;IACb,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;AACrG,CAAC;AAED,SAAS,GAAG,CAAC,IAAc,EAAE,GAAW,EAAE,OAAO,GAAG,MAAM;IACxD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3G,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QACvB,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACpC,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAsB,CAAC;QAClG,OAAO,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAyB,CAAC;QACrG,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC;AAC/B,MAAM,cAAc,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;AAEzD,8FAA8F;AAC9F,iGAAiG;AACjG,SAAS,kBAAkB,CAAC,GAAW,EAAE,KAAa;IACpD,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,CAAC;IAC5D,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAChH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,iBAAiB,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC3B,SAAS,CAAC;QACR,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC;gBACH,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACxC,CAAC;oBAAS,CAAC;gBACT,SAAS,CAAC,EAAE,CAAC,CAAC;YAChB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,aAAa,CAAC,KAAK,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAG,GAAG,MAAM,EAAE,EAAE,eAAwC,IAAI;IACzF,OAAO;QACL,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC;QAChC,cAAc,EAAE,qBAAqB,CAAC,GAAG,CAAC;QAC1C,YAAY;KACb,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAG,GAAG,MAAM,EAAE;IAC/C,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,WAAW,SAAS,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;
|
|
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,
|
|
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"}
|
package/docs/configuration.md
CHANGED
|
@@ -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. |
|
package/docs/onboarding.md
CHANGED
|
@@ -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
|
|
package/docs/operations.md
CHANGED
|
@@ -13,7 +13,7 @@ nterminal restart
|
|
|
13
13
|
nterminal stop
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The script starts
|
|
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
package/scripts/nterminalctl
CHANGED
|
@@ -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
|
|
354
|
+
nohup setsid bash "$SCRIPT_DIR/nterminalctl" supervise >> "$LOG_PATH" 2>&1 &
|
|
278
355
|
else
|
|
279
|
-
nohup
|
|
356
|
+
nohup bash "$SCRIPT_DIR/nterminalctl" supervise >> "$LOG_PATH" 2>&1 &
|
|
280
357
|
fi
|
|
281
|
-
local
|
|
282
|
-
disown "$
|
|
283
|
-
echo "$
|
|
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
|
|
324
|
-
|
|
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="$(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 "$@" ;;
|