diff --git a/README.md b/README.md index 0bc141c9..f5242acc 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Resilient remote tmux terminal & 4-level guarded Agent Broker across Web, Mobile ## ✨ Highlights -- **Outbound-Only Node A (`Computer → Term → Window → Pane`)**: Computer A dials out over TLS/WSS to Control Plane B with zero inbound ports (`A 主动连接 B`, `A 不开放端口`); closing browsers or losing mobile connectivity never interrupts running `tmux` jobs. +- **Outbound-Only Node A (`Computer → Term → Window → Pane`)**: Computer A dials out over TLS/WSS to Control Plane B with zero inbound ports (`A connects outbound to B`, `A opens zero inbound ports`); closing browsers or losing mobile connectivity never interrupts running `tmux` jobs. - **Mobile-First Web & Native Terminal**: Responsive `xterm.js` workspace equipped with a tactile `MobileKeyBar` (`Esc`, `Tab`, `Ctrl`, `Alt`, arrow keys, and quick tmux chords) plus 7 curated geek themes. - **4-Level Guarded Agent Broker (`OpenCode`)**: Replayable agent event streams with a 4-tier risk guard and mandatory human-in-the-loop approval before any write or critical terminal action executes. - **Zero-Trust TOTP & One-Time Pairing**: Control Plane authentication protected by TOTP MFA, short-lived one-time node enrollment tokens, and device authorization via QR code or pairing code. @@ -77,7 +77,7 @@ Detach anytime with `Ctrl+B` then `D` (`termflow attach project-a` to re-enter). ### Standalone Control Plane Container (Terminal Only, Without Agent Runtime) -When you only need remote terminal routing without the OpenCode Agent runtime (`B 的 Web/API 通过宿主机 loopback 端口发布;A 主动连接 B,是连接 B 的客户端,不是 B 的网关;A 不开放端口`): +When you only need remote terminal routing without the OpenCode Agent runtime (Control Plane B's Web/API is published on a host loopback port; Node A connects outbound to B as a client rather than a gateway, with zero inbound ports on A): ```bash mkdir -p data totp-secrets diff --git a/README_CN.md b/README_CN.md index 8f8c9157..f7757153 100644 --- a/README_CN.md +++ b/README_CN.md @@ -73,7 +73,7 @@ termflow new --name project-a 按 `Ctrl+B` 再按 `D` 可随时退出当前视图且后台保持运行,使用 `termflow attach project-a` 重新进入。
-📦 Standalone Control Plane, Offline Tarball & Packaging Reference +📦 独立控制面、离线归档包与打包参考 ### 单容器 Control Plane B(仅终端转发,不含 Agent 运行时) diff --git a/apps/clients/tauri/src/views/NativeConnectView.test.ts b/apps/clients/tauri/src/views/NativeConnectView.test.ts index 45aaed94..de5b2d2f 100644 --- a/apps/clients/tauri/src/views/NativeConnectView.test.ts +++ b/apps/clients/tauri/src/views/NativeConnectView.test.ts @@ -85,11 +85,12 @@ describe('NativeConnectView', () => { it('presents the remote-control registration action in product language', async () => { const { wrapper } = await render() - expect(wrapper.get('.eyebrow').text()).toBe('Connect to Server') + expect(wrapper.get('.eyebrow').text()).toBe('远程连接') expect(wrapper.get('h1').text()).toBe('连接到服务器') expect(wrapper.get('label[for="server-url"]').text()).toBe('服务器地址') expect(wrapper.get('[data-action="browser-login"]').text()).toContain('本机浏览器登录') expect(wrapper.get('[data-action="device-authorize"]').text()).toContain('其他设备授权') + expect(wrapper.find('[data-action="toggle-locale"]').exists()).toBe(true) expect(wrapper.find('.native-auth-options').classes()).toContain('native-auth-options') expect(wrapper.get('[data-action="browser-login"]').attributes('title')).toContain('本机系统浏览器') expect(wrapper.get('[data-action="device-authorize"]').attributes('title')).toContain('不会打开本机浏览器') diff --git a/apps/clients/tauri/src/views/NativeConnectView.vue b/apps/clients/tauri/src/views/NativeConnectView.vue index e1d87240..7ae15d60 100644 --- a/apps/clients/tauri/src/views/NativeConnectView.vue +++ b/apps/clients/tauri/src/views/NativeConnectView.vue @@ -1,26 +1,42 @@