The plan pins gpui-kit 0.7.3 (locked to gpui-pre 0.3.9) as the client stack, keeps the backend untouched behind the existing HTTP/WS API, and ships the client for Windows, macOS and Linux. The dev baseline records the verified versions, the knowledge sources that outrank memory, the entry-point skeleton, and the platform facts the next sessions must not relitigate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
10 KiB
vps-switch 计划
2026-10-10 起,2026-10-13 按「先做好五大核心功能板块、最后将现成链路工具化为 MCP」重定主线。 vps-switch 是 1Shell(Node + Electron,冻结在 4.7.7)的全面重构与升级;旧项目在本项目可用之前照常运行,且随时作为实测对照。 本文是"一页边界":不在这里的东西不进仓库。要加,先改边界那句话。
边界
一个轻量级 VPS 管理工具:先把 VPS 仓库、终端、文件浏览器、文件上传下载、探针五大核心板块做到极致,最后将这些现成链路加上护栏工具化为 MCP Server。交付两个产物:GPUI 原生的桌面客户端(Windows / macOS / Linux,vps-switch-gpui)与无头的守护进程(vps-switch,Linux/Windows),两者共用同一后端与同一套 HTTP/WS API。
设计准则:
- 沿用
AGENTS.md:不堆提示词(本项目零模型调用)、不堆架构(一份底层实现,UI 与 MCP 共同复用)、不对 agent 隐藏上下文。 - 概念数必须比 1Shell 少。 不设内置 AI 聊天、不设协议 agent 入驻、不设技能/脚本库。
- 先做好人用的本体,再做工具化。 MCP 不是另起炉灶的第二套系统,而是对前五个板块已验证底层链路的薄封装。
为什么要按这个路径重构
直接调用并复盘正在运行的 1Shell(1 台 local + 29 台 VPS,共 30 个目标),它的核心问题很清楚:
| 1Shell 的痛点 | 根源 | vps-switch 的解法 |
|---|---|---|
| 定位散乱、体积臃肿(80k 行) | 第一次做项目时误打误撞,把内置 AI 对话、Claude/Codex 驻留面板、技能库、脚本库、工作负载全塞了进来 | 砍掉所有内置 AI 与多余概念,回归纯粹的轻量级 VPS 管理工具 + 外部 MCP 接口 |
| 主机仓库信息滞后 | osName 等信息首次探测后成了死缓存(如某台机器重装为 Ubuntu 后列表仍显示 Alpine 3.23) |
SSH 连接建立时轻量静默刷新真实 OS/内核/架构信息,保持仓库数据鲜活 |
| 终端总有小 bug | Node 仅做字节透传,服务端无终端状态机;切页丢屏、UTF-8 多字节截断乱码、resize 错位、不知命令何时结束 | 参考 Pebrel 技术栈:Rust 侧 alacritty_terminal::Term 持有权威网格状态 + 字节环重连恢复 + 随包 Windows ConPTY + OSC 133/7 真实命令边界与 exit code + WebSocket 纯二进制帧 |
| 文件上传下载困难(尤其 Agent 调用时) | 传文件被拆成 start/append/finish_file_upload 等 9 个工具,逼大模型在上下文里手搓 base64 分块,慢且极易断 |
做独立的 Rust 流式传输引擎(接收 本机路径 ↔ 远端路径),内部自动流式分片、断点续传、SHA256 校验;UI 队列与 MCP 共用同一条链路 |
| 探针过重、后台刷屏 | 塞了 Agentless / Go Agent / Relay 级联三种模式与复杂告警,40,826 次 SSH 轮询占了 76% 活动,告警刷出 1.1 万条 | 重做轻量探针:复用 SSH 连接或按需/低频采样(CPU、内存、磁盘、实时网速/流量、基础负载),打开面板时实时刷新,后台静默不折腾 |
六大板块与推进路线
采用一个板块一个板块做透的节奏:每个板块先结合 1Shell 实际体验细化讨论,打磨好前端形态与 Rust 底层链路,验收通过后再进入下一板块。
板块一:VPS 仓库(底座与前端形态定型)
先把轻量级工具的前端整体骨架与视觉形态打磨定型,同时把底层主机管理与 SSH 连接池做扎实:
- 主机模型(Host):支持本机(
local)与远端 SSH 主机;字段涵盖地址、端口、用户名、认证方式(密码 / 私钥加密存储)、跳板机(jump_host_id)、分组/标签、置顶、排序、备注链接,以及连接时自动刷新的os信息(系统家族、发行版、内核、架构)。 - 1Shell 一键导入:直接读取并解密本机现有 1Shell 数据库里的 29 台 VPS,一键迁入,开发第一天起就能用真实机队测试。
- SSH 连接底座(
russh):单主机连接池与多 channel 复用(终端、执行、SFTP、探针共用连接,支持跳板机透明穿透),并在真机队(OpenSSH 8.4 ~ 10.2、Alpine、Windows OpenSSH 9.5)上验通。 - 前端打磨:确定整个软件的导航布局、配色主题、主机列表/卡片视图、搜索与标签过滤、快速新建/编辑与连接测试交互。
板块二:终端(参考 Pebrel 技术栈)
Rust 侧持有终端状态,前端只负责高速渲染。 借鉴 Pebrel(Apache-2.0 的 alacritty_terminal 引擎,不抄 GPL 代码)的成熟终端工程实践:
- 双解析器与状态保活:每个终端 pane 在 Rust 守护进程中对应一个
alacritty_terminal::Term(持有网格与 scrollback)+ 有界字节环(默认 2 MiB);同一份二进制字节流经 WebSocket 喂给前端xterm.js(WebGL addon)。切页面、关窗口、闪断重连瞬间恢复现场。 - PTY 链路:本机使用
portable-pty并随包携带 Windows Terminal 的conpty.dll+OpenConsole.exe(告别系统老旧 ConPTY bug);远端复用板块一的russh连接打开 PTY channel。 - Shell Integration(OSC 133 / OSC 7):连接时静默注入 bash / zsh / fish / PowerShell 钩子,在 Rust 解析回调中精确截获每条命令的开始、结束、真实
exit_code与当前工作目录cwd。 - 输入正确性:支持 bracketed paste、按当前终端模式编码控制键与回车,杜绝粘贴多行直接误执行和乱码。
- 多 Tab 与分屏树:支持同一主机或跨主机多 Tab、任意方向分屏与拖拽调整占比,布局持久化。
板块三:文件浏览器
本机文件系统与远端 russh-sftp 复用同一套抽象接口:
- 目录浏览与操作:目录树/列表双视图、面包屑与路径直达、隐藏文件切换、权限/大小/修改时间展示、新建文件/文件夹、重命名、删除、修改权限。
- 在线编辑:集成 CodeMirror 6,支持语法高亮、搜索替换、保存直写远端(带可选备份),顺手改配置文件不必下载再上传。
- 与终端联动:支持跟随当前终端
cwd(由 OSC 7 提供)或在当前目录一键打开终端。
板块四:文件上传下载
把文件传输从普通读写里独立出来,做成一个真正的高速流式传输引擎:
- 核心链路:直接基于
本机文件路径 ↔ 远端文件路径流式读写,不经过内存全量缓冲、不走 base64 编码。 - 大文件与弱网保障:内部自动按大小分块流式传输、支持断点续传、传输完成后校验大小与 SHA256、写临时文件再原子 rename(防止传一半搞坏线上文件)。
- 传输队列 UI:支持拖拽上传、批量上传下载、实时显示传输速率、进度百分比、剩余时间,支持暂停/继续/取消。
- 为工具化铺路:这套 Rust 传输函数做好后,板块六的 MCP 工具只需传
{host, local_path, remote_path}即可直接调用,彻底消灭 1Shell 里让大模型手搓 9 个分片工具的顽疾。
板块五:探针
砍掉 1Shell 里繁琐的级联与告警轰炸,做一个轻量、干净、好看的 VPS 状态看板:
- 核心指标:在线状态与连接延迟、系统运行时长(Uptime)、CPU 使用率与负载(Load)、内存与 Swap、磁盘占用、实时上下行网速与累计流量、关键端口/进程概览。
- 轻量采集机制:优先复用已建立的 SSH 连接或采用极低开销的单次合并脚本采样;按需高频、后台低频/静默(人打开探针页或选中主机时实时刷新,平时不疯狂建连刷日志)。
- 兼容 Linux 与 Windows:Linux(Debian/Ubuntu/Alpine)读取
/proc与系统指标,Windows 走轻量性能计数采集。
板块六:工具化(MCP Server + 安全护栏)
前五个板块全部打磨成熟后,零重复建设,直接把已有的底层链路封装为 MCP Server 暴露给外部 Agent(如 Claude Code):
- 链路直接复用:
- 查主机 / 看状态 → 复用 板块一(VPS 仓库) + 板块五(探针)
- 执行命令(同步等待或转后台任务,含 Windows PowerShell 编码与 CLIXML 处理)→ 复用 板块一/二(SSH & 本机执行链路)
- 列目录 / 读写改删文件 → 复用 板块三(文件浏览器内核)
- 上传 / 下载大文件 → 复用 板块四(文件上传下载引擎),一次调用完成传输
- 命令黑名单护栏:
- 一份全局名单(
data/deny-list.txt,一行一条、*通配、按词边界,首启写出内置的不可逆灾难,之后用户自己增删),只覆盖vps_exec与vps_terminal的命令通道;文件写/传输类不判定。 - 命中即拒绝执行并说明命中了哪条;没有白名单、确认流程、风险分级与安全挡位。
- 存在的理由只有一个:MCP 工具一旦被外部 agent 放行,参数里的命令就不再受它自身权限系统检查,这里是唯一的兜底。
- 边界:防手滑,不防蓄意绕过(
r\m -rf /、$(echo rm) -rf /这类形态纯模式匹配必然漏)。
- 一份全局名单(
- 双传输支持:
--mcp-stdio(供本机 Claude Code 零配置直连)+ Streamable HTTP(带范围令牌)。
技术栈
| 层 | 选型 | 备注 |
|---|---|---|
| 后端语言与运行时 | Rust + tokio |
单一常驻进程,轻量低内存 |
| SSH / SFTP | russh 0.63 + russh-sftp |
纯 Rust,连接池 + 多 channel 复用 + 跳板机穿透 |
| 终端引擎 | alacritty_terminal(Apache-2.0) |
借鉴 Pebrel:Rust 侧持有网格与 scrollback,解析回调截获 OSC 133/7 |
| 本机 PTY | portable-pty + 随包 Windows Terminal conpty.dll / OpenConsole.exe |
解决 Windows 原生 ConPTY 兼容性与渲染 bug |
| Web 服务与实时通信 | axum |
REST API + 终端二进制 WebSocket + 状态/探针/传输进度 SSE |
| 本地存储 | rusqlite(bundled) |
单文件 SQLite + 凭据加密存储 |
| MCP 协议 | rmcp(≥ 1.4.0) |
板块六接入,支持 stdio 与 Streamable HTTP |
| 桌面壳 | GPUI(gpui-kit 0.7.3,内部锁 gpui-pre 0.3.9) |
GPUI 原生桌面客户端(Windows / macOS / Linux);Linux 无头服务不带壳。详见 docs/gpui-client.md |
| 前端 | Vue 3 + TypeScript + Tailwind CSS + xterm.js(WebGL)+ CodeMirror 6 | 轻量、响应迅速、围绕五大板块打造精致 UI |