Xuz
|
388a1aa68a
|
UI 测试按功能拆成模块:tests/ui.rs → tests/ui/
- 仍是一个测试程序(tests/ui/main.rs,cargo test --test ui),每个文件单独成测试程序会再链接一遍 GPUI
- 按功能分 11 个模块:host_dialog、host_tree、connection、terminal、workspace、settings、
sftp、transfer、forward、credential、update
- 两个以上模块共用的夹具和假实现放进 support/:mod.rs 是公共的 use、种子 id 和通用助手,
其余按终端、SFTP、端口转发、测试连接、凭据分文件;只有一个模块用的留在那个模块里
- 纯搬移,测试逻辑不变:147 个测试名称与搬移前一致,全部通过
- CLAUDE.md 写明模块划分和新测试该放哪里,AGENTS.md、README 改路径
|
2026-10-01 14:53:33 +08:00 |
|
Xuz
|
ef83812f45
|
表结构发布前重构,「会话」在代码和数据库里统一改名为 Host
- 数据库升到第 13 版:主机的登录、连接方式、代理和备注合进 hosts 一行,只有一对多的跳板、书签和端口转发单独成表;全部表改为 STRICT,并用 CHECK 写明约束;用凭据的主机不再冗余存用户名,凭据外键不再级联,在用的凭据删不掉
- 表名 sessions → hosts、session_jumps → host_jumps,session_id → host_id,地址列 host → address;schema 比对去掉排版,以后加字段可以直接 ADD COLUMN
- 删除开发期的历史迁移代码:版本 1–12 的库直接拒绝打开、不动文件
- 代码里 Session / SessionId / SessionStore 等改为 Host*,模块 session/ → host/,Host.host → Host.address,菜单命令与界面元素 id 同步改名
- 外部 CLI 的参数、JSON 字段和错误码改为 host(host_not_found),协议版本升到 2
- CLAUDE.md、AGENTS.md、README 与 Agent skill 同步更新
|
2026-10-01 14:04:30 +08:00 |
|
Xuz
|
f0690fe6b2
|
在线升级:后台检查、下载并在重启或退出时安装新版本,发布流水线与应用图标
- 新增 update 模块:从 dl.shellrs.com 取已签名的更新清单(minisign,签名绑定通道和版本),
按大小和 SHA-256 校验安装包;下载可续传、可换镜像,走系统代理
- 按安装方式安装:macOS 整包交换并核对开发者签名,Windows 静默运行安装程序,Linux 覆盖 AppImage;
开发构建和无法自更新的安装只提示前往下载页
- 设置新增「关于」:版本信息、检查更新、下载进度和「自动检查并下载更新」开关;
新版本就绪后标题栏右上角提示,更新对话框写明重启会中断什么;退出时自动安装,新版本启动后提示已更新
- 数据库拒绝打开更新版本建的库,迁移已有的库之前先备份成 shellrs.db.v<旧版本>.bak
- 新增 release workflow 和 packaging 脚本:universal macOS 包签名公证、Inno Setup 安装程序、
AppImage、上传 R2、生成并签名更新清单;新增 CHANGELOG.md
- 应用图标放在 assets/logo;开发模式下 macOS Dock 显示 logo,Windows exe 嵌入图标
- 修正 AppImage 里 shellrs 命令链接到临时挂载点;启动时刷新已安装但过期的 Agent skill
- 新增清单、验签、下载、各平台安装器和界面的单元测试与 UI 测试
|
2026-10-01 12:33:01 +08:00 |
|
Xuz
|
d6d052de9e
|
凭据(密码 / 密钥 / SSH Agent),主机的认证方式分「手动输入 / 使用凭据」
凭据
- 标题栏「ShellRS」后面加第三个图标「凭据」,侧栏的第三个列表:搜索、
↑↓ 与回车编辑、双击编辑、右键编辑 / 删除,空列表里有「新建凭据…」
- 三种:密码(用户名 + 密码)、密钥(用户名 + 本机私钥文件路径 + 口令)、
SSH Agent(用户名)。凭据带用户名,改了之后用它的主机一起变;改用户名、
类型或私钥文件会让已连接的主机重连,只改名称不会
- 密码进钥匙串,账户名 credential:<随机 keychain_id>,不用会被复用的数字
id;口令照旧按私钥文件归属
- 删除仍在用的凭据先确认并写明台数,那些主机改成「手动输入 · 自动」、
保留用户名,已打开的连接不断开,凭据的密码随之删掉
- 库升到 v9:新增 credentials 与 session_credentials 两张表(不给 sessions
加列,ALTER TABLE 会破坏「升级后与新库逐字相同」),迁移改成按 STEPS
逐级升级
主机对话框
- 「认证方式」改为「手动输入 / 使用凭据」单选。手动输入原样保留
自动 / 密码 / 私钥文件;使用凭据时选凭据,用户名和秘密都来自凭据,
「测试连接」读钥匙串里凭据保存的密码
- 密码、私钥文件、口令三个字段连同异步预填和 secret_change 抽成
session::SecretFields,主机和凭据两个对话框共用
- 地址与端口同一行的四列布局
登录
- 新的 SessionLogin:store 在 UI 线程查好凭据生成的登录快照,终端、SFTP、
端口转发的 provider 和外部 CLI 的 CliTarget 都改收它;主机和凭据的修改
按前后快照是否相等决定是否重连
- SSH Agent 凭据只走 agent,连不上、没有钥匙、服务器都不接受时明确报错;
agent 位置可注入(AgentLocation),Windows 接 OpenSSH Agent 的命名管道,
手动的「自动」也走同一个 connect_agent
- LoginTest 分 typed(表单说了算)和 saved(读钥匙串)
测试
- 单元:凭据模型、登录快照、v8→v9 迁移、store 的凭据接口与用户名同步、
删除规则
- 协议:密码凭据只读自己的钥匙串条目;进程内 russh agent 服务端覆盖
Agent 登录成功和几种失败
- UI:侧栏切换、新建 / 编辑 / 删除凭据、类型决定字段、主机使用凭据、
测试连接、终端拿到的登录、改用户名重连;新建主机的校验测试改为等待
错误行出现(对话框滑入时它在最底下一行)
文档:README 新增「凭据」一节;CLAUDE.md 同步架构和不变量,并更正
转发对话框「选完主机移走焦点」的描述(代码里从未有这个处理)
|
2026-10-01 07:45:58 +08:00 |
|
Xuz
|
837ccb7f89
|
端口转发(本地 / 远程 / 动态),「会话」改称「主机」,同一数据目录只运行一个实例
端口转发
- 标题栏「ShellRS」后面两个图标切换左侧栏:主机列表 / 端口转发列表。
侧栏是一个面板(workspace::Sidebar)里的两个列表,「设置」页脚两边
都有;有转发在跑时图标旁显示数量
- 三种转发:本地(direct-tcpip)、远程(tcpip-forward)、动态(手写的
SOCKS5 / SOCKS4 / 4a)。每条规则经由一台已保存的主机,启动时自己建
一条 SSH 连接,不计入主机的连接状态,「断开连接」不停它;删除主机或
分组连同规则一起删,确认框写明数量
- 本地 / 动态转发先监听再登录,端口被占用在任何问答之前就报出来;
断线后按 1、3、10 秒自动重连三次,重连不弹问答;断线靠 SSH 处理器被
丢弃来发现
- 规则和主机同库:schema 升到 8,新增 forwards 表和 7→8 的迁移步骤
- 列表:搜索、启停按钮、状态(连接中 / 运行中及连接数 / 重连 / 失败
原因)、右键菜单、↑↓ 与回车;规则可设「启动 ShellRS 时自动开启」
- 配置对话框:一行三张类型卡片、随表单填入地址的示意图、一句话说明
和一直循环的流向动画(gpui-kit 的 animate_keyframes)。示意图里的
服务器按角色叫「SSH 服务器」;「经由主机」默认留空;远程转发填了非
回环地址时提示服务器要设置 GatewayPorts
- 测试:进程内 russh 服务器加回显服务驱动真实工作线程(protocol_tests),
UI 测试注入 FakeForwardProvider
界面文案
- 左侧列表里保存的一项从「会话」改称「主机」(量词「台」),主机对话框
里填 IP / 域名的字段改叫「地址」;代码标识符仍是 Session,外部 CLI 的
英文说明和 session_not_found 不变
- 所有对话框点外面不再关闭,只能用取消、关闭按钮或 Esc
单实例与启动
- 再次打开 ShellRS 时把已有窗口调到前面、新进程退出:启动图形界面前
先连外部 CLI 的套接字发 Request::Activate,不受「启用外部 CLI」开关
影响
- 修正两处启动即崩溃:数据库 / 设置读不出来、外部 CLI 启动失败时,在
窗口的 Root 挂上之前弹通知会 panic,改为 notify_once_open 延后
其他
- parse_port、confirm_delete 移到 shared/dialog.rs;SshConnector 增加
connect_forwarding 与 is_network_error
- README、CLAUDE.md、AGENTS.md 同步
|
2026-10-01 00:46:51 +08:00 |
|
Xuz
|
e3b5e20efe
|
程序改名为 ShellRS,命名空间改为 shellrs
- 界面显示名(窗口标题、标题栏、文案)改为 ShellRS
- crate、二进制、动作命名空间、线程名改为 shellrs
- 数据目录、数据库文件、SHELLRS_DATA_DIR、钥匙串服务名改为 shellrs;程序尚未发布,不保留旧名兼容代码
|
2026-09-25 10:49:37 +08:00 |
|
Xuz
|
23da7a6724
|
实现真实 SFTP 上传与 WinSCP 式断点续传
|
2026-09-16 10:32:50 +08:00 |
|
 XuzandClaude Opus 5
|
698b9ed925
|
主机徽章去掉描边,开始页也用它
- 去掉徽章的边框。加描边本来是防纯黑或纯白的品牌在同色主题下糊掉,
但那两个(Apple、AlmaLinux)用的是 foreground / background,跟着
主题翻转,天然高对比,描边是多余的。
- 徽章抽成 shared::HostMark,会话树和「最近连接」开始页共用一份。
尺寸走 Sizable:树里 small(20px),开始页默认 medium(32px),
照着那行两行文字的高度定的。尺寸和字号都用 rem 助手,跟着缩放走。
- 开始页原来那个通用服务器图标换掉了;空状态里的大图标保留,那是
插图不是主机标记。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ub6VpmWWAJB15MnYLT9G5
|
2026-09-12 17:13:33 +08:00 |
|
 XuzandClaude Opus 5
|
d8e41646ec
|
系统图标改成品牌色徽章
图标从 14px 提到 20px,加上该系统品牌色的圆形底。
- 品牌色用各项目公布的官方值,写在 host_os! 表里而不是渲染处;设计
规范禁止界面写死颜色,但留了「颜色本身即数据」这一档,品牌色属于
这一类。
- logo 一律白色,只有 Tux 和 OpenBSD 这两个黄色品牌换成黑色,判据是
WCAG 相对亮度,阈值取得比正文对比度要求高,因为几乎所有品牌都用白
标画自己的 logo。
- AlmaLinux 和 macOS 没有单一官方色,改用 foreground / background 跟
随主题,这也是 Apple 官方的画法。
- 徽章沿用 Avatar 的画法:主题圆角加一圈 border 描边。描边是纯黑或
纯白品牌在明暗两个主题下都还看得见的原因。
- 分组行和其他行用 plain_mark 占同宽槽位,否则标签对不齐。
- 未探测到的会话退回 muted 底色加名称首字,aria_label 也从那个字改成
「未探测到系统」,屏幕阅读器读一个孤零零的字没有意义。
顺带在文档里记下:GPUI 的 svg() 是单色遮罩,要彩色只能走 img()。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ub6VpmWWAJB15MnYLT9G5
|
2026-09-12 13:52:04 +08:00 |
|
 XuzandClaude Opus 5
|
321a65d842
|
探测主机操作系统并用它标记会话列表
每次连接成功后探测一次远端系统,会话树前面的图标换成对应的发行版
logo;没探测过或探测失败就画会话名的第一个字。
- 探测走一条独立的 exec 通道,跑 `uname -s; cat /etc/os-release`,
在主 IO 循环里和 shell 输出一起轮询,终端不会为此多等一个往返。
POSIX 那条毫无输出时(Windows 的 shell 就是这样)再问一次
`cmd /c ver`,仍认不出就放弃,会话保留原来的标记。
- 认 14 个发行版加通用 Linux、macOS、Windows 和三个 BSD。派生发行版
靠 ID_LIKE 兜底,Linux Mint 因此显示 Ubuntu。
- 结果沿 TerminalTransportEvent::HostOsDetected → 引擎 → TerminalView
→ TerminalPanel → 工作区 → SessionStore::set_host_os 这条链走,和
prompt 是同一套管线。os 列由 set_host_os 单独写,update_session 不
碰它,和 last_connected_at 一样。
- 图标是 assets/icons/os/ 下 20 个单色 SVG,取自 Simple Icons(CC0);
Windows 那个是自己画的四格,Simple Icons 已把微软图标下架。
- 加一步 V3 迁移补 os 列,这样已有的本地库不用删。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ub6VpmWWAJB15MnYLT9G5
|
2026-09-12 12:36:20 +08:00 |
|
 XuzandClaude Opus 5
|
f0d66c4f8b
|
用系统钥匙串保存 SSH 密码与私钥口令
会话对话框新增密码字段和私钥口令字段,填一次之后连接就不再弹认证框。
秘密存进系统钥匙串(keyring 4:macOS Keychain / Windows 凭据管理器 /
Secret Service),数据库里依然不出现任何秘密。
- 新增 secrets 模块:SecretRef 按 user@host:port 归属密码、按文件路径
归属私钥口令,所以会话改名、复制都不丢,同一把钥匙只问一次。
SecretStore 的方法全是阻塞的,只能在后台执行器或传输层工作线程上调用。
- SSH 认证在弹框前先查钥匙串;被服务器拒绝时退回弹框并说明原因,条目
保留不动,因为那是用户在对话框里填的。
- 写入的唯一入口是 SessionStore::save_secret,失败沿用 PersistFailed。
会话换端点或被删除时,用 password_in_use 判断旧条目是否还有人用。
- 对话框的预填是异步的,*_loaded 置上之前空字段不算「用户清空了」,
预填还没回来就点保存不会误删。
- 修正 CLAUDE.md / AGENTS.md 里「SSH 仍是 mock」的过期描述。
测试服务端原先对错误密码返回 UnsupportedMethod,russh 会因此摘掉密码
方式,真实服务器不是这个行为;改成 OpenSSH 那样拒绝但保留密码方式。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ub6VpmWWAJB15MnYLT9G5
|
2026-09-12 10:23:22 +08:00 |
|
 since2006andClaude Opus 5
|
6bec390ecd
|
用 SQLite 持久化会话与分组
会话和分组不再只活在进程里。`SessionStore` 带 `Context` 的 mutator 现在
「改内存 → 写库 → notify」,落到 `~/Library/Application Support/shellr/
shellr.db`(`SHELLR_DATA_DIR` 可覆盖目录)。内存仍是唯一事实来源:写库
失败只丢持久化、不丢用户的编辑,store 发 `PersistFailed`,工作区据此弹
错误通知,绝不静默吞掉。
分组从只读的种子数据变成真正的配置项:任意层级嵌套,可新建 / 重命名 /
改上级 / 删除,删除按外键 `ON DELETE CASCADE` 连同子分组和里面的会话一起
带走,确认框写明数量。会话因此可以不属于任何分组,渲染在树的根层级——
首次启动是空库,第一个会话必须能在还没有任何分组时建出来。
- rusqlite 0.40(bundled):同步写、WAL、外键、`PRAGMA user_version` 迁移
- `app/paths.rs` 解析数据目录;`dirs` 6 已在依赖树里,不增加编译量
- `Workspace::new` 改为外部注入 store:`main.rs` 从库加载,测试注入 seed
- `ConnectionState` 不入库;`last_connected_at` 入库,最近连接跨启动保留
- 新增 5 个 UI 测试,其中一个走真实写路径后用第二个连接读回同一个文件
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcMDBhETbHS7rEucBMAVvv
|
2026-09-11 22:32:10 +08:00 |
|
Xuz
|
3bceb8879d
|
初始化 shellr 项目
|
2026-09-11 20:41:07 +08:00 |
|