herdr-remote 0.2.33 → 0.2.35
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 +3 -1
- package/README.zh-CN.md +2 -1
- package/dist/i18n/en.js +4 -17
- package/dist/i18n/zh.js +4 -17
- package/dist/tui/App.js +3 -25
- package/dist/tui/api.js +3 -3
- package/dist/tui/screens/About.js +18 -27
- package/dist/update-command.js +16 -19
- package/dist/updater.js +91 -48
- package/herdr-plugin.toml +1 -1
- package/node_modules/herdr-remote-relay/LICENSE +21 -0
- package/node_modules/herdr-remote-relay/README.md +76 -0
- package/node_modules/herdr-remote-relay/README.zh-CN.md +76 -0
- package/node_modules/herdr-remote-relay/bin/herdr-remote-relay.js +116 -0
- package/node_modules/herdr-remote-relay/config.example.json +18 -0
- package/node_modules/herdr-remote-relay/deploy/cloudflared/config.yml.example +9 -0
- package/node_modules/herdr-remote-relay/deploy/docker/compose.yaml +23 -0
- package/node_modules/herdr-remote-relay/deploy/nginx/herdr-remote-relay.conf.example +49 -0
- package/node_modules/herdr-remote-relay/deploy/systemd/herdr-remote-relay.service +41 -0
- package/node_modules/herdr-remote-relay/deploy/systemd/relay.env.example +25 -0
- package/node_modules/herdr-remote-relay/dist/auth-store.d.ts +114 -0
- package/node_modules/herdr-remote-relay/dist/auth-store.js +289 -0
- package/node_modules/herdr-remote-relay/dist/metrics.d.ts +76 -0
- package/node_modules/herdr-remote-relay/dist/metrics.js +249 -0
- package/node_modules/herdr-remote-relay/dist/protocol/frames.d.ts +27 -0
- package/node_modules/herdr-remote-relay/dist/protocol/frames.js +110 -0
- package/node_modules/herdr-remote-relay/dist/protocol/herdr-keys.d.ts +8 -0
- package/node_modules/herdr-remote-relay/dist/protocol/herdr-keys.js +34 -0
- package/node_modules/herdr-remote-relay/dist/protocol/http.d.ts +165 -0
- package/node_modules/herdr-remote-relay/dist/protocol/http.js +3 -0
- package/node_modules/herdr-remote-relay/dist/protocol/index.d.ts +7 -0
- package/node_modules/herdr-remote-relay/dist/protocol/index.js +9 -0
- package/node_modules/herdr-remote-relay/dist/protocol/messages.d.ts +362 -0
- package/node_modules/herdr-remote-relay/dist/protocol/messages.js +20 -0
- package/node_modules/herdr-remote-relay/dist/protocol/paste.d.ts +14 -0
- package/node_modules/herdr-remote-relay/dist/protocol/paste.js +50 -0
- package/node_modules/herdr-remote-relay/dist/protocol/release.d.ts +8 -0
- package/node_modules/herdr-remote-relay/dist/protocol/release.js +17 -0
- package/node_modules/herdr-remote-relay/dist/protocol/terminal.d.ts +79 -0
- package/node_modules/herdr-remote-relay/dist/protocol/terminal.js +150 -0
- package/node_modules/herdr-remote-relay/dist/relay-config.d.ts +74 -0
- package/node_modules/herdr-remote-relay/dist/relay-config.js +316 -0
- package/node_modules/herdr-remote-relay/dist/relay-server.d.ts +64 -0
- package/node_modules/herdr-remote-relay/dist/relay-server.js +194 -0
- package/node_modules/herdr-remote-relay/dist/scroll-input.d.ts +17 -0
- package/node_modules/herdr-remote-relay/dist/scroll-input.js +124 -0
- package/node_modules/herdr-remote-relay/dist/server/client-channel.d.ts +3 -0
- package/node_modules/herdr-remote-relay/dist/server/client-channel.js +396 -0
- package/node_modules/herdr-remote-relay/dist/server/font-proxy.d.ts +19 -0
- package/node_modules/herdr-remote-relay/dist/server/font-proxy.js +155 -0
- package/node_modules/herdr-remote-relay/dist/server/host-broadcasts.d.ts +27 -0
- package/node_modules/herdr-remote-relay/dist/server/host-broadcasts.js +83 -0
- package/node_modules/herdr-remote-relay/dist/server/host-channel.d.ts +3 -0
- package/node_modules/herdr-remote-relay/dist/server/host-channel.js +271 -0
- package/node_modules/herdr-remote-relay/dist/server/http-api.d.ts +3 -0
- package/node_modules/herdr-remote-relay/dist/server/http-api.js +214 -0
- package/node_modules/herdr-remote-relay/dist/server/maintenance.d.ts +5 -0
- package/node_modules/herdr-remote-relay/dist/server/maintenance.js +64 -0
- package/node_modules/herdr-remote-relay/dist/server/requests.d.ts +34 -0
- package/node_modules/herdr-remote-relay/dist/server/requests.js +142 -0
- package/node_modules/herdr-remote-relay/dist/server/sessions.d.ts +36 -0
- package/node_modules/herdr-remote-relay/dist/server/sessions.js +230 -0
- package/node_modules/herdr-remote-relay/dist/server/sockets.d.ts +12 -0
- package/node_modules/herdr-remote-relay/dist/server/sockets.js +64 -0
- package/node_modules/herdr-remote-relay/dist/server/status.d.ts +11 -0
- package/node_modules/herdr-remote-relay/dist/server/status.js +99 -0
- package/node_modules/herdr-remote-relay/dist/server/transport.d.ts +16 -0
- package/node_modules/herdr-remote-relay/dist/server/transport.js +110 -0
- package/node_modules/herdr-remote-relay/dist/server/types.d.ts +131 -0
- package/node_modules/herdr-remote-relay/dist/server/types.js +3 -0
- package/node_modules/herdr-remote-relay/dist/server/version.d.ts +2 -0
- package/node_modules/herdr-remote-relay/dist/server/version.js +5 -0
- package/node_modules/herdr-remote-relay/dist/state.d.ts +6 -0
- package/node_modules/herdr-remote-relay/dist/state.js +47 -0
- package/node_modules/herdr-remote-relay/package.json +76 -0
- package/node_modules/herdr-remote-relay/web/dist/assets/index-BeveQ9Di.js +61 -0
- package/node_modules/herdr-remote-relay/web/dist/assets/index-XYYRsgSb.css +32 -0
- package/node_modules/herdr-remote-relay/web/dist/assets/vendor-react-CYSfZuHu.js +17 -0
- package/node_modules/herdr-remote-relay/web/dist/assets/vendor-xterm-BhCxil_4.js +9 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/SymbolsNerdFontMono-Regular.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/OFL.txt +93 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-ext-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-ext-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-ext-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/cascadia-code/cascadia-code-latin-ext-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/fira-code/OFL.txt +93 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/fira-code/fira-code-latin-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/fira-code/fira-code-latin-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/fira-code/fira-code-latin-ext-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/fira-code/fira-code-latin-ext-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/OFL.txt +93 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-ext-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-ext-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-ext-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/ibm-plex-mono/ibm-plex-mono-latin-ext-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/OFL.txt +93 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-ext-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-ext-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-ext-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/jetbrains-mono/jetbrains-mono-latin-ext-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/OFL.txt +93 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-ext-400-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-ext-400-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-ext-700-italic.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/fonts/source-code-pro/source-code-pro-latin-ext-700-normal.woff2 +0 -0
- package/node_modules/herdr-remote-relay/web/dist/index.html +36 -0
- package/node_modules/ws/LICENSE +20 -0
- package/node_modules/ws/README.md +548 -0
- package/node_modules/ws/browser.js +8 -0
- package/node_modules/ws/index.js +22 -0
- package/node_modules/ws/lib/buffer-util.js +131 -0
- package/node_modules/ws/lib/constants.js +19 -0
- package/node_modules/ws/lib/event-target.js +292 -0
- package/node_modules/ws/lib/extension.js +203 -0
- package/node_modules/ws/lib/limiter.js +55 -0
- package/node_modules/ws/lib/permessage-deflate.js +530 -0
- package/node_modules/ws/lib/receiver.js +743 -0
- package/node_modules/ws/lib/sender.js +607 -0
- package/node_modules/ws/lib/stream.js +161 -0
- package/node_modules/ws/lib/subprotocol.js +62 -0
- package/node_modules/ws/lib/validation.js +152 -0
- package/node_modules/ws/lib/websocket-server.js +562 -0
- package/node_modules/ws/lib/websocket.js +1407 -0
- package/node_modules/ws/package.json +74 -0
- package/node_modules/ws/wrapper.mjs +21 -0
- package/package.json +7 -3
- package/dist/relay-updater.js +0 -81
- package/dist/tui/screens/useRelayUpdate.js +0 -122
package/README.md
CHANGED
|
@@ -7,11 +7,13 @@ Web terminal client for [Herdr](https://herdr.dev) workspaces. Mobile-friendly U
|
|
|
7
7
|
## Installation & Usage
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g herdr-remote
|
|
10
|
+
npm install -g https://github.com/dibin666/herdr-remote/releases/latest/download/herdr-remote.tgz
|
|
11
11
|
herdr-remote
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
Running `herdr-remote` without arguments launches the setup wizard and configuration TUI.
|
|
15
|
+
Releases go to [GitHub Releases](https://github.com/dibin666/herdr-remote/releases) first and to
|
|
16
|
+
npm as a fallback (`npm install -g herdr-remote`); `herdr-remote update` follows the same order.
|
|
15
17
|
|
|
16
18
|
Native Windows 10/11 is supported with Node.js 22+; install Herdr from PowerShell with
|
|
17
19
|
`powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"`.
|
package/README.zh-CN.md
CHANGED
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
## 安装与运行
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g herdr-remote
|
|
10
|
+
npm install -g https://github.com/dibin666/herdr-remote/releases/latest/download/herdr-remote.tgz
|
|
11
11
|
herdr-remote
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
直接运行 `herdr-remote` 即可启动向导并进入配置 TUI。
|
|
15
|
+
新版本先发布到 [GitHub Releases](https://github.com/dibin666/herdr-remote/releases),npm 作为备用渠道(`npm install -g herdr-remote`);`herdr-remote update` 按同样的顺序更新。
|
|
15
16
|
|
|
16
17
|
已支持 Windows 10/11 原生运行(需 Node.js 22+),请在 PowerShell 中执行
|
|
17
18
|
`powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"` 安装 Herdr。
|
package/dist/i18n/en.js
CHANGED
|
@@ -229,16 +229,16 @@ const en = {
|
|
|
229
229
|
'update.title': 'Updates',
|
|
230
230
|
'update.banner': 'herdr-remote {latest} is out (running {current}). Press 7 and Enter on the update row to install.',
|
|
231
231
|
'update.check': 'Check for updates',
|
|
232
|
-
'update.checking': 'Checking npm…',
|
|
232
|
+
'update.checking': 'Checking GitHub Releases and npm…',
|
|
233
233
|
'update.upToDate': 'Up to date ({version})',
|
|
234
234
|
'update.available': 'Update {version} available (press Enter to install)',
|
|
235
235
|
'update.updating': 'Installing {version}…',
|
|
236
236
|
'update.updatingRetry': 'Installing {version}… (npm has not caught up yet, attempt {attempt})',
|
|
237
237
|
'update.done': 'Updated to {version}',
|
|
238
238
|
'update.restartHint': 'Update installed. Restart herdr-remote to apply.',
|
|
239
|
-
'update.errorNetwork': 'Could not reach any npm registry',
|
|
240
|
-
'update.errorNetworkDetail': '
|
|
241
|
-
'update.errorFailed': 'Update failed. Run: npm install -g
|
|
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
242
|
'update.errorFailedDetail': 'npm: {message}',
|
|
243
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
244
|
'update.errorNotApplied': 'npm reported success, but {installed} is still installed',
|
|
@@ -253,18 +253,5 @@ const en = {
|
|
|
253
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
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
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
|
-
'relayUpdate.check': 'Relay {version}: check for updates',
|
|
257
|
-
'relayUpdate.checking': 'Relay: checking npm…',
|
|
258
|
-
'relayUpdate.upToDate': 'Relay up to date ({version})',
|
|
259
|
-
'relayUpdate.available': 'Relay {latest} available, installed {installed} (press Enter to install)',
|
|
260
|
-
'relayUpdate.needsCli': 'Relay {latest} needs a newer herdr-remote: update herdr-remote first',
|
|
261
|
-
'relayUpdate.updating': 'Installing relay {version}…',
|
|
262
|
-
'relayUpdate.updatingRetry': 'Installing relay {version}… (npm has not caught up yet, attempt {attempt})',
|
|
263
|
-
'relayUpdate.restart': 'Relay {version} installed, {running} still running (press Enter to restart)',
|
|
264
|
-
'relayUpdate.restarting': 'Restarting herdr-remote…',
|
|
265
|
-
'relayUpdate.restarted': 'herdr-remote restarted; the relay now runs {version}.',
|
|
266
|
-
'relayUpdate.done': 'Relay updated to {version}',
|
|
267
|
-
'relayUpdate.errorNotApplied': 'npm finished, but relay {installed} is still installed',
|
|
268
|
-
'relayUpdate.banner': 'Relay {latest} is out (installed {current}). Press 7 and Enter on the relay row to install.',
|
|
269
256
|
};
|
|
270
257
|
export default en;
|
package/dist/i18n/zh.js
CHANGED
|
@@ -228,16 +228,16 @@ const zh = {
|
|
|
228
228
|
'update.title': '更新',
|
|
229
229
|
'update.banner': 'herdr-remote {latest} 已发布(当前 {current}),按 7 进入「语言与关于」,在更新一行按 Enter 安装。',
|
|
230
230
|
'update.check': '检查更新',
|
|
231
|
-
'update.checking': '查询 npm 中…',
|
|
231
|
+
'update.checking': '查询 GitHub Releases 与 npm 中…',
|
|
232
232
|
'update.upToDate': '已是最新({version})',
|
|
233
233
|
'update.available': '新版本 {version} 可用(按 Enter 安装)',
|
|
234
234
|
'update.updating': '安装 {version} 中…',
|
|
235
235
|
'update.updatingRetry': '安装 {version} 中…(npm 尚未同步,第 {attempt} 次尝试)',
|
|
236
236
|
'update.done': '已更新至 {version}',
|
|
237
237
|
'update.restartHint': '更新已安装,重启 herdr-remote 生效。',
|
|
238
|
-
'update.errorNetwork': '
|
|
239
|
-
'update.errorNetworkDetail': '
|
|
240
|
-
'update.errorFailed': '更新失败,可手动执行:npm install -g
|
|
238
|
+
'update.errorNetwork': 'GitHub Releases 与所有 npm registry 均无法连接',
|
|
239
|
+
'update.errorNetworkDetail': '均无应答:{message}',
|
|
240
|
+
'update.errorFailed': '更新失败,可手动执行:npm install -g {url}',
|
|
241
241
|
'update.errorFailedDetail': 'npm:{message}',
|
|
242
242
|
'update.errorNotYetPublished': 'npm 还没同步到 {version}(刚发布的几分钟内常见),稍后按 Enter 重试。',
|
|
243
243
|
'update.errorNotApplied': 'npm 报告成功,但安装的仍是 {installed}',
|
|
@@ -252,18 +252,5 @@ const zh = {
|
|
|
252
252
|
'update.brokerRestartFailed': '管理员终端 broker 没有重新启动。重新登录 Windows,或运行 herdr-remote admin-broker restart。',
|
|
253
253
|
'update.brokerBusy': '有管理员终端开着,broker 继续运行旧版本。关闭所有管理员终端后运行 herdr-remote admin-broker restart。',
|
|
254
254
|
'update.errorBusy': "仍有进程占用 herdr-remote 的安装目录,旧版本设置的管理员终端 broker 会这样。先在管理员 PowerShell 中执行:Get-ScheduledTask -TaskName 'HerdrRemoteAdminBroker-*' | Stop-ScheduledTask,再回到这里重新运行 herdr-remote update,最后以管理员身份运行 herdr-remote admin-broker install。",
|
|
255
|
-
'relayUpdate.check': 'Relay {version}:检查更新',
|
|
256
|
-
'relayUpdate.checking': 'Relay:查询 npm 中…',
|
|
257
|
-
'relayUpdate.upToDate': 'Relay 已是最新({version})',
|
|
258
|
-
'relayUpdate.available': 'Relay 新版本 {latest} 可用,当前 {installed}(按 Enter 安装)',
|
|
259
|
-
'relayUpdate.needsCli': 'Relay {latest} 需要更新 herdr-remote,请先更新上一行',
|
|
260
|
-
'relayUpdate.updating': '安装 relay {version} 中…',
|
|
261
|
-
'relayUpdate.updatingRetry': '安装 relay {version} 中…(npm 尚未同步,第 {attempt} 次尝试)',
|
|
262
|
-
'relayUpdate.restart': 'Relay {version} 已安装,运行中的仍是 {running}(按 Enter 重启生效)',
|
|
263
|
-
'relayUpdate.restarting': '正在重启 herdr-remote…',
|
|
264
|
-
'relayUpdate.restarted': 'herdr-remote 已重启,relay 现在运行 {version}。',
|
|
265
|
-
'relayUpdate.done': 'Relay 已更新至 {version}',
|
|
266
|
-
'relayUpdate.errorNotApplied': 'npm 已完成,但安装的仍是 relay {installed}',
|
|
267
|
-
'relayUpdate.banner': 'Relay {latest} 已发布(当前 {current}),按 7 进入「语言与关于」,在 Relay 一行按 Enter 安装。',
|
|
268
255
|
};
|
|
269
256
|
export default zh;
|
package/dist/tui/App.js
CHANGED
|
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import { Box, Text, useApp, useInput } from 'ink';
|
|
4
4
|
import { useMouse, useMouseTarget } from './mouse/index.js';
|
|
5
5
|
import { theme } from './theme.js';
|
|
6
|
-
import {
|
|
6
|
+
import { checkForUpdate, createDraft, createTranslator, detectLocale, ensureRuntime, fullStatus, loadConfig, requiresRestart, updateChecksEnabled, } from './api.js';
|
|
7
7
|
import { Overview } from './screens/Overview.js';
|
|
8
8
|
import { PairScreen } from './screens/Pair.js';
|
|
9
9
|
import { Services } from './screens/Services.js';
|
|
@@ -30,7 +30,7 @@ function Tab({ label, active, onSelect, }) {
|
|
|
30
30
|
function Footer({ hints }) {
|
|
31
31
|
return (_jsx(Box, { marginTop: 1, paddingX: 1, children: _jsx(Text, { color: theme.muted, children: hints.join(' · ') }) }));
|
|
32
32
|
}
|
|
33
|
-
export function App({ initialLanguage, needsWizard, updateChecker = updateChecksEnabled() ? checkForUpdate : null,
|
|
33
|
+
export function App({ initialLanguage, needsWizard, updateChecker = updateChecksEnabled() ? checkForUpdate : null, }) {
|
|
34
34
|
const { exit } = useApp();
|
|
35
35
|
const mouse = useMouse();
|
|
36
36
|
const [config, setConfig] = useState(() => loadConfig());
|
|
@@ -43,8 +43,6 @@ export function App({ initialLanguage, needsWizard, updateChecker = updateChecks
|
|
|
43
43
|
const [editingId, setEditingId] = useState(null);
|
|
44
44
|
const [wizardDone, setWizardDone] = useState(!needsWizard);
|
|
45
45
|
const [updateCheck, setUpdateCheck] = useState(null);
|
|
46
|
-
const [relayUpdateCheck, setRelayUpdateCheck] = useState(null);
|
|
47
|
-
const localRelay = runsLocalRelay(config);
|
|
48
46
|
// Every time the TUI opens: that is when someone is here to act on it.
|
|
49
47
|
// Failure says nothing; the About tab can still be asked by hand.
|
|
50
48
|
useEffect(() => {
|
|
@@ -61,21 +59,6 @@ export function App({ initialLanguage, needsWizard, updateChecker = updateChecks
|
|
|
61
59
|
cancelled = true;
|
|
62
60
|
};
|
|
63
61
|
}, [updateChecker]);
|
|
64
|
-
// A relay somewhere else is somebody else's to update.
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
if (!relayUpdateChecker || !localRelay)
|
|
67
|
-
return undefined;
|
|
68
|
-
let cancelled = false;
|
|
69
|
-
relayUpdateChecker()
|
|
70
|
-
.then((result) => {
|
|
71
|
-
if (!cancelled && result?.ok)
|
|
72
|
-
setRelayUpdateCheck(result);
|
|
73
|
-
})
|
|
74
|
-
.catch(() => { });
|
|
75
|
-
return () => {
|
|
76
|
-
cancelled = true;
|
|
77
|
-
};
|
|
78
|
-
}, [relayUpdateChecker, localRelay]);
|
|
79
62
|
const locale = useMemo(() => detectLocale({ preference: initialLanguage ?? draft.ui.language }), [initialLanguage, draft.ui.language]);
|
|
80
63
|
const t = useMemo(() => createTranslator(locale), [locale]);
|
|
81
64
|
const dirty = useMemo(() => JSON.stringify(config) !== JSON.stringify(draft), [config, draft]);
|
|
@@ -153,8 +136,6 @@ export function App({ initialLanguage, needsWizard, updateChecker = updateChecks
|
|
|
153
136
|
message,
|
|
154
137
|
updateCheck,
|
|
155
138
|
setUpdateCheck,
|
|
156
|
-
relayUpdateCheck,
|
|
157
|
-
setRelayUpdateCheck,
|
|
158
139
|
};
|
|
159
140
|
useInput((input, key) => {
|
|
160
141
|
if (key.ctrl && input === 'c') {
|
|
@@ -214,8 +195,5 @@ export function App({ initialLanguage, needsWizard, updateChecker = updateChecks
|
|
|
214
195
|
: t('hint.mouseUnsupported'),
|
|
215
196
|
t('hint.quit'),
|
|
216
197
|
].filter(Boolean);
|
|
217
|
-
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: t('app.name') }), _jsx(Text, { color: theme.muted, children: ` ${t('app.tagline')}` })] }), updateCheck?.updateAvailable ? (_jsx(Text, { color: theme.warn, children: t('update.banner', { latest: updateCheck.latest ?? '', current: updateCheck.current }) })) : null,
|
|
218
|
-
latest: relayUpdateCheck.latest ?? '',
|
|
219
|
-
current: relayUpdateCheck.current,
|
|
220
|
-
}) })) : null] }), _jsx(Box, { marginBottom: 1, children: TABS.map((entry, entryIndex) => (_jsx(Tab, { label: `${entryIndex + 1} ${t(entry.labelKey)}`, active: entry.id === tab, onSelect: () => setTab(entry.id) }, entry.id))) }), tab === 'overview' ? _jsx(Overview, { ctx: context }) : null, tab === 'pair' ? _jsx(PairScreen, { ctx: context }) : null, tab === 'services' ? _jsx(Services, { ctx: context }) : null, tab === 'relay' ? _jsx(RelayScreen, { ctx: context }) : null, tab === 'keepalive' ? _jsx(Keepalive, { ctx: context }) : null, tab === 'herdr' ? _jsx(HerdrScreen, { ctx: context }) : null, tab === 'about' ? _jsx(About, { ctx: context }) : null, restartPending ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.warn, children: t('hint.restartRequired') }) })) : null, _jsx(Footer, { hints: hints })] }));
|
|
198
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: t('app.name') }), _jsx(Text, { color: theme.muted, children: ` ${t('app.tagline')}` })] }), updateCheck?.updateAvailable ? (_jsx(Text, { color: theme.warn, children: t('update.banner', { latest: updateCheck.latest ?? '', current: updateCheck.current }) })) : null] }), _jsx(Box, { marginBottom: 1, children: TABS.map((entry, entryIndex) => (_jsx(Tab, { label: `${entryIndex + 1} ${t(entry.labelKey)}`, active: entry.id === tab, onSelect: () => setTab(entry.id) }, entry.id))) }), tab === 'overview' ? _jsx(Overview, { ctx: context }) : null, tab === 'pair' ? _jsx(PairScreen, { ctx: context }) : null, tab === 'services' ? _jsx(Services, { ctx: context }) : null, tab === 'relay' ? _jsx(RelayScreen, { ctx: context }) : null, tab === 'keepalive' ? _jsx(Keepalive, { ctx: context }) : null, tab === 'herdr' ? _jsx(HerdrScreen, { ctx: context }) : null, tab === 'about' ? _jsx(About, { ctx: context }) : null, restartPending ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.warn, children: t('hint.restartRequired') }) })) : null, _jsx(Footer, { hints: hints })] }));
|
|
221
199
|
}
|
package/dist/tui/api.js
CHANGED
|
@@ -16,9 +16,9 @@ import { ensureRuntime, regenerateHostIdentity, setRelayPassword } from '../runt
|
|
|
16
16
|
import { pair, readLogTail } from '../service.js';
|
|
17
17
|
import { fullStatus, restartAll, startAll, stopAll, whileServicesStopped } from '../lifecycle.js';
|
|
18
18
|
import * as keepalive from '../keepalive/index.js';
|
|
19
|
-
import { canSelfUpdate, checkForUpdate,
|
|
20
|
-
|
|
21
|
-
export { detectLocale, listReachableAddresses, MIN_HERDR_VERSION, OFFICIAL_RELAY_URL, isOfficialRelay, selectedMode, canSelfUpdate, checkForUpdate,
|
|
19
|
+
import { canSelfUpdate, checkForUpdate, currentVersion, updateChecksEnabled, installKind, installedRelayVersion, performUpdate, } from '../updater.js';
|
|
20
|
+
export { cliTarballUrl } from 'herdr-remote-relay/protocol';
|
|
21
|
+
export { detectLocale, listReachableAddresses, MIN_HERDR_VERSION, OFFICIAL_RELAY_URL, isOfficialRelay, selectedMode, canSelfUpdate, checkForUpdate, currentVersion, updateChecksEnabled, installKind, performUpdate, installedRelayVersion, runsLocalRelay, bindAddress, configExists, configPath, createDraft, createTranslator, ensureRuntime, extractPairingCode, fieldsForMode, fullStatus, getField, getFieldPlaceholder, herdrVersion, keepalive, loadConfig, pair, readLogTail, regenerateHostIdentity, requiresRestart, restartAll, saveDraft, setField, setRelayPassword, startAll, stateDir, stopAll, whileServicesStopped, };
|
|
22
22
|
export async function adminBrokerStatus({ waitForStart = false } = {}) {
|
|
23
23
|
if (process.platform !== 'win32')
|
|
24
24
|
return false;
|
|
@@ -2,18 +2,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Box, Text, useInput } from 'ink';
|
|
4
4
|
import { theme } from '../theme.js';
|
|
5
|
-
import { useRelayUpdate } from './useRelayUpdate.js';
|
|
6
5
|
import { Message, Panel, Row, Selectable } from '../components/common.js';
|
|
7
|
-
import { canSelfUpdate, checkForUpdate, configPath, currentVersion, detectLocale, installKind, performUpdate, saveDraft, setField, stateDir, whileServicesStopped, } from '../api.js';
|
|
6
|
+
import { canSelfUpdate, cliTarballUrl, checkForUpdate, configPath, currentVersion, detectLocale, installKind, installedRelayVersion, performUpdate, runsLocalRelay, saveDraft, setField, stateDir, whileServicesStopped, } from '../api.js';
|
|
8
7
|
/** `https://registry.npmmirror.com` → `registry.npmmirror.com`, for one line of text. */
|
|
9
|
-
const
|
|
8
|
+
const sourceHost = (source) => source.replace(/^https?:\/\//, '');
|
|
10
9
|
export function About({ ctx }) {
|
|
11
10
|
const { t, draft } = ctx;
|
|
12
11
|
const [selected, setSelected] = useState('auto');
|
|
13
12
|
const [update, setUpdate] = useState({ phase: 'idle' });
|
|
14
|
-
/** Why the install will come from somewhere other than
|
|
13
|
+
/** Why the install will come from somewhere other than where some sources said. */
|
|
15
14
|
const [sourceNote, setSourceNote] = useState(null);
|
|
16
|
-
const checkRef = useState(() => ({ current: {
|
|
15
|
+
const checkRef = useState(() => ({ current: { source: '', sources: [] } }))[0];
|
|
17
16
|
const detected = detectLocale({ preference: 'auto' });
|
|
18
17
|
const languageOptions = [
|
|
19
18
|
{ id: 'auto', label: t('about.languageAuto', { detected }) },
|
|
@@ -43,24 +42,19 @@ export function About({ ctx }) {
|
|
|
43
42
|
return t('update.check');
|
|
44
43
|
}
|
|
45
44
|
})();
|
|
46
|
-
const
|
|
47
|
-
const options = [
|
|
48
|
-
...languageOptions,
|
|
49
|
-
{ id: 'update', label: updateLabel },
|
|
50
|
-
...(relay.visible ? [{ id: 'relay-update', label: relay.label }] : []),
|
|
51
|
-
];
|
|
45
|
+
const options = [...languageOptions, { id: 'update', label: updateLabel }];
|
|
52
46
|
/** Show a check's answer, whether this screen asked or the TUI did on opening. */
|
|
53
47
|
const applyCheck = (result) => {
|
|
54
|
-
checkRef.current = {
|
|
55
|
-
// A
|
|
48
|
+
checkRef.current = { source: result.source ?? '', sources: result.sources ?? [] };
|
|
49
|
+
// A registry that has not synced the release yet used to be the whole
|
|
56
50
|
// answer. It is still asked, and said to be behind.
|
|
57
51
|
const behind = result.behind ?? [];
|
|
58
|
-
setSourceNote(result.updateAvailable && behind.length > 0 && result.
|
|
52
|
+
setSourceNote(result.updateAvailable && behind.length > 0 && result.source
|
|
59
53
|
? {
|
|
60
54
|
registries: behind
|
|
61
|
-
.map((entry) => `${
|
|
55
|
+
.map((entry) => `${sourceHost(entry.source)} ${entry.version ?? ''}`.trim())
|
|
62
56
|
.join(', '),
|
|
63
|
-
source:
|
|
57
|
+
source: sourceHost(result.source),
|
|
64
58
|
}
|
|
65
59
|
: null);
|
|
66
60
|
setUpdate(result.updateAvailable
|
|
@@ -79,7 +73,7 @@ export function About({ ctx }) {
|
|
|
79
73
|
const result = await checkForUpdate();
|
|
80
74
|
if (!result.ok) {
|
|
81
75
|
setUpdate({ phase: 'error', messageKey: result.errorKey ?? 'update.errorNetwork' });
|
|
82
|
-
// Which
|
|
76
|
+
// Which sources were tried, and what each of them said. Without this
|
|
83
77
|
// the row reads "could not reach npm registry" on a machine where
|
|
84
78
|
// `npm install` works perfectly, and there is nothing to act on.
|
|
85
79
|
const { message } = result;
|
|
@@ -93,13 +87,17 @@ export function About({ ctx }) {
|
|
|
93
87
|
const runUpdate = async (latest) => {
|
|
94
88
|
setUpdate({ phase: 'updating', latest, attempt: 1 });
|
|
95
89
|
const result = await whileServicesStopped(ctx.config, () => performUpdate({
|
|
96
|
-
|
|
90
|
+
source: checkRef.current.source,
|
|
97
91
|
sources: checkRef.current.sources,
|
|
98
92
|
version: latest,
|
|
99
93
|
onAttempt: ({ attempt }) => setUpdate({ phase: 'updating', latest, attempt }),
|
|
100
94
|
}));
|
|
101
95
|
if (!result.ok) {
|
|
102
|
-
const params = {
|
|
96
|
+
const params = {
|
|
97
|
+
version: latest,
|
|
98
|
+
installed: result.installed ?? '',
|
|
99
|
+
url: cliTarballUrl(latest),
|
|
100
|
+
};
|
|
103
101
|
setUpdate({ phase: 'error', messageKey: result.errorKey ?? 'update.errorFailed', params });
|
|
104
102
|
// npm's own words: "update failed" alone is what left this unfixable.
|
|
105
103
|
ctx.notify((t) => result.summary
|
|
@@ -149,10 +147,6 @@ export function About({ ctx }) {
|
|
|
149
147
|
}
|
|
150
148
|
};
|
|
151
149
|
const activate = (id) => {
|
|
152
|
-
if (id === 'relay-update') {
|
|
153
|
-
relay.activate();
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
150
|
if (id === 'update') {
|
|
157
151
|
activateUpdate();
|
|
158
152
|
return;
|
|
@@ -174,8 +168,5 @@ export function About({ ctx }) {
|
|
|
174
168
|
}, onHover: () => setSelected(option.id), children: `${option.label}${draft.ui.language === option.id ? ' ✓' : ''}` }, option.id))) }), _jsx(Text, { color: theme.muted, children: t('update.title') }), _jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [_jsx(Selectable, { selected: selected === 'update', onSelect: () => {
|
|
175
169
|
setSelected('update');
|
|
176
170
|
activateUpdate();
|
|
177
|
-
}, onHover: () => setSelected('update'), children: updateLabel }), sourceNote ? (_jsx(Text, { color: theme.muted, children: ` ${t('update.mirrorBehind', sourceNote)}` })) : null,
|
|
178
|
-
setSelected('relay-update');
|
|
179
|
-
relay.activate();
|
|
180
|
-
}, onHover: () => setSelected('relay-update'), children: relay.label })) : null] }), _jsx(Row, { label: t('about.version'), children: _jsx(Text, { color: theme.muted, children: currentVersion() }) }), relay.visible ? (_jsx(Row, { label: t('about.relayPackage'), children: _jsx(Text, { color: theme.muted, children: relay.installed ?? '?' }) })) : null, _jsx(Row, { label: t('about.configPath'), children: _jsx(Text, { color: theme.muted, children: configPath() }) }), _jsx(Row, { label: t('about.statePath'), children: _jsx(Text, { color: theme.muted, children: stateDir() }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.muted, children: t('about.docs') }) }), _jsx(Message, { text: ctx.message?.text ?? null, level: ctx.message?.level ?? 'info' })] }));
|
|
171
|
+
}, onHover: () => setSelected('update'), children: updateLabel }), sourceNote ? (_jsx(Text, { color: theme.muted, children: ` ${t('update.mirrorBehind', sourceNote)}` })) : null] }), _jsx(Row, { label: t('about.version'), children: _jsx(Text, { color: theme.muted, children: currentVersion() }) }), runsLocalRelay(ctx.config) ? (_jsx(Row, { label: t('about.relayPackage'), children: _jsx(Text, { color: theme.muted, children: installedRelayVersion() ?? '?' }) })) : null, _jsx(Row, { label: t('about.configPath'), children: _jsx(Text, { color: theme.muted, children: configPath() }) }), _jsx(Row, { label: t('about.statePath'), children: _jsx(Text, { color: theme.muted, children: stateDir() }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.muted, children: t('about.docs') }) }), _jsx(Message, { text: ctx.message?.text ?? null, level: ctx.message?.level ?? 'info' })] }));
|
|
181
172
|
}
|
package/dist/update-command.js
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
// still runs the old code, and would start the services as the old release
|
|
7
7
|
// described them.
|
|
8
8
|
import { spawnSync } from 'node:child_process';
|
|
9
|
+
import { cliTarballUrl } from 'herdr-remote-relay/protocol';
|
|
9
10
|
import { loadConfig } from './config.js';
|
|
10
11
|
import { startAdminBrokerTask, stopAdminBroker, waitForAdminBroker, } from './connector/admin-broker.js';
|
|
11
12
|
import { cliEntryPoint } from './keepalive/environment.js';
|
|
12
13
|
import { servicesRunning, startAll, stopAll } from './lifecycle.js';
|
|
13
|
-
import { checkForRelayUpdate, performRelayUpdate } from './relay-updater.js';
|
|
14
14
|
import { checkForUpdate, performUpdate } from './updater.js';
|
|
15
15
|
import { heldByAnotherProcess } from './updater/in-place.js';
|
|
16
16
|
const RESTART_TIMEOUT_MS = 120_000;
|
|
@@ -27,16 +27,11 @@ function restartWithInstalledRelease() {
|
|
|
27
27
|
}
|
|
28
28
|
export async function runUpdate(t, options = {}) {
|
|
29
29
|
const config = () => options.config ?? loadConfig();
|
|
30
|
-
const { platform = process.platform, checkCli = () => checkForUpdate(),
|
|
31
|
-
|
|
30
|
+
const { platform = process.platform, checkCli = () => checkForUpdate(), installCli = (check, onAttempt) => performUpdate({
|
|
31
|
+
source: check.source,
|
|
32
32
|
sources: check.sources,
|
|
33
33
|
version: check.latest,
|
|
34
34
|
onAttempt,
|
|
35
|
-
}), installRelay = (check, onAttempt) => performRelayUpdate({
|
|
36
|
-
registry: check.registry,
|
|
37
|
-
sources: check.sources,
|
|
38
|
-
relayVersion: check.latest ?? '',
|
|
39
|
-
onAttempt,
|
|
40
35
|
}), isRunning = () => servicesRunning(config()), stop = () => stopAll(config()), start = () => startAll(config()), restartInstalled = restartWithInstalledRelease, stopBroker = stopAdminBroker, startBroker = async () => {
|
|
41
36
|
try {
|
|
42
37
|
startAdminBrokerTask(t);
|
|
@@ -47,20 +42,18 @@ export async function runUpdate(t, options = {}) {
|
|
|
47
42
|
return waitForAdminBroker();
|
|
48
43
|
}, report = (line) => process.stdout.write(`${line}\n`), } = options;
|
|
49
44
|
report(t('update.checking'));
|
|
50
|
-
const
|
|
45
|
+
const cli = await checkCli();
|
|
51
46
|
const { current } = cli;
|
|
52
47
|
if (!cli.ok) {
|
|
53
48
|
report(t('update.errorNetworkDetail', { message: cli.message ?? '' }));
|
|
54
49
|
return { ok: false, current, updated: null, restarted: false, errorKey: cli.errorKey };
|
|
55
50
|
}
|
|
56
|
-
|
|
57
|
-
// current one needs the relay installed by itself.
|
|
58
|
-
const updated = cli.updateAvailable ? 'cli' : relay.ok && relay.updateAvailable ? 'relay' : null;
|
|
59
|
-
if (!updated) {
|
|
51
|
+
if (!cli.updateAvailable) {
|
|
60
52
|
report(t('update.upToDate', { version: current }));
|
|
61
|
-
return { ok: true, current, updated, restarted: false };
|
|
53
|
+
return { ok: true, current, updated: null, restarted: false };
|
|
62
54
|
}
|
|
63
|
-
const
|
|
55
|
+
const updated = 'cli';
|
|
56
|
+
const version = cli.latest ?? '';
|
|
64
57
|
const wasRunning = isRunning();
|
|
65
58
|
// Windows refuses to replace files a running process holds, as services
|
|
66
59
|
// started by older releases do. Elsewhere they keep serving until the restart.
|
|
@@ -78,18 +71,22 @@ export async function runUpdate(t, options = {}) {
|
|
|
78
71
|
report(t(back ? 'update.brokerRestarted' : 'update.brokerRestartFailed'));
|
|
79
72
|
return back ? 'restarted' : 'failed';
|
|
80
73
|
};
|
|
81
|
-
report(t(
|
|
74
|
+
report(t('update.updating', { version }));
|
|
82
75
|
const onAttempt = ({ attempt }) => {
|
|
83
76
|
if (attempt > 1)
|
|
84
77
|
report(t('update.updatingRetry', { version, attempt }));
|
|
85
78
|
};
|
|
86
|
-
const result =
|
|
79
|
+
const result = await installCli(cli, onAttempt);
|
|
87
80
|
if (!result.ok) {
|
|
88
81
|
// Nothing was replaced, so the old release starts as it was.
|
|
89
82
|
if (stopped)
|
|
90
83
|
start();
|
|
91
84
|
const adminBroker = await restoreBroker();
|
|
92
|
-
report(t(result.errorKey ?? 'update.errorFailed', {
|
|
85
|
+
report(t(result.errorKey ?? 'update.errorFailed', {
|
|
86
|
+
version,
|
|
87
|
+
installed: result.installed ?? '',
|
|
88
|
+
url: cliTarballUrl(version),
|
|
89
|
+
}));
|
|
93
90
|
if (result.summary)
|
|
94
91
|
report(t('update.errorFailedDetail', { message: result.summary }));
|
|
95
92
|
if (platform === 'win32' && heldByAnotherProcess(result.output)) {
|
|
@@ -99,7 +96,7 @@ export async function runUpdate(t, options = {}) {
|
|
|
99
96
|
return { ok: false, current, updated, restarted: false, adminBroker, errorKey, summary };
|
|
100
97
|
}
|
|
101
98
|
const installed = result.installed ?? version;
|
|
102
|
-
report(t(
|
|
99
|
+
report(t('update.done', { version: installed }));
|
|
103
100
|
let ok = true;
|
|
104
101
|
let restarted = false;
|
|
105
102
|
if (!wasRunning) {
|