Files

114 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 支持指定另一台 SSH 跳板机或本机代理端口 `local-proxy`)、分组/标签、置顶、排序、备注链接,以及连接时自动刷新的 `os` 信息(系统家族、发行版、内核、架构)。
- **1Shell 一键导入**:直接读取并解密本机现有 1Shell 数据库里的 29 台 VPS,一键迁入,开发第一天起就能用真实机队测试。
- **SSH 连接底座(`russh`)**:单主机连接池与多 channel 复用(终端、执行、SFTP、探针共用连接,支持 SSH 跳板机透明穿透与本机代理端口 SOCKS5/HTTP CONNECT 出口路由),并在真机队(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 |