herdr-remote 0.2.39 → 0.3.31
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/dist/chunks/353DMT35.js +3 -0
- package/dist/chunks/42KARAL4.js +31 -0
- package/dist/chunks/7AUQHB3O.js +10 -0
- package/dist/chunks/7SMZ43LI.js +9 -0
- package/dist/chunks/AM3OEMFK.js +16 -0
- package/dist/chunks/ANNJESOL.js +10 -0
- package/dist/chunks/AWB4A65P.js +63 -0
- package/dist/chunks/C2UUZY6J.js +2 -0
- package/dist/chunks/DGUZCGQN.js +3 -0
- package/dist/chunks/H24ZP5D5.js +16 -0
- package/dist/chunks/I6NRCYLI.js +3 -0
- package/dist/chunks/JJGEV4EZ.js +3 -0
- package/dist/chunks/KRSURB5L.js +5 -0
- package/dist/chunks/KRVF37OW.js +3 -0
- package/dist/chunks/KUDCC7ZO.js +6 -0
- package/dist/chunks/M3NRPJK2.js +77 -0
- package/dist/chunks/M4AFZHKH.js +3 -0
- package/dist/chunks/M52LJEES.js +6 -0
- package/dist/chunks/O2LNVFUT.js +3 -0
- package/dist/chunks/OJPBI7KB.js +3 -0
- package/dist/chunks/OMN6C7J6.js +3 -0
- package/dist/chunks/PBMBFWLQ.js +3 -0
- package/dist/chunks/PBRQ3HEG.js +3 -0
- package/dist/chunks/PFFVGFPL.js +45 -0
- package/dist/chunks/QRGNEKME.js +5 -0
- package/dist/chunks/TNLCNVA2.js +3 -0
- package/dist/chunks/U27JJKJ6.js +3 -0
- package/dist/chunks/U6QAYG3E.js +3 -0
- package/dist/chunks/UEOQE77N.js +4 -0
- package/dist/chunks/WSACSE45.js +4 -0
- package/dist/chunks/WY7WHEJ4.js +3 -0
- package/dist/chunks/XJKWLK43.js +4 -0
- package/dist/chunks/XN6D5S55.js +3 -0
- package/dist/chunks/YD3MIP7B.js +5 -0
- package/dist/chunks/YXDQ62BB.js +4 -0
- package/dist/cli.js +21 -294
- package/dist/connector/admin-broker.js +3 -303
- package/dist/connector/main.js +20 -18
- package/dist/harfbuzz-subset.wasm +0 -0
- package/dist/postinstall.js +17 -0
- package/herdr-plugin.toml +1 -1
- package/node_modules/herdr-remote-relay/bin/herdr-remote-relay.js +33 -92
- package/node_modules/herdr-remote-relay/package.json +3 -46
- package/package.json +8 -27
- package/dist/agent-status.js +0 -130
- package/dist/binary-plist.js +0 -157
- package/dist/config.js +0 -278
- package/dist/connector/admin-broker-setup.js +0 -40
- package/dist/connector/admin-shell.js +0 -67
- package/dist/connector/admin-tab.js +0 -90
- package/dist/connector/adminBrokerEndpoint.js +0 -68
- package/dist/connector/agent-watch.js +0 -123
- package/dist/connector/elevatedPty.js +0 -141
- package/dist/connector/font-server.js +0 -165
- package/dist/connector/herdr-prefix-keys.js +0 -28
- package/dist/connector/host-connector.js +0 -433
- package/dist/connector/host-hello.js +0 -32
- package/dist/connector/lock.js +0 -73
- package/dist/connector/sessions.js +0 -381
- package/dist/connector/update-report.js +0 -70
- package/dist/connector/wire.js +0 -42
- package/dist/exit-codes.js +0 -13
- package/dist/font-subset.js +0 -116
- package/dist/herdr-api.js +0 -254
- package/dist/herdr-command.js +0 -245
- package/dist/herdr-plugin.js +0 -120
- package/dist/herdr-server.js +0 -190
- package/dist/i18n/en.js +0 -257
- package/dist/i18n/index.js +0 -48
- package/dist/i18n/zh.js +0 -256
- package/dist/keepalive/detached.js +0 -97
- package/dist/keepalive/environment.js +0 -44
- package/dist/keepalive/index.js +0 -129
- package/dist/keepalive/launchd.js +0 -117
- package/dist/keepalive/systemd.js +0 -112
- package/dist/keepalive/types.js +0 -1
- package/dist/keepalive/windows-service-setup.js +0 -138
- package/dist/keepalive/windows-service.js +0 -272
- package/dist/keepalive/windows-task.js +0 -191
- package/dist/lib/process.js +0 -132
- package/dist/lifecycle.js +0 -79
- package/dist/net-interfaces.js +0 -82
- package/dist/node-pty-loader.js +0 -80
- package/dist/pasted-files.js +0 -115
- package/dist/paths.js +0 -74
- package/dist/pty-session.js +0 -133
- package/dist/relay-client.js +0 -106
- package/dist/relay-urls.js +0 -99
- package/dist/runtime.js +0 -107
- package/dist/service.js +0 -267
- package/dist/settings-model.js +0 -298
- package/dist/socket-discovery.js +0 -70
- package/dist/supervisor.js +0 -323
- package/dist/terminal-font/deps.js +0 -83
- package/dist/terminal-font/files.js +0 -357
- package/dist/terminal-font/formats.js +0 -355
- package/dist/terminal-font/index.js +0 -187
- package/dist/terminal-font/readers.js +0 -373
- package/dist/terminal-font/terminals.js +0 -147
- package/dist/terminal-palette.js +0 -399
- package/dist/tui/App.js +0 -199
- package/dist/tui/api.js +0 -91
- package/dist/tui/components/TextField.js +0 -50
- package/dist/tui/components/common.js +0 -80
- package/dist/tui/index.js +0 -36
- package/dist/tui/mouse/index.js +0 -164
- package/dist/tui/mouse/protocol.js +0 -96
- package/dist/tui/mouse/source.js +0 -79
- package/dist/tui/screens/About.js +0 -172
- package/dist/tui/screens/Herdr.js +0 -75
- package/dist/tui/screens/Keepalive.js +0 -141
- package/dist/tui/screens/Overview.js +0 -36
- package/dist/tui/screens/Pair.js +0 -74
- package/dist/tui/screens/Relay.js +0 -243
- package/dist/tui/screens/Services.js +0 -63
- package/dist/tui/screens/Wizard.js +0 -241
- package/dist/tui/terminal.js +0 -39
- package/dist/tui/theme.js +0 -33
- package/dist/update-command.js +0 -118
- package/dist/updater/in-place.js +0 -83
- package/dist/updater/npm.js +0 -62
- package/dist/updater.js +0 -401
- package/node_modules/herdr-remote-relay/README.md +0 -76
- package/node_modules/herdr-remote-relay/README.zh-CN.md +0 -76
- package/node_modules/herdr-remote-relay/config.example.json +0 -18
- package/node_modules/herdr-remote-relay/deploy/cloudflared/config.yml.example +0 -9
- package/node_modules/herdr-remote-relay/deploy/docker/compose.yaml +0 -23
- package/node_modules/herdr-remote-relay/deploy/nginx/herdr-remote-relay.conf.example +0 -49
- package/node_modules/herdr-remote-relay/deploy/systemd/herdr-remote-relay.service +0 -41
- package/node_modules/herdr-remote-relay/deploy/systemd/relay.env.example +0 -25
- package/node_modules/herdr-remote-relay/dist/auth-store.d.ts +0 -114
- package/node_modules/herdr-remote-relay/dist/auth-store.js +0 -289
- package/node_modules/herdr-remote-relay/dist/metrics.d.ts +0 -76
- package/node_modules/herdr-remote-relay/dist/metrics.js +0 -249
- package/node_modules/herdr-remote-relay/dist/protocol/frames.d.ts +0 -27
- package/node_modules/herdr-remote-relay/dist/protocol/frames.js +0 -110
- package/node_modules/herdr-remote-relay/dist/protocol/herdr-keys.d.ts +0 -8
- package/node_modules/herdr-remote-relay/dist/protocol/herdr-keys.js +0 -34
- package/node_modules/herdr-remote-relay/dist/protocol/http.d.ts +0 -165
- package/node_modules/herdr-remote-relay/dist/protocol/http.js +0 -3
- package/node_modules/herdr-remote-relay/dist/protocol/index.d.ts +0 -7
- package/node_modules/herdr-remote-relay/dist/protocol/index.js +0 -9
- package/node_modules/herdr-remote-relay/dist/protocol/messages.d.ts +0 -362
- package/node_modules/herdr-remote-relay/dist/protocol/messages.js +0 -20
- package/node_modules/herdr-remote-relay/dist/protocol/paste.d.ts +0 -14
- package/node_modules/herdr-remote-relay/dist/protocol/paste.js +0 -50
- package/node_modules/herdr-remote-relay/dist/protocol/release.d.ts +0 -8
- package/node_modules/herdr-remote-relay/dist/protocol/release.js +0 -17
- package/node_modules/herdr-remote-relay/dist/protocol/terminal.d.ts +0 -79
- package/node_modules/herdr-remote-relay/dist/protocol/terminal.js +0 -150
- package/node_modules/herdr-remote-relay/dist/relay-config.d.ts +0 -74
- package/node_modules/herdr-remote-relay/dist/relay-config.js +0 -316
- package/node_modules/herdr-remote-relay/dist/relay-server.d.ts +0 -67
- package/node_modules/herdr-remote-relay/dist/relay-server.js +0 -196
- package/node_modules/herdr-remote-relay/dist/scroll-input.d.ts +0 -17
- package/node_modules/herdr-remote-relay/dist/scroll-input.js +0 -124
- package/node_modules/herdr-remote-relay/dist/server/client-channel.d.ts +0 -3
- package/node_modules/herdr-remote-relay/dist/server/client-channel.js +0 -396
- package/node_modules/herdr-remote-relay/dist/server/font-proxy.d.ts +0 -19
- package/node_modules/herdr-remote-relay/dist/server/font-proxy.js +0 -155
- package/node_modules/herdr-remote-relay/dist/server/host-broadcasts.d.ts +0 -27
- package/node_modules/herdr-remote-relay/dist/server/host-broadcasts.js +0 -83
- package/node_modules/herdr-remote-relay/dist/server/host-channel.d.ts +0 -3
- package/node_modules/herdr-remote-relay/dist/server/host-channel.js +0 -271
- package/node_modules/herdr-remote-relay/dist/server/http-api.d.ts +0 -4
- package/node_modules/herdr-remote-relay/dist/server/http-api.js +0 -219
- package/node_modules/herdr-remote-relay/dist/server/maintenance.d.ts +0 -5
- package/node_modules/herdr-remote-relay/dist/server/maintenance.js +0 -64
- package/node_modules/herdr-remote-relay/dist/server/requests.d.ts +0 -34
- package/node_modules/herdr-remote-relay/dist/server/requests.js +0 -142
- package/node_modules/herdr-remote-relay/dist/server/sessions.d.ts +0 -36
- package/node_modules/herdr-remote-relay/dist/server/sessions.js +0 -230
- package/node_modules/herdr-remote-relay/dist/server/sockets.d.ts +0 -12
- package/node_modules/herdr-remote-relay/dist/server/sockets.js +0 -64
- package/node_modules/herdr-remote-relay/dist/server/status.d.ts +0 -11
- package/node_modules/herdr-remote-relay/dist/server/status.js +0 -99
- package/node_modules/herdr-remote-relay/dist/server/transport.d.ts +0 -16
- package/node_modules/herdr-remote-relay/dist/server/transport.js +0 -110
- package/node_modules/herdr-remote-relay/dist/server/types.d.ts +0 -133
- package/node_modules/herdr-remote-relay/dist/server/types.js +0 -3
- package/node_modules/herdr-remote-relay/dist/server/version.d.ts +0 -2
- package/node_modules/herdr-remote-relay/dist/server/version.js +0 -5
- package/node_modules/herdr-remote-relay/dist/state.d.ts +0 -6
- package/node_modules/herdr-remote-relay/dist/state.js +0 -47
- package/node_modules/ws/LICENSE +0 -20
- package/node_modules/ws/README.md +0 -548
- package/node_modules/ws/browser.js +0 -8
- package/node_modules/ws/index.js +0 -22
- package/node_modules/ws/lib/buffer-util.js +0 -131
- package/node_modules/ws/lib/constants.js +0 -19
- package/node_modules/ws/lib/event-target.js +0 -292
- package/node_modules/ws/lib/extension.js +0 -203
- package/node_modules/ws/lib/limiter.js +0 -55
- package/node_modules/ws/lib/permessage-deflate.js +0 -530
- package/node_modules/ws/lib/receiver.js +0 -743
- package/node_modules/ws/lib/sender.js +0 -607
- package/node_modules/ws/lib/stream.js +0 -161
- package/node_modules/ws/lib/subprotocol.js +0 -62
- package/node_modules/ws/lib/validation.js +0 -152
- package/node_modules/ws/lib/websocket-server.js +0 -562
- package/node_modules/ws/lib/websocket.js +0 -1407
- package/node_modules/ws/package.json +0 -74
- package/node_modules/ws/wrapper.mjs +0 -21
package/dist/herdr-server.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
// Whether Herdr's server is running on this workstation, and starting it when
|
|
2
|
-
// the user asked for that.
|
|
3
|
-
//
|
|
4
|
-
// herdr-remote never starts Herdr on its own initiative. It starts one when a
|
|
5
|
-
// browser paired to this workstation asks for it, or at service start when the
|
|
6
|
-
// user switched that on — and both go through here.
|
|
7
|
-
//
|
|
8
|
-
// Two traps shape this file:
|
|
9
|
-
//
|
|
10
|
-
// - A socket file is not a server. Herdr leaves `herdr.sock` behind when it dies
|
|
11
|
-
// without cleaning up (a crash, a power cut), and a `herdr` client pointed at
|
|
12
|
-
// a dead socket quietly starts a server of its own. So "running" means a
|
|
13
|
-
// connection was accepted, not that the path exists.
|
|
14
|
-
// - A server started from inside herdr-remote's systemd service lives in that
|
|
15
|
-
// service's cgroup, and `systemctl restart herdr-remote` — an update, a keep-
|
|
16
|
-
// alive restart, Herdr's own plugin startup hook — would kill it along with
|
|
17
|
-
// every agent in it. Under a service it is therefore started in a transient
|
|
18
|
-
// scope of its own, the same place it would live had the user started it
|
|
19
|
-
// from a terminal.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import net from 'node:net';
|
|
22
|
-
import path from 'node:path';
|
|
23
|
-
import { spawn } from 'node:child_process';
|
|
24
|
-
import { herdrEndpoint, inspectSocket } from './socket-discovery.js';
|
|
25
|
-
import { ensureDir } from 'herdr-remote-relay/state';
|
|
26
|
-
/** A Unix socket either accepts at once or is dead; this only guards a hang. */
|
|
27
|
-
const PROBE_TIMEOUT_MS = 1_000;
|
|
28
|
-
/** Herdr restores the saved session before its API socket opens. */
|
|
29
|
-
const START_TIMEOUT_MS = 20_000;
|
|
30
|
-
const START_POLL_MS = 200;
|
|
31
|
-
/**
|
|
32
|
-
* Is Herdr's server answering on `socketPath`?
|
|
33
|
-
*
|
|
34
|
-
* Resolves `{ state }`: `running`, `stopped` (no socket, or a socket nothing is
|
|
35
|
-
* listening on), or `unavailable` with a `reason` — a path that is not a socket
|
|
36
|
-
* or belongs to another user. That last one is never "stopped": the socket may
|
|
37
|
-
* well be live, just not ours to use, and starting a second server beside it
|
|
38
|
-
* would be starting somebody else's Herdr.
|
|
39
|
-
*/
|
|
40
|
-
function probeHerdrServer(socketPath, { connect = net.connect, timeout = PROBE_TIMEOUT_MS } = {}) {
|
|
41
|
-
const info = inspectSocket(socketPath);
|
|
42
|
-
if (!info.ok) {
|
|
43
|
-
return Promise.resolve(info.missing ? { state: 'stopped' } : { state: 'unavailable', reason: info.reason });
|
|
44
|
-
}
|
|
45
|
-
return new Promise((resolve) => {
|
|
46
|
-
let socket;
|
|
47
|
-
const finish = (result) => {
|
|
48
|
-
clearTimeout(timer);
|
|
49
|
-
if (socket) {
|
|
50
|
-
socket.removeAllListeners();
|
|
51
|
-
socket.on('error', () => { });
|
|
52
|
-
socket.destroy();
|
|
53
|
-
}
|
|
54
|
-
resolve(result);
|
|
55
|
-
};
|
|
56
|
-
// A socket that neither accepts nor refuses has a listener behind it that
|
|
57
|
-
// is slow, not absent; starting another server would only fight it.
|
|
58
|
-
const timer = setTimeout(() => finish({ state: 'running' }), timeout);
|
|
59
|
-
if (typeof timer.unref === 'function')
|
|
60
|
-
timer.unref();
|
|
61
|
-
socket = connect(herdrEndpoint(socketPath));
|
|
62
|
-
socket.once('connect', () => finish({ state: 'running' }));
|
|
63
|
-
socket.once('error', (error) => finish(error.code === 'ECONNREFUSED' || error.code === 'ENOENT'
|
|
64
|
-
? { state: 'stopped', stale: true }
|
|
65
|
-
: { state: 'unavailable', reason: error.message }));
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* True when this process is a systemd service (herdr-remote's keep-alive), so
|
|
70
|
-
* anything it starts would be killed with it.
|
|
71
|
-
*/
|
|
72
|
-
function runningInSystemdService({ platform = process.platform, readCgroup = () => fs.readFileSync('/proc/self/cgroup', 'utf8'), } = {}) {
|
|
73
|
-
if (platform !== 'linux')
|
|
74
|
-
return false;
|
|
75
|
-
try {
|
|
76
|
-
const unified = readCgroup()
|
|
77
|
-
.split('\n')
|
|
78
|
-
.find((line) => line.startsWith('0::'));
|
|
79
|
-
return unified !== undefined && /\.service$/.test(unified.trim());
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
/** The server's environment: the one a Herdr pane would give its client. */
|
|
86
|
-
function serverEnv(socketPath, env = process.env) {
|
|
87
|
-
const next = { ...env };
|
|
88
|
-
for (const key of Object.keys(next)) {
|
|
89
|
-
if (key.startsWith('HERDR_'))
|
|
90
|
-
delete next[key];
|
|
91
|
-
}
|
|
92
|
-
if (socketPath)
|
|
93
|
-
next.HERDR_SOCKET_PATH = socketPath;
|
|
94
|
-
return next;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* The argv that starts Herdr's server: Herdr's own global arguments (a
|
|
98
|
-
* `--session`, say) followed by `server`, wrapped in `systemd-run --scope` when
|
|
99
|
-
* the caller is a systemd service.
|
|
100
|
-
*/
|
|
101
|
-
function serverCommand({ command, args = [], inService = runningInSystemdService(), }) {
|
|
102
|
-
const herdr = [command, ...args, 'server'];
|
|
103
|
-
if (!inService)
|
|
104
|
-
return { file: herdr[0], args: herdr.slice(1) };
|
|
105
|
-
return {
|
|
106
|
-
file: 'systemd-run',
|
|
107
|
-
args: [
|
|
108
|
-
'--user',
|
|
109
|
-
'--scope',
|
|
110
|
-
'--quiet',
|
|
111
|
-
'--collect',
|
|
112
|
-
'--description=Herdr server started by herdr-remote',
|
|
113
|
-
'--',
|
|
114
|
-
...herdr,
|
|
115
|
-
],
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Start Herdr's server in the background. Detached from this process, with its
|
|
120
|
-
* output appended to `logPath` rather than piped here: a pipe would break the
|
|
121
|
-
* moment herdr-remote exits and take the server with it.
|
|
122
|
-
*/
|
|
123
|
-
function launchHerdrServer({ command, args = [], socketPath, cwd, logPath, spawnProcess = spawn, inService, }) {
|
|
124
|
-
const { file, args: argv } = serverCommand({ command, args, inService });
|
|
125
|
-
ensureDir(path.dirname(logPath));
|
|
126
|
-
const out = fs.openSync(logPath, 'a');
|
|
127
|
-
let child;
|
|
128
|
-
try {
|
|
129
|
-
child = spawnProcess(file, argv, {
|
|
130
|
-
cwd,
|
|
131
|
-
env: serverEnv(socketPath),
|
|
132
|
-
detached: true,
|
|
133
|
-
windowsHide: true,
|
|
134
|
-
stdio: ['ignore', out, out],
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
finally {
|
|
138
|
-
fs.closeSync(out);
|
|
139
|
-
}
|
|
140
|
-
child.on('error', () => { });
|
|
141
|
-
child.unref();
|
|
142
|
-
return child;
|
|
143
|
-
}
|
|
144
|
-
function readLogTail(logPath, bytes = 2_000) {
|
|
145
|
-
try {
|
|
146
|
-
const text = fs.readFileSync(logPath, 'utf8');
|
|
147
|
-
return text.slice(-bytes).trim();
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
return '';
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Make sure Herdr's server is running, starting it if it is not.
|
|
155
|
-
*
|
|
156
|
-
* Resolves `{ started }`, or rejects with a message that says what happened:
|
|
157
|
-
* the socket belongs to someone else, the server exited, or it never opened
|
|
158
|
-
* its socket. The last lines Herdr printed ride along, because "did not start"
|
|
159
|
-
* with no reason is a message nobody can act on.
|
|
160
|
-
*/
|
|
161
|
-
async function ensureHerdrServer({ command, args = [], socketPath, cwd, logPath, probe = probeHerdrServer, launch = launchHerdrServer, timeout = START_TIMEOUT_MS, interval = START_POLL_MS, }) {
|
|
162
|
-
const before = await probe(socketPath);
|
|
163
|
-
if (before.state === 'running')
|
|
164
|
-
return { started: false };
|
|
165
|
-
if (before.state === 'unavailable') {
|
|
166
|
-
throw new Error(`Herdr socket at ${socketPath} cannot be used: ${before.reason}`);
|
|
167
|
-
}
|
|
168
|
-
const child = launch({ command, args, socketPath, cwd, logPath });
|
|
169
|
-
// Assigned by the listener; `as` keeps TypeScript from assuming it stays null.
|
|
170
|
-
let exit = null;
|
|
171
|
-
child.once('exit', (code, signal) => {
|
|
172
|
-
exit = { code, signal };
|
|
173
|
-
});
|
|
174
|
-
const deadline = Date.now() + timeout;
|
|
175
|
-
for (;;) {
|
|
176
|
-
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
177
|
-
const now = await probe(socketPath);
|
|
178
|
-
if (now.state === 'running')
|
|
179
|
-
return { started: true };
|
|
180
|
-
const tail = readLogTail(logPath);
|
|
181
|
-
const detail = tail ? `\n${tail}` : '';
|
|
182
|
-
if (exit) {
|
|
183
|
-
throw new Error(`Herdr server exited (${exit.signal || `code ${exit.code}`}) before opening ${socketPath}.${detail}`);
|
|
184
|
-
}
|
|
185
|
-
if (Date.now() >= deadline) {
|
|
186
|
-
throw new Error(`Herdr server did not open ${socketPath} within ${Math.round(timeout / 1000)}s.${detail}`);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
export { probeHerdrServer, runningInSystemdService, serverEnv, serverCommand, ensureHerdrServer };
|
package/dist/i18n/en.js
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
// English message catalogue. This file is the reference: zh.ts must define
|
|
2
|
-
// exactly the same keys, which its type and tests/i18n.test.js enforce.
|
|
3
|
-
const en = {
|
|
4
|
-
'app.name': 'Herdr Remote',
|
|
5
|
-
'app.tagline': 'Remote browser access to Herdr workspaces',
|
|
6
|
-
'common.yes': 'Yes',
|
|
7
|
-
'common.no': 'No',
|
|
8
|
-
'common.on': 'on',
|
|
9
|
-
'common.off': 'off',
|
|
10
|
-
'common.none': 'none',
|
|
11
|
-
'common.auto': 'auto',
|
|
12
|
-
'common.unknown': 'unknown',
|
|
13
|
-
'common.running': 'running',
|
|
14
|
-
'common.stopped': 'stopped',
|
|
15
|
-
'common.connected': 'connected',
|
|
16
|
-
'common.disconnected': 'disconnected',
|
|
17
|
-
'common.installed': 'installed',
|
|
18
|
-
'common.notInstalled': 'not installed',
|
|
19
|
-
'common.enabled': 'enabled',
|
|
20
|
-
'common.disabled': 'disabled',
|
|
21
|
-
'common.loading': 'Working…',
|
|
22
|
-
'common.save': 'Save settings',
|
|
23
|
-
'common.saved': 'Configuration saved to {path}',
|
|
24
|
-
'common.back': 'Back',
|
|
25
|
-
'common.cancel': 'Cancel',
|
|
26
|
-
'common.confirm': 'Confirm',
|
|
27
|
-
'common.pid': 'pid {pid}',
|
|
28
|
-
'common.notApplicable': 'n/a',
|
|
29
|
-
'nav.overview': 'Overview',
|
|
30
|
-
'nav.pair': 'Pair a device',
|
|
31
|
-
'nav.services': 'Services',
|
|
32
|
-
'nav.relay': 'Relay',
|
|
33
|
-
'nav.keepalive': 'Keep-alive',
|
|
34
|
-
'nav.herdr': 'Herdr',
|
|
35
|
-
'nav.about': 'Language & about',
|
|
36
|
-
'mode.local': 'This machine only',
|
|
37
|
-
'mode.lan': 'Local network / Tailscale',
|
|
38
|
-
'mode.official': 'Official relay',
|
|
39
|
-
'mode.remote': 'Self-hosted relay',
|
|
40
|
-
'mode.local.description': 'Relay listens on 127.0.0.1. Local browser only.',
|
|
41
|
-
'mode.lan.description': 'Relay listens on 0.0.0.0. Accessible over LAN or Tailscale.',
|
|
42
|
-
'mode.official.description': 'Connect via official relay. No server needed.',
|
|
43
|
-
'mode.remote.description': 'Connect via self-hosted relay for external access.',
|
|
44
|
-
'overview.title': 'Status',
|
|
45
|
-
'overview.mode': 'Access mode',
|
|
46
|
-
'overview.relay': 'Relay',
|
|
47
|
-
'overview.host': 'Host connector',
|
|
48
|
-
'overview.socket': 'Herdr socket',
|
|
49
|
-
'overview.webUrl': 'Web UI',
|
|
50
|
-
'overview.keepalive': 'Keep-alive',
|
|
51
|
-
'overview.devices': 'Browsers',
|
|
52
|
-
'overview.hosts': 'Workstations',
|
|
53
|
-
'overview.uptime': 'Relay uptime',
|
|
54
|
-
'overview.relayLocal': 'local, {bind}:{port}',
|
|
55
|
-
'overview.relayRemote': 'remote, {url}',
|
|
56
|
-
'overview.socketMissing': 'not found — is Herdr running?',
|
|
57
|
-
'overview.unreachable': 'unreachable: {message}',
|
|
58
|
-
'overview.notStarted': 'Services not running. Open Services tab to start.',
|
|
59
|
-
'pair.title': 'Pair a device',
|
|
60
|
-
'pair.generate': 'Generate pairing code',
|
|
61
|
-
'pair.regenerate': 'Regenerate code',
|
|
62
|
-
'pair.working': 'Generating pairing code…',
|
|
63
|
-
'pair.code': 'Pairing code',
|
|
64
|
-
'pair.url': 'Access URL',
|
|
65
|
-
'pair.expires': 'Expires in {minutes} (at {time})',
|
|
66
|
-
'pair.expired': 'Code expired. Generate a new one.',
|
|
67
|
-
'pair.instructions': 'Open URL and enter code to pair.',
|
|
68
|
-
'pair.qrHint': 'Scan QR code to open URL.',
|
|
69
|
-
'pair.qrUnavailable': 'Terminal too narrow for QR code; use URL above.',
|
|
70
|
-
'pair.failed': 'Could not create pairing code: {message}',
|
|
71
|
-
'pair.hostOffline': 'Relay has no workstation connected. Start services first.',
|
|
72
|
-
'services.title': 'Services',
|
|
73
|
-
'services.start': 'Start services',
|
|
74
|
-
'services.stop': 'Stop services',
|
|
75
|
-
'services.restart': 'Restart services',
|
|
76
|
-
'services.started': 'Services started.',
|
|
77
|
-
'services.stopped': 'Services stopped.',
|
|
78
|
-
'services.restarted': 'Services restarted.',
|
|
79
|
-
'services.startFailed': 'Could not start services: {message}',
|
|
80
|
-
'services.stopFailed': 'Could not stop services: {message}',
|
|
81
|
-
'services.unsavedBlocked': 'Unsaved changes. Save before restarting.',
|
|
82
|
-
'services.managedNotice': 'Managed by {manager}; applied via keep-alive service.',
|
|
83
|
-
'services.logs': 'Recent logs',
|
|
84
|
-
'services.logEmpty': 'No logs.',
|
|
85
|
-
'services.logRelay': 'Relay',
|
|
86
|
-
'services.logHost': 'Host connector',
|
|
87
|
-
'adminBroker.windowsOnly': 'The administrator terminal broker only runs on Windows.',
|
|
88
|
-
'adminBroker.needsElevation': 'Open the Windows TUI and choose Set up admin terminal access. Approve the one-time Windows prompt under the same account as Herdr Remote.',
|
|
89
|
-
'adminBroker.busy': 'An admin terminal is open; close it before restarting the broker.',
|
|
90
|
-
'adminBroker.title': 'Admin terminal broker',
|
|
91
|
-
'adminBroker.checking': 'Checking…',
|
|
92
|
-
'adminBroker.ready': 'Ready',
|
|
93
|
-
'adminBroker.notReady': 'Not configured or stopped',
|
|
94
|
-
'adminBroker.install': 'Set up admin terminal access',
|
|
95
|
-
'adminBroker.uninstall': 'Remove admin terminal access',
|
|
96
|
-
'adminBroker.installDone': 'Admin terminal broker setup task registered.',
|
|
97
|
-
'adminBroker.uninstallDone': 'Admin terminal broker setup task removed.',
|
|
98
|
-
'adminBroker.elevationCancelled': 'Administrator approval was declined; no changes were made.',
|
|
99
|
-
'adminBroker.setupFailed': 'Could not configure the administrator terminal broker.',
|
|
100
|
-
'adminBroker.tuiHint': 'Set this up once. Windows asks for administrator approval; later WebUI admin terminals open without UAC.',
|
|
101
|
-
'adminShell.needsTerminal': 'admin-shell must run in a terminal.',
|
|
102
|
-
'adminShell.brokerUnavailable': 'The administrator terminal broker is not running. Open the herdr-remote TUI, go to Keep-alive, and choose Set up admin terminal access.',
|
|
103
|
-
'adminShell.tabLabel': 'Admin',
|
|
104
|
-
'relay.title': 'Relay settings',
|
|
105
|
-
'relay.settings': 'Settings',
|
|
106
|
-
'relay.locked': 'fixed',
|
|
107
|
-
'relay.officialFixed': 'The official relay address is fixed and cannot be edited.',
|
|
108
|
-
'relay.officialHint': 'Official relay: address is fixed and no password is needed.',
|
|
109
|
-
'relay.password': 'Relay password',
|
|
110
|
-
'relay.passwordHint': 'Must match RELAY_PASSWORD on relay. Leave empty if public.',
|
|
111
|
-
'relay.passwordSet': 'set',
|
|
112
|
-
'relay.passwordEmpty': 'not set (public)',
|
|
113
|
-
'relay.passwordSaved': 'Relay password saved. Restart services to apply.',
|
|
114
|
-
'relay.showPassword': 'Show password',
|
|
115
|
-
'relay.hidePassword': 'Hide password',
|
|
116
|
-
'relay.identity': 'Workstation ID',
|
|
117
|
-
'relay.regenerate': 'Generate new ID',
|
|
118
|
-
'relay.regenerated': 'New workstation identity generated. Restart services to re-register.',
|
|
119
|
-
'relay.envSnippet': 'Relay startup command',
|
|
120
|
-
'relay.envHint': 'Run this command on the relay host.',
|
|
121
|
-
'relay.test': 'Test relay connection',
|
|
122
|
-
'relay.testOk': 'Relay reachable: version {version}, {hosts} workstation(s) connected.',
|
|
123
|
-
'relay.testFailed': 'Relay unreachable: {message}',
|
|
124
|
-
'relay.selectAddress': 'Choose advertised address',
|
|
125
|
-
'relay.listenAddress': 'Listen address',
|
|
126
|
-
'relay.listenAddressHint': 'Server bind address. Browsers use advertised address below.',
|
|
127
|
-
'relay.addressTailscale': 'Tailscale',
|
|
128
|
-
'relay.addressLan': 'LAN',
|
|
129
|
-
'relay.addressVirtual': 'virtual',
|
|
130
|
-
'relay.addressLoopback': 'loopback',
|
|
131
|
-
'relay.noAddresses': 'No non-loopback addresses found.',
|
|
132
|
-
'relay.docsHint': 'Self-hosting guide: docs/self-hosted-relay.md',
|
|
133
|
-
'keepalive.title': 'Keep-alive service',
|
|
134
|
-
'keepalive.manager': 'Manager',
|
|
135
|
-
'keepalive.state': 'State',
|
|
136
|
-
'keepalive.install': 'Install and start',
|
|
137
|
-
'keepalive.uninstall': 'Stop and remove',
|
|
138
|
-
'keepalive.restart': 'Restart service',
|
|
139
|
-
'keepalive.installed': 'Keep-alive installed with {manager}.',
|
|
140
|
-
'keepalive.uninstalled': 'Keep-alive removed.',
|
|
141
|
-
'keepalive.restarted': 'Keep-alive service restarted.',
|
|
142
|
-
'keepalive.failed': 'Keep-alive operation failed: {message}',
|
|
143
|
-
'keepalive.unitPath': 'Unit file',
|
|
144
|
-
'keepalive.logsHint': 'View logs: {command}',
|
|
145
|
-
'keepalive.linger': 'Start at boot',
|
|
146
|
-
'keepalive.lingerEnabled': 'Start at boot enabled.',
|
|
147
|
-
'keepalive.lingerDisabled': 'Start at boot disabled (runs while logged in).',
|
|
148
|
-
'keepalive.enableLinger': 'Enable start at boot',
|
|
149
|
-
'keepalive.lingerDone': 'Start at boot enabled for {username}.',
|
|
150
|
-
'keepalive.fallbackNote': 'No system service manager found; background process will not survive reboot.',
|
|
151
|
-
'keepalive.windowsTaskNote': 'Starts after you sign in as your account. It needs no password or administrator rights and does not run before sign-in.',
|
|
152
|
-
'keepalive.serviceNote': 'Runs as a Windows service under your account and starts before sign-in. Installing or removing it asks for administrator rights, and Windows may require your account password.',
|
|
153
|
-
'keepalive.serviceWindowHint': 'Finish the installation in the administrator window that opens.',
|
|
154
|
-
'keepalive.elevationCancelled': 'Administrator rights were not granted; nothing was installed.',
|
|
155
|
-
'keepalive.passwordPrompt': 'Windows account password for {account} (not a PIN; press Enter if there is no password):',
|
|
156
|
-
'keepalive.passwordRejected': 'Windows could not start the service with those credentials. Check the account password and service logon policy.',
|
|
157
|
-
'keepalive.serviceInstalled': 'Service {id} is installed and running.',
|
|
158
|
-
'keepalive.wrongAccount': 'Run this as the account that will use herdr-remote, not another administrator account.',
|
|
159
|
-
'keepalive.pressEnter': 'Press Enter to close this window.',
|
|
160
|
-
'herdr.title': 'Herdr integration',
|
|
161
|
-
'herdr.socketPath': 'Socket path',
|
|
162
|
-
'herdr.args': 'Extra arguments',
|
|
163
|
-
'herdr.autoStartHint': 'Off: Herdr starts only when you run it, or when you confirm it from a browser. On: herdr-remote also starts it every time it starts, at boot included. Takes effect the next time herdr-remote starts.',
|
|
164
|
-
'herdr.cliMissing': 'Command herdr not found. Set HERDR_BIN_PATH to its full path.',
|
|
165
|
-
'herdr.version': 'Herdr version',
|
|
166
|
-
'herdr.versionOutdated': 'Herdr {version} is older than {minimum}. Run "herdr update": window titles, large pastes, taps on a pane and Alt shortcuts misbehave in browser windows before that release.',
|
|
167
|
-
'about.title': 'Language & about',
|
|
168
|
-
'about.language': 'Interface language',
|
|
169
|
-
'about.languageAuto': 'Follow system ({detected})',
|
|
170
|
-
'about.languageZh': '中文',
|
|
171
|
-
'about.languageEn': 'English',
|
|
172
|
-
'about.version': 'Version',
|
|
173
|
-
'about.configPath': 'Config file',
|
|
174
|
-
'about.statePath': 'State directory',
|
|
175
|
-
'about.relayPackage': 'Relay package',
|
|
176
|
-
'about.docs': 'Self-hosting guide: docs/self-hosted-relay.md',
|
|
177
|
-
'wizard.title': 'First-time setup',
|
|
178
|
-
'wizard.step': 'Step {current} of {total}',
|
|
179
|
-
'wizard.languageTitle': 'Choose language',
|
|
180
|
-
'wizard.accessTitle': 'Access mode',
|
|
181
|
-
'wizard.accessHint': 'Can be changed later in Relay settings.',
|
|
182
|
-
'wizard.addressTitle': 'Browser access address',
|
|
183
|
-
'wizard.relayTitle': 'Relay server',
|
|
184
|
-
'wizard.relayUrlLabel': 'Relay URL (wss://…)',
|
|
185
|
-
'wizard.relayHint': 'Relay must be running. See docs/self-hosted-relay.md.',
|
|
186
|
-
'wizard.passwordTitle': 'Relay password',
|
|
187
|
-
'wizard.passwordHint': 'RELAY_PASSWORD of the relay. Leave empty if unset.',
|
|
188
|
-
'wizard.finishTitle': 'Finish',
|
|
189
|
-
'wizard.finishHint': 'Configuration will be saved to {path}.',
|
|
190
|
-
'wizard.startNow': 'Start services now',
|
|
191
|
-
'wizard.installKeepalive': 'Run in background',
|
|
192
|
-
'wizard.finish': 'Save and finish',
|
|
193
|
-
'field.mode': 'Access mode',
|
|
194
|
-
'field.port': 'Relay port',
|
|
195
|
-
'field.lanHost': 'Browser address',
|
|
196
|
-
'field.remoteUrl': 'Relay URL',
|
|
197
|
-
'field.publicUrl': 'Browser URL override',
|
|
198
|
-
'field.socketPath': 'Herdr socket path',
|
|
199
|
-
'field.herdrArgs': 'Herdr arguments',
|
|
200
|
-
'field.herdrAutoStart': 'Auto-start Herdr',
|
|
201
|
-
'field.language': 'Language',
|
|
202
|
-
'field.keepalive': 'Keep-alive manager',
|
|
203
|
-
'placeholder.autoDiscovered': 'auto-discovered',
|
|
204
|
-
'placeholder.none': 'none',
|
|
205
|
-
'error.invalidMode': 'Unknown access mode.',
|
|
206
|
-
'error.invalidPort': 'Port must be a number between 1 and 65535.',
|
|
207
|
-
'error.invalidLanHost': 'Browser address must be a reachable LAN or Tailscale address, not loopback or 0.0.0.0.',
|
|
208
|
-
'error.invalidRelayUrl': 'Relay URL must start with wss://, ws://, https:// or http://.',
|
|
209
|
-
'error.invalidPublicUrl': 'Browser URL must start with https:// or http:// and cannot use 0.0.0.0 or ::.',
|
|
210
|
-
'error.invalidLanguage': 'Unknown language.',
|
|
211
|
-
'error.invalidKeepalive': 'Unknown keep-alive manager.',
|
|
212
|
-
'error.unknownField': 'Unknown setting.',
|
|
213
|
-
'error.remoteUrlRequired': 'Relay URL is required for self-hosted relay mode.',
|
|
214
|
-
'error.removedHerdrArg': 'Herdr 0.9.0 removed --no-session; remove it from the extra arguments.',
|
|
215
|
-
'error.saveFailed': 'Could not save configuration: {message}',
|
|
216
|
-
'hint.navigate': '↑↓ move',
|
|
217
|
-
'hint.select': '↵ select',
|
|
218
|
-
'hint.edit': '↵ edit',
|
|
219
|
-
'hint.tabs': '← → switch tab',
|
|
220
|
-
'hint.back': 'esc back',
|
|
221
|
-
'hint.quit': 'q quit',
|
|
222
|
-
'hint.mouseOn': 'm mouse off',
|
|
223
|
-
'hint.mouseOff': 'm mouse on',
|
|
224
|
-
'hint.mouseUnsupported': 'mouse unsupported',
|
|
225
|
-
'hint.restartRequired': 'Restart services to apply changes.',
|
|
226
|
-
'hint.unsavedChanges': 'Unsaved changes (press s to save).',
|
|
227
|
-
'hint.save': 's save',
|
|
228
|
-
'hint.editing': '↵ confirm · esc cancel',
|
|
229
|
-
'update.title': 'Updates',
|
|
230
|
-
'update.banner': 'herdr-remote {latest} is out (running {current}). Press 7 and Enter on the update row to install.',
|
|
231
|
-
'update.check': 'Check for updates',
|
|
232
|
-
'update.checking': 'Checking GitHub Releases and npm…',
|
|
233
|
-
'update.upToDate': 'Up to date ({version})',
|
|
234
|
-
'update.available': 'Update {version} available (press Enter to install)',
|
|
235
|
-
'update.updating': 'Installing {version}…',
|
|
236
|
-
'update.updatingRetry': 'Installing {version}… (npm has not caught up yet, attempt {attempt})',
|
|
237
|
-
'update.done': 'Updated to {version}',
|
|
238
|
-
'update.restartHint': 'Update installed. Restart herdr-remote to apply.',
|
|
239
|
-
'update.errorNetwork': 'Could not reach GitHub Releases or any npm registry',
|
|
240
|
-
'update.errorNetworkDetail': 'Nothing answered: {message}',
|
|
241
|
-
'update.errorFailed': 'Update failed. Run: npm install -g {url}',
|
|
242
|
-
'update.errorFailedDetail': 'npm: {message}',
|
|
243
|
-
'update.errorNotYetPublished': 'npm has not caught up with {version} yet (common in the first minutes after a release). Press Enter to try again shortly.',
|
|
244
|
-
'update.errorNotApplied': 'npm reported success, but {installed} is still installed',
|
|
245
|
-
'update.mirrorBehind': '{registries} still has an older version; installing from {source}',
|
|
246
|
-
'update.cannot.source': 'Source checkout — update with git',
|
|
247
|
-
'update.cannot.linked': 'Linked package — managed by npm link',
|
|
248
|
-
'update.stoppingServices': 'Stopping services while npm replaces their files…',
|
|
249
|
-
'update.restarting': 'Restarting services on the new release…',
|
|
250
|
-
'update.notRunning': 'Services were not running and were left stopped. Start them with: herdr-remote start',
|
|
251
|
-
'update.restartFailed': 'Installed, but the services did not restart: {message}',
|
|
252
|
-
'update.brokerRestarted': 'Admin terminal broker restarted.',
|
|
253
|
-
'update.brokerRestartFailed': 'The admin terminal broker did not start again. Sign out of Windows and back in, or run herdr-remote admin-broker restart.',
|
|
254
|
-
'update.brokerBusy': 'An admin terminal is open, so the broker keeps running the previous release. Close admin terminals, then run herdr-remote admin-broker restart.',
|
|
255
|
-
'update.errorBusy': "A process still holds the herdr-remote folder; an admin terminal broker set up by an older release does. In an administrator PowerShell run: Get-ScheduledTask -TaskName 'HerdrRemoteAdminBroker-*' | Stop-ScheduledTask. Then run herdr-remote update again here, and afterwards herdr-remote admin-broker install as administrator.",
|
|
256
|
-
};
|
|
257
|
-
export default en;
|
package/dist/i18n/index.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import en from './en.js';
|
|
2
|
-
import zh from './zh.js';
|
|
3
|
-
const CATALOGUES = { en, zh };
|
|
4
|
-
const DEFAULT_LOCALE = 'en';
|
|
5
|
-
function isLocale(value) {
|
|
6
|
-
return typeof value === 'string' && Object.hasOwn(CATALOGUES, value);
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Work out the interface language from the environment.
|
|
10
|
-
*
|
|
11
|
-
* Order matters: an explicit override wins, then the saved preference, then the
|
|
12
|
-
* POSIX locale variables in the order the C library itself consults them.
|
|
13
|
-
*/
|
|
14
|
-
function detectLocale({ env = process.env, preference = 'auto', } = {}) {
|
|
15
|
-
if (preference && preference !== 'auto' && isLocale(preference))
|
|
16
|
-
return preference;
|
|
17
|
-
if (isLocale(env.HERDR_REMOTE_LANG))
|
|
18
|
-
return env.HERDR_REMOTE_LANG;
|
|
19
|
-
const raw = env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE || '';
|
|
20
|
-
const primary = String(raw).split(/[:.@]/)[0].toLowerCase();
|
|
21
|
-
if (primary.startsWith('zh'))
|
|
22
|
-
return 'zh';
|
|
23
|
-
return DEFAULT_LOCALE;
|
|
24
|
-
}
|
|
25
|
-
function interpolate(template, values) {
|
|
26
|
-
if (!values)
|
|
27
|
-
return template;
|
|
28
|
-
return template.replace(/\{(\w+)\}/g, (match, key) => Object.hasOwn(values, key) ? String(values[key]) : match);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Build a translator for a locale.
|
|
32
|
-
*
|
|
33
|
-
* A missing key falls back to English and finally to the key itself, so a typo
|
|
34
|
-
* shows up as a visible key rather than an empty gap in the layout.
|
|
35
|
-
*/
|
|
36
|
-
function createTranslator(locale = DEFAULT_LOCALE) {
|
|
37
|
-
const active = isLocale(locale) ? CATALOGUES[locale] : CATALOGUES[DEFAULT_LOCALE];
|
|
38
|
-
const fallback = CATALOGUES[DEFAULT_LOCALE];
|
|
39
|
-
const t = (key, values) => {
|
|
40
|
-
const template = active[key] ?? fallback[key] ?? key;
|
|
41
|
-
return interpolate(template, values);
|
|
42
|
-
};
|
|
43
|
-
return Object.assign(t, {
|
|
44
|
-
locale,
|
|
45
|
-
has: (key) => Object.hasOwn(active, key),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
export { CATALOGUES, detectLocale, createTranslator, interpolate };
|