nterminal 1.2.13 → 1.2.14
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 +7 -34
- package/bin/nterminal.js +10 -23
- package/dist/client/assets/{MarkdownPreview-DfZZD0C0.js → MarkdownPreview-DBMjXHXe.js} +1 -1
- package/dist/client/assets/index-BprWaATf.css +1 -0
- package/dist/client/assets/index-DJRitqb8.js +44 -0
- package/dist/client/index.html +2 -2
- package/dist/scripts/onboarding.js +15 -53
- package/dist/scripts/onboarding.js.map +1 -1
- package/dist/scripts/proxySetup.js +1 -5
- package/dist/scripts/proxySetup.js.map +1 -1
- package/dist/server/agent/agentRoutes.js +4 -2
- package/dist/server/agent/agentRoutes.js.map +1 -1
- package/dist/server/auth/cookies.js +0 -8
- package/dist/server/auth/cookies.js.map +1 -1
- package/dist/server/config.js +1 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/routes/agentManagementRoutes.js +87 -13
- package/dist/server/routes/agentManagementRoutes.js.map +1 -1
- package/dist/server/routes/updateRoutes.js +2 -2
- package/dist/server/routes/updateRoutes.js.map +1 -1
- package/dist/server/update/{gitUpdate.d.ts → packageUpdate.d.ts} +1 -9
- package/dist/server/update/packageUpdate.js +140 -0
- package/dist/server/update/packageUpdate.js.map +1 -0
- package/dist/server/update/runtimeUninstall.d.ts +2 -0
- package/dist/server/update/runtimeUninstall.js +45 -0
- package/dist/server/update/runtimeUninstall.js.map +1 -0
- package/dist/shared/protocol.d.ts +6 -8
- package/dist/shared/protocol.js.map +1 -1
- package/docs/configuration.md +6 -23
- package/docs/features.md +1 -1
- package/docs/onboarding.md +3 -44
- package/docs/operations.md +26 -45
- package/package.json +1 -1
- package/scripts/nterminalctl +78 -69
- package/dist/client/assets/index-CMVGLebq.js +0 -43
- package/dist/client/assets/index-DiQ82H7w.css +0 -1
- package/dist/server/update/gitUpdate.js +0 -241
- package/dist/server/update/gitUpdate.js.map +0 -1
|
@@ -60,6 +60,12 @@ export interface AgentPingResponse {
|
|
|
60
60
|
ok: boolean;
|
|
61
61
|
latencyMs: number;
|
|
62
62
|
}
|
|
63
|
+
export interface AgentUninstallResponse {
|
|
64
|
+
ok: boolean;
|
|
65
|
+
message: string;
|
|
66
|
+
disconnecting: boolean;
|
|
67
|
+
disconnected?: boolean;
|
|
68
|
+
}
|
|
63
69
|
export interface SystemStatsResponse {
|
|
64
70
|
cpuPercent: number | null;
|
|
65
71
|
memoryPercent: number;
|
|
@@ -76,16 +82,8 @@ export interface SystemStatsResponse {
|
|
|
76
82
|
export interface VersionInfo {
|
|
77
83
|
version: string;
|
|
78
84
|
runningVersion: string;
|
|
79
|
-
commit: string | null;
|
|
80
|
-
runningCommit: string | null;
|
|
81
|
-
branch: string | null;
|
|
82
|
-
dirty: boolean;
|
|
83
|
-
isGit: boolean;
|
|
84
|
-
installMode: 'git' | 'package';
|
|
85
85
|
}
|
|
86
86
|
export interface UpdateCheckResponse {
|
|
87
|
-
behind: number | null;
|
|
88
|
-
commit: string | null;
|
|
89
87
|
currentVersion?: string;
|
|
90
88
|
latestVersion?: string | null;
|
|
91
89
|
updateAvailable?: boolean | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAwVA,MAAM,UAAU,0BAA0B,CAAC,GAAW;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,MAAwC,CAAC;QACzD,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3G,OAAO,OAAgC,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC7E,OAAO,OAAgC,CAAC;QAC1C,CAAC;QACD,IACE,OAAO,CAAC,IAAI,KAAK,QAAQ;YACzB,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ;YACtC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9B,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAC9B,CAAC;YACD,OAAO,OAAgC,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACjE,OAAO,OAAgC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/docs/configuration.md
CHANGED
|
@@ -4,33 +4,16 @@ Configuration comes from `.env` or process environment variables.
|
|
|
4
4
|
|
|
5
5
|
## `.env.example`
|
|
6
6
|
|
|
7
|
-
`.env.example` is the
|
|
7
|
+
`.env.example` is the runtime template. Keep it in source control, but never commit the copied `.env` file.
|
|
8
8
|
|
|
9
|
-
The template intentionally contains only the core values
|
|
9
|
+
The template intentionally contains only the core values. Add advanced settings from the table below only when you need to override the defaults.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
For manual local setup:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
cp .env.example .env
|
|
17
|
-
npm run generate:secrets
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Paste the generated `NTERMINAL_SESSION_SECRET=...` value into `.env`.
|
|
21
|
-
|
|
22
|
-
For normal package installs, prefer:
|
|
11
|
+
NTerminal package installs launched through `nterminal` read the runtime env file from `~/.nterminal/.env`.
|
|
23
12
|
|
|
24
13
|
```bash
|
|
25
14
|
nterminal onboarding
|
|
26
15
|
```
|
|
27
16
|
|
|
28
|
-
For source checkouts:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm run onboarding
|
|
32
|
-
```
|
|
33
|
-
|
|
34
17
|
Onboarding writes `.env` for you, including an absolute `NTERMINAL_STATE_PATH` so password/TOTP state is read from the same file when the service starts.
|
|
35
18
|
|
|
36
19
|
## Settings
|
|
@@ -41,7 +24,7 @@ Onboarding writes `.env` for you, including an absolute `NTERMINAL_STATE_PATH` s
|
|
|
41
24
|
| `NTERMINAL_PORT` | `3107` | HTTP server port. |
|
|
42
25
|
| `NTERMINAL_WORKSPACE_ROOT` | home directory | Startup directory for new terminal tabs. |
|
|
43
26
|
| `NTERMINAL_SHELL` | `$SHELL`, then `/bin/bash` | Shell path for new PTYs. |
|
|
44
|
-
| `NTERMINAL_STATE_PATH` |
|
|
27
|
+
| `NTERMINAL_STATE_PATH` | `~/.nterminal/state.json` | Local state file for password and layout data. Onboarding writes an absolute path. |
|
|
45
28
|
| `NTERMINAL_SESSION_SECRET` | required | Server secret for password hashing and session cookies. |
|
|
46
29
|
| `NTERMINAL_SESSION_TTL_SECONDS` | `43200` | Session lifetime in seconds. |
|
|
47
30
|
| `NTERMINAL_COOKIE_SECURE` | `false` locally | Set `true` when serving through HTTPS. |
|
|
@@ -54,8 +37,8 @@ Onboarding writes `.env` for you, including an absolute `NTERMINAL_STATE_PATH` s
|
|
|
54
37
|
| `NTERMINAL_FILE_LIST_MAX_ENTRIES` | `2000` | Maximum entries returned in one file explorer directory listing. |
|
|
55
38
|
| `NTERMINAL_FILE_TEXT_MAX_BYTES` | `1048576` | Maximum bytes loaded for text or Markdown view/edit. |
|
|
56
39
|
| `NTERMINAL_FILE_PREVIEW_MAX_BYTES` | `52428800` | Maximum bytes served for browser file previews. |
|
|
57
|
-
| `NTERMINAL_PID_PATH` |
|
|
58
|
-
| `NTERMINAL_LOG_PATH` |
|
|
40
|
+
| `NTERMINAL_PID_PATH` | `~/.nterminal/nterminal.pid` | PID file for the control script. |
|
|
41
|
+
| `NTERMINAL_LOG_PATH` | `~/.nterminal/nterminal.log` | Log file for the control script. |
|
|
59
42
|
| `NTERMINAL_HEALTH_TIMEOUT_SECONDS` | `15` | Startup health-check timeout for the control script. |
|
|
60
43
|
| `NTERMINAL_STOP_TIMEOUT_SECONDS` | `20` | Graceful stop timeout for the control script. |
|
|
61
44
|
|
package/docs/features.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
- Each server keeps its own terminal layout, tabs, split panes, detached terminals, and file context.
|
|
18
18
|
- The sidebar switches servers without tearing down the inactive server workspaces.
|
|
19
19
|
- Server cards show CPU, memory, disk, and swap usage with percentages and absolute values.
|
|
20
|
-
- Settings includes an Updates section for checking
|
|
20
|
+
- Settings includes an Updates section for checking npm package updates on each server.
|
|
21
21
|
- Update all runs secondary server updates in parallel first, then updates the main server last.
|
|
22
22
|
- Background update checks run hourly and badge Settings/Updates when an update is available.
|
|
23
23
|
|
package/docs/onboarding.md
CHANGED
|
@@ -2,22 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
NTerminal uses one interactive command for both the main server and secondary servers.
|
|
4
4
|
|
|
5
|
-
For npm package installs:
|
|
6
|
-
|
|
7
5
|
```bash
|
|
8
6
|
npm install -g nterminal
|
|
9
7
|
nterminal onboarding
|
|
10
8
|
```
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
For source checkouts:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm run onboarding
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
`npm install` runs automatically as the `preonboarding` hook, so a fresh checkout does not need a separate install step.
|
|
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.
|
|
21
11
|
|
|
22
12
|
## Main Server
|
|
23
13
|
|
|
@@ -35,7 +25,7 @@ The main setup flow:
|
|
|
35
25
|
2. Requires a public `https://<domain>` URL for the proxy setup path. Raw IPs, `http://`, `localhost`, and `.local` URLs are rejected in that path.
|
|
36
26
|
3. Writes `.env`, including a generated `NTERMINAL_SESSION_SECRET` and absolute `NTERMINAL_STATE_PATH`.
|
|
37
27
|
4. Sets the login password and enables TOTP headlessly. The CLI prints a terminal QR code, base32 secret, and `otpauth://` URI, then verifies the 6-digit code.
|
|
38
|
-
5. Optionally starts the
|
|
28
|
+
5. Optionally starts the installed package with `nterminal deploy`.
|
|
39
29
|
6. Optionally provisions nginx, DNS verification, firewall rules, and Let's Encrypt TLS.
|
|
40
30
|
|
|
41
31
|
The final summary prints the public URL, internal bind, and next steps.
|
|
@@ -58,7 +48,7 @@ The secondary setup flow:
|
|
|
58
48
|
4. Generates a session secret and `NTERMINAL_AGENT_TOKEN`, then writes `.env` with an absolute state path.
|
|
59
49
|
5. Prompts for the main server URL, password, and authenticator code.
|
|
60
50
|
6. Registers this secondary server with the main server automatically.
|
|
61
|
-
7. Optionally starts the
|
|
51
|
+
7. Optionally starts the installed package.
|
|
62
52
|
|
|
63
53
|
Onboard the main server first. The main must already have password and TOTP configured before a secondary server can register itself.
|
|
64
54
|
|
|
@@ -84,37 +74,6 @@ Privileged work uses one of two modes:
|
|
|
84
74
|
|
|
85
75
|
The "Main is ready" summary is printed only after the selected setup path has completed its checks.
|
|
86
76
|
|
|
87
|
-
## Local-Only Start
|
|
88
|
-
|
|
89
|
-
For a localhost-only development run without nginx/TLS onboarding:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
npm install
|
|
93
|
-
cp .env.example .env
|
|
94
|
-
npm run generate:secrets
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Paste the generated value into `.env`:
|
|
98
|
-
|
|
99
|
-
```env
|
|
100
|
-
NTERMINAL_SESSION_SECRET=replace-with-generate-secrets-output
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Then build and start:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
npm run build
|
|
107
|
-
npm start
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Open:
|
|
111
|
-
|
|
112
|
-
```text
|
|
113
|
-
http://127.0.0.1:3107
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
On the first visit, set the local NTerminal password and configure TOTP.
|
|
117
|
-
|
|
118
77
|
## Re-Running Onboarding
|
|
119
78
|
|
|
120
79
|
You can re-run onboarding to refresh generated config or register a secondary server again.
|
package/docs/operations.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Local Service Management
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Use the `nterminal` command:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
nterminal doctor
|
|
@@ -13,69 +13,56 @@ nterminal restart
|
|
|
13
13
|
nterminal stop
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
For source checkouts, use the bundled control script through npm:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npm run ctl -- doctor
|
|
20
|
-
npm run ctl -- build
|
|
21
|
-
npm run ctl -- start
|
|
22
|
-
npm run ctl -- status
|
|
23
|
-
npm run ctl -- logs
|
|
24
|
-
npm run ctl -- restart
|
|
25
|
-
npm run ctl -- stop
|
|
26
|
-
```
|
|
27
|
-
|
|
28
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.
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
One-command source checkout deploy:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm run deploy:local
|
|
36
|
-
```
|
|
18
|
+
Runtime files are kept under `~/.nterminal`.
|
|
37
19
|
|
|
38
20
|
Short aliases:
|
|
39
21
|
|
|
40
22
|
```bash
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
23
|
+
nterminal status
|
|
24
|
+
nterminal start
|
|
25
|
+
nterminal stop
|
|
26
|
+
nterminal restart
|
|
27
|
+
nterminal logs
|
|
46
28
|
```
|
|
47
29
|
|
|
48
30
|
## Updates
|
|
49
31
|
|
|
50
|
-
Each server updates itself
|
|
32
|
+
Each server updates itself as an npm package install.
|
|
51
33
|
|
|
52
34
|
The **updates** panel in the main server sidebar footer can manage the fleet:
|
|
53
35
|
|
|
54
|
-
- **Check for updates**
|
|
55
|
-
- **Update** runs `
|
|
36
|
+
- **Check for updates** checks the npm registry.
|
|
37
|
+
- **Update** runs `npm install -g nterminal@latest` plus restart.
|
|
56
38
|
- **Update all** updates secondary servers in parallel first and the main server last.
|
|
57
39
|
|
|
58
40
|
Notes:
|
|
59
41
|
|
|
60
|
-
- `--ff-only` stops and reports an error when a checkout has local commits or a diverged branch.
|
|
61
42
|
- npm package updates run as the same user that owns the running server process. Use a user-writable npm prefix, not a root-owned global install, if you want UI updates to work without sudo.
|
|
62
|
-
-
|
|
43
|
+
- An npm registry or permission error is reported as an explanatory status.
|
|
63
44
|
- Update endpoints require the same auth boundary as the rest of NTerminal.
|
|
64
45
|
|
|
65
|
-
## Clean
|
|
46
|
+
## Clean Uninstall
|
|
66
47
|
|
|
67
|
-
To
|
|
48
|
+
To remove the local runtime before uninstalling the npm package:
|
|
68
49
|
|
|
69
50
|
```bash
|
|
70
|
-
nterminal
|
|
51
|
+
nterminal uninstall --force
|
|
52
|
+
npm uninstall -g nterminal
|
|
71
53
|
```
|
|
72
54
|
|
|
73
|
-
|
|
74
|
-
|
|
55
|
+
`npm uninstall -g nterminal` cannot run cleanup automatically on modern npm versions. Run `nterminal uninstall --force` first; it stops the managed server, unloads an NTerminal launchd agent when present, kills NTerminal tmux sessions, removes runtime state under `~/.nterminal`, and removes `~/.nterminal/.env`.
|
|
56
|
+
|
|
57
|
+
If you already removed the package while a server is still running, reinstall or use npx to run the cleanup command, then uninstall again:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx nterminal@latest uninstall --force
|
|
61
|
+
npm uninstall -g nterminal
|
|
62
|
+
```
|
|
75
63
|
|
|
76
|
-
|
|
64
|
+
Option:
|
|
77
65
|
|
|
78
|
-
- omit `--env` to keep `.env`
|
|
79
66
|
- add `--keep-tmux` to preserve live tmux-backed panes
|
|
80
67
|
|
|
81
68
|
## Verification
|
|
@@ -114,17 +101,11 @@ If native PTY install or startup fails for a package install:
|
|
|
114
101
|
npm explore -g nterminal -- npm rebuild node-pty --build-from-source
|
|
115
102
|
```
|
|
116
103
|
|
|
117
|
-
For source checkouts:
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
npm rebuild node-pty --build-from-source
|
|
121
|
-
```
|
|
122
|
-
|
|
123
104
|
If the service script will not start:
|
|
124
105
|
|
|
125
106
|
```bash
|
|
126
|
-
|
|
127
|
-
|
|
107
|
+
nterminal doctor
|
|
108
|
+
nterminal logs
|
|
128
109
|
```
|
|
129
110
|
|
|
130
111
|
If you lose the local NTerminal password, stop the server and remove the local state file at `NTERMINAL_STATE_PATH`. The next browser visit will show the first-run password setup screen again.
|
package/package.json
CHANGED
package/scripts/nterminalctl
CHANGED
|
@@ -4,7 +4,8 @@ set -Eeuo pipefail
|
|
|
4
4
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
5
|
DEFAULT_APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
6
6
|
APP_DIR="${NTERMINAL_APP_DIR:-$DEFAULT_APP_DIR}"
|
|
7
|
-
|
|
7
|
+
DEFAULT_RUNTIME_DIR="${HOME:-$APP_DIR}/.nterminal"
|
|
8
|
+
ENV_FILE="${NTERMINAL_ENV_FILE:-$DEFAULT_RUNTIME_DIR/.env}"
|
|
8
9
|
|
|
9
10
|
COMMAND="${1:-help}"
|
|
10
11
|
if [[ $# -gt 0 ]]; then
|
|
@@ -65,16 +66,9 @@ resolve_path() {
|
|
|
65
66
|
|
|
66
67
|
load_env_file
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
DEFAULT_LOG_PATH=".nterminal/nterminal.log"
|
|
72
|
-
else
|
|
73
|
-
DEFAULT_RUNTIME_DIR="${HOME:-$APP_DIR}/.nterminal"
|
|
74
|
-
DEFAULT_STATE_PATH="$DEFAULT_RUNTIME_DIR/state.json"
|
|
75
|
-
DEFAULT_PID_PATH="$DEFAULT_RUNTIME_DIR/nterminal.pid"
|
|
76
|
-
DEFAULT_LOG_PATH="$DEFAULT_RUNTIME_DIR/nterminal.log"
|
|
77
|
-
fi
|
|
69
|
+
DEFAULT_STATE_PATH="$DEFAULT_RUNTIME_DIR/state.json"
|
|
70
|
+
DEFAULT_PID_PATH="$DEFAULT_RUNTIME_DIR/nterminal.pid"
|
|
71
|
+
DEFAULT_LOG_PATH="$DEFAULT_RUNTIME_DIR/nterminal.log"
|
|
78
72
|
|
|
79
73
|
HOST="${NTERMINAL_HOST:-127.0.0.1}"
|
|
80
74
|
PORT="${NTERMINAL_PORT:-3107}"
|
|
@@ -120,16 +114,8 @@ ensure_app_dir() {
|
|
|
120
114
|
[[ -d "$APP_DIR" ]] || die "app directory not found: $APP_DIR"
|
|
121
115
|
}
|
|
122
116
|
|
|
123
|
-
is_source_checkout() {
|
|
124
|
-
[[ -f "$APP_DIR/tsconfig.server.json" && -d "$APP_DIR/src" ]]
|
|
125
|
-
}
|
|
126
|
-
|
|
127
117
|
missing_env_message() {
|
|
128
|
-
|
|
129
|
-
printf '.env not found at %s; copy .env.example and run npm run generate:secrets' "$ENV_FILE"
|
|
130
|
-
else
|
|
131
|
-
printf '.env not found at %s; run nterminal onboarding' "$ENV_FILE"
|
|
132
|
-
fi
|
|
118
|
+
printf '.env not found at %s; run nterminal onboarding' "$ENV_FILE"
|
|
133
119
|
}
|
|
134
120
|
|
|
135
121
|
ensure_env_file() {
|
|
@@ -140,9 +126,6 @@ ensure_runtime() {
|
|
|
140
126
|
if [[ -f "$RUNTIME_ENTRY" ]]; then
|
|
141
127
|
return 0
|
|
142
128
|
fi
|
|
143
|
-
if is_source_checkout; then
|
|
144
|
-
die "dist/server/index.js not found; run scripts/nterminalctl build first"
|
|
145
|
-
fi
|
|
146
129
|
die "dist/server/index.js not found; reinstall nterminal"
|
|
147
130
|
}
|
|
148
131
|
|
|
@@ -215,6 +198,31 @@ launchd_controls_app() {
|
|
|
215
198
|
esac
|
|
216
199
|
}
|
|
217
200
|
|
|
201
|
+
launchd_agent_plist() {
|
|
202
|
+
local home_dir="${HOME:-}"
|
|
203
|
+
[[ -n "$home_dir" ]] || return 1
|
|
204
|
+
printf '%s/Library/LaunchAgents/%s.plist' "$home_dir" "$LAUNCHD_LABEL"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
unload_launchd_if_controlled() {
|
|
208
|
+
launchd_controls_app || return 0
|
|
209
|
+
local domain
|
|
210
|
+
domain="$(launchd_domain)" || return 0
|
|
211
|
+
launchctl bootout "$domain" >/dev/null 2>&1 || launchctl remove "$LAUNCHD_LABEL" >/dev/null 2>&1 || true
|
|
212
|
+
rm -f "$PID_PATH"
|
|
213
|
+
info "NTerminal launchd agent unloaded label=$LAUNCHD_LABEL"
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
remove_owned_launchd_plist() {
|
|
217
|
+
local plist
|
|
218
|
+
plist="$(launchd_agent_plist || true)"
|
|
219
|
+
[[ -n "$plist" && -f "$plist" ]] || return 0
|
|
220
|
+
if grep -F "$APP_DIR" "$plist" >/dev/null 2>&1; then
|
|
221
|
+
rm -f "$plist"
|
|
222
|
+
info "NTerminal launchd plist removed path=$plist"
|
|
223
|
+
fi
|
|
224
|
+
}
|
|
225
|
+
|
|
218
226
|
remove_stale_pid() {
|
|
219
227
|
local pid
|
|
220
228
|
pid="$(read_pid || true)"
|
|
@@ -388,37 +396,14 @@ cmd_restart() {
|
|
|
388
396
|
|
|
389
397
|
cmd_build() {
|
|
390
398
|
ensure_app_dir
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
info "Package install uses bundled dist; no build needed."
|
|
394
|
-
return 0
|
|
395
|
-
fi
|
|
396
|
-
(
|
|
397
|
-
cd "$APP_DIR"
|
|
398
|
-
"$NPM_BIN" run build
|
|
399
|
-
)
|
|
399
|
+
ensure_runtime
|
|
400
|
+
info "Package install uses bundled dist; no build needed."
|
|
400
401
|
}
|
|
401
402
|
|
|
402
403
|
cmd_deploy() {
|
|
403
404
|
ensure_app_dir
|
|
404
405
|
ensure_env_file
|
|
405
|
-
|
|
406
|
-
cd "$APP_DIR"
|
|
407
|
-
if is_source_checkout && [[ -f package-lock.json ]]; then
|
|
408
|
-
"$NPM_BIN" ci
|
|
409
|
-
elif is_source_checkout; then
|
|
410
|
-
"$NPM_BIN" install
|
|
411
|
-
fi
|
|
412
|
-
if is_source_checkout; then
|
|
413
|
-
"$NPM_BIN" run typecheck
|
|
414
|
-
# node-pty's install script always compiles from source (no prebuilt
|
|
415
|
-
# download); ask npm to rebuild it explicitly after dependency updates.
|
|
416
|
-
"$NPM_BIN" rebuild node-pty --build-from-source
|
|
417
|
-
"$NPM_BIN" run build
|
|
418
|
-
else
|
|
419
|
-
ensure_runtime
|
|
420
|
-
fi
|
|
421
|
-
)
|
|
406
|
+
ensure_runtime
|
|
422
407
|
cmd_restart
|
|
423
408
|
}
|
|
424
409
|
|
|
@@ -470,16 +455,10 @@ clean_state_paths() {
|
|
|
470
455
|
local state_path="$1"
|
|
471
456
|
local pid_path="$2"
|
|
472
457
|
local log_path="$3"
|
|
473
|
-
local default_state_dir="$4"
|
|
474
458
|
local state_dir
|
|
475
459
|
state_dir="$(dirname "$state_path")"
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
else
|
|
479
|
-
rm -f "$state_path" "$pid_path" "$log_path" "$state_dir/update.lock"
|
|
480
|
-
rm -rf "$state_dir/notification-assets"
|
|
481
|
-
rm -rf "$default_state_dir"
|
|
482
|
-
fi
|
|
460
|
+
rm -f "$state_path" "$pid_path" "$log_path" "$state_dir/update.lock"
|
|
461
|
+
rm -rf "$state_dir/notification-assets"
|
|
483
462
|
}
|
|
484
463
|
|
|
485
464
|
cmd_clean() {
|
|
@@ -508,7 +487,7 @@ cmd_clean() {
|
|
|
508
487
|
|
|
509
488
|
local state_dir
|
|
510
489
|
state_dir="$(dirname "$STATE_PATH")"
|
|
511
|
-
clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH"
|
|
490
|
+
clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH"
|
|
512
491
|
if (( remove_env == 1 )); then
|
|
513
492
|
rm -f "$ENV_FILE"
|
|
514
493
|
fi
|
|
@@ -516,13 +495,39 @@ cmd_clean() {
|
|
|
516
495
|
info "NTerminal cleaned state_dir=$state_dir env_removed=$remove_env tmux_killed=$kill_tmux"
|
|
517
496
|
}
|
|
518
497
|
|
|
498
|
+
cmd_uninstall() {
|
|
499
|
+
local force=0
|
|
500
|
+
local kill_tmux=1
|
|
501
|
+
while [[ $# -gt 0 ]]; do
|
|
502
|
+
case "$1" in
|
|
503
|
+
--force) force=1 ;;
|
|
504
|
+
--keep-tmux) kill_tmux=0 ;;
|
|
505
|
+
*) die "unknown uninstall option: $1" ;;
|
|
506
|
+
esac
|
|
507
|
+
shift
|
|
508
|
+
done
|
|
509
|
+
|
|
510
|
+
if (( force != 1 )); then
|
|
511
|
+
die "uninstall is destructive; rerun with: $(control_command uninstall) --force [--keep-tmux]"
|
|
512
|
+
fi
|
|
513
|
+
|
|
514
|
+
ensure_app_dir
|
|
515
|
+
unload_launchd_if_controlled
|
|
516
|
+
stop_pid_file "$PID_PATH"
|
|
517
|
+
if (( kill_tmux == 1 )) && command -v tmux >/dev/null 2>&1; then
|
|
518
|
+
tmux -L nterminal kill-server >/dev/null 2>&1 || true
|
|
519
|
+
fi
|
|
520
|
+
clean_state_paths "$STATE_PATH" "$PID_PATH" "$LOG_PATH"
|
|
521
|
+
rm -f "$ENV_FILE"
|
|
522
|
+
remove_owned_launchd_plist
|
|
523
|
+
|
|
524
|
+
info "NTerminal runtime uninstalled state_dir=$(dirname "$STATE_PATH") env_removed=1 tmux_killed=$kill_tmux"
|
|
525
|
+
info "Package files are still installed. To remove them, run: npm uninstall -g nterminal"
|
|
526
|
+
}
|
|
527
|
+
|
|
519
528
|
control_command() {
|
|
520
529
|
local command="$1"
|
|
521
|
-
|
|
522
|
-
printf 'scripts/nterminalctl %s' "$command"
|
|
523
|
-
else
|
|
524
|
-
printf 'nterminal %s' "$command"
|
|
525
|
-
fi
|
|
530
|
+
printf 'nterminal %s' "$command"
|
|
526
531
|
}
|
|
527
532
|
|
|
528
533
|
cmd_pid() {
|
|
@@ -595,17 +600,20 @@ cmd_doctor() {
|
|
|
595
600
|
|
|
596
601
|
cmd_help() {
|
|
597
602
|
cat <<EOF
|
|
598
|
-
Usage:
|
|
603
|
+
Usage: nterminal <command>
|
|
599
604
|
|
|
600
605
|
Commands:
|
|
601
606
|
status Show process status. Exit 0 when running, 3 when stopped.
|
|
602
607
|
start Start the built server in the background.
|
|
603
608
|
stop Stop the managed server with SIGTERM, then SIGKILL after timeout.
|
|
604
609
|
restart Stop and start the server.
|
|
605
|
-
build
|
|
606
|
-
deploy
|
|
610
|
+
build No-op for package installs; verifies the bundled runtime exists.
|
|
611
|
+
deploy Restart the installed package using the bundled runtime.
|
|
607
612
|
clean --force Stop server, kill NTerminal tmux sessions, and remove local state/log/pid files.
|
|
608
613
|
Add --env to also remove .env. Add --keep-tmux to preserve live panes.
|
|
614
|
+
uninstall --force
|
|
615
|
+
Stop server, unload NTerminal launchd agent, remove local runtime files and .env.
|
|
616
|
+
Add --keep-tmux to preserve live panes.
|
|
609
617
|
logs [N] Show the last N log lines. Default: 100.
|
|
610
618
|
logs -f [N] Follow logs.
|
|
611
619
|
doctor Check Node/npm/env/runtime/pid/log/port readiness.
|
|
@@ -616,9 +624,9 @@ Commands:
|
|
|
616
624
|
Environment:
|
|
617
625
|
NTERMINAL_APP_DIR Override app directory.
|
|
618
626
|
NTERMINAL_ENV_FILE Override .env path.
|
|
619
|
-
NTERMINAL_STATE_PATH Default
|
|
620
|
-
NTERMINAL_PID_PATH Default
|
|
621
|
-
NTERMINAL_LOG_PATH Default
|
|
627
|
+
NTERMINAL_STATE_PATH Default ~/.nterminal/state.json.
|
|
628
|
+
NTERMINAL_PID_PATH Default ~/.nterminal/nterminal.pid.
|
|
629
|
+
NTERMINAL_LOG_PATH Default ~/.nterminal/nterminal.log.
|
|
622
630
|
NTERMINAL_HEALTH_TIMEOUT_SECONDS Default 15.
|
|
623
631
|
NTERMINAL_STOP_TIMEOUT_SECONDS Default 20.
|
|
624
632
|
NTERMINAL_LAUNCHD_LABEL Default com.nterminal.local. Used when a loaded LaunchAgent controls this app.
|
|
@@ -633,6 +641,7 @@ case "$COMMAND" in
|
|
|
633
641
|
build) cmd_build "$@" ;;
|
|
634
642
|
deploy) cmd_deploy "$@" ;;
|
|
635
643
|
clean|purge) cmd_clean "$@" ;;
|
|
644
|
+
uninstall|remove) cmd_uninstall "$@" ;;
|
|
636
645
|
logs|log) cmd_logs "$@" ;;
|
|
637
646
|
doctor) cmd_doctor "$@" ;;
|
|
638
647
|
pid) cmd_pid "$@" ;;
|