# myshell **Repository Path**: argustang/myshell ## Basic Information - **Project Name**: myshell - **Description**: 我想写一个好看且好用得shell工具 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-06-13 - **Last Updated**: 2026-10-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MyShell 一款基于 Tauri v2 构建的跨平台 SSH/SFTP/FTP 桌面客户端,灵感来自 FinalShell。

MyShell

![Version](https://img.shields.io/badge/version-1.10.1-blue) ![Tauri](https://img.shields.io/badge/Tauri-v2-green) ![Vue](https://img.shields.io/badge/Vue-3-42b883) ![Rust](https://img.shields.io/badge/Rust-1.70+-orange) ## 功能特性 ### 连接管理 - 支持 **SSH**、**SFTP**、**FTP** 协议 - 连接分组管理(树形结构) - **拖拽移动**:长按连接(600ms)拖到文件夹即可移动归类,拖拽中只展示文件夹、隐藏文件夹内连接,避免连接过多需下滑找目标;ESC 取消、空白区/同文件夹不触发,普通点击/双击不受影响 - **模糊搜索**:快速定位服务器连接 - **文件夹快速选择**:编辑服务器时可快速选择所属文件夹 - 导入/导出连接配置(AES-256-GCM 加密) - 连接配置持久化存储(SQLite + OS Keyring) - 代理支持(SOCKS5、HTTP) - **连接高级选项**(SSH/SFTP):地址族(自动 / 强制 IPv4 / 强制 IPv6,绕开 IPv6 黑洞)、每连接连接超时、SSH Keepalive 间隔 - **主机密钥变更自助恢复**(SSH/SFTP):服务器重装/换密钥导致主机指纹变化时,报错明确列出新旧指纹(而非含糊的 "Unknown server key"),错误屏的「重新连接」按钮变为「重置密钥并重连」,一键自动清除旧记录并重新信任(保留 MITM 防护,不自动接受) ### 终端功能 - 基于 xterm.js 的高性能终端模拟 - Catppuccin Mocha 深色主题 - **暗黑模式**:支持深色/浅色主题切换 - 终端自适应尺寸调整 - **连接状态指示**:tab 页顶部显示在线(绿色)/离线(红色)/异常(红色×)状态 - **连接失败重连**:tab 页右下角显示失败提示,支持一键重连 - **命令历史栏**:最近 50 条命令 + 钉住置顶 - **快捷命令**:全局快捷命令 + 服务器专属快捷命令,多行命令按行顺序一键执行(`#` 注释与空行自动跳过),支持广播到多终端;支持**行间延迟**——三档模式:`##delay:500`(或 `##delay:1s`)在两行之间精确等待、固定延迟、或「智能等待」(监听终端输出,等上一行输出静止后再发下一行,自动适配命令速度、能处理 `sudo`/`mysql` 密码提示);在「设置 → 快捷命令」配置 - **广播输入**:同时向多个终端发送相同命令 - ZMODEM 协议支持(rz/sz 文件传输):原生 Rust 收发(零 JS 数据路径),128 KB 子包批量直写 SSH channel,双向进度 IPC 事件 100ms 节流削减跨进程开销(进度条紧贴实时数字),传输期间进度条实时显示、取消可用;`sz -r 目录` 递归下载文件夹(接收端按 offer 相对路径自动建目录镜像子树,路径段清洗防 `..`/盘符逃逸),rz 上传可选文件夹递归(ZFILE offer 携带相对路径,lrzsz rz 在远端自动重建目录树);远端中止(文件无权限 / 是目录 / 进程被杀)时自动识别 lrzsz 取消序列与 ZABORT 帧,sz 无权限报错文本 2 秒内回显终端并快速退出,30s 静默超时兜底——超时/中止均发送 CAN 序列敲掉挂死的 sz 保证 shell 立即可用并显示失败原因;文件/文件夹选择器弹出前微移鼠标指针显形(绕过 WebView2「键入时隐藏指针」缺陷)。协议为单流串行——多文件按顺序传输,无并发 - 服务器状态实时监控(CPU、内存、磁盘) - **本地终端**:直连本地 PowerShell / CMD / WSL / 自定义 shell,作为可保存的连接,体验等同 SSH 终端 - **终端字体**:从系统已安装字体下拉选择(也可手输),默认字体栈 Nerd Font 优先,正确渲染 Powerline / 图标字形(Oh My Posh / Starship / powerlevel10k 等);支持**按连接单独覆盖字体** - **本地终端编码自适应**:cmd / Windows PowerShell 5.1 启动自动切 UTF-8,中文系统不再 GBK 乱码;并向 shell 声明 `TERM=xterm-256color` / `COLORTERM=truecolor`,提示符引擎完整渲染 - **终端截图**:每个终端窗口工具栏的 📷 按钮一键截取当前终端画面(仅终端 viewport,不含标签栏/工具栏/输入命令栏),自动保存到「设置 → MCP 支持 → 附件目录」配置的目录,文件名带毫秒防覆盖;直接读 xterm buffer 自绘,完整还原颜色(16 色/216 cube/24 灰阶/24-bit RGB)和文字属性(bold/italic/underline/inverse) ### 文件传输 - SFTP/FTP/FTPS 文件浏览器 - 文件操作:上传、下载、重命名、删除 - **FTPS(显式/隐式 TLS)**:连接对话框选 explicit(AUTH TLS,默认 21)或 implicit(默认 990),rustls + Mozilla 根证书链,证书校验始终开启 - **FTP/FTPS 上传下载**:与 SFTP 同一套传输 UI(进度浮层 / 取消 / 错误列表);FTP 无并行数据连接能力,下载按顺序执行 - **文件夹递归下载**:勾选文件夹一键下载整个子树(空目录保留,符号链接循环有深度保护),本地按 `<目标目录>/<文件夹名>/...` 镜像;远端文件名严格按单一路径组件校验(反斜杠/盘符/保留设备名等非法名报错跳过),构建目标前检查符号链接,杜绝越出下载目录 - **SFTP 多文件并发下载**:可设并发线程数(设置 → 文件传输,默认 3,1–16),所有线程复用同一条 SSH 连接,海量小文件提速明显 - 目录导航历史记录 ### 诊断与日志 - **结构化日志**:关键路径(启动、SSH 生命周期、连接管理、快捷命令)记录 `info` / `warn` / `error` 级日志,按天落盘,便于事后定位问题 - **日志自动清理**:默认保留 **7 天**,每次启动自动清理超期日志 - **动态调试**:需要更详细输出时设置环境变量 `RUST_LOG=myshell=debug` 提升日志级别 - **用户反馈**:左下角「反馈与建议」入口,可提交问题报告 / 功能建议(支持截图与本地图片,自动附带脱敏后的运行日志),通过邮箱送达开发者;提交失败时自动打包本地反馈包兜底 ### 安全特性 - 应用启动密码保护 - 登录密码与数据加密密钥(DEK)分离 - PBKDF2-HMAC-SHA256 密钥派生(600k 迭代,OWASP 2023 推荐;旧 vault 首次解锁时透明迁移) - AES-256-GCM 数据加密 - **命令历史 / 快捷命令密文存储**(AES-GCM,保险库解锁后自动迁移旧明文;设置 → 隐私可开启「不记录命令历史」后端强制开关) - **密码查看原子验证**:查看连接/代理明文密码须在后端同一命令内完成主密码验证 + 解密,无法绕过前端弹窗 - **MCP 命令确认逐段判定**:复合命令按分号/管道/换行等分段独立评估,白名单不能豁免黑名单命中,GUI 与 headless MCP 共用同一 Rust 策略源 - **MCP 高危命令危害说明 + 弹窗置顶**:确认弹窗逐条列出命中的黑名单规则及具体危害(如「rm 递归强制删除且不可恢复」),弹窗出现时窗口自动置顶、聚焦并闪烁任务栏,人工审核不再被后台窗口淹没 - **黑名单 wrapper 绕过封堵 + 规则收窄**:nohup/xargs/env/timeout 等 13 个中性前缀在判定前剥离(`find | xargs rm`、`nohup rm -rf` 不再免确认);补齐 npx/nc/modprobe/wipefs/ip/doas/systemd-run/terraform/云 CLI 等默认规则;mkdir/touch 移出黑名单,git/docker/kubectl/curl 收窄为写子命令/写参数才确认 - **黑名单分词器重写**:判定不再对原始文本直接套正则——先去引号、跳过分组符与控制关键字、剥离中性 wrapper,再把真实命令名归位到命令位。`'rm' -rf /x`、`( rm -rf /x )`、`{ rm -rf /x; }`、`do rm -rf "$f"`、`nohup 'rm' -rf /x`、`/bin/rm -rf /x` 此前均可无确认执行(一个引号即击穿整套规则),现在全部拦截;仅重写命令头 token,参数逐字节保留,不会把引号内的 `;` 变成假分段边界 - **确认门 fail-closed**:GUI 与 CLI 在规则加载/解析失败时一律弹窗或拒绝执行,绝不因一次 IPC/IO 错误放行;规则文件写入改为 tmp+rename 原子替换,杜绝半截 JSON 静默降级为更弱的内置默认 - **zsh MULTIOS 写重定向**:仅 `>&<数字fd>` 视为 fd 复制;`echo x >&/etc/crontab` 此前判定为安全(zsh 把 `>&file` 解释为 `&>file`),现在会拦截 - SSH 主机键 TOFU 验证(按 `(host, port)` 隔离,指纹变更自动拒绝) - 严格 CSP 白名单(关闭 XSS 暴露面) - OSC 52 剪贴板劫持防护 - 命令历史敏感命令过滤(passwd/sudo/密钥参数等不入库) - Tauri 命令加固:PEM 头校验、文件大小上限、路径校验、错误脱敏 - **AI 供应商密钥不外发**:编辑已保存的供应商时改 Base URL 并点「测试」,需显式确认才会把已存 API Key 发往新主机(默认拒绝) - **内置 Ollama 预设可用**:本地免鉴权供应商不再被要求填写 API Key;AI 命令的 Base URL 缺失时返回明确错误而非崩溃 - **MCP 不谎报成功**:命令已发出后不再无头重跑;远端未返回退出码(连接中断/被信号终止)一律视为失败而非 `exit_code 0`;并发的长任务 ID 不再碰撞 - **传输失败显式报错**:磁盘写满/设备拔出/落盘失败会中止传输并报错,不再把截断文件报成 100% 成功;落盘队列有 64 MB 上限,避免慢磁盘拖垮内存 - **FTP 下载不毁本地文件**:先建立远端连接再创建本地文件,远端失败时保留原有副本(与 SFTP 行为一致) - **递归下载深度护栏**:SFTP 与 FTP 共用同一层级上限,符号链接成环不再无界递归 - **ZMODEM 协议修正**:ZRPOS 偏移越界即中止(此前可让远端用一个越界偏移换取「零内容文件上传成功」);未协商 ESCCTL 时不再丢弃 0x91/0x93 数据字节 - **保险库失败一律偏向拒绝**:KDF 迭代数被钳制在安全区间(防止配置文件被改成 0 轮或超大值);暴力破解计数文件损坏/不可读时按已锁定处理,而不是悄悄清零;保险库目录创建失败会明确记录 - **SQLite 并发加固**:启用 WAL + 5 秒忙等待,GUI/CLI/MCP 三个进程同时访问同一数据库时不再出现 "database is locked",外键级联删除也真正生效 - **ZMODEM 保存路径校验**:落盘点自行校验路径并拒绝上级引用与软链跳转,不再依赖调用方自觉 - **日志脱敏覆盖主目录**:Windows / Linux 用户目录中的本机账号名不再随反馈日志外发 - **主密码不留存**:密码验证失败后立即清空输入;导出/导入对话框的取消路径也会清除口令 - **前端偏好白名单**:localStorage 中的界面偏好只接受白名单键,不会因为外部写入而静默授予"本会话放行全部危险命令" - **界面与后端字段名一致**:锁定提示、回收站删除时间、备份日期、打开日志文件夹按钮此前因大小写不匹配而恒为空,现已修复 - **中文输入法不误触发**:命令栏在输入法确认候选词时按回车不会提交 - **状态读取失败会明示**:命令历史隐私开关读取失败时禁用并说明原因,回收站加载失败可重试,不再显示成相反的结论 - **ZMODEM 帧解析更严格**:按协议要求帧头 ZPAD 前缀(此前转义数据字节会被误判为帧头并永久卡死、吞掉后续全部终端输出)、把 ZCRCW 正确识别为数据帧帧尾(此前会把后续帧头写进文件)、发送侧接受 ZBIN32、缓冲位置按小端解析 - **锁定保险库真正擦除密钥**:数据加密密钥与主密码改用 `zeroize` 包装,离开作用域即从内存擦除——此前"锁定"只是释放分配,密钥仍留在已释放的堆页里 - **凭据解密后即擦除**:所有凭据唯一的解密出口返回零化缓冲,读取密码时连字符串也一并擦除——明文不再长时间滞留在进程堆上 - **拖拽中途卸载会正确解绑**:界面消失后不再可能因为一次松手而移动连接 - **确认弹窗高亮跟随规则设置**:在设置里改过黑名单后立即生效,不再需要重启 - **截图使用当前终端配色**:与窗口里看到的颜色一致(此前 10 套配色里有 9 套是错的) - **保险库单文件原子提交**:salt / 校验器 / 加密 DEK / KDF 参数合并为 `vault.bundle`,一次 tmp+rename 写入。此前四个文件顺序写入,改密码中途失败会留下「DEK 用新口令、校验器用旧口令」的组合——新旧两个口令都打不开,只能删库重录 - **改密码同步轮换备份**:备份目录里的保险库副本会用新口令重新加密;否则旧口令可长期打开整个凭据库 - **回退需重启**:回退不再覆盖运行中的数据库,改为下次启动、打开数据库之前执行 - **导出备份会提示缺失凭据**:读不到密码的连接会逐条列出,不再显示为「导出成功」 - **MCP 项目上传/下载校验远端结果**:读取远端退出码与完成哨兵,失败时返回错误而非「✅ 成功」 - **私钥不再下发前端**:`private_key_pem` 标记 `skip_serializing`,连接列表只返回 `has_private_key` 布尔量;私钥在连接时从保险库解密,GUI / CLI / MCP 三条路径行为一致 - **编辑连接不再销毁私钥**:保存时省略私钥表示「保持不变」,删除必须是对话框里显式的 ✕ - **图片读取收敛**:背景图 / 反馈截图读取要求保险库已解锁、限定图片扩展名,且永不读取 MyShell 配置目录与 `~/.ssh` - **日志脱敏**:主机名 / 用户名 / IP 在写入日志前掩码(如 `192.168.1.10`→`192.*.*.10`),反馈日志二次脱敏,密码 / 密钥本就不记录 - ZMODEM 写入路径保护(拒绝软链与系统目录) - 密码错误锁定机制(3 次错误锁定 5 分钟,每日最多 30 次) - 敏感信息存储于 OS Keyring - **GUI IPC 资源边界**:单请求 1 MiB 上限、并发连接上限 32、逐连接线程,拒绝资源耗尽型本地滥用 - **安装器数据删除二次确认**:卸载/更新时勾选「删除应用数据」会弹危险提示并要求二次确认(默认「否」),明确告知将删除连接 / 密码 / 历史 / 密钥库且不可恢复,防止误删 ### 版本管理 - 自动版本备份(升级前) - 一键回滚到历史版本 - 最多保留 5 个备份版本 ### 应用更新 - **侧边栏底部版本号**:常驻显示当前版本,发现新版本时版本号旁出现绿点提示,点击打开关于对话框 - **登录后自动检查**:每次登录进入主页后台静默检测 Gitee 最新 release(网络超时 30s) - **左下角更新提示**:检测到新版本时左下角弹出「发现新版本 vX.X.X」卡片(带绿点),可忽略(按版本记忆) - **自动下载安装**:点「立即更新」后台下载安装包(带进度条)→「安装并重启」自动启动安装器并退出 App 接管安装;下载失败可回退浏览器手动下载 - **关于对话框**:手动「检查更新」+「去下载」+ 查看更新日志(内置 CHANGELOG,版本升级后首启自动展示) - **单实例检测**:启动时检测已有 MyShell 实例,弹窗选择「覆盖启动」(结束旧实例并继续启动)或「退出」(保持现有);覆盖启动优先优雅退出(清理会话),超时兜底强杀 ### CLI 与 MCP 服务器 MyShell 提供命令行工具和 MCP 协议服务器,让 AI agent(Claude Desktop、Cursor、ZCode 等)能直接使用已保存的 SSH/SFTP 连接。 **myshell-cli** — 命令行工具: ```bash myshell-cli list --json # 列出所有连接 myshell-cli exec myserver "uname -a" --json # 远程执行命令 myshell-cli sftp ls myserver /var/log --json # 列出远程目录 myshell-cli sftp get myserver /etc/hosts ./hosts # 下载文件 myshell-cli sftp put myserver ./file.txt /tmp/ # 上传文件 myshell-cli test myserver # 测试连接 myshell-cli ssh myserver # 交互式终端 ``` Vault 解锁:使用 `--passphrase` 参数,或交互式提示。 > **危险操作确认:** `exec` 会先用与 GUI/MCP 相同的命令规则引擎判定,命中即拒绝执行并列出命中的规则;`sftp put` / `sftp rm` / `sftp rename` 与 MCP 策略一致,一律要求人工确认。终端上没有弹窗,**确认方式为显式 `--yes`(或 `-y`)**: > ```bash > myshell-cli exec myserver "rm -rf /tmp/x" --yes # 不加 --yes 会被拒绝并说明命中规则 > myshell-cli sftp rm myserver /tmp/f --yes > ``` > 规则文件(`<配置目录>/myshell/mcp-command-rules.json`)读不出来时**拒绝执行**而非放行。 **myshell-mcp** — MCP 协议服务器(stdio 传输): ```json // Claude Desktop / Cursor / ZCode 配置 { "mcpServers": { "myshell": { "command": "myshell-mcp" }}} ``` > **安全模型**:MCP server 不存储 vault 密码,也不持有解密密钥。所有服务器访问必须经过 MyShell GUI——ssh_exec 在 GUI 终端标签页内执行(用户已在 GUI 中解锁 vault),SFTP 工具通过 IPC 向 GUI 请求解密后的连接凭证。GUI↔MCP 的 localhost IPC 桥要求**每条命令携带随机会话令牌**(写入用户配置目录的端口文件中,受用户目录 ACL 保护;令牌缺失/错误一律在分发动作前拒绝),本机其他用户的进程无法再窃取凭证。**所有工具(除任务状态查询)都要求保险库已解锁**:GUI 未运行时 MCP 自动拉起应用(含识别并清理崩溃残留的 IPC 端口文件);保险库锁定时立即返回明确的「保险库未解锁」错误并把 MyShell 窗口置顶(密码门正对用户),不做静默等待——解锁后重试即恢复。锁定状态下连 `list_connections` 都不可用,AI 无法获取任何连接元数据。 暴露 15 个 MCP 工具:`list_connections`、`ssh_exec`、`sftp_list`、`sftp_download`、`sftp_upload`、`sftp_mkdir`、`sftp_remove`、`sftp_rename`、`upload_project`、`download_project`、`test_connection`、`screenshot_terminal`、`open_in_gui`、`zmodem_download`、`zmodem_upload`。连接参数支持三种形式:name / group-path / host-IP;重名场景自动按工具类型(ssh vs sftp)消歧。高危操作(`ssh_exec` / `sftp_remove` / `sftp_rename` / `sftp_upload` / `zmodem_upload`)必须弹 OS 级对话框人工确认,AI 无法跳过;命令类确认(`ssh_exec` / `ssh_run`)会逐条列出命中的黑名单规则及具体危害说明,弹窗出现时 MyShell 窗口自动置顶、聚焦并闪烁任务栏,避免人工审核被遗漏;用户点「取消」拒绝时返回硬性停止(HARD STOP)错误——AI 必须立即停止当前任务的所有后续操作(不重试、不换工具绕过)、向用户输出任务进度说明,并等待用户明确确认是否继续(`ssh_run` 后台任务拒绝后经 `ssh_status` 同样处理)。`open_in_gui` 通过 localhost IPC 通道驱动 GUI 打开连接 tab 并聚焦窗口(需 GUI 正在运行):支持 `tab_type`(auto/terminal/sftp,可对 SSH 连接强制开 SFTP 文件浏览 tab),默认聚焦已有 tab(同一连接已打开时切换过去不重复开)。`zmodem_download`/`zmodem_upload` 通过远端 `sz -r`/`rz`(lrzsz)走 ZMODEM 协议传输文件,双向支持目录递归(zmodem_download 子树按相对路径镜像到 local_dir;zmodem_upload 目录展开后按相对路径 offer,远端 rz 重建目录树),用于 SFTP 子系统不可用的受限 shell / 堡垒机 / 嵌入式设备场景——优先用 zmodem_*,技术性失败(如远端无 lrzsz)时再回退 sftp_*。 ## 更新日志 ### v2.15.3(2026-10-01) **🐛 修复** - 安装/升级时进程占用检测静默失效:安装器的 `CheckIfAppIsRunning` 此前传裸文件名,Restart Manager 按相对路径匹配不到占用进程,"检测到运行→确认→强制结束"的对话框从不触发——`myshell-mcp.exe` 被 AI 客户端(Claude/Cursor/ZCode 等)常驻占用时仍被强行覆盖,安装"成功"但 MCP 对客户端静默失效,安装目录只剩 `.old` 残留。已补全为 `$INSTDIR` 完整路径(安装/卸载共 6 处,含主程序) - 复制 MCP/CLI 二进制前新增二次占用检测:AI 客户端可能在安装开头检查通过后、文件复制前重新拉起 MCP 进程(MCP 配置面越广越容易触发),此前会再次撞锁失败;现在复制前再确认一次,仍是"用户确认后结束进程",不做静默强杀 ### v2.15.2(2026-09-29) **🐛 修复** - 数据库单元测试每次运行都向系统临时目录泄漏一个 ~92 KB 的测试库(清理逻辑误用 remove_dir_all 删除文件,且错误被静默吞掉,已积压 78 个) - `zmodem_download` 的工具描述谎称支持目录下载(实测 `sz` 无法打开目录、且 `-r` 实为断点续传而非递归),AI 误信后会撞上指不到真因的报错;已改为明确说明仅支持单文件并指向 `download_project` ### v2.15.1(2026-09-29) **🔒 安全** - 命令黑名单分词器重写:引号/分组/控制关键字/绝对路径等绕过形态(`'rm' -rf /x`、`( rm -rf /x )`、`do rm -rf`)全部拦截 - MCP 危险命令确认门改为 fail-closed:规则加载或解析失败时一律弹窗/拒绝,不再因一次 IPC 错误放行 - 私钥不再下发前端渲染进程,连接列表只返回「是否已存私钥」布尔量 - 背景图/反馈截图的文件读取收敛:要求保险库已解锁、限定图片类型,且永不读取配置目录与 ~/.ssh - CLI 的 exec / sftp put / sftp rm / sftp rename 接入同一套命令确认规则,命中即拒绝(需显式 --yes) - 保险库改为单文件原子提交:改主密码中途失败不再导致新旧口令都打不开、数据无法恢复 - 修改主密码时同步用新口令重新加密本地备份,避免旧口令长期有效 - 编辑 AI 供应商并修改 Base URL 后,已保存的 API Key 不再自动发送到新主机,需显式确认 - 保险库 KDF 迭代数不再被配置文件任意指定(0 会使密码派生塌缩为单次 HMAC) - 暴力破解锁定计数文件损坏或不可读时按已锁定处理,不再静默清零 - ZMODEM 保存路径现由落盘点自行校验,拒绝上级引用与软链跳转 - 日志脱敏新增 Windows / Linux 主目录规则,反馈日志不再带出本机账号名 - 锁定保险库时真正擦除内存中的数据加密密钥(此前只是释放分配,密钥仍留在已释放的堆页里) - 主密码与派生密钥改用 zeroize 包装,离开作用域即擦除,覆盖 GUI 的 8 个命令入口与 CLI 的环境变量/交互式读取 - 解密后的明文缓冲改用 zeroize 包装——所有凭据(连接密码、代理密码、命令历史、API key)唯一的解密出口不再把明文留在堆上 - 读取密码时返回零化字符串,主密码与各连接凭据离开作用域即从内存擦除 **🛠️ 优化** - 非法命令规则正则从静默忽略改为写入日志,便于发现失效的保护规则 - 反馈对话框如实说明截图仅打包到本地 zip,不会上传到任何服务器 - 侧栏折叠状态现在会持久化,此前只有顶栏折叠会保存 - 终端截图改用当前配色方案,此前多数配色下截图颜色与窗口不一致 - 仅使用 ZMODEM 传输时不再无限累积已完成的传输任务 - 新增 zeroize 类型守卫与反向对照脚本,防止密钥类型被静默改回裸字节数组 - 字体枚举移出 Tauri 命令层,保住三个二进制「库不依赖 Tauri」的解耦边界 **🐛 修复** - 编辑私钥认证的连接会在保存时静默销毁私钥,删除改为需显式确认 - zsh 下 `>&文件` 被误判为安全的文件描述符复制 - 配置回退不再覆盖运行中的数据库,改为重启后生效(此前会与运行中的 SQLite 句柄和旧 DEK 冲突) - 导出连接备份时凭据读取失败不再静默忽略,改为逐条列出缺失项 - AI 的 upload_project / download_project 现在校验远端退出码与完成标记,失败时不再谎报成功 - 内置「Ollama(本地)」AI 预设此前每次对话都报「未配置 API key」,现已可直接使用 - AI 供应商 Base URL 为空时后端会崩溃,改为返回明确错误提示 - MCP 不会把同一条命令执行两遍:命令已送达终端后不再静默无头重跑 - 远端未返回退出码(连接中断/被信号终止)时不再上报 `exit_code 0` 成功 - 同一秒内发起的多个 MCP 长任务 ID 会相互覆盖,导致 ssh_cancel 取消错对象 - 旧连接迁移到保险库时,跳过的行其主机名/用户名/私钥路径会被整表 DROP 连带销毁 - ZMODEM 下载时磁盘写满/设备拔出不再谎报 100% 成功,改为显式报错并中止 - 慢磁盘下 ZMODEM 落盘队列无界增长可能耗尽内存,现设 64 MB 上限 - FTP 下载远端失败时会先清空本地同名文件,改为先连接远端再创建本地文件 - SFTP 递归下载的层级上限此前是死代码,符号链接成环会导致无界递归 - 上传/下载的落盘(磁盘满、配额)错误被忽略,短文件被报成传输成功 - ZMODEM 上传时远端返回越界偏移会被当作成功(实际传了零内容) - ZMODEM 下载含 0x91/0x93 字节的二进制文件会被静默损坏 - GUI / CLI / MCP 同时访问数据库时可能出现 "database is locked",MCP 服务器甚至会直接退出 - 主密码验证失败后密码仍留在输入框;导出/导入对话框取消时口令不清空 - 第二个 MyShell 实例的互斥体从未被真正持有,可能出现多实例同时写同一个数据库 - `myshell-cli vault status` 会消耗密码错误次数,三次调用即锁住保险库 - 回收站不显示删除时间、备份列表不显示日期、反馈对话框缺少「打开日志文件夹」按钮、密码错误次数提示不显示 - 命令栏在中文输入法确认候选词时按回车会误提交未合成的拼音 - 「不记录命令历史」开关在设置读取失败时会错误显示为正在记录 - 回收站加载失败会显示成「回收站为空」,掩盖了仍可恢复的连接 - SFTP 文件列表出现 `.` / `..` 条目,下载报文件名非法、删除会误对当前目录执行 - 遥测上报在 4xx/5xx 时被误判为成功,导致该版本事件永久丢失 - ZMODEM 接收端可能把后续帧头当作文件内容写入(以 ZCRCW 结束数据帧的发送方) - ZMODEM 接收端可能因转义数据字节被误判为帧头而永久卡死、吞掉后续全部终端输出 - ZMODEM 上传时对端以 binary32 应答控制头会挂起;缓冲位置大小端与写入端不一致 - ZMODEM 上传在文件中途被截断时仍报告为完整成功 - 快捷命令删除失败无提示、重排序中断后顺序永久错乱 - 拖拽连接过程中界面被卸载后,仍可能在任意位置松开鼠标导致连接被移动 - MCP 确认弹窗的命令高亮在首次加载失败或设置改动后不再更新 - ZMODEM 下载进度条永远显示 0%:完成时未回填总字节数,状态按 0/0 计算百分比 - ZMODEM 下载多文件时进度被清零(sz -r 传目录时每来一个新文件进度都会重置) - 端口号越界时静默变成 0,连接时只报「无法连接」的困惑错误 - 保险库状态查询偶发失败时把已有保险库显示成「未初始化」,只能重启应用才能恢复 ### v2.15.0(2026-09-20) #### ✨ 新增 - **前端整体迁移 Vue 3 + myui 统一界面框架**:五区壳层(全局顶栏/连接树/工作区/AI 右栏/状态栏)与全部面板、对话框重写为 Vue 3 组件;设计令牌、亮暗主题、中英文国际化、外观设置(配色预设/背景图/毛玻璃)与设置抽屉全部对齐 myui 框架。后端 Rust IPC 契约零改动,React 旧实现保留于 src-legacy 备查。 - **界面观感与框架组件统一**:8 个对话框统一 MyDialog 壳、设置中心换 MyNav 导航、取色器与终端字体选择器迁移框架组件(MyColorField/MyCombobox:模糊过滤 + 命中高亮 + 自由输入)、连接树侧栏与 AI 右栏毛玻璃背景(设置背景图后透出模糊底图)、登录门禁换品牌 Logo 并修正输入框对齐。 - **MCP 高危命令确认支持「本轮会话均允许」**:确认框新增第三按钮,点击后本轮 AI 会话内所有高危命令(命令执行、文件上传/删除/重命名、项目上传下载、ZMODEM 上传)直接执行、不再弹窗;顶栏常驻「已放行高危」警示胶囊显示授权状态,可一键撤销(撤销后恢复逐条确认)。授权随 MCP 进程结束自动失效,不跨会话保留;「取消/拒绝」的硬停止语义不变。 #### 🛠️ 优化 - **myui 组件库升级 v0.12.0 → v0.18.0**:六个版本均为向后兼容增量(MyDropdown/MyCollapse/MyForm/MyUpload 等新组件、tooltip/下拉统一观感、输入件 focus()/blur() 编程接口、线性图标实心块修复),本项目零代码改动。 - **构建链迁移 pnpm**:移除 package-lock.json 改由 pnpm-lock.yaml 接管,版本同步脚本同步适配。 - **发布脚本自动感知 cargo 自定义 target-dir**:cargo 产物目录不在项目内(CARGO_HOME 配置了其他磁盘)时,Gitee/GitHub 发布脚本也能正确定位安装包。 #### 🐛 修复 - **服务器监控条被终端文字遮挡**:终端区域止于监控条上方(新增 work-panes 定位层),监控条改为实底色 + 上边框——此前引用了未定义的主题令牌导致背景透明,终端文字直接透过监控条。 ### v2.14.1(2026-09-08) #### 🛠️ 优化 - **ZMODEM 传输中取消按钮偶发无响应**:下载方向进度事件此前无节流(高速传输时每秒 200+ IPC 事件淹没 WebView),现在与上传同样按 100ms 节流,点击即时生效,传输期间 CPU 占用同步下降。 #### 🐛 修复 - **ZMODEM 下载(sz)无权限时无任何反应**:sz 打不开文件时把报错直接打到终端后退出(不发取消序列),错误文本被 ZMODEM 接收器静默吞掉、终端假死 30 秒。现在 2 秒内回显远端报错原文并自动退出 ZMODEM 模式。 - **ZMODEM 接收超时后无法继续输入命令**:超时/失败收场时补发 8×CAN 中止序列,敲掉仍挂在远端终端上的 sz、shell 立即恢复可用,同时回显此前被吞的输出。 - **ZMODEM 下载进度条滞后于百分比数字**:进度事件节流(见上)+ 进度条动画由 0.3s ease 改为 120ms 线性,进度条紧贴实时数字。 - **sz/rz 选择文件夹对话框中鼠标指针不可见**:绕过 WebView2「在键入时隐藏鼠标指针」缺陷(MicrosoftEdge/WebView2Feedback#5687),文件/文件夹选择器弹出前微移鼠标指针使其显形。 ### v2.14.0(2026-09-05) #### ✨ 新增 - **FTP/FTPS 功能闭环**:FTP 连接支持 explicit FTPS(rustls 标准信任链)与 implicit FTPS;FTP 上传/下载与 SFTP 同一套传输 UI(递归展开、进度浮层、取消、错误列表);并修复 FTP 会话归还导致第二次操作必失败的 bug。 - **MCP 高危命令确认弹窗新增「危害说明」**:逐条列出命中的黑名单规则及具体危害(约 70 条内置描述,自定义规则回退显示正则),弹窗自动置顶、聚焦、闪烁任务栏提醒人工审核,headless MessageBoxW 详情同步附带。 #### 🛠️ 优化 - **连接后展示登录横幅**:Last login 时间/IP 与 MOTD,对齐 Xshell 首屏体验——修复前端监听就绪前的 banner 字节丢失。 - **降低确认噪音**:mkdir/touch 移出默认黑名单(只创建不覆盖不删除);git/docker/kubectl 改为写子命令才确认(status/log/diff、ps/logs、get 免确认);curl 收窄为带写文件/发数据参数才确认(纯 GET 免确认),wget 保持整体确认。 - **MCP 文件传输顺序反转**:zmodem(rz/sz)优先,技术性失败(如远端无 lrzsz、超时)后再回退 SFTP——工具描述与系统提示同步翻转,用户拒绝确认弹窗仍为硬停止不回退。 #### 🐛 修复 - **中文 locale 服务器系统监控内存显示 0 B/0 B**(如 Ubuntu zh_CN):内存改为直读 /proc/meminfo(free -b 兜底),不再受 free 本地化标签影响。 #### 🔒 安全 - **修复 MCP 命令确认白名单绕过**:改为逐命令段判定(引号/转义感知),白名单不再能豁免黑名单命中,GUI 与 MCP 共用同一 Rust 判定。 - **修复 Windows 下 SFTP 递归下载本地路径逃逸**:远端文件名严格按单一路径组件校验(反斜杠/盘符/保留设备名/尾点尾空格等),构建目标前检查符号链接与 reparse point。 - **suppaftp 8.0.5 → 10.0.2**(RUSTSEC-2026-0271 FTP CRLF 命令注入),并在后端对所有 FTP 参数统一拒绝 CR/LF/NUL。 - **密码查看改为后端原子「验证主密码 + 解密」命令**(reveal_connection_password),WebView 无法再绕过前端二次验证。 - **GUI localhost IPC 加固**:单请求上限 1 MiB、并发连接上限 32、逐连接线程处理,长 exec_in_tab 不再阻塞后续请求。 - **修复「一键配置 MCP」对损坏配置的覆盖风险**:无效 JSON 直接报错不写、非对象节点拒绝覆盖、临时文件 + rename 原子写、原文件自动备份 .bak。 - **命令历史与快捷命令 AES-GCM 加密存储**(保险库解锁后自动迁移旧明文),并提供后端强制的「不记录命令历史」开关。 - **封堵黑名单 wrapper 绕过**:nohup/xargs/env/timeout/nice/setsid/busybox 等 13 个中性前缀在判定前剥离,`find | xargs rm`、`nohup rm -rf`、`ps|awk|xargs kill` 不再免确认。 - **补齐高危命令默认黑名单**:npx/bun/uv、nc/socat(反弹 shell)、modprobe/insmod(内核模块)、chattr、wipefs/sfdisk、ip/ifconfig/nmcli(自断连接)、doas/pkexec/runuser(提权)、dpkg/rpm、systemd-run/update-rc.d(持久化)、supervisorctl、fuser -k、chpasswd、setenforce、sysctl、podman、terraform/ansible/helm、aws/gcloud/az 等云 CLI。 ### v2.13.0(2026-09-02) #### ✨ 新增 - **SFTP 文件夹递归下载 + 多文件并发下载**:勾选文件夹(可与文件混选)递归下载整个子树,本地按 `<目标目录>/<文件夹名>/...` 镜像、空目录保留、符号链接循环有深度保护;多文件按可配置线程数并行拉取(设置 → 文件传输,默认 3 线程、1–16 可调,即时生效),所有线程复用同一条 SSH 连接,海量小文件提速明显。单文件下载、上传、取消行为不变。 - **ZMODEM 文件夹递归传输(双向)**:下载 `sz -r 目录` / MCP `zmodem_download` 传目录递归拉回子树(接收端按 offer 相对路径建目录,路径逐段清洗防 `..`/盘符逃逸);上传 rz 弹「选择文件 / 选择文件夹」选择条,文件夹按相对路径 offer、远端 lrzsz rz 自动重建目录树(MCP `zmodem_upload` 同样支持目录)。ZMODEM 为协议单流串行——多文件顺序传输、无并发(设置页已注明)。 #### 🐛 修复 - **sz 下载两类卡死:远端文件无读权限或目标是目录时应用假死**:接收器不识别 lrzsz 的 10×CAN 中止序列导致会话永不结束,shell 后续输出全部被吞、终端冻结。现自动识别 CAN 连发与 ZABORT/ZFERR 帧立即恢复终端并显示错误原因,另加 30s 空闲超时兜底;前端补上 `zmodem_error` 订阅(此前失败原因无人消费)。顺带修复 `command_rules` 单元测试的既有编译错误。 ### v2.12.2(2026-08-28) #### 🛠️ 优化 - **MCP 高危操作被用户拒绝后返回「硬性停止」指令**:AI 必须立即停止当前任务的一切后续操作(不重试、不换工具绕过),向用户输出当前任务说明(在做什么、已完成哪些步骤、被拒绝的是哪一步、剩余计划),等待用户明确确认是否继续。覆盖全部确认弹窗出口与异步任务(ssh_run / zmodem_upload),GUI 确认框提示语同步更新。 - **前后端依赖全量更新**:npm 漏洞清零(nanoid / postcss 两个 high)+ 21 包更新(tauri 前端套件最新补丁版);Rust 侧 160+ 包(tauri 2.11.5、rustls 0.23.43、russh-sftp 2.4.0 等)。React 19 / Vite 8 / xterm 6 / TypeScript 7 等大版本有意不升。 #### 🔒 安全 - **GUI↔MCP localhost IPC 桥增加随机会话令牌认证**:每条 IPC 命令必须携带端口文件中随 GUI 每次启动轮换的随机令牌,否则在分发动作前一律拒绝——本机其他用户的进程无法再在保险库解锁状态下窃取解密凭证。旧格式端口文件向后兼容;版本错配时返回明确的升级提示。 - **russh 0.50 → 0.60.3,修复两个 high 漏洞**(RUSTSEC-2026-0154/0153):恶意 SSH 服务器可触发无上限内存分配导致客户端拒绝服务。加密后端换预编译 ring(免 NASM/CMake 依赖),业务代码零改动,`cargo audit` 两个 high 清零。 ### v2.12.1(2026-08-24) #### 🐛 修复 - **AI 模型选择器即时刷新**:设置里新增模型后立即出现在 AI 面板的模型选择器中、立即可选(原先需重启应用)。头部标签与下拉高亮同步修正为显示当前实际选中的具体模型(原先固定显示供应商主模型,选了新模型看不出已生效)。 ### v2.12.0(2026-08-20) #### ✨ 新增 - **启动时单实例检测**:已有实例运行时弹 TaskDialog 选择「覆盖启动」(结束旧实例并继续启动)或「退出」(保持现有实例)。覆盖启动优先走 IPC 优雅退出(旧实例 `app.exit(0)`,正确清理 SSH/PTY 会话与 IPC 端口文件),超时兜底强杀;检测用 named mutex(`Global\MyShellSingleInstanceMutex`),进程崩溃自动释放、零 stale 风险。杜绝双实例并存导致的 SSH 会话分裂与 `gui-ipc-port` 互相覆盖(升级安装 / 误双击场景)。 #### 🛠️ 优化 - **MCP 调用时 GUI 未运行自动拉起应用**:所有工具统一走 `ensure_gui_running()`(原先仅 ssh_run 等少数路径会拉起,其余直接报错)。同时识别崩溃残留的陈旧 IPC 端口文件——探测端口无监听即删除残留并重新拉起 GUI;连接成功但无响应只报错不重启(避免触发单实例「覆盖启动」误杀挂起但存活的实例)。 - **保险库锁定时 MCP 立即提示,不再静默等待 30 秒**:原「每 3s 轮询、最多 30s」逻辑删除,改为单次状态查询直出错误;锁定时先经新增的 `focus_unlock` IPC 把 MyShell 窗口置顶(密码输入框正对用户),再返回可操作的「保险库未解锁」提示——AI 转告用户、解锁后重试即恢复。保险库未初始化(首次使用)同样立即给出引导。 #### 🔒 安全 - **MCP 保险库门禁覆盖全部工具**:豁免名单从 9 个收到 3 个(仅 `ssh_status` / `ssh_cancel` / `zmodem_status` 任务状态查询保留),`list_connections`、`open_in_gui`、`screenshot_terminal`、`zmodem_*`、`ssh_run` 全部纳入——锁定状态下 AI 无法获取任何连接元数据(连接名称 / 分组也不行)。 - **修复 upload_project / download_project 远端路径命令注入**:远端路径原先未转义直接拼进 `sudo mkdir/mv/tar/rm` 命令链与内联 Python 代码,含引号的路径可逃逸为 root 权限任意命令执行。现统一 `shell_quote()`(标准 `'\''` 转义),Python 打包命令改为环境变量传路径(`MYTAR` / `MYDIR`)。顺带修复:zmodem `sz` / `cd` 路径转义丢撇号、`download_project` 体积统计恒为 0(原先在删除临时文件后才读 metadata)、`screenshot_terminal` 输出的 user@host 恒为空(改用解密解析)。 ### v2.11.2(2026-08-17) #### 🛠️ 优化 - **MCP exec 互斥锁自愈**:GUI 端"上一条命令还在跑"误锁改为 Map+timestamp,超 60s 自动释放,不再需要重启 GUI。 - **MCP ssh_exec/ssh_run 输出上限可配置**:`MCP_SSH_MAX_OUTPUT_BYTES` 环境变量(默认 4 MiB,64 KiB~1 GiB),解决大镜像/大仓安装日志静默截断。 - **MCP 新增 `ssh_run`/`ssh_status`/`ssh_cancel`**:异步长任务通道——`ssh_run` 立即返回 task_id,`ssh_status` 轮询进度,`ssh_cancel` 中断 runaway 任务(保留截至取消点的输出)。适配 apt upgrade / docker pull / git clone 等 5min+ 任务。 - **ssh_exec 默认 timeout 30s → 60s**(上限 1h);`myshell-cli exec` 同步 60s + `--timeout` 范围校验 1s~3600s。 - Umami 统计事件名加 `myshell_` 前缀,与 zcode-assistant 区分。 ### v2.11.1(2026-08-13) #### 🛠️ 优化 - **快捷命令多行执行支持行间延迟**,避免下一条命令在交互提示/密码输入就绪前被提前送出。在「设置 → 快捷命令 → ⏱ 行间延迟」选择模式: - **智能等待**:监听终端输出,等上一行输出静止后再发下一行,自动适配命令速度,能处理 `sudo`/`mysql` 密码提示(推荐); - **固定延迟**:每行之间固定等待; - **关闭**:一次性全部发出(旧行为)。 - **行内延迟指令** `##delay:500`(或 `##delay:1s`)在两行之间精确等待,作为最小下限与模式叠加生效;命令编辑器标题旁新增 `?` 按钮可展开/收起编写规则说明。 ### v2.11.0(2026-08-10) #### ✨ 新增 - **MCP 新增 lrzsz(ZMODEM) 文件传输**:`zmodem_download`/`zmodem_upload` 覆盖 SFTP 子系统不可用的受限 shell/堡垒机/嵌入式设备场景。上传走 native pump 架构,中/大文件实测 SHA256 完全一致。 #### 🛠️ 优化 - **底部状态栏内存占用**改用内核 MemAvailable 口径,与 htop / node_exporter 一致,不再虚高。 - **rz 上传提速**:专用 pump task + 1 MB 批量写,子包 64→128 KB;进度 IPC 事件 100ms 节流(100MB 文件减少 ~8× IPC)。 #### 🐛 修复 - **MCP `ssh_exec` 高频调用导致 GUI 卡死**:IPC 监听器串行阻塞改为独立线程处理,单条命令不再冻结整个通道;移除 exec 每次抢焦点骚扰。 - **ZMODEM(rz) 上传中/大文件卡死**:ZEOF 收尾帧经跨进程回路丢失导致永久卡死,已重构为 native pump 架构 + fast-finish + 30s 超时双重兜底。 ### v2.10.0(2026-08-03) #### ✨ 新增 - **多窗口模式**:点击🪟多窗口按钮,选择多个 SSH 会话以网格布局同时展示。支持配置行列数、自动最大化、滚动溢出、动态均衡布局。 - **会话管理增强**:当前会话下拉新增全部重连/全部广播/每行广播开关;广播组下拉新增退出全部广播。 #### 🛠️ 优化 - **CommandBar 窄屏自适应**:窗口宽度不足时按钮只显示图标,防止输入框挤压。 ### v2.9.0(2026-07-30) #### ✨ 新增 - **防止 shell 空闲自动登出(TMOUT)**:连接高级选项新增独立开关,登录时注入 `export TMOUT=0`,不额外开通道、受限账号可用。 #### 🛠️ 优化 - **移除「应用级保活(exec 心跳)」**:该功能每 N 秒开 exec 通道会打死受限单会话账号;russh 15s keepalive 对普通服务器已足够,TMOUT 防护由独立开关覆盖。 #### 🐛 修复 - **窗口最小化后自动锁定不触发**:后台 webview 节流挂起定时器,新增窗口恢复前台时按时间戳补锁。 - **编辑连接后点「重连」仍用旧配置**:重连改为读取最新连接配置,与侧边栏重开一致。 ### v2.8.1(2026-07-30) #### 🐛 修复 - **SSH 应用级保活防不住 TMOUT 自动登出**:勾选保活后 SSH 仍被服务器以 `timed out waiting for input: auto-logout` 踢出。现改为仅对该连接在 shell 启动时注入 `export TMOUT=0`(不误伤其它会话、对编辑器无干扰),exec 心跳保留防 NAT 断连。 - **窗口最小化后自动锁定不触发**:后台 webview 节流挂起定时器导致不锁定,新增窗口恢复前台时按时间戳补锁。 ### v2.8.0(2026-07-29) #### ✨ 新增 - **空闲自动锁定**:无操作超过设定时长后自动锁定,需重新输入密码。设置→安全可配置(10分钟/30分钟/1小时/不启用),默认30分钟。 ### v2.7.0(2026-07-29) #### ✨ 新增 - **SFTP 传输取消**:下载/上传过程中可随时取消,后端 32 KB 块边界即时响应。 #### 🛠️ 优化 - **SFTP 传输进度面板重做**:仿 ZMODEM 四行布局,新增速度、开始时间、已用时间、预计剩余。 - **ZMODEM 进度面板增强**:新增开始时间、已用时间、预计剩余,刷新间隔改为 1 秒。 #### 🐛 修复 - **ZMODEM 下载大文件卡死**:改为 256 KB 缓冲批量写入,IPC 调用量降低 32 倍。 - **ZMODEM 原生下载文件大小不一致**:CRC 完整性检查提前到 payload 写入之前,消除子包重复写入。 - **ZMODEM 取消后终端打印垃圾**:改为 500 ms 时间窗口抑制协议尾字节。 ### v2.6.2(2026-07-27) #### 🐛 修复 - **服务器主机密钥变更后无法连接**:重装/换密钥后连接报含糊的 "Unknown server key" 且无法恢复。现报错明确列出新旧指纹,错误屏「重置密钥并重连」一键清除旧记录并重新信任(仅 SSH/SFTP,保留 MITM 防护)。 ### v2.6.1(2026-07-27) #### 🐛 修复 - **服务器主机密钥变更后无法连接**:服务器重装/换密钥后连接报含糊的 "Unknown server key" 且无法恢复。现报错明确列出新旧指纹,连接 ⋯ 菜单新增「重置主机密钥信任」(仅 SSH/SFTP),重置后重新信任;保留 MITM 防护,不自动接受。 ### v2.6.0(2026-07-26) #### ✨ 新增 - **连接高级选项(SSH/SFTP)**:连接对话框新增「高级选项」组——地址族(自动 / 强制 IPv4 / 强制 IPv6,绕开 IPv6 黑洞)、每连接连接超时(默认 10s)、SSH Keepalive 间隔(默认 15s)。默认值与原行为一致,不影响既有连接。 ### v2.5.5(2026-07-25) #### 🐛 修复 - **MCP 高危命令重复弹窗**:GUI 确认框超时后不再回退 headless 弹第二个 Windows 弹窗。只有 GUI 真正不可用才回退。 - **应用内检查更新检测不到新版本**:Gitee 的 `/releases/latest` 接口不可靠(一直返回 v1.11.2 而非真实的 v2.5.5),改用列表接口并在客户端用版本比较选出真正的最新版。 ### v2.5.4(2026-07-25) #### 🐛 修复 - **AI 面板「服务器信息」巡检在连接失效时报错**(`Open exec channel failed (ConnectFailed)`):现自动重连+重试一次,不再要求用户手动重连 tab。 ### v2.5.3(2026-07-25) #### 🐛 修复 - **MCP ssh_exec 长耗时命令导致会话挂起**:新增命令互斥锁——同一连接前一条没完成时拒绝新命令,提示 AI 用 `nohup ... &` + 轮询日志。 - **超时后 PTY 残留进程**:硬超时后发 `Ctrl+C` 打断残留进程,恢复干净 prompt。 ### v2.5.2(2026-07-25) #### ✨ 新增 - **MCP 工具调用等待保险库解锁**:AI 调用 ssh_exec / sftp_* 时若 GUI 未解锁,每 3s 轮询一次、最多等 30s,给用户输入主密码的时间。超时才报错。`list_connections` 不受影响。 ### v2.5.1(2026-07-25) #### 🐛 修复 - **匿名统计上报被 CSP 拦截**:`connect-src` 未放行 `cloud.umami.is`,Umami 后台收不到数据。已加白名单。 - **统计上报失败无法重试**:改为 fetch 成功后才写 version stamp,失败下次静默重试。 #### 🛠️ 优化 - **同意策略改为「同意一次后静默」**:不再每次升级都重新弹同意框。 ### v2.5.0(2026-07-25) #### ✨ 新增 - **MCP 会话超时自动原地重连**:服务器 TMOUT 踢断后复用同 tab + 终端快照保留历史,不再开新标签页。 #### 🛠️ 优化 - **MCP ssh_exec 会话复用提速**:会话已存在时从 5-6s 降至 <1s(砍掉 `open_connection` + 固定 sleep)。 - **MCP 大输出处理**:outputBuf 4MB 上限 + 尾部正则,避免 O(n²) 卡死。 - **保险库锁定快速失败**:MCP 命令立即报错,不再等 30s 超时。 #### 🐛 修复 - **MCP 双连接竞态**、**ssh_exec 输出丢失颜色**(ANSI 保留版定位)、**大输出命令误报超时**(sentinel 扫描窗口 2KB→16KB + 输出静止 5s 兜底)。 ### v2.4.0(2026-07-24) #### ✨ 新增 - **MCP `screenshot_terminal`**:AI 可请求 GUI 对终端 tab 截图(PNG data URL),用于视觉检查输出;GUI 未运行时自动拉起聚焦。 #### 🔒 安全 - **`list_connections` 不再泄露 host/port/username**:改用纯文本列查询,IP/用户名仅在 GUI 解锁后可访问;IP 直连查询要求 GUI 在线 + vault 解锁。 #### 🐛 修复 - **sz 多文件竞态挂起**(offer 丢失 → 队列缓冲)、**sz 收尾卡死**(写入未排干即关句柄 → `Promise.all` drain)、**sz 启动 rz 噪音**(切换点剥离 auto-start 通告)。 ### v2.3.0(2026-07-22) #### ✨ 新增 - **MCP upload_project / download_project**:AI 一键上传/下载整个项目目录(tar 打包 + SSH 管道直传)。 - **终端 sentinel 噪音过滤**:`__MCP_DONE_` 行在渲染层丢弃,终端零噪音(智能缓冲不影响交互)。 #### 🛠️ 优化 - **upload_project** SSH 管道直传替代 SFTP 分块,速度 10x+;download_project 支持 sudo tar + UTF-8 中文文件名。 - **sentinel 简化**:去掉 stty 三行辅助命令,改单行 sentinel + 截断式清洗。 - **命令确认规则 UI**:黑白名单改列表式——搜索、自动排序、字号放大、逐条删除。 #### 🐛 修复 - **ssh_exec 空输出**(订阅时序 + 提示符剥离)、**连续开新 tab**(focus_existing)、**stdout 残留辅助命令**(截断清洗)。 #### 🔒 安全 - **删除 MCP vault 密码 keyring 明文存储**:MCP 不再持有 DEK/passphrase,所有服务器访问强制经 GUI 解锁(ssh_exec 走 GUI tab,SFTP 经 IPC 解密凭证)。删除 GUI Vault 同步 UI + CLI save-passphrase。 ### v2.2.0(2026-07-22) #### ✨ 新增 - **MCP ssh_exec 界面同步展示**:AI 执行的命令现在实时显示在 GUI 终端 tab,用户可见可干预,输出回传给 AI(sentinel 标记法捕获 PTY 输出边界)。GUI 未运行时 MCP 自动拉起 `myshell.exe`。可在「设置 → MCP 支持 → 命令确认规则」开关。 #### 🛠️ 优化 - **ssh_exec 命令确认规则(黑名单正则 + 白名单豁免)**:只读命令(`ps`/`ls`/`cat`/`grep` 等)不再弹确认框,只有危险命令(`rm`/`kill`/`sudo`/写重定向/管道到 shell)才弹框;白名单豁免误报(`grep rm` 不误杀)。用户可在设置编辑黑/白名单和严格模式。19 个单元测试覆盖。 #### 🐛 修复 - **NSIS 升级报「无法打开要写入的文件:myshell-mcp.exe」**:安装/升级/卸载前新增对 `myshell-mcp.exe` / `myshell-cli.exe` 的运行检查(原先只检查主程序),被 AI 客户端常驻拉起时提前提示关闭。顺带修复 `myshell-mcp.exe` 重复打包 + 卸载 `Delete` 加 `/REBOOTOK`。 ### v2.1.0(2026-07-22) #### ✨ 新增 - **MCP `open_in_gui` 工具**:AI 可驱动 MyShell GUI 自动打开已保存连接的标签页并聚焦窗口(用户说"在 MyShell 打开 prod-db"即可)。通过 localhost TCP IPC 桥实现(MCP 与 GUI 独立进程,零新依赖、只绑 `127.0.0.1`);GUI 未运行时返回明确错误并建议改用 `ssh_exec`。 - **`tab_type` 参数**:`auto`/`terminal`/`sftp`(可对 SSH 连接强制开 SFTP 文件浏览 tab)。 - **智能聚焦**:默认聚焦已有 tab,同一连接已打开时切换过去不重复开。 - MCP 工具数 10 → 11。 ### v2.0.0(2026-07-21) > 重大版本:从「SSH/SFTP 客户端」进化为「AI agent 可集成的 SSH/SFTP 工作台」。新增 CLI、MCP Server、终端截图三大模块,提取 `myshell_core` 共享库实现 GUI/CLI/MCP 三二进制架构。 #### ✨ 新增 - **CLI 工具(myshell-cli)**:命令行访问已保存的 SSH/SFTP 连接,让 AI agent 和高级用户可在脚本/终端直接使用。支持 `list / exec / ssh / sftp / test / vault` 等命令,`--json` 输出对自动化友好。 - **MCP Server(myshell-mcp)**:通过 Model Context Protocol(stdio 传输)将 SSH/SFTP 能力暴露给 AI agent(Claude Desktop / Cursor / ZCode / opencode 等)。10 个工具:连接管理 + 远程命令执行 + SFTP 文件操作 + 连接测试 + 终端截图。 - **三二进制共享架构**:提取 `myshell_core` 库,GUI / CLI / MCP 三个二进制共享同一核心逻辑、同一 SQLite、同一 vault 和 keyring。 - **MCP 管理设置页**:「设置 → MCP 支持」集中管理:启用/禁用、自动检测已安装 AI 工具并一键写入配置。 - **MCP 连接智能查找**:连接参数支持 name / group-path / host-IP 三种形式;重名场景(同 IP 多类型)自动按工具类型消歧。 - **终端截图功能**:CommandBar 新增 📷 按钮,截取纯终端 viewport(不含标签栏/工具栏/输入栏)。读 xterm buffer 自绘,支持完整颜色和文字属性。文件名带毫秒防覆盖。 - **附件目录设置**:截图自动归档;保存后弹"已保存 + 打开"toast,跨平台调系统文件管理器并选中文件。 - **Linux deb 打包支持** + **应用内更新平台分发**(Windows=auto,Linux/macOS=browser)。 #### 🛠️ 优化 - **MCP 工具描述全面重写**:每个工具含 WHEN TO USE / WHEN NOT TO USE / OUTPUT / SIDE EFFECTS;新增 server-level `instructions` 字段(MCP 2025-06-18 规范)。 - **Cargo.toml `default-run = "myshell"`**:三二进制架构下 `cargo run` / `tauri dev` 不再需要 `--bin`。 #### 🔒 安全 - **MCP 高危操作人工确认**:`ssh_exec / sftp_remove / sftp_rename / sftp_upload` 必须弹 OS 级对话框,AI 无法跳过。 - **Vault 密码改用 Windows 凭证管理器(DPAPI 加密)**:替代明文环境变量方案,配置文件绝不出现明文密码。 ### v1.11.2(2026-07-17) #### 🐛 修复 - **匿名统计弹窗同版本重复弹出**:用户点击"暂不"后版本未标记已处理,导致下次启动再次弹窗;现在无论同意或拒绝都立即标记版本已处理,同一版本不再重复弹出 ### v1.11.1(2026-07-15) #### 🛠️ 优化 - **升级安装静默卸载旧版**:升级时双击新安装包,旧版本自动后台静默卸载(不再弹出旧版卸载向导界面),从"先卸载再安装"两步合并为一步 - **匿名统计每次升级都询问**:版本升级首次启动时都弹窗征求匿名统计同意,不再记住首次偏好后静默上报 #### 🐛 修复 - **长命令执行时 SSH 连接被误断**:执行长时间无输出的命令(如 `find | sort | uniq -c`)时 SSH 连接被 30 秒静默超时误杀,改用 keepalive 心跳维持连接(与 OpenSSH/MobaXterm 同机制),仅连续 3 次心跳无响应才判定断开 ### v1.11.0(2026-07-14) #### ✨ 新增 - **AI 设置界面左右布局**:左侧供应商列表(新建 / 选中 / 双击重命名 / 启用禁用开关),右侧详情编辑(预设模板下拉选择 / 基本信息 / 模型管理) - **供应商多模型管理**:每个供应商支持多个模型,可从接口自动获取可用模型(勾选添加)、手动添加、主模型标记 - **AI 聊天窗口两步模型选择**:先选供应商再选具体模型,仅展示已启用的自定义供应商 #### 🛠️ 优化 - **新建供应商校验**:需添加模型并通过测试后才可创建,避免无效配置 - **操作反馈改为 Toast 浮层**:测试 / 保存 / 删除等结果以顶部居中浮层提示 - **设置窗口固定高度**:切换类别时窗口大小不再跳变 - **测试针对性修复**:测试针对用户正在编辑的供应商而非全局活跃供应商 #### 🐛 修复 - **获取模型列表 key 无效**:新增服务端解密 key 的获取命令,保存后不再失败 - **alert 弹窗失效**:授权 dialog 权限,修复 Tauri v2 下 window.alert 被拦截 ### v1.10.2(2026-07-13) #### 🛠️ 优化 - **反馈提交改造**:弃用不稳定的 Web3Forms 和第三方图床(已封禁),改为唤起本地邮件客户端(mailto),反馈内容自动复制到剪贴板,弹窗提醒用户粘贴 - **Gitee Issue 入口**:反馈窗口底部新增 Gitee Issue 提交链接 - **反馈目录自动清理**:关闭反馈窗口时自动清空本地反馈包目录,防止磁盘堆积 - **资源管理器去重**:打开反馈文件夹时,如已有同名目录窗口则激活已有窗口,不再重复打开 #### 🐛 修复 - **打开反馈文件夹无效**:修复 `reveal_path` 白名单限制导致无法打开 feedback 目录的问题 - **反馈失败提示不明显**:提交失败时改为红色 ❌ 醒目提示,与成功状态明显区分 ### v1.10.1(2026-07-09) #### ✨ 新增 - **匿名版本统计**:每次版本升级首次启动时弹窗征求同意,匿名上报一次(随机设备 ID + 版本号 + 操作系统,不含任何连接信息),帮助了解各版本的真实用户覆盖量 ### v1.10.0(2026-07-09) #### ✨ 新增 - **左下角反馈入口**:侧边栏版本号右侧新增 💬 反馈图标,可提交问题报告 / 功能建议 / 其他反馈,支持截图(截屏或本地选图),自动附带脱敏后的运行日志,通过邮箱送达开发者;截图上传免费图床(ImgBB),提交失败时自动打包本地反馈包兜底 #### 🔒 安全 - **日志脱敏**:主机名 / 用户名 / IP 地址在写入日志前掩码(如 `192.168.1.10` → `192.*.*.10`),反馈日志二次脱敏;密码 / 密钥本就不记录 ### v1.9.1(2026-07-01) #### 🐛 修复 - **终端光标不闪烁**:修复连接后光标不闪烁、切换窗口后也不闪烁的问题(补全 focus 时序与窗口重新聚焦时的光标状态机重启) - **AI 上下文记忆丢失**:修复同一会话中 AI 不记得前文的问题(每次请求现在会携带完整对话历史) ### v1.9.0(2026-06-29) 终端渲染健壮性与可诊断性增强:渲染后端可选、光标更稳定、全链路日志监控,并重构设置面板为分类导航。 #### ✨ 新增 - **设置面板分类导航**:设置改为左右分栏,按「外观 / AI / 安全 / 数据管理 / 快捷命令」分类组织 - **终端渲染后端可选**:新增「自动 / Canvas / WebGL / DOM」渲染后端切换,解决部分用户光标和选区不可见的问题 - **全局日志监控**:前端崩溃、未捕获异常自动转发到后台日志文件,便于异常定位与用户反馈分析 #### 🛠️ 优化 - **终端默认改用 Canvas 渲染器**:配合条形光标(cursorStyle: bar),光标更稳定可见且不丢失闪烁 - **后端关键路径补全日志**:SSH / SFTP / 本地终端 / 数据库 / 备份 / AI / 代理 各模块失败与生命周期事件完整记录,会话链路可追溯 - **禁用 GPU 硬件加速开关**:设置新增「禁用 GPU 硬件加速」选项,作为 GPU 合成异常时的最终兜底(重启生效) #### 🐛 修复 - **光标样式遗留缺陷**:修复 forceVisibleCursor 注释声明 cursorStyle:"bar" 但代码从未实际设置的缺陷 ### v1.8.0(2026-06-26) 连接回收与侧栏交互增强:删除的连接可找回,侧栏操作菜单重构,多项体验优化与问题修复。 #### ✨ 新增 - **连接软删除 + 回收站**:删除的连接可在「设置 → 找回连接」恢复,最多保留 30 条 - **找回连接窗口**:新增「找回连接」窗口,按删除时间倒序排列,支持单条找回、彻底删除和清空回收站 #### 🛠️ 优化 - **连接重命名移入 ⋯ 菜单**:连接重命名移入「⋯ 更多操作」菜单,连接右键不再弹菜单 - **删除二次确认弹窗**:删除连接和文件夹改为自定义确认弹窗,修复部分环境下系统确认框不弹出的问题 - **删除文件夹联动回收站**:删除文件夹时,其下连接一并进入回收站(可恢复),不再移到根目录 #### 🐛 修复 - **大尺寸背景图不生效**:选图后自动压缩到 1920px / JPEG,避免超出本地存储配额导致设置无效 - **终端光标/选区不可见**:强制光标使用高对比前景色,选区提升不透明度,解决部分用户看不到光标和选区的问题 ### v1.7.0(2026-06-25) 侧栏交互增强、会话管理面板、广播级联重连等新功能。 #### ✨ 新增 - **侧栏拖拽调宽**:连接管理面板支持拖拽调整宽度(宽度持久化),鼠标悬停连接名可查看全称及主机地址 - **会话管理面板**:新增「当前会话」与「广播」下拉面板,可查看全部标签页全称、快速切换与关闭,支持一键清理所有掉线会话 - **广播级联重连**:点击重连一个掉线会话,同广播组其他掉线会话自动一起重连 - **AI 选区预览折叠**:AI 助手选区预览默认单行展示,双击展开完整内容 ### v1.6.3(2026-06-25) 表单必填校验与 AI 交互细节优化。 #### 🛠️ 优化 - **AI 面板终端输出截断**:自动附带的终端输出限制为 5000 字符,超长时显示截断提示 - **AI 面板引用内容折叠**:用户引用内容默认单行,双击展开完整内容 - **新建连接必填校验**:保存时标红必填字段,自动聚焦首个未填项并抖动提示 - **连接名称自动填充优化**:手动修改名称后不再被主机输入覆盖 - **快捷命令必填标注**:名称和命令字段标注红色星号,未填写时禁用保存 - **自定义主题色校验**:颜色值增加 HEX 格式校验,非法输入时禁用保存 ### v1.6.2(2026-06-24) 更新流程体验打磨与安装稳定性修复。 #### 🛠️ 优化 - **更新弹窗简化**:去掉双层玻璃外壳,改为单层卡片;按钮文案改为「忽略」和「更新」 - **关于对话框「更新」按钮**:由「去下载」改为「更新」—— 点击后自动下载安装(进度条 + 安装并重启),下载失败才回退浏览器下载;同时保留「网页下载」按钮作为备选 #### 🐛 修复 - **「安装并重启」os error 740**:非管理员用户点「安装并重启」报错「请求的操作需要提升」—— 改用 `ShellExecuteW` + `runas` 触发 UAC 提权,普通用户也能正常升级 - **更新弹窗版本号双 v**:tag 已含 `v` 前缀时不再重复添加,修复显示 `vv1.6.1` - **进度条先跳中间再从 0 开始**:点击更新时进度条会先跳到中间再回到 0 —— 下载进度 `pct` 为 null 时的初始宽度从 30% 改为 0% ### v1.6.1(2026-06-24) #### 🐛 修复 - 修复「更新内容」对话框泄露 CHANGELOG 头部 HTML 注释(不再把 `` 显示在更新日志里) ### v1.6.0(2026-06-24) 应用更新:自动下载安装 + 登录即检查。 #### ✨ 新增 - **自动下载安装更新**:发现新版本后点「立即更新」,App 后台下载安装包(带进度条)→「安装并重启」自动启动安装器并退出 App 接管安装;下载失败可回退浏览器手动下载 - **左下角更新提示卡片**:检测到新版本时左下角弹出「发现新版本 vX.X.X」卡片(带绿点),可忽略(按版本记忆),替代原先的弹窗提示 - **登录后自动检查**:每次登录进入主页后台静默检测新版本(网络超时 30s),替代原先的 24h 节流 ### v1.5.1(2026-06-24) 开源准备与维护性更新(应用功能无变化,二进制行为与 v1.5.0 等价)。 #### 🛠️ 优化 - **发布脚本网络重试**:上传 Gitee release 遇连接超时自动重试 3 次,发布更稳 - **开源仓库整理**:移除脚本里硬编码的个人 cargo 路径(改用 `%USERPROFILE%` / `$HOME`,跨机器可移植);代码注释中脱敏用户名/主机名 #### 🔒 安全 - 应用逻辑与密钥存储无变化;本次为开源前仓库整理 ### v1.5.0(2026-06-24) 版本信息展示 + 自动检测更新体系首版。 #### ✨ 新增 - **版本号展示**:侧边栏底部常驻显示当前版本号(如 `v1.5.0`),点击打开关于对话框;发现新版本时版本号旁出现青色提示红点 - **自动检测更新**:启动后台静默检测 Gitee 最新 release(每 24h 节流一次,避免频繁请求);发现新版本首次弹出「发现新版本 vX.X.X」提示并提供「去下载」(同一新版本只提示一次,后续仅留红点,不打扰);关于对话框内可手动「检查更新」并「去下载」跳转浏览器。检测走 Rust 后端 `reqwest`,不受前端 CSP 限制 - **更新内容展示**:版本升级后首次启动自动弹出更新日志(CHANGELOG);首次安装静默不弹(不打扰新用户);更新日志内置打包,离线可用、与已装版本对应 - **连接测试按钮**:新建/编辑连接对话框新增「测试」按钮,保存前即可验证 SSH/SFTP/FTP/本地终端能否连通(支持新建填表与编辑模式 keyring 取密钥、代理、15s 超时、防空密码触发锁号);测试与真实连接共用同一条拨号+认证+主机键 TOFU 路径,结果含耗时与认证方式,失败给出可读原因 - **AI 配置测试按钮**:设置 → AI 助手,「保存 AI 配置」旁新增「测试」按钮,用当前表单值(含未保存的 API Key)发起一次最小请求验证,无需先保存;空 Key 回退用 vault 已存的,200 视为通过并回显模型回复片段,失败给出接口状态码与截断错误 - **AI 助手输入框加高**:主页 AI 助手输入框由 2 行加高到 4 行(minHeight 96px),随便几个字不再溢出,多行提问更舒适 - **连接拖拽移动**:连接管理侧栏支持长按连接(600ms)拖到文件夹即移动归类;拖拽激活时列表切换为「只展示文件夹」视图(隐藏文件夹内连接),避免连接过多需下滑才能找到目标文件夹;ESC 取消、空白区/同文件夹不触发,点击/双击等既有交互不受影响;移动后自动展开目标文件夹 - **启动白屏消除**:主窗口启动时先隐藏,前端首帧绘制完成后再显示,应用启动到登录页之间不再有白屏 #### 🛠️ 优化 - **新建连接字体字段移到底部**:新建/编辑连接对话框的「终端字体(可选)」从靠前位置移到表单最底部,让连接名称 / 主机 / 端口 / 认证等常用字段优先露出,字体外观项靠后更顺 - **一键发布流水线**:新增 `打包` 触发的自动发版流程(bump 版本 + 生成更新内容 + 打包 + 上传 Gitee release),`scripts/publish-gitee-release.mjs` #### 🔒 安全 - 更新检测 HTTP 放 Rust 后端,**无需放宽 CSP**(前端 connect-src 保持锁定);打开外链命令强制校验 `http(s)://` 前缀;检测失败一律降级为「无更新」,绝不抛错到前端 ### v1.0.0 首个正式发布版本。 #### ✨ 新增 - **快捷命令**:支持「全局快捷命令」+「服务器专属快捷命令」两级管理,多行命令按行顺序一键执行;行首 `#` 注释与空行自动跳过;支持广播到多个终端同时执行 - **结构化诊断日志**:启动、SSH 生命周期、连接管理、快捷命令等关键路径落盘 `info`/`warn`/`error` 日志;按天滚动,默认保留 **7 天**,启动时自动清理超期日志;支持 `RUST_LOG=myshell=debug` 动态提级 - **全新应用图标**:Aurora Prompt `>_`,OLED 暗底 + 极光辉光 + 靛蓝→青色品牌渐变,与应用视觉语言统一(源文件 `src-tauri/icons/source-a.svg`,可一键重新生成全套尺寸) #### 🎨 优化 - 连接管理侧栏交互重设计:新建按钮统一为渐变主操作、展开/收起改为圆形「边缝手柄」搭配旋转指示箭头 - 暗黑/亮色主题、终端在线/离线/异常状态指示、连接失败一键重连、连接模糊搜索、文件夹快速选择等体验打磨 #### 🔒 安全加固(延续 0.x) - PBKDF2-HMAC-SHA256(600k 迭代)密钥派生、AES-256-GCM 数据加密、SSH 主机键 TOFU、CSP 白名单、OSC 52 防护、密码错误锁定等 --- ### v1.2.x 本地终端与体验增强。 #### ✨ 新增 - **本地终端**:直连本地 PowerShell / CMD / WSL / 自定义 shell,作为可保存的连接,体验等同 SSH 终端;支持「启动命令」开 tab 自动执行 - **终端字体选择**:从系统已安装字体下拉选择(非手输),默认字体栈 Nerd Font 优先渲染 Powerline / 图标字形;支持按连接单独覆盖字体 - **安装器数据删除二次确认**:卸载/更新勾选「删除应用数据」时弹危险提示 + 二次确认(默认「否」),并改用直白文案,防误删全部连接 / 密码 / 历史 / 密钥库 - **以管理员运行**:设置面板可一键以管理员重启 MyShell(Windows UAC 授权),重启后所有本地终端获得管理员权限;自动检测并展示当前权限状态。本地终端继承 MyShell 权限,需管理员命令时整体提权重启即可(单连接提权受 ConPTY + UAC 完整性级别隔离限制) #### 🛠️ 优化 - 本地终端编码自适应:cmd / Windows PowerShell 5.1 启动自动切 UTF-8(中文系统不再 GBK 乱码),并向 shell 声明 `TERM` / `COLORTERM` 让提示符引擎完整渲染 - **对话框防误关**:设置 / 快捷命令 / 主密码 / 密码验证等弹窗,点击遮罩区域(操作框外)不再意外关闭,必须用关闭/取消按钮,避免误触丢失已填内容(行为与新建连接对话框一致) - **字体选择升级**:终端字体改为模糊搜索下拉——输入关键字(如 `nerd mono`)即时过滤、匹配片段高亮,自定义主题化下拉面板替换原生 datalist;支持 `↑↓` / 回车 / Esc 键盘导航,仍可手动输入任意字体名 ### v1.3.x 体验打磨与工程整理。 #### 🛠️ 优化 - **连接类型图标**:ssh / sftp / ftp / 本地连接图标改用 iconfont 字体图标(服务器 / SFTP / ftp / 电脑),替换原先跨平台渲染不一致的 emoji(🖥️ / 📁 / 📤 / 💻);侧栏、连接对话框、标签栏三处统一渲染,颜色按类型语义化(ssh 主蓝 / sftp 副青 / ftp 警告黄 / 本地次级灰) - **历史命令过滤**:仅由 a/d 字符组成的误触命令(如 "A"、"AD")不再进入历史命令 - **新建连接保存按钮悬浮**:底部「取消/保存」常驻可见,长表单无需滚到底即可保存 - **版本号单一源**:只需改 `Cargo.toml` 一处版本号,`tauri.conf.json` / `package.json` 自动同步(build 时) - **图标重生成**:用矢量源重新生成全平台图标,确保 exe / 安装器 / 各尺寸高清一致 - **本地终端输入错位修复**:修正终端列宽(cols)计算被容器 padding 污染的问题——承载 xterm 的容器在全局 `box-sizing:border-box` 下不应带 padding(会被 FitAddon 计入可用宽度、多算约 1 列),改为外层 wrapper 留内缩;本地 PowerShell / ConPTY 输入长命令时不再字符跳出界面、不再背景左移 - **本地终端输入错位修复(二)**:修字体异步加载导致列宽漂移——xterm 改字体后会重新测量单元格宽度却不重算 cols,现改为等字体真正加载完成(`document.fonts.ready`)再 `fit()` 并把正确 cols 同步给 PTY;避免 pwsh 的 PSReadLine 按过期列宽重绘输入行、把字符画进错误单元格(透明背景图下表现为"字符挤开背景") - **本地终端输入回卷错位修复(三)**:修终端与本地 PTY 的列数(cols)初始同步时机——PTY 以 80 列启动、PSReadLine 缓存后,若初始 resize(shell 未就绪时发送)被丢弃,后端会一直停在 80 列、与前端真实列数不符,导致输入超过 80 列时一方换行一方不换行、编辑行错位("背景左移"),换行后恢复;现改为首帧输出后多次延迟(0/250/600ms)把真实列数同步给 PTY,覆盖 PSReadLine/ConPTY 冷启动就绪窗口 ### v1.4.x AI 助手集成。 #### ✨ 新增 - **AI 终端助手**:右侧全局聊天栏(Cursor 风格),多提供商可切换(Claude / OpenAI / Ollama 本地)。四项能力:**命令生成**(自然语言→命令,一键插入终端)、**输出诊断**(选中报错或附带最近输出让 AI 排查)、**命令解释**、**服务器主动巡检**(预设只读脚本采集 CPU/内存/磁盘/进程/日志 + AI 流式健康报告)。流式回复 + Markdown 渲染 + 代码块复制/插入。API key 经主密码库(vault)AES-256-GCM 加密存储,AI 调用在 Rust 后端进行(key 不进前端)。支持**网络代理**(http / https / socks5,应对无法直连 Claude/OpenAI 的环境) #### 🔒 安全与健壮性加固 - **修复快捷命令类型漂移(线上 bug)**:命令历史/快捷命令的 IPC 字段统一为 camelCase,此前 `isGlobal`/`sortOrder`/`createdAt` 在前端读到 `undefined`,导致快捷命令分组错乱、排序失效 - **拒绝空密码 SSH 认证**:密钥库缺密码时返回明确错误,不再向服务器发送空串(避免触发账户锁定) - **文件读取 TOCTOU 加固**:私钥/背景图读取改为「打开一次 + 句柄取元数据 + 限长读」,杜绝路径二次解析被掉包绕过尺寸上限 - **回滚路径穿越防御 + 修复每次启动重复备份**:回滚版本号格式校验;回滚标记改写当前版本号(原 `X (rolled back)` 触发每次启动都备份) - **文件夹改名 LIKE 注入修复**:含 `%`/`_` 的文件夹名不再误匹配并改写其他连接的 `group_path` - **暴力破解锁定文件原子写**:`lockout.json` 改 tmp+rename,崩溃不再留半截文件静默重置计数 - **代理目标 host 校验**:拦截 `\r\n`/控制符,防 HTTP CONNECT 请求走私 - **其它**:`exec_once`/本地巡检输出加上限与超时防 OOM/卡死;`truncate` 步进 UTF-8 字符边界防 panic;FTP 时间格式改用 chrono;命令历史去重保留已置顶项;ZMODEM 下载路径防 `..` 逃逸 + 发送失败自动中止;多 tab 输入聚焦回归本 tab;AI 面板宽度持久化值 clamp;导入/导出密码失败即清零;自定义主题 hex 归一化 - **冗余清理**:删除未引用的 `PassphraseDialog` 组件、死导出(`lockVault`/`onSshExit`)、空 `forEach`、只写不读的 DOM 属性等 #### 🎛️ 体验优化(v1.4.1) - **广播去重**:同一个连接在两个 tab 同时打开并入广播组时,不再对同一台服务器重复发送按键(按连接去重,避免双执行) - **终端选区可见性**:修复选中文字几乎看不到选中色的问题(多主题选区透明度过低),现在选中范围有清晰的蓝底高亮 - **Windows 任务栏图标**:修复打包后任务栏显示默认图标(exe 图标正常但任务栏不对)——设置 AppUserModelID + 显式窗口图标,重新打包后任务栏/标题栏显示 MyShell 图标 - **连接排序**:侧栏文件夹下的连接已按名称(中文 locale)排序,确认无需改动 #### 🐛 修复(v1.4.2) - **SFTP 打开即报错修复**:连接后 SFTP 面板直接提示 `Read dir failed: No such file: No such file`。根因是初始路径用 `~`,而 SFTP 协议没有 shell、不会展开 `~`(把 `~` 当字面目录名),服务器上又没有该目录。改为后端用 SFTP REALPATH 把 `~` 解析成真实 home 路径后再列目录,新建/删除/重命名同步适配;从 home 进入子目录后地址栏自动显示真实绝对路径 - **编译阻断修复**:`Cargo.toml` 中 rusqlite 的 feature 拼写错误(`bundclaudled`,不存在的 feature)导致 cargo 全量编译失败,已改回正确的 `bundled` - **SFTP 点击目录报 "SSH session not found" 修复**:SFTP-only 账号(shell 秒退)连接后,shell 通道关闭会把整个 SSH session 连同连接句柄一起删掉,导致后续 SFTP 操作全失败。根因是 session 生命周期被绑死在 shell 通道上——russh 一条连接多路复用多个通道,shell 通道死 ≠ 连接死。改为 session 仅在显式断开时清理(shell 通道关闭只代表终端断开,不影响 SFTP 继续复用同一连接,行为与 FinalShell 一致);并修复关闭「已断开」标签页时后端 session 泄漏 - **SFTP 批量文件上传/下载**:工具栏新增「⬆上传」「⬇下载」按钮(仅 SSH 连接)。支持多选文件批量传输(本地→远端 / 远端→本地),覆盖已有同名单个文件,失败不中断整批;实时进度浮层显示当前文件、`i/N`、总进度条、错误列表。上传通过系统文件选择器选文件,下载先勾选远端文件再选目标本地目录 - **SFTP 连接不再误报「重连」**:SFTP-only / nologin 账户(登录 shell 立即退出)连接后不再弹出「连接已断开 / 重连」遮罩。根因是后端给 SFTP 连接也请求了交互 shell,nologin 账户 shell 秒退触发 `ssh_closed` 事件被前端误判为整条连接断开;改为 SFTP 连接跳过 shell 请求(SFTP 子系统本就独立于 shell 通道),只保留真·TCP 断开时的断连提示 - **SFTP 文件面板视觉统一**:文件夹图标/名称颜色改用与 SSH 终端一致的 accent 蓝(原为青绿色,与整体风格割裂);类型列去掉多色背景徽章改为纯文字标签降噪;文件图标精简、选中态整行高亮、行间距与全局缓动对齐——SFTP 与 SSH 标签现在视觉语言统一 - **FTP 连接日志与错误诊断**:FTP 连接失败原先后台无任何日志、且 `os error 10060`(TCP 握手超时)以裸字符串抛出,难以判断是 IP/端口填错还是网络不通。现在 FTP 连接全程落日志(按天滚动日志文件,与 SSH 对称),且 10060/超时类错误改写为中文诊断提示——指明这是网络可达性问题(防火墙/IP 端口/服务未运行)而非密码错误 --- ## 已知限制 - **中文输入法(IME)输入时终端会短暂左移**:这是 Windows ConPTY 对中文输入法预编辑串(composition string)宽度计算的[上游 bug](https://github.com/microsoft/vscode/issues/255285)(VS Code 终端同样存在,非应用层可根治)。字母 / 英文输入不受影响;输入法确认(空格 / 回车)后左移立即恢复。**缓解**:分段确认输入、避免单次超长拼音;待 Windows 更新修复 ConPTY。详见 `progress.md` 阶段 23。 --- ## 技术栈 | 层级 | 技术 | |------|------| | 前端框架 | Vue 3 + TypeScript + Element Plus + myui(统一界面框架) | | 桌面框架 | Tauri v2 | | 终端模拟 | xterm.js + FitAddon + WebLinksAddon | | 后端语言 | Rust | | SSH 协议 | russh + russh-sftp | | FTP 协议 | suppaftp | | 数据库 | SQLite (rusqlite) | | 加密 | AES-256-GCM + PBKDF2 | | 密钥存储 | OS Keyring (keyring-rs) | ## 项目结构 ``` myShell/ ├── src/ # Vue 3 前端(myui 组件库) │ ├── components/ # UI 组件 │ │ ├── App.tsx # 主应用入口 │ │ ├── Sidebar.tsx # 连接管理侧边栏 │ │ ├── TerminalPanel.tsx # 终端面板 │ │ ├── SftpPanel.tsx # SFTP 文件浏览器 │ │ ├── CommandBar.tsx # 命令历史栏 │ │ ├── SettingsPanel.tsx # 设置面板 │ │ └── ... │ ├── utils/ # 工具函数 │ ├── api.ts # Tauri 命令封装 │ └── main.tsx # 入口文件 ├── src-tauri/ # Rust 后端 │ ├── src/ │ │ ├── main.rs # Tauri 命令定义 │ │ ├── ssh.rs # SSH 连接管理 │ │ ├── sftp.rs # SFTP 文件操作 │ │ ├── ftp.rs # FTP 协议实现 │ │ ├── db.rs # SQLite 数据库 │ │ ├── vault.rs # 加密与密钥管理 │ │ ├── crypto.rs # 加密工具 │ │ ├── backup.rs # 版本备份 │ │ └── ... │ ├── Cargo.toml # Rust 依赖 │ └── tauri.conf.json # Tauri 配置 └── scripts/ # 构建脚本 ``` ## 界面架构与原型 - [统一界面架构设计](docs/统一界面架构设计.md):前端分层、状态域、设计令牌、浮层系统与渐进迁移方案。 - [统一应用主界面原型](docs/ui-prototype/index.html):可直接打开的高保真交互原型,包含收缩侧栏、全局顶栏、版本升级提示、亮暗主题、国际化、设置抽屉、右侧辅助区与响应式布局。 - [统一界面 Vue + MyUI 实现](F:/personalProject/MyUI/src/views/cases/unified-ui):MyUI 中的统一界面参考实现(五区壳层、命令面板、设置抽屉、升级弹窗、i18n、主题持久化)。 - [原型使用说明](docs/ui-prototype/README.md):区域职责、交互清单及复用到其他软件的方法。 ## 快速开始 ### 环境要求 - Node.js >= 18 - Rust >= 1.70 - pnpm/npm/yarn **Linux 额外构建依赖(用于打包 .deb):** ```bash sudo apt install -y \ build-essential pkg-config \ libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev \ libgtk-3-dev librsvg2-dev libglib2.0-dev libsoup-3.0-dev \ libsecret-1-dev libayatana-appindicator3-dev libdbus-1-dev ``` ### 安装依赖 ```bash # 安装前端依赖 npm install # Rust 依赖会在首次构建时自动安装 ``` ### 开发模式 ```bash # 启动开发服务器(热重载) npm run tauri:dev # 或 cd src-tauri && cargo tauri dev ``` ### 构建生产版本 ```bash # 构建桌面应用 npm run tauri:build # 输出位置:src-tauri/target/release/bundle/ # - Windows: nsis/MyShell_x.y.z_x64-setup.exe # - Linux: deb/MyShell_x.y.z_amd64.deb(apt 安装时自动拉运行时依赖) ``` **Linux 安装:** ```bash # 推荐:apt install 会自动解决运行时依赖(webkit/gtk/secret/ayatana) sudo apt install ./src-tauri/target/release/bundle/deb/MyShell_*_amd64.deb # 不推荐 dpkg -i:它不会自动拉依赖,缺库时会配置失败 # 若已用了 dpkg -i,补救:sudo apt --fix-broken install ``` ### 类型检查 ```bash # TypeScript 类型检查 npm run test:ts # Rust 编译检查 npm run test:rust # 同时检查 npm run test:compile ``` ## 配置文件 应用数据存储位置: | 平台 | 路径 | |------|------| | Windows | `%APPDATA%\myshell\` | | macOS | `~/Library/Application Support/myshell/` | | Linux | `~/.config/myshell/` | 配置文件说明: | 文件 | 说明 | |------|------| | `connections.db` | 连接配置数据库(加密) | | `vault.salt` | 密钥派生盐值 | | `vault.verifier` | 密码验证数据 | | `dek.enc` | 加密的 DEK(数据加密密钥) | | `vault.kdf` | KDF 算法与迭代数元数据(旧版本缺失,首次解锁自动生成) | | `lockout.json` | 密码错误锁定状态 | | `logs/` | 按天滚动的运行日志(`myshell-YYYY-MM-DD.log`,默认保留 7 天) | | `backups/` | 版本备份目录 | ## 快捷键 | 快捷键 | 功能 | |--------|------| | `Ctrl+Shift+T` | 新建终端标签 | | `Ctrl+W` | 关闭当前标签 | | `Ctrl+Tab` | 切换到下一个标签 | | `Ctrl+Shift+Tab` | 切换到上一个标签 | ## 开发说明 ### 添加新的 Tauri 命令 需要同步修改三个位置: 1. `src-tauri/src/main.rs` — 定义 `#[tauri::command]` 函数 2. 相关模块(`ssh.rs` / `sftp.rs` / `db.rs`)— 实现逻辑 3. `src/api.ts` — 添加 TypeScript 封装 ### 类型定义 共享类型(如 `ConnectionConfig`、`FileEntry`)需要在 Rust 和 TypeScript 两边定义并保持同步。 ## 许可证 MIT License ## 致谢 - [Tauri](https://tauri.app/) - 跨平台桌面应用框架 - [russh](https://github.com/warp-tech/russh) - Rust SSH 库 - [xterm.js](https://xtermjs.org/) - 终端模拟器 - [FinalShell](http://www.hostbuf.com/) - 设计灵感来源