一体化开发运维终端 —— SSH · WinRM · 文件 · Docker · 数据库 · AI,装进同一个窗口
桌面 App 与浏览器版共用同一份 Rust 内核。凭据加密存储,AI 全程在权限护栏内执行。
运维工具链历来分散:SSH 客户端、SFTP 工具、Docker 面板、数据库客户端各占一个窗口,AI 助手还要切出去粘贴报错。NexTerm 将它们收进同一个三层工作区——工作区、分屏面板、标签,并为 AI 提供一条看得见、管得住的执行通道:每条命令、每次文件修改实时可见,危险操作先经确认。
同一份内核现在有两种跑法:装在自己电脑上的桌面 App,和部署到服务器、浏览器直接打开的服务端。两者之间用资产同步打通——桌面上配好的主机与凭据,一键送到对端。
| 桌面 App | 服务端 nexterm-server |
|
|---|---|---|
| 装在哪 | 本机(Windows / macOS) | 服务器或容器,浏览器访问 |
| 内核 | 进程内嵌同一份 | 进程内嵌同一份 |
| 凭据落点 | 本机(DPAPI / 主密码) | 服务端实例(平台注入的主密钥) |
| 适合 | 日常主力工作台 | 换设备接着用、多端访问 |
| 同步角色 | 发起方 | 被同步的对端 |
两端共用同一份命令清单(132 条),行为一致。「桌面行为逐字节不变」不是口头承诺,而是由双平台 CI 把关的。
服务端版本不装客户端,浏览器打开即用;手机平板受限于没有 Ctrl 键与右键菜单,终端体验有限,已在包元数据里显式声明不支持的平台,而不是让用户装上一个用不了的应用。
桌面版和服务端是两个独立实例,各持一份 SQLite。没有同步,用户就得两边各配一遍,改了一边另一边立刻变旧。同步搬运的范围是资产 + 分组 + 凭据。
- 方向显式 —— 勾中资产,按「推送到对端」或「从对端拉取」。内核只提供
export/apply两个原语,不猜方向:SSH 私钥这类载荷根本不可合并,与其做个半吊子的自动合并让人不敢用,不如把选择交给你。 - 默认不覆盖更新的那一份 ——
apply会跳过「本机这份更新」的条目并逐条说明原因。同步最常见的误操作是「拿一台旧机器的包盖掉新改动」;而「跳过了什么」是能看懂、能补救的(看报告 → 勾强制覆盖 → 重来)。 - 凭据明文过河,落地重封 —— 两端密钥体系各自独立(桌面是 DPAPI / 主密码,服务端是注入的根密钥),密文搬过去解不开。所以是「源端解密 → HTTPS 传输 → 目标端用自己的密钥重新加密」。源端凭据库没解锁会明确报错,不静默跳过——静默的后果是「资产过去了、密码没过去」,等你在另一端点连接才发现。
- 公网强制 HTTPS —— 只有本机与私有网段地址才放行明文 HTTP。访问令牌走明文等于交给同链路上的任何人。
- 不搬的东西各有理由 —— AI 对话 / 审计日志 / 终端录制是本地行为记录,搬过去不是「同一件事」;主机指纹必须以目标端实际握手结果为准(接受远端指纹等于关掉 TOFU 保护)。
填「对端地址 + 同步令牌」就能连上,不用管对端装在哪:
- 懒猫微服 —— 平台的公网入口默认要求登录,应用只把同步入口这一条路径从登录门里放行,请求这才到达容器,由应用自己校验令牌。
- 自建服务器 —— 不经平台网关,直接连到服务端,同样由应用自己校验令牌。
两种位置的令牌是同一个机制(对端服务端自己生成的那一串),部署位置只影响界面提示,不影响协议。
⚠️ 完整版服务端上,这个令牌等同于该实例的完全控制权——它调的是同一张 RPC 表,能执行任何已注册命令,不只是同步资产。别外传。只想在公网上做同步,就用 onlyServer(见下方「部署服务端」):它的命令表只有同步那三条, 令牌泄漏也拿不到终端、文件与容器。这不是"少注册几件事"的省事做法,而是拆开部署的唯一理由。
| 模块 | 能力 |
|---|---|
| 终端 | SSH 真 PTY、本地 ConPTY、WinRM;多标签与分屏、搜索、会话录制,支持 UTF-8 / GBK / GB18030 / Big5 编码切换 |
| 会话 | 一台资产一条连接复用,关标签不断连;SSH / WinRM 指数退避自动重连(本机会话没有"重连"这件事,不会假装在重连) |
| 资产 | 内置「当前设备」本地资产 —— 装好即有一台机器(本机终端 / 文件树 / 容器面板都落在它上面),不可删除、可改名、可配默认 Shell 与起始目录;另有 SSH / WinRM / Docker / MySQL / Redis 资产,支持分组、搜索、拖拽归类 |
| 文件 | SFTP 浏览与虚拟滚动、带进度与断点续传的传输;内置编辑器支持查找替换、LF/CRLF 转换与编码切换;MD5 / SHA256 校验 |
| 挂载 | Windows net use 映射盘、Linux sshfs(本机文件直接看文件树,不需要挂载) |
| Docker | 容器列表、日志 follow、容器终端、启停删、镜像管理、容器文件浏览、批量操作;SSH 主机与本机都可用 |
| 数据库 | MySQL 库表浏览与 SQL 工作台;Redis SCAN 分页、类型感知查看与命令台 |
| 端口转发 | SSH 本地转发,复用已有会话打通内网数据库 |
| AI 助手 | OpenAI 兼容多模型、工具调用、权限护栏、终端接管、文件变更 diff、计划模式、上下文用量与缓存命中统计 |
| 凭据库 | 两级密钥信封加密、集中管理面板、引用关系与删除保护、日志自动脱敏 |
| 服务端 | 同一套界面在浏览器里跑,部署到服务器或容器;无桌面依赖 |
| 资产同步 | 桌面 ↔ 服务端双向搬运资产、分组与凭据,方向显式、冲突可审 |
AI 不是贴在旁边的聊天框,而是接进了内核。
- 工具调用透明 —— AI 执行的每条命令以卡片进入对话流,展开可见完整输出与退出码;命令运行在独立执行通道,不伪装成向终端打字。
- 权限护栏 —— 操作按风险分级:安全操作直接执行;敏感操作弹确认卡片,可对本会话放行同类;格式化、批量删除等危险命令一律拒绝。只读、读写、静默三档模式随时切换。
- 文件变更可审 ——
write_file/edit_file在确认卡片上先给出逐行 diff(新建文件整份标为新增),执行后再落一张「变更记录」卡片。改动一目了然,而且是批准之前就一目了然。
- 终端接管 · 实验性 —— 基于内核侧终端状态机读屏、判定空闲、发送按键;按任意键立即夺回,全程显示接管横幅。
- 多模型与成本可见 —— 任意 OpenAI 兼容端点,两步连接测试;上下文用量环与缓存命中率常驻侧栏底部。
三层结构:工作区对应一台机器或一个连接,其下分屏,屏内开标签。标签始终挂载,切换不重连、不丢终端状态;分屏比例持久化,为一边敲命令、一边看日志的场景而设计。
连接资产后左栏切换为文件树,双击进入内置编辑器;命令面板提供宽幅文件浏览器。
到 Releases 下载。每次发版产出五类产物:
| # | 产物 | 文件名 / 形态 | 装在哪 |
|---|---|---|---|
| ① | Windows 客户端 | NexTerm_x.y.z_x64-setup.exe |
Windows 10/11 x64,NSIS 安装器双击即装 |
| ② | macOS 客户端 | NexTerm_x.y.z_aarch64.dmg |
Apple Silicon(M 系列),拖入「应用程序」 |
| ③ | 懒猫微服专版 | 应用商店安装包 | 在微服应用中心里安装,不经 Release 下载 |
| ④ | LinuxServer | NexTerm-x.y.z-linux-amd64.tar.gz |
任意 Linux(amd64),带浏览器界面 |
| ⑤ | onlyServer | NexTerm-onlyServer-x.y.z-linux-amd64.tar.gz |
任意 Linux(amd64),只做资产同步 |
四个客户端/服务端产物由 CI 自动构建;③ 因为要拉私有镜像仓库(凭证只在微服上), 由维护者手工出包后附到 Release 上。
④ 和 ⑤ 是同一个二进制,
--sync-only一个开关切换形态(见下)。 分两个包只是为了让你拿到手就是对的形态,不用读文档才发现「原来还要加参数」。
安装包是 ad-hoc 签名、未公证的(没有 Apple Developer 证书),所以首次打开会被 Gatekeeper 拦一次。 这是预期行为,不是文件损坏:
- 双击应用,看到「无法验证开发者 / 无法检查是否包含恶意软件」的提示 → 点完成
- 打开 系统设置 → 隐私与安全性,下拉到「安全性」,点 「仍要打开」
- 之后正常双击即可
若提示的是**「已损坏,无法打开」**(而不是"无法验证开发者"),那是签名问题,用命令行一次修掉:
xattr -dr com.apple.quarantine /Applications/NexTerm.app只有 Intel Mac?目前只发 Apple Silicon 包,可用 Rosetta 或从源码构建 (
pnpm tauri build --target x86_64-apple-darwin)。
服务端适合放在常开的机器上:换一台设备,浏览器打开接着用;它同时是桌面版资产同步的对端。
三种部署位置,按「你在哪、要什么」选:
| 部署位置 | 用哪个包 | 浏览器界面 | 公网 | 适合 |
|---|---|---|---|---|
| 懒猫微服 | 应用商店安装包 | ✅ | ✅(平台登录门 + 应用令牌) | 有微服,要一个随处可开的浏览器工作台 |
| LinuxServer | NexTerm-x.y.z-linux-amd64.tar.gz |
✅ | 自建机器 / 内网 VPS,自己接反代 | |
| onlyServer | NexTerm-onlyServer-x.y.z-linux-amd64.tar.gz |
❌ | ✅ 设计目标 | 公网只当同步中转,ssh 上去配 |
后两者是同一个二进制:onlyServer 就是加了 --sync-only。它少了什么、为什么少,见下。
本仓库自带 LPK v2 打包与提审链路(lazycat/ 与 scripts/),产物为应用商店可用的安装包:
lzc-cli project build # 产出 cloud.lazycat.app.nexterm-v<版本>.lpk
lzc-cli project deploy # 部署到自己的微服微服的公网入口默认要求登录,应用在 public_path 里只放行了同步入口一条路径,
靠应用自己的令牌把关 —— 用浏览器打开应用,体验不变。
下载 tarball 解压,里面有二进制、前端产物、systemd 单元和一份 README.md(安装步骤就在里面):
tar xzf NexTerm-x.y.z-linux-amd64.tar.gz
cd NexTerm-x.y.z-linux-amd64 && less README.md跑起来就三步:建用户 → 放文件 → 起 systemd 单元。单元默认监听 127.0.0.1:8080,
对外要自己接一层带鉴权的反代:
# 凭据库根密钥(≥ 8 位)。不设也能起,但密码类资产与「带凭据同步」不可用
printf 'NEXTERM_MASTER_KEY=%s\n' "$(openssl rand -base64 32)" \
| sudo tee /etc/nexterm/nexterm.env >/dev/null
sudo chmod 0600 /etc/nexterm/nexterm.env
sudo systemctl enable --now nexterm-server⛔
/rpc与浏览器界面没有任何自身鉴权。 懒猫那边是平台登录门在挡,裸 Linux 上那道门不存在 —— 能连上端口的人就拿到了终端、任意文件、Docker 与凭据库。所以:默认只听127.0.0.1; 别改成0.0.0.0了事;不建议公网部署。
tar xzf NexTerm-onlyServer-x.y.z-linux-amd64.tar.gz
cd NexTerm-onlyServer-x.y.z-linux-amd64 && less README.md--sync-only 的形态只有两个端点(/sync/rpc、/healthz)和三条命令
(sync_digest / sync_export / sync_import)—— 没有浏览器界面,没有 /rpc。
这不是「顺手精简」,而是这种部署存在的理由:/sync/rpc 的令牌走的是同一张命令表,
全量注册时它等于整个实例的控制权;只注册对端真正会调的三条,令牌泄漏最多也就读写这份资产库。
所有选项命令行与环境变量等价(命令行 > 环境变量 > 内置默认),懒猫那份 manifest 用的是环境变量,所以两边一份定义:
| 选项 | 环境变量 | 默认 | 说明 |
|---|---|---|---|
--listen |
NEXTERM_LISTEN |
0.0.0.0:8080 |
监听地址。默认给容器用(平台从容器网络另一侧访问),裸机请显式改 |
--data-dir |
NEXTERM_DATA_DIR |
有 /lzcapp/var 用它,否则 ./data |
SQLite / 日志 / 令牌落点 |
--web-root |
NEXTERM_WEB_ROOT |
自动探测(/app/dist、dist) |
前端静态资源;--sync-only 下用不到 |
--master-key |
NEXTERM_MASTER_KEY |
无 | 凭据库根密钥(≥ 8 位)。不给则凭据库保持未初始化 |
--sync-only |
— | 关 | 切成只做同步的形态 |
三条子命令,serve 可省略(容器不带任何参数启动,走的就是 serve):
nexterm-server # = serve,容器里就是这一条
nexterm-server --sync-only --listen 0.0.0.0:9000 --data-dir /var/lib/nexterm
nexterm-server token # 打印同步令牌(没有就生成;只有令牌进 stdout)
nexterm-server rotate-token # 重新生成 —— 旧令牌立即失效token 只把令牌写 stdout,说明文字走 stderr,所以可以直接 TOKEN=$(nexterm-server token)——
onlyServer 没有界面,这条命令是拿到令牌的唯一途径。
两句自查:
curl -s 127.0.0.1:8080/healthz # 完整版应报 commands:132;onlyServer 是 commands:3 + syncOnly:true--help 会列出全部选项与示例。
公开部署请自行评估:完整版服务端是常开解锁状态,凭据库随进程可用 —— 要公网就换 onlyServer,并确保前面有 TLS(令牌明文放在请求头里)。
支持 Windows 与 macOS,从源码构建:
# 依赖:Rust stable(≥1.98)、Node 22+、pnpm 11+
# Windows:MSVC 工具链;macOS:Xcode Command Line Tools
git clone https://github.com/ProbiusOfficial/NexTerm.git
cd NexTerm
pnpm install
pnpm tauri dev # 开发窗口
pnpm tauri build # Windows 出 NSIS 安装器;macOS 出 .app + .dmg双平台 CI(Windows + macOS 各跑 fmt / clippy / test / typecheck / lint)在每次 push 时把关;
打 v* tag 由 release.yml 自动出两个平台的安装包并挂到 Release。
免编译 Rust 预览全部界面,在线演示直接访问 probiusofficial.github.io/NexTerm/demo。
前后端仅 src/ipc/commands.ts 的 call() 一个接口,纯浏览器运行或 URL 带 ?demo=1 时自动切换内存 mock:
pnpm dev # http://localhost:1420/演示包含一台回显虚拟 shell,支持 ls、cat、systemctl、docker ps 与 Tab 补全、历史记录;另有 8 台资产、MySQL / Redis 面板、文件树与编辑器、AI 流式对话与确认卡片,命令块、搜索、录制全部可用。mock 为独立 chunk,生产包不加载;URL 加 ?demo=0 回到真实后端。
前端只有一份,运行环境三态:桌面(Tauri 容器)、服务端(浏览器 + 真后端)、演示(纯前端假数据)。三态靠同步读取的标记判定,不需要探测后端。
┌──────── WebView(React 19 + xterm.js)────────┐ ┌──── 浏览器 ────┐
│ 资产树 · 标签/分屏 · 终端 · 文件 · DB · AI │ │ 同一份前端产物 │
└──────────────────── Tauri IPC ────────────────┘ └── HTTP / WS ───┘
│
┌──────────────── Rust 内核(Tokio)────────────────┐ │
│ session/ 会话池·重连 terminal/ PTY+vt100 状态机 │ │
│ transport/ ssh·winrm·local·forward fs/ 传输·挂载 │◄─┘
│ docker/ CLI 通道 db/ mysql·redis ai/ agent·护栏 │
│ vault/ 两级密钥加密 store/ SQLite(WAL) sync/ 同步 │
└────────────────────────────────────────────────────┘
▲ 内嵌同一份(桌面) ▲ 内嵌同一份(服务端 axum)
命令层是一份 macro_rules! nexterm_commands,桌面侧喂给 Tauri 的 generate_handler!,服务端侧喂给一个 Vec<Entry>;平台差异靠 ipc_shim 收束,所以 132 条 #[tauri::command] 一行都不用改。
关键设计:
- 终端字节流不走 JSON —— PTY 输出经
Channel<Vec<u8>>直送 xterm.js,输入走 invoke。服务端模式同理走二进制 WebSocket。 - 内核侧终端状态机 —— PTY 字节流同步喂给内核
vt100::Parser,是 AI 读屏、空闲判定与终端接管的唯一数据源。 - 端到端背压 —— 本地 PTY 以阻塞线程加有界通道桥接;4MB 暂停、节流事件、隐藏标签批量刷新。
- 凭据两级密钥 —— 主密码经 Argon2id 派生 KEK,信封加密 DEK;凭据以 XChaCha20-Poly1305 加密;支持 Windows DPAPI 免主密码模式;日志统一脱敏。
- AI 护栏独立成层 —— 风险分级与放行决策单一入口,不散落在调用点。
cargo fmt --all --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --workspace
pnpm typecheck && pnpm lintdocs/diagrams/*.svg 是本仓库架构图的源文件,用 node scripts/render-diagrams.mjs 渲染成 docs/images/*.png。
独立同步核心(可脱离桌面单独部署的密钥中转)在设计中;其他系统正在构建中。








