Xuz
|
48ac2b95aa
|
测试连接改为真实登录,结果以通知呈现
|
2026-09-24 22:38:22 +08:00 |
|
Xuz
|
6b1cd97317
|
通知层绘制在对话框之上
|
2026-09-24 22:37:54 +08:00 |
|
Xuz
|
fa87917d9c
|
标签栏显示 SSH 连接延迟
|
2026-09-24 22:37:18 +08:00 |
|
Xuz
|
4428237b25
|
标签页增加右键菜单与主机徽章,统一「…」菜单
|
2026-09-24 22:36:24 +08:00 |
|
Xuz
|
1af8d0df97
|
新建、编辑会话增加测试连接功能
|
2026-09-24 20:55:38 +08:00 |
|
Xuz
|
4b9dac8fb8
|
修复会话树右键后选中高亮残留
|
2026-09-24 19:05:15 +08:00 |
|
Xuz
|
47b2efdcc7
|
调整会话树展示并持久化分组展开状态
|
2026-09-24 18:55:37 +08:00 |
|
Xuz
|
b78aa7f937
|
实现会话树拖动排序并调整选中与连接交互
|
2026-09-24 18:27:47 +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 |
|
Xuz
|
05e05709f0
|
实现真实 SSH 客户端并支持多连接
|
2026-09-12 09:27:14 +08:00 |
|
 since2006andClaude Opus 5
|
5459fe0378
|
SFTP 标签页激活时接管焦点
中间区一次只渲染激活的那个标签页。会话的终端标签失活后不再渲染,焦点却
还留在它身上,句柄于是不在这一帧的派发树里——「×」用 window.dispatch_action
派发 CloseTerminal / CloseExplorer,动作没有落点就被丢掉,两个标签的关闭
按钮一起失效,⌘W 和其它快捷键同理。
ExplorerPanel::set_active 漏了接管焦点,TerminalPanel 和 LocalTerminalPanel
都有。补上,三个面板一致。
回归测试 both_tabs_of_one_session_stay_closable:连上 db-01,开 SFTP,先关
SFTP 再关终端,两次都得真的关掉。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TChp1yPThAzy3UcdXZcZA9
|
2026-09-11 23:42:39 +08:00 |
|
 since2006andClaude Opus 5
|
b0cb99f2bc
|
修复右键树节点时的无障碍焦点崩溃
gpui-component 的 ContextMenu 在 request_layout 里就把焦点抢给弹出菜单,
而树行是 uniform_list 在 prepaint 阶段才渲染布局的,于是焦点在一帧的中途
易主:树容器(被右键点击聚焦,且带无障碍角色)在这一帧更早的 prepaint 里
已经报告过自己是焦点节点,弹出菜单再报告一次就撞上 gpui 的断言
「set_focus called more than once in a single frame」。只在开了辅助功能的
调试构建里 panic,release 构建打警告。
把 .context_menu(..) 从每行挪到 #session-tree 容器上,容器走正常布局阶段,
焦点在 prepaint 开始前就定下来了。指针下的节点用 Rc<Cell<Option<SessionNode>>>
传递:容器在捕获阶段先清空,被命中的行在冒泡阶段写回自己——所有捕获处理器
都先于任何冒泡处理器,顺序有保证。gpui-kit 自带的 Table 也是这么挂的,所以
SFTP 文件列表一直没崩。
顺带:在行下方的空白处右键现在会出根菜单,以前没反应。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TChp1yPThAzy3UcdXZcZA9
|
2026-09-11 23:16:51 +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 |
|