@mentiko/pty-mgr 1.4.3 → 1.5.0
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/CHANGELOG.md +21 -0
- package/lib/pty-manager.mjs +61 -23
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.0 - 2026-07-18
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `p daemons` lists every running daemon on the machine — one line per daemon
|
|
8
|
+
with pid, uptime, session counts, and cwd, in the same style as `p list`. The
|
|
9
|
+
currently-selected daemon (`@name` / `$PTY_DAEMON`) is marked with a leading
|
|
10
|
+
`*`; a socket that no longer answers is shown as `(stale)` and one with an
|
|
11
|
+
empty name as `(unnamed)`. It is read-only — unlike `p stop all` it never
|
|
12
|
+
removes stale sockets. Both commands now share one socket-enumeration helper.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- The installer no longer reports success while an older `pty-mgr` shadows the
|
|
17
|
+
freshly installed one. `install.sh` used to print `PATH is set.` once
|
|
18
|
+
`~/.pty-mgr/bin` was on `PATH`, which said nothing about *which* copy answers:
|
|
19
|
+
a stale binary earlier in `PATH` (e.g. a hand-placed `/usr/local/bin/pty-mgr`,
|
|
20
|
+
which sits on line 1 of macOS `/etc/paths`) would win silently. The installer
|
|
21
|
+
now scans every `PATH` entry after installing and prints any other `pty-mgr`
|
|
22
|
+
or `p` it finds, with an exact `rm` line to remove them.
|
|
23
|
+
|
|
3
24
|
## 1.4.3 - 2026-07-07
|
|
4
25
|
|
|
5
26
|
### Fixed
|
package/lib/pty-manager.mjs
CHANGED
|
@@ -42,7 +42,7 @@ import { fileURLToPath } from "node:url";
|
|
|
42
42
|
import { spawn as spawnChild } from "node:child_process";
|
|
43
43
|
|
|
44
44
|
// kept in sync by scripts/version-sync.cjs (rewrites this literal on release)
|
|
45
|
-
export const VERSION = "1.
|
|
45
|
+
export const VERSION = "1.5.0";
|
|
46
46
|
import xterm from "@xterm/headless";
|
|
47
47
|
import { SerializeAddon } from "@xterm/addon-serialize";
|
|
48
48
|
|
|
@@ -1479,6 +1479,32 @@ function sendCommandTo(sock, req) {
|
|
|
1479
1479
|
return requestSocket(sock, req, "daemon not running");
|
|
1480
1480
|
}
|
|
1481
1481
|
|
|
1482
|
+
// enumerate every daemon socket: ~/.pty-manager/*.sock plus legacy
|
|
1483
|
+
// /tmp/pty-manager-*.sock. returns [{ name, sockFile }]. shared by `stop all`
|
|
1484
|
+
// and `daemons` so both see the same set. presence of a .sock file does not
|
|
1485
|
+
// prove the daemon is alive -- the caller probes it.
|
|
1486
|
+
function listDaemonSockets() {
|
|
1487
|
+
const found = [];
|
|
1488
|
+
const dir = join(homedir(), ".pty-manager");
|
|
1489
|
+
try {
|
|
1490
|
+
for (const f of readdirSync(dir)) {
|
|
1491
|
+
if (f.endsWith(".sock")) {
|
|
1492
|
+
found.push({ name: f.replace(/\.sock$/, ""), sockFile: join(dir, f) });
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
} catch { /* dir doesn't exist yet */ }
|
|
1496
|
+
try {
|
|
1497
|
+
const tmp = tmpdir();
|
|
1498
|
+
for (const f of readdirSync(tmp)) {
|
|
1499
|
+
if (f.startsWith("pty-manager-") && f.endsWith(".sock")) {
|
|
1500
|
+
const name = f.replace(/^pty-manager-/, "").replace(/\.sock$/, "");
|
|
1501
|
+
found.push({ name, sockFile: join(tmp, f) });
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
} catch { /* tmp unreadable */ }
|
|
1505
|
+
return found;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1482
1508
|
// send to the daemon selected by @name / --daemon / $PTY_DAEMON.
|
|
1483
1509
|
function sendCommand(req) {
|
|
1484
1510
|
return requestSocket(SOCKET_PATH, req, "daemon not running. start with: pty-mgr daemon");
|
|
@@ -1642,6 +1668,7 @@ const USAGE = `pty-mgr - PTY session manager
|
|
|
1642
1668
|
usage:
|
|
1643
1669
|
p daemon start daemon (background: &)
|
|
1644
1670
|
p daemon @myproject named daemon (isolated sessions)
|
|
1671
|
+
p daemons list all running daemons (* = current)
|
|
1645
1672
|
p status daemon info + config
|
|
1646
1673
|
p config show current config
|
|
1647
1674
|
p config screen 100x50 set default terminal size
|
|
@@ -3059,32 +3086,13 @@ async function cli() {
|
|
|
3059
3086
|
const target = args[0]; // "all" or undefined (= current daemon)
|
|
3060
3087
|
if (target === "all") {
|
|
3061
3088
|
// find all pty-manager sockets and shut them down
|
|
3062
|
-
const
|
|
3063
|
-
|
|
3064
|
-
try {
|
|
3065
|
-
socks = readdirSync(dir).filter((f) => f.endsWith(".sock"));
|
|
3066
|
-
} catch { /* dir doesn't exist */ }
|
|
3067
|
-
// also check legacy /tmp/ location for old sockets
|
|
3068
|
-
try {
|
|
3069
|
-
const tmp = tmpdir();
|
|
3070
|
-
const legacy = readdirSync(tmp).filter((f) => f.startsWith("pty-manager-") && f.endsWith(".sock"));
|
|
3071
|
-
for (const s of legacy) socks.push("__legacy__/" + s);
|
|
3072
|
-
} catch {}
|
|
3073
|
-
if (socks.length === 0) {
|
|
3089
|
+
const daemons = listDaemonSockets();
|
|
3090
|
+
if (daemons.length === 0) {
|
|
3074
3091
|
console.log("no daemons running");
|
|
3075
3092
|
return;
|
|
3076
3093
|
}
|
|
3077
3094
|
const stopped = [];
|
|
3078
|
-
for (const
|
|
3079
|
-
let sockFile, name;
|
|
3080
|
-
if (sock.startsWith("__legacy__/")) {
|
|
3081
|
-
const legacyName = sock.replace("__legacy__/", "");
|
|
3082
|
-
sockFile = join(tmpdir(), legacyName);
|
|
3083
|
-
name = legacyName.replace("pty-manager-", "").replace(".sock", "");
|
|
3084
|
-
} else {
|
|
3085
|
-
sockFile = join(dir, sock);
|
|
3086
|
-
name = sock.replace(".sock", "");
|
|
3087
|
-
}
|
|
3095
|
+
for (const { name, sockFile } of daemons) {
|
|
3088
3096
|
try {
|
|
3089
3097
|
const res = await sendCommandTo(sockFile, { cmd: "shutdown" });
|
|
3090
3098
|
if (res.ok) stopped.push(name);
|
|
@@ -3107,6 +3115,36 @@ async function cli() {
|
|
|
3107
3115
|
return;
|
|
3108
3116
|
}
|
|
3109
3117
|
|
|
3118
|
+
if (command === "daemons") {
|
|
3119
|
+
// read-only listing of every daemon socket. probes each for live status;
|
|
3120
|
+
// unlike `stop all` it never removes stale sockets. one line per daemon,
|
|
3121
|
+
// matching the `list` house style. current daemon (@name/$PTY_DAEMON) is
|
|
3122
|
+
// marked with a leading '*'.
|
|
3123
|
+
const daemons = listDaemonSockets();
|
|
3124
|
+
if (daemons.length === 0) {
|
|
3125
|
+
console.log("no daemons running");
|
|
3126
|
+
return;
|
|
3127
|
+
}
|
|
3128
|
+
for (const { name, sockFile } of daemons) {
|
|
3129
|
+
const marker = sockFile === SOCKET_PATH ? "*" : " ";
|
|
3130
|
+
let st = null;
|
|
3131
|
+
try {
|
|
3132
|
+
const res = await sendCommandTo(sockFile, { cmd: "status" });
|
|
3133
|
+
if (res.ok) st = res.status;
|
|
3134
|
+
} catch { /* stale: file exists but nothing is listening */ }
|
|
3135
|
+
const label = name || "(unnamed)";
|
|
3136
|
+
if (st) {
|
|
3137
|
+
const s = st.sessions;
|
|
3138
|
+
let line = `${marker} ${label} pid=${st.pid} up=${st.uptime} ${s.alive}/${s.total} sessions`;
|
|
3139
|
+
if (st.cwd) line += ` ${st.cwd}`; // older daemons may not report cwd
|
|
3140
|
+
console.log(line);
|
|
3141
|
+
} else {
|
|
3142
|
+
console.log(`${marker} ${label} (stale)`);
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
return;
|
|
3146
|
+
}
|
|
3147
|
+
|
|
3110
3148
|
if (command === "attach") {
|
|
3111
3149
|
const name = args[0];
|
|
3112
3150
|
if (!name) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentiko/pty-mgr",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "PTY session manager with terminal emulation for programmatic session control.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/pty-manager.mjs",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"@xterm/headless": "^6.0.0"
|
|
27
27
|
},
|
|
28
28
|
"optionalDependencies": {
|
|
29
|
-
"@mentiko/pty-mgr-linux-x64": "1.
|
|
30
|
-
"@mentiko/pty-mgr-linux-arm64": "1.
|
|
31
|
-
"@mentiko/pty-mgr-darwin-x64": "1.
|
|
32
|
-
"@mentiko/pty-mgr-darwin-arm64": "1.
|
|
29
|
+
"@mentiko/pty-mgr-linux-x64": "1.5.0",
|
|
30
|
+
"@mentiko/pty-mgr-linux-arm64": "1.5.0",
|
|
31
|
+
"@mentiko/pty-mgr-darwin-x64": "1.5.0",
|
|
32
|
+
"@mentiko/pty-mgr-darwin-arm64": "1.5.0"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
|
35
35
|
"bun": ">=1.0"
|