herdr-remote 0.2.18 → 0.2.20

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 (95) hide show
  1. package/bin/herdr-remote.js +3 -225
  2. package/dist/agent-status.js +130 -0
  3. package/dist/binary-plist.js +157 -0
  4. package/dist/cli.js +255 -0
  5. package/dist/config.js +270 -0
  6. package/dist/connector/agent-watch.js +110 -0
  7. package/dist/connector/font-server.js +165 -0
  8. package/dist/connector/host-connector.js +430 -0
  9. package/dist/connector/lock.js +66 -0
  10. package/dist/connector/main.js +18 -0
  11. package/dist/connector/sessions.js +366 -0
  12. package/dist/connector/update-report.js +67 -0
  13. package/dist/connector/wire.js +42 -0
  14. package/{src → dist}/exit-codes.js +1 -4
  15. package/dist/font-subset.js +110 -0
  16. package/dist/herdr-api.js +246 -0
  17. package/dist/herdr-command.js +223 -0
  18. package/dist/herdr-plugin.js +116 -0
  19. package/dist/herdr-server.js +189 -0
  20. package/dist/i18n/en.js +223 -0
  21. package/dist/i18n/index.js +48 -0
  22. package/dist/i18n/zh.js +222 -0
  23. package/dist/keepalive/detached.js +78 -0
  24. package/dist/keepalive/environment.js +44 -0
  25. package/dist/keepalive/index.js +110 -0
  26. package/dist/keepalive/launchd.js +117 -0
  27. package/dist/keepalive/systemd.js +108 -0
  28. package/dist/keepalive/types.js +1 -0
  29. package/dist/lib/process.js +12 -0
  30. package/dist/lifecycle.js +59 -0
  31. package/dist/net-interfaces.js +73 -0
  32. package/dist/pasted-files.js +115 -0
  33. package/dist/paths.js +62 -0
  34. package/dist/pty-session.js +96 -0
  35. package/dist/relay-client.js +106 -0
  36. package/dist/relay-urls.js +99 -0
  37. package/dist/runtime.js +106 -0
  38. package/dist/service.js +260 -0
  39. package/dist/settings-model.js +298 -0
  40. package/dist/socket-discovery.js +48 -0
  41. package/dist/supervisor.js +319 -0
  42. package/dist/terminal-font/deps.js +73 -0
  43. package/dist/terminal-font/files.js +354 -0
  44. package/dist/terminal-font/formats.js +335 -0
  45. package/dist/terminal-font/index.js +187 -0
  46. package/dist/terminal-font/readers.js +316 -0
  47. package/dist/terminal-font/terminals.js +128 -0
  48. package/dist/terminal-palette.js +339 -0
  49. package/dist/tui/App.js +195 -0
  50. package/dist/tui/api.js +79 -0
  51. package/dist/tui/components/TextField.js +50 -0
  52. package/dist/tui/components/common.js +80 -0
  53. package/dist/tui/index.js +36 -0
  54. package/dist/tui/mouse/index.js +164 -0
  55. package/dist/tui/mouse/protocol.js +96 -0
  56. package/dist/tui/mouse/source.js +74 -0
  57. package/dist/tui/screens/About.js +166 -0
  58. package/dist/tui/screens/Herdr.js +74 -0
  59. package/dist/tui/screens/Keepalive.js +84 -0
  60. package/dist/tui/screens/Overview.js +36 -0
  61. package/dist/tui/screens/Pair.js +74 -0
  62. package/dist/tui/screens/Relay.js +242 -0
  63. package/dist/tui/screens/Services.js +63 -0
  64. package/dist/tui/screens/Wizard.js +235 -0
  65. package/dist/tui/terminal.js +39 -0
  66. package/dist/tui/theme.js +33 -0
  67. package/dist/updater.js +382 -0
  68. package/herdr-plugin.toml +1 -1
  69. package/package.json +8 -8
  70. package/dist/tui.mjs +0 -5775
  71. package/src/agent-status.js +0 -139
  72. package/src/binary-plist.js +0 -146
  73. package/src/config.js +0 -454
  74. package/src/font-subset.js +0 -110
  75. package/src/herdr-api.js +0 -244
  76. package/src/herdr-command.js +0 -231
  77. package/src/herdr-plugin.js +0 -130
  78. package/src/herdr-server.js +0 -201
  79. package/src/host-connector.js +0 -1069
  80. package/src/i18n/en.js +0 -240
  81. package/src/i18n/index.js +0 -56
  82. package/src/i18n/zh.js +0 -239
  83. package/src/keepalive.js +0 -460
  84. package/src/lifecycle.js +0 -62
  85. package/src/net-interfaces.js +0 -76
  86. package/src/pasted-files.js +0 -176
  87. package/src/pty-session.js +0 -92
  88. package/src/service.js +0 -530
  89. package/src/settings-model.js +0 -323
  90. package/src/socket-discovery.js +0 -60
  91. package/src/state.js +0 -47
  92. package/src/supervisor.js +0 -250
  93. package/src/terminal-font.js +0 -1204
  94. package/src/terminal-palette.js +0 -325
  95. package/src/updater.js +0 -394
@@ -1,201 +0,0 @@
1
- 'use strict';
2
-
3
- // Whether Herdr's server is running on this workstation, and starting it when
4
- // the user asked for that.
5
- //
6
- // herdr-remote never starts Herdr on its own initiative. It starts one when a
7
- // browser paired to this workstation asks for it, or at service start when the
8
- // user switched that on — and both go through here.
9
- //
10
- // Two traps shape this file:
11
- //
12
- // - A socket file is not a server. Herdr leaves `herdr.sock` behind when it dies
13
- // without cleaning up (a crash, a power cut), and a `herdr` client pointed at
14
- // a dead socket quietly starts a server of its own. So "running" means a
15
- // connection was accepted, not that the path exists.
16
- // - A server started from inside herdr-remote's systemd service lives in that
17
- // service's cgroup, and `systemctl restart herdr-remote` — an update, a keep-
18
- // alive restart, Herdr's own plugin startup hook — would kill it along with
19
- // every agent in it. Under a service it is therefore started in a transient
20
- // scope of its own, the same place it would live had the user started it
21
- // from a terminal.
22
-
23
- const fs = require('node:fs');
24
- const net = require('node:net');
25
- const path = require('node:path');
26
- const { spawn } = require('node:child_process');
27
- const { inspectSocket } = require('./socket-discovery');
28
- const { ensureDir } = require('./state');
29
-
30
- /** A Unix socket either accepts at once or is dead; this only guards a hang. */
31
- const PROBE_TIMEOUT_MS = 1_000;
32
- /** Herdr restores the saved session before its API socket opens. */
33
- const START_TIMEOUT_MS = 20_000;
34
- const START_POLL_MS = 200;
35
-
36
- /**
37
- * Is Herdr's server answering on `socketPath`?
38
- *
39
- * Resolves `{ state }`: `running`, `stopped` (no socket, or a socket nothing is
40
- * listening on), or `unavailable` with a `reason` — a path that is not a socket
41
- * or belongs to another user. That last one is never "stopped": the socket may
42
- * well be live, just not ours to use, and starting a second server beside it
43
- * would be starting somebody else's Herdr.
44
- */
45
- function probeHerdrServer(socketPath, { connect = net.connect, timeout = PROBE_TIMEOUT_MS } = {}) {
46
- const info = inspectSocket(socketPath);
47
- if (!info.ok) {
48
- return Promise.resolve(info.missing ? { state: 'stopped' } : { state: 'unavailable', reason: info.reason });
49
- }
50
- return new Promise((resolve) => {
51
- let socket;
52
- const finish = (result) => {
53
- clearTimeout(timer);
54
- if (socket) {
55
- socket.removeAllListeners();
56
- socket.on('error', () => {});
57
- socket.destroy();
58
- }
59
- resolve(result);
60
- };
61
- // A socket that neither accepts nor refuses has a listener behind it that
62
- // is slow, not absent; starting another server would only fight it.
63
- const timer = setTimeout(() => finish({ state: 'running' }), timeout);
64
- if (typeof timer.unref === 'function') timer.unref();
65
- socket = connect(socketPath);
66
- socket.once('connect', () => finish({ state: 'running' }));
67
- socket.once('error', (error) => finish(
68
- error.code === 'ECONNREFUSED' || error.code === 'ENOENT'
69
- ? { state: 'stopped', stale: true }
70
- : { state: 'unavailable', reason: error.message },
71
- ));
72
- });
73
- }
74
-
75
- /**
76
- * True when this process is a systemd service (herdr-remote's keep-alive), so
77
- * anything it starts would be killed with it.
78
- */
79
- function runningInSystemdService({ platform = process.platform, readCgroup = () => fs.readFileSync('/proc/self/cgroup', 'utf8') } = {}) {
80
- if (platform !== 'linux') return false;
81
- try {
82
- const unified = readCgroup().split('\n').find((line) => line.startsWith('0::'));
83
- return Boolean(unified) && /\.service$/.test(unified.trim());
84
- } catch {
85
- return false;
86
- }
87
- }
88
-
89
- /** The server's environment: the one a Herdr pane would give its client. */
90
- function serverEnv(socketPath, env = process.env) {
91
- const next = { ...env };
92
- for (const key of Object.keys(next)) {
93
- if (key.startsWith('HERDR_')) delete next[key];
94
- }
95
- if (socketPath) next.HERDR_SOCKET_PATH = socketPath;
96
- return next;
97
- }
98
-
99
- /**
100
- * The argv that starts Herdr's server: Herdr's own global arguments (a
101
- * `--session`, say) followed by `server`, wrapped in `systemd-run --scope` when
102
- * the caller is a systemd service.
103
- */
104
- function serverCommand({ command, args = [], inService = runningInSystemdService() }) {
105
- const herdr = [command, ...args, 'server'];
106
- if (!inService) return { file: herdr[0], args: herdr.slice(1) };
107
- return {
108
- file: 'systemd-run',
109
- args: ['--user', '--scope', '--quiet', '--collect', '--description=Herdr server started by herdr-remote', '--', ...herdr],
110
- };
111
- }
112
-
113
- /**
114
- * Start Herdr's server in the background. Detached from this process, with its
115
- * output appended to `logPath` rather than piped here: a pipe would break the
116
- * moment herdr-remote exits and take the server with it.
117
- */
118
- function launchHerdrServer({ command, args = [], socketPath, cwd, logPath, spawnProcess = spawn, inService }) {
119
- const { file, args: argv } = serverCommand({ command, args, inService });
120
- ensureDir(path.dirname(logPath));
121
- const out = fs.openSync(logPath, 'a');
122
- let child;
123
- try {
124
- child = spawnProcess(file, argv, {
125
- cwd,
126
- env: serverEnv(socketPath),
127
- detached: true,
128
- stdio: ['ignore', out, out],
129
- });
130
- } finally {
131
- fs.closeSync(out);
132
- }
133
- child.on('error', () => {});
134
- child.unref();
135
- return child;
136
- }
137
-
138
- function readLogTail(logPath, bytes = 2_000) {
139
- try {
140
- const text = fs.readFileSync(logPath, 'utf8');
141
- return text.slice(-bytes).trim();
142
- } catch {
143
- return '';
144
- }
145
- }
146
-
147
- /**
148
- * Make sure Herdr's server is running, starting it if it is not.
149
- *
150
- * Resolves `{ started }`, or rejects with a message that says what happened:
151
- * the socket belongs to someone else, the server exited, or it never opened
152
- * its socket. The last lines Herdr printed ride along, because "did not start"
153
- * with no reason is a message nobody can act on.
154
- */
155
- async function ensureHerdrServer({
156
- command,
157
- args = [],
158
- socketPath,
159
- cwd,
160
- logPath,
161
- probe = probeHerdrServer,
162
- launch = launchHerdrServer,
163
- timeout = START_TIMEOUT_MS,
164
- interval = START_POLL_MS,
165
- }) {
166
- const before = await probe(socketPath);
167
- if (before.state === 'running') return { started: false };
168
- if (before.state === 'unavailable') {
169
- throw new Error(`Herdr socket at ${socketPath} cannot be used: ${before.reason}`);
170
- }
171
-
172
- const child = launch({ command, args, socketPath, cwd, logPath });
173
- let exit = null;
174
- child.once('exit', (code, signal) => { exit = { code, signal }; });
175
-
176
- const deadline = Date.now() + timeout;
177
- for (;;) {
178
- await new Promise((resolve) => setTimeout(resolve, interval));
179
- const now = await probe(socketPath);
180
- if (now.state === 'running') return { started: true };
181
- const tail = readLogTail(logPath);
182
- const detail = tail ? `\n${tail}` : '';
183
- if (exit) {
184
- throw new Error(`Herdr server exited (${exit.signal || `code ${exit.code}`}) before opening ${socketPath}.${detail}`);
185
- }
186
- if (Date.now() >= deadline) {
187
- throw new Error(`Herdr server did not open ${socketPath} within ${Math.round(timeout / 1000)}s.${detail}`);
188
- }
189
- }
190
- }
191
-
192
- module.exports = {
193
- PROBE_TIMEOUT_MS,
194
- START_TIMEOUT_MS,
195
- probeHerdrServer,
196
- runningInSystemdService,
197
- serverEnv,
198
- serverCommand,
199
- launchHerdrServer,
200
- ensureHerdrServer,
201
- };