Bill
7bccd5303a
feat(workspace): 模式按钮双击收展侧栏
...
CI / typecheck + test + build (windows) (push) Waiting to run
图标栏的「终端工作区 / SSH 工作区」按钮新增双击手势:双击当前工作区
按钮展开/收起侧栏;单击(含双击另一个按钮)只切换工作区,侧栏不动。
判定逻辑抽成零 import 纯模块 modeRailGesture.ts,用浏览器原生
MouseEvent.detail 连击计数识别手势——detail=2 到达时 store 已被
第一击更新,故在 detail=1 时把「手势前模式」存入 ref 再比对。
新增 tests/mode-rail-gesture.mjs 表驱动测试(10 例),测试数 35→36。
2026-10-20 23:59:28 +08:00
Bill
eac4704e9e
docs(website): 更新站点至 v1.0.30
...
CI / typecheck + test + build (windows) (push) Waiting to run
Deploy website to GitHub Pages / deploy (push) Waiting to run
- hero 下载按钮/版本号、spec 版本号、下载表文件名与直链改为 1.0.30
- 更新日志新增 1.0.30、1.0.29 两节,按规则裁到最近 5 条
- i18n.js 四语言块补齐新键并移除被裁版本(1.0.24 / 1.0.25)
- README 保留列表同步为实际内容
2026-10-20 15:12:56 +08:00
Bill
be243fd111
chore(release): v1.0.30 版本号与 CHANGELOG 四语同步
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.30
2026-10-18 10:17:36 +08:00
Bill
fc0d1afdce
feat(highlight): 主进程 ReDoS 校验闸门与 renderer 性能时间线
2026-10-18 10:09:07 +08:00
Bill
68fa46b2e3
fix(highlight): ReDoS 检测降级为编辑器提示(实测漏判,不可作拒绝闸门)
...
上一提交把 isReDoSProne 当作 compileRules 的拒绝闸门,声称"9/9 危险全抓"。
独立复查证伪了这个结论:
## 实测漏判 —— 危险规则仍会进热路径
| pattern | 静态检测 | 实测 |
|---|---|---|
| [(](a+)+$ | 放行 | 30 字符 4065ms |
| (?:a\|a)+$ | 放行 | 26 字符 7547ms |
| ((a\|a))+$ | 放行 | 24 字符 16212ms |
| (\w\|\d)+$ | 放行 | 26 字符 14451ms |
根因三条:外层扫描不跟踪字符类状态([(] 里的 ( 被当组起始)、遇到不闭合
组时 return false 让整个函数交白卷、分支比较只做字面相等抓不到语义重叠。
## 实测误判 —— 合法规则被拒
(?:a{2,3})+ 等把 {n,m} 范围重复当成 {n} 固定重复。
尝试修复后每修一处引入新问题(补字符类状态后又误杀 (?:\d{2})+ 与 ipv4
预设),证明手写正则语法扫描有本质缺陷。
## 三个替代方案均否决(有实测依据)
1. 运行时熔断(循环内查时钟):**原理上无效**。单次 exec 阻塞 28426ms,
时钟检查根本执行不到
2. re2:不支持 lookbehind,perm/okstate/http 三条预设依赖它
3. Worker + 超时:**可靠**(6/6 危险全抓、806ms 内 tick 51 次主线程未阻塞)
但往返 0.11ms/块 vs 直接 0.035ms,且终端高亮必须同步(WriteBatcher 消费
同步染色结果)——只适合规则的异步校验,不适合热路径
## 本次改动
- compileRules 不再因 isReDoSProne 跳过规则:拒绝闸门会静默禁用合法规则
(已证实会误杀)却仍放进危险规则(已证实会漏判),两头都不对
- isReDoSProne 保留给编辑器提示:漏判不比改动前差,误判只是多一个警告而非
禁用功能
- 注释与 AGENTS.md 如实标注"只有提示没有根治",并记录三个方案的否决理由,
避免后来者重复踩坑
热路径的实际边界仍是 MAX_LINE_LEN(>4KB 行不进用户正则)+ MAX_PER_RULE。
真正的解法(Worker 异步校验 + 存盘前把关)列为未完成项。
2026-10-17 23:19:19 +08:00
Bill
c6aca15134
fix(highlight): ReDoS 改用静态结构分析根治;fit 加耗时埋点
...
## ReDoS:从「限制损害」改为「阻止发生」
原防线(MAX_PATTERN_LEN 限幅 + 编辑器实跑探测)都拦不住真正的灾难性回溯:
`(a+)+$` 配 30 个字符实测 8.2 秒,而 MAX_LINE_LEN=4KB 限的是长度不是回溯成本。
两个候选方案都被实测否决:
- re2:不支持 lookbehind,会废掉 perm/okstate/http 三条依赖它的预设——
治了病废了功能
- Worker + 超时:往返开销 0.11ms/块(直接执行 0.035ms,4.1x),且终端高亮
必须同步(WriteBatcher 消费同步染色结果),异步化会打乱 HighlightStream
的 carry/flush 语义
采用静态结构分析 isReDoSProne():编译期扫描两种可证危险的形状——嵌套量词
((a+)+ / (.*)* / ([a-z]+)*)与同分支重复((a|a)*),命中即拒绝该规则,
不进编译集,永远到不了热路径。开销是纯字符串遍历。
关键细节:
- 有界量词不算危险:(?:\d{1,3}\.){3}(ipv4 预设)外层 {3} 固定重复,不会
指数回溯。只对 *、+、{n,} 这类开放式重复判定。曾因把 {n} 也算进去误杀 ipv4
- 断言组((?= (?<= (?<!)不是重复单元,跳过
实测 9/9 危险全抓、6/6 安全无误判、22 条出厂预设全部通过。编辑器改用同一
函数,警告在用户输入时出现而不是等预览卡住。
## fit 耗时埋点
stall 日志(10-14 至 10-17 每天 23-67 次,平均 27.5 秒,34/35 是渲染线程)
经查证是 v1.0.29 之前就存在的既有问题,与本轮改动无关。高亮引擎已排除
(512KB 仅 0.3ms)。
真正候选是 fit 的全量 reflow(代价正比 scrollback 行数),但通用 stall 看门狗
只会说「渲染层卡了」,不可行动。故给 scheduleFit 加耗时记录:超 200ms 写诊断
日志,含 cols/rows/scrollback。正常路径只多一次 performance.now()。
不盲改 reflow 逻辑——先有数据再优化。
2026-10-17 22:43:49 +08:00
Bill
cee616a23a
feat: 字体与高亮系统改进(CJK 对齐、ReDoS 防护、链接规则、崩溃类设置修复)
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
基于两轮专项调研(字体/高亮各两路,子代理实测探针交叉印证)实施的完整改进。
## 修复的真实 bug
**设置越界导致窗格永久死亡(用户报告)**
行高设 0.95 → xterm 构造/热更抛错 → 错误边界卸载整个 dockview 窗格;坏值已
落盘,每次重启都崩。根因是一整类缺陷:UI 允许值 / 配置能写值 与 xterm 硬约束
不一致,且主进程不校验。同类还有 scrollback<0(抛错)、cursorStyle 非法值
(更隐蔽:构造期被吞掉、只有热更期抛错,导致「重试」按钮永远无效、窗格死循环)。
修复:FONT_LIMITS/CURSOR_STYLES/RENDERER_MODES 收拢到 shared 层单一来源,
主进程加载时钳制 + 白名单化,healClampedFontSettings() 回写自愈;设置页
InputNumber、字体热键共用同一常量(照 LOCK_AUTO_DELAYS 先例,杜绝再次漂移)。
**perm 预设锚定失效**
^[-dlbcps]... 的 ^ 锚定的是「转义序列之间的 text run 起点」而非行首,ls -l
多行输出只有第一行权限位上色;带颜色的 ls(run 以转义切开)完全不触发。
改为 (?<=^|\s)[-dlbcps][rwxstST-]{9}(?![rwxstST-])——用负向前瞻而不是
(?=\s|$) 是因为后者会让带 ACL `+` / macOS `@` 后缀的真实 ls -l 输出不再染色。
旧 pattern 登记进 LEGACY_BUILTIN_PATTERNS,存量安装下次启动自动升级。
**高亮 span 吃掉应用自身 SGR**
wrap 固定追加 \x1b[0m,把应用设的颜色一并清掉。改为 SgrState 跟踪并重放。
四条护栏(每条都踩过坑,详见 AGENTS.md):
- reset 判定解析参数:ESC[00m/ESC[0;0m/ESC[0;32m(Go/Java 日志库常写)原先
被追加进累积器,逐行增长直到撞上限,之后所有 span 恢复永久失效
- 回放闸门按序列条数而非字节数:同一个"单个前景色"长度差近 4 倍,按字节卡
会砍掉真彩色却放过索引色
- 恢复串只插在可见间隙和最后一个 span 后:每 span 都重放会让 Kimi 这类全彩
TUI(~19 span/行)把 9.5KB 输出膨胀到 40.8KB(4.30x),渲染线程实测卡
18.4 秒。现为 3.05x 且长间隙着色正常
- 基准测试守门(膨胀 < 3.2x),改参数必须重跑
**CSI 私有参数导致整行失去高亮**
ESCAPE_RE 漏了 <>= 前缀与中间字节,\x1b[>4;1m(modifyOtherKeys)、
\x1b[<0;1;2M(SGR 鼠标)、\x1b[=1;1$y(DECRQM) 让整行成含裸 ESC 的文本,该行
之后所有关键词失去高亮(vim/tmux 常发)。
**超长行拖垮整段高亮**:一条 >4KB 的行让整个 text run 失去高亮。改为逐行降级。
**统计「最后写入者赢」**:模块级 totals 被各 pane 覆盖,设置页数据在窗格间
跳动。改为按 pane 实例 UUID 聚合(不能用 sessionId——SSH 分屏同一 session 挂
两个 pane,正好复制该 bug)。
## 新增能力
- **CJK 对齐三件套**:@xterm/addon-unicode11@0.10 .0-beta.301(peer 恰好接受
锁定的 6.1.0-beta.304,升 xterm 必须同步重配)、rescaleOverlappingGlyphs、
cjkFontFamily 回退槽位。默认字体栈没有任何 CJK 字体,中文靠 Chromium 回退
到比例字体导致列错位
- **字体名引号包裹**:quoteFontStack() 逐段判定(含反斜杠转义——只转义 " 会
让尾部反斜杠把闭合引号转义掉,CSS 字符串不终止)
- **等宽徽标**:canvas measureText 逐字符采样,等宽排前
- **规则按行匹配**(lineAnchor → m flag)
- **命中提醒**(notify + onMatch 事件出口,60s 冷却,只显示规则名不显示原文)
- **可点击链接规则**(WezTerm hyperlink_rules 式,安全闸门在生成 span 时就
丢弃非 http/https 目标)
## 其它
- 主题语义变量改为单一命名体系:semanticVars() 键就是最终 CSS 属性名,字面量
键联合让拼错成为编译错误;删除 cssVarName()/semanticCssVars() 中间层
(自定义属性名大小写敏感,转换被绕过会静默回落到深色兜底值)
- 删除死代码:automaticFontFallback 与顶层 overviewRuler 在 6.1.0-beta.304
中均不存在,且移除了让任何伪造键都能通过 tsc 的 as 断言
- ReDoS 防护(MAX_PATTERN_LEN + 编辑器 backtracksBadly 实时探测)——注意这
只是止血,(a+)+$ 配 30 字符实测仍卡 8.2 秒,根治需把正则执行挪进 Worker
测试 29 → 32(新增 font-stack、link-rules),全部通过;AGENTS.md 已同步。
2026-10-17 20:23:56 +08:00
Bill
619e4ac57f
chore(release): package-lock 根版本对齐 1.0.29
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.29
2026-10-16 23:57:42 +08:00
Bill
2aeea53da1
chore(release): v1.0.29 版本号与 CHANGELOG 四语同步
2026-10-16 23:44:53 +08:00
Bill
81748e4470
fix(theme): 浅色主题标签强调色改为按 WCAG 加深(实测 4.0:1 -> 4.9:1)
...
浅色分支此前固定 mix(accent, #000 , 0.35),默认绿 #3fb950 得 #297834:在强调色
染过的激活标签底(≈#dae8df)上只有 4.0:1,低于 AA,用户自定义的浅色强调色还会
更差。改用 darkenToRatio(accent, chromeBg, 5.5)——对 chrome 底色保证 5.5:1,
落到更深的染色底上仍有 4.9:1。深色分支(mix 白 0.18)不动。
chrome.ts 新增 chromeBg 记录当前 chrome 底色(applyTabAccent 可能在
applyChromeTheme 之前被设置变更单独调用);#181818 是 pre-JS 深色默认值,
登记进 css-theme-vars 白名单(与 global.css 的 --chrome-bg 同值)。
2026-10-16 23:44:48 +08:00
Bill
3b86d62111
fix(theme): --ot-* 变量名 camelCase/kebab-case 不匹配导致浅色分支静默失效
...
CSS 自定义属性名大小写敏感,而 semanticVars() 的键是 camelCase、样式表读的是
kebab-case:chrome.ts 直接写 `--ot-${key}` 时,9 个多词变量(--ot-text-muted、
--ot-text-secondary、--ot-surface-raised、--ot-border-strong、--ot-success-fg、
--ot-danger-fg、--ot-warning-fg、--ot-info-fg、--ot-scrollbar-active、
--ot-focus-ring)从未真正生效,元素一律回落到 global.css :root 的深色兜底值——
浅色主题正是靠这些变量修可读性的,等于白改(--ot-text-muted 48 处引用仍是
#8a8a8a,白底 3.25:1;--ot-danger-fg 仍是 #f85149,3.15:1)。
- 键 `muted` 改名 `textMuted`(CSS 读的是 --ot-text-muted)
- 新增 semantic.ts 的 cssVarName()/semanticCssVars(),chrome.ts 只调用它们,
命名逻辑单一来源
- 新增 tests/ot-var-names.mjs:把「CSS 引用名 = JS 写入名 = :root 声明名」
三集合锁在一起(值测试看不出这类问题),已用「去掉转换」验证会失败
- AGENTS/STATE 同步该铁律;测试数 22/25 的陈旧计数修正为实际的 29
2026-10-16 23:29:03 +08:00
Bill
9e424138b5
Merge remote-tracking branch 'origin/Dev_20261001'
2026-10-16 23:10:29 +08:00
Bill
5bc91fd498
test(theme): 颜色字面量 fail-closed 守门(css-theme-vars)+ 基线清零;AGENTS/STATE 同步语义层与浅色主题铁律
2026-10-16 20:34:22 +08:00
Bill
beaa6f1f04
refactor(theme): SFTP/监控/设置/高亮/锁屏面板颜色语义变量化;MonitorPanel 图表色随主题明暗派生(canvas 需实色)
2026-10-16 20:29:53 +08:00
Bill
83384b7233
refactor(theme): 工作区/连接侧栏/命令面板颜色语义变量化(徽章文本按 -fg 分流)
2026-10-16 20:27:09 +08:00
Bill
606ee0fa02
refactor(theme): global/terminal 硬编码颜色收敛进 --ot-* 语义变量(含滚动条/阴影/浮层,铁律例外保留)
2026-10-16 20:25:35 +08:00
Bill
79bea68c13
fix(theme): 浅色主题 ANSI 调色板重做到 WCAG AA + MCR/bold 动态开关 + antd 算法随亮度切换;github-light 底色柔化 #f6f8fa
2026-10-16 20:23:33 +08:00
Bill
2136221f2c
feat(theme): 语义变量层基座 --ot-*(深色锁现值/浅色按 WCAG 派生)+ 表测试
2026-10-16 20:21:40 +08:00
Bill
0a7bdda2d3
docs(theme): 主题系统 A+B+C 改造设计文档与实施计划(含对抗性审查记录)
2026-10-16 20:20:04 +08:00
Bill
2b658520a4
fix(updater): 禁用注定失败的差量下载,修复更新下载两次;官网同步 v1.0.28(补 1.0.26/1.0.27)
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.28
2026-10-16 00:53:00 +08:00
Bill
cff5454346
feat(workspace): 标签关闭二次确认(终端/SSH 双开关 + 键盘 Backspace/Delete 误关拦截),v1.0.27
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.27
2026-10-15 10:35:20 +08:00
Bill
bca7033689
fix(terminal): 缩放/高频输出冻结修复(reflow 节流 + 写入批量化),新增诊断日志(7 天滚动 + 开关),v1.0.26
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.26
2026-10-11 09:52:39 +08:00
Bill
fd4f1a3956
docs(roadmap): 补录通道重传缺口(exe/blockmap 409 无删除重试路径)
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-10 17:02:35 +08:00
Bill
2027fa3310
fix(updater,i18n): 对抗性审查修复(1中 + 3低)
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
- [中] 手动检查不再丢弃「已下载」事实:runCheck('manual') 原来无条件清
抑制记录,导致下载完成后点「检查更新」会把关于页从「重启安装」退回
「下载」(包已在磁盘)。改为保留 downloaded 记录,只清 announcement
记账;测试 §19 补 manual-check 保持 downloaded 的口径(153 断言)
- website 首帧脚本:?lang= 的 decodeURIComponent 包 try/catch(畸形转义
会在 IIFE 内抛 URIError,跳过 html[lang] 与防闪标记,指定语言被静默
忽略);zh-Hant-TW/zh-Hant-HK/zh-Hant 按 BCP-47 语义判为繁体
(normalize 与 i18n-apply.js 双处同步)
- ZmodemOffers 是 App 兄弟节点,语言切换时父级 children bailout 不重渲染:
订阅 language 并以 tFor 显式翻译(事件回调内的 t() 保留)
- ROADMAP 补录对抗性审查推迟项(周期检查可被设置写入推迟、启动开关
即时生效语义、下载无整体超时、--channel-only/--skip-gitea 矛盾)
v1.0.25
2026-10-10 16:51:10 +08:00
Bill
7c2044fdf4
fix(i18n): 崩溃兜底页不再停留旧语言
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
ErrorBoundary / PanelErrorBoundary 是 class 组件(拥有错误生命周期),
不能用 hook 订阅 settings store;根边界还是 App 的父级,语言切换时
App 的重渲染传导不到它——崩溃兜底页因此停留在启动时的语言,恰好是
用户最需要读得懂的一屏。
修法:导出改为一层薄函数包装(订阅 language 传 prop),class 内部经
tFor(language, …) 翻译。错误边界行为不变(边界仍是 class、仍在
children 之上)。使用方(main.tsx / TerminalPanel)无需改动。
ROADMAP 已知待办补录两项 i18n 质量专项:zh-TW 用语统一(命令/指令、
口令/密碼 等)、ja 片假名长音符号统一(フォルダ/フォルダー)。
2026-10-10 15:35:56 +08:00
Bill
b344af4691
chore(release): v1.0.25
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-10 15:21:05 +08:00
Bill
b89f9c6c95
website: v1.0.25 — 四语言站点 + 更新下载与日志
...
- 单页 + 语言层:assets/i18n.js(147 键 × zh-CN/zh-TW/en/ja)+
i18n-apply.js(data-i18n / data-i18n-html / data-i18n-attr 三种挂键方式,
首帧前定语言,?lang= → localStorage → navigator → zh-CN)
- 导航栏新增语言切换;html[lang]、title、meta description / og:* 同步
- 版本号/下载直链 → v1.0.25;近期更新补 1.0.25 / 1.0.24,裁到 5 条
- style.css 仅追加(语言选择器样式 + 首帧防闪),既有规则零改动
- README 补语言层说明与发版清单
2026-10-10 15:18:50 +08:00
Bill
7a1b11dad7
fix(i18n): 日文布局菜单的分割标签仍是中文
...
ja 的 workspace.layout.splitRight/splitBelow 值为「水平分割/垂直分割」
(中文句式),改为日语 UI 惯用的「左右に分割/上下に分割」。zh-TW 的
「水平分割/垂直分割」是通顺繁体且与 zh-TW 全文件用词(分割)一致,保留。
2026-10-10 15:18:49 +08:00
Bill
402bf368fc
fix(i18n): 语言切换后 dockview/memo 组件不再停留旧语言
...
dockview 渲染的组件(面板内容/标签/header actions)不在 App→Workspace 的
重渲染路径上,React.memo 且 prop 恒定的组件也被挡住——它们的渲染期 t()
读模块级 current,不重渲染就停留旧值。日文界面下「+」按钮 tooltip、
SFTP 表头、搜索条等因此停留在中文。
修法沿用仓库既有惯例:组件自己订阅 settings.system.language,渲染文案改
tFor(language, …)(显式语言,不依赖模块级状态)。共 8 文件 145 处:
- TerminalTab / SshHostBadge / TerminalPanel / SshBottomPanel /
TabActions(+按钮)/ BroadcastToggleButton / BroadcastPopover
- FilePanel(memo,60处) / PermissionModal / 传输面板行 / MonitorPanel
- TerminalView:搜索条、右键菜单、工具栏 tooltip、粘贴确认、结束遮罩;
搜索命中提示改为「存标签、渲染期翻译」(消除 effect 闭包过期风险)
刻意不改:事件回调动作时构造的字符串(t() 在调用时刻已是新语言);
不给 DockviewReact 加 key={language}(会重挂载杀掉全部会话);
retitleAutoTitles 的存储标题机制保持不变。
2026-10-10 15:18:48 +08:00
Bill
c94e3358ea
test(updater): 覆盖调度、自动下载、同版本抑制与气泡
...
updater-fallback 从 82 扩到 150 断言(新增 11 节):周期节拍与关闭、重排、
启动检查只武装一次、并发检查共用同一 promise、自动下载开关、同版本去重、
换版本恢复、手动检查不被抑制、已下载状态保持(含不卡 checking 与
fetchHandled/downloaded 区分)、气泡的窗口可见性守卫。electron-stub 的
Tray 补 displayBalloon 记录、BrowserWindow.getAllWindows 可注入假窗口。
AGENTS.md 更新机制一节补录三条来源、注入式调度、自动下载、同版本抑制与
气泡守卫。
2026-10-10 13:36:55 +08:00
Bill
bf79036599
feat(settings): 更新开关的界面与四语言文案
...
- 系统设置页加「定时检查更新」下拉(选项由 UPDATE_CHECK_INTERVALS 白名单
生成,标签用 Record<UpdateCheckInterval, string> 保证漏项即编译错误)与
「自动下载更新」开关
- 关于页:后台自动下载完成时用 statusDownloadedAuto 文案,与用户手动下载
区分
- 四语言补齐 13 个键(含托盘气泡文案),已用 i18n parity 校验 617 键对齐
2026-10-10 13:36:54 +08:00
Bill
9cc856fc8f
feat(updater): 定时检查更新与后台自动下载
...
设置 → 系统新增两个开关:定时检查更新(从不/4/12/24 小时,默认 4)与
自动下载更新(默认关)。安装时机仍交给用户——绝不因下载完成自动退出,
autoInstallOnAppQuit 只覆盖用户自己退出时装上。
- runCheck(source) 统一三条来源(启动/周期/手动),UpdateState.scheduled
标记来源;已有在途检查返回同一 promise,避免 electron-updater 的去重把
来源标记记到错的调用方
- 周期调度器经 settingsStore.setUpdateScheduleApplier 注入(updater 已
import settingsStore,反向 import 成环);幂等重排,启动检查由
startupArmed 保证每进程只武装一次;所有 timer 带 unref
- 自动下载由 settings.autoDownloadUpdate 驱动,autoUpdater.autoDownload
保持 false(单一事实源在 settings);失败不重试,等下一周期
- 同版本抑制(actedRelease 单槽,actedFor 版本不同即替换):否则长开机
的应用每 4 小时重复弹气泡、重复走一遍 downloadUpdate;手动检查无条件
清空记录
- downloaded 与 fetchHandled 分开:前者仅在 update-downloaded 置位,用于
阻止后续 update-available 把状态从 downloaded 翻回 available(否则「关于」
页按钮会从「重启安装」退回「下载」)
- tray.notifyUpdate 弹 Windows 托盘气泡;非 win32 / 无 tray / 有可见窗口
都不弹
2026-10-10 13:36:53 +08:00
Bill
d3529bb9dc
chore(release): v1.0.24
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.24
2026-10-09 15:51:12 +08:00
Bill
12ee779040
test(renderer): 新增 cwd/链接/broadcast 纯函数表驱动测试
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
渲染层纯逻辑此前零测试覆盖。三个新测试直接 import .ts 源文件(Node
22.18+ 原生类型剥离,不经 esbuild bundle):
- terminal-cwd(69 断言):cdArgument 全部 shell 变体与 conemuCwd 载荷
- terminal-links(92 断言):findUrls 真实合同——尾随标点剥离、重叠
收敛、裸 host 补 scheme、36 条不变式
- broadcast-store(39 断言):broadcastFanOut 扇出与 pruneOnTargetLoss
(经 unregisterSession 间接覆盖)
2026-10-09 11:31:26 +08:00
Bill
64982993f3
build(scripts): 发布护栏 fail-closed 与 flag 语义;文档对齐
...
- release.cjs:assertNoDowngrade 的通道探测原先对网络错误/5xx/解析失败
一律放行(fail-open),旧分支发旧版本号撞上探测失败会覆盖 latest.yml
并让 pruneChannel 删掉线上更新版本的 exe。现仅通道真空(404)放行,
其余抛错中止发布;prune 前的探测保持 best-effort
- 新增 --skip-gitea-release(只跳 Gitea release、通道照常上传);
--skip-gitea 保持原行为但打印醒目警告;usage 补全 flag 语义
- 文档对齐:STATE.md(v1.0.23、19→22 离线测试、清除 MSI 描述、bundle
清单补全)、ROADMAP 补 M12/M13、ci.yml 与 AGENTS.md 测试计数、
AGENTS.md 补录本轮关键不变式(legacy 模板门控、SESSION_STATE/
pendingOpens、zmodem 背压钩子、主机密钥 TTL);.gitignore 清重复与
死条目
2026-10-09 11:31:25 +08:00
Bill
6a218ec6c0
fix(renderer): 界面与设置页一轮修补
...
- FilePanel 上传进度监听器组件卸载时清理(原先只在终态/reject 时 off)
- MonitorPanel:首采即失败时显示中断错误条,不再被 meta 门挡成永远
'采集中'
- HighlightImportExport:blob 下载延迟 revokeObjectURL(原先同步回收
会中止下载);FileReader 补 onerror
- HighlightTab 新建规则改 getState() 读法防 stale(对齐 replaceRule)
- ConnectionSidebar/CommandsPanel 三处删除/清空 handler 补 try/catch
与 message.error(原先失败静默)
- highlightIO 导入信封补 version 校验、kind 缺失不再放行
- i18n:补 settings.highlight.builtin.percent 四语言键(原先唯一缺失
的内置规则,非中文界面显示中文 note)
2026-10-09 11:31:10 +08:00
Bill
172cce1962
fix(stores): 配置文件形状不符先备份再回退;日志尾部同步落盘
...
- commands/connections/settings 三个 store 原先只对 JSON.parse 抛错做
.bak 备份,合法 JSON 但形状不符(如 [1,2,3])会静默回退空/默认,下次
写盘把命令库/书签凭据/自定义主题整体销毁。现统一为形状不符也先备份
(与 knownHosts 的 fail-closed 策略对齐),三个 store 测试补对应用例
- sanitizeRules 回退分支返回预设副本而非模块级共享数组引用,并在回退时
记录 warning(原先连警告都没有)
- 会话日志尾部:logStop 触发的最后一轮 flush 改同步落盘(在途异步写未
落地时由 drain 循环做保序的最终同步轮),before-quit 不再丢日志尾巴
2026-10-09 11:31:06 +08:00
Bill
e23010f950
fix(zmodem): 接收路径写背压;sftp 删除容忍 ENOENT;sysinfo 停止关流
...
- zmodem 接收:fs WriteStream 缓冲无上限,慢盘 + 快对端可把内存涨到接近
文件大小。write() 返回 false 时暂停喂入 sentry 的 ssh 流、drain 恢复;
touchActivity 只在写入被接受或 drain 恢复时计数,stall 看门狗不再把
'堆在缓冲里'当进展;finalize/detach 解除悬挂暂停
- sftp 删除路径 ENOENT 一律视为已删成功(文件已被他人删除/重复删除/
传输重跑后目标已消失),不再汇成假 delete failed;真错误仍报错
(tests/sftp-timeout.mjs 新增 5 断言含防过度吞错用例)
- sysinfo:exec 回调里 state.stopped 分支先 close 到手的 stream
2026-10-09 11:30:51 +08:00
Bill
81ac112dac
fix(main): PTY_EXIT 补偿查询、SSH 飞行连接登记与双窗口守卫
...
- 新增 SESSION_STATE 查询通道(契约先行):PTY_EXIT 只广播一次不重放,
绑定晚于退出的窗格订阅后补查一次退出状态,快速退出的 shell 不再留下
永远空白、无死亡遮罩的窗格(退出码登记表上限 512 条 FIFO)
- openSession 在 connectSsh 返回前登记 pendingOpens(owner + onClient
最早引用),killPtysByOwner/killAllPtys 可中止飞行中的握手,renderer
崩溃后不再留下无主孤儿 SSH 会话
- whenReady 的 createWindow 加已有窗口守卫,堵住与 second-instance
showOrCreate 的双窗口竞态
- killAllPtys 补 replayBuffers.clear(),与 killSession 拆卸清单对齐
- promptUser 注释 30s 改为实际 120s;pty.ts 顺带注入 zmodem 背压钩子
(见下一提交)
2026-10-09 11:30:51 +08:00
Bill
0289dcbd1d
fix(workspace): 旧版布局模板不再误杀 SSH 会话
...
legacy(M6.1 前单 dockview)模板只喂 terminal dockview,成功路径却无条件
rebind 两个 dockview 并 kill 全部 previousSessions,SSH 活面板被降级为本地
终端、会话被静默销毁。成功路径改为按 sshTouched 门控 rebind、按 live 集合
过滤收尾 kill(与错误路径同一语义)。
另:handleApplyTemplate 加在途守卫(并发应用会互杀对方刚恢复的会话);
主机密钥队列加 120s TTL 清扫(主进程超时后不再广播,陈旧弹窗会永远占住
只渲染队头的队列),respondHostKey 移出 setState updater。
2026-10-09 11:30:34 +08:00
Bill
06cfc61392
chore: 对齐 package-lock 根版本号到 1.0.23
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-09 08:47:07 +08:00
Bill
e9e0f7592f
website: v1.0.23 — SFTP 列表改造、字体缩放与空白处右键菜单
CI / typecheck + test + build (windows) (push) Canceled after 0s
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
2026-10-09 08:38:32 +08:00
Bill
3ab4b50afb
chore(release): v1.0.23
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.23
2026-10-09 08:35:12 +08:00
Bill
6e7c9d5376
feat(sftp): 文件面板列头/排序、字体缩放与空白处右键菜单
...
- 列表头改为 sticky 并支持点击排序(名称/大小/修改时间/权限/用户/组,目录恒在前)
- 时间显示改为 YYYY/M/D HH:MM,大小显示改为 30.7 KB 风格
- 新增字体缩放 0.8–1.8(A-/A+ 与 Ctrl+滚轮),行高字号联动并记忆到 localStorage
- 行高/字号统一由 FilePanel.tsx 计算,经 CSS 变量下发,sftp.css 只消费变量
- 主进程新增 readdirDetailed + parseLongnameOwner,从 OpenSSH longname 解析真实的用户/组
- 列表空白处右键弹出菜单(行内右键仍走原菜单,两者不叠加)
- 修复:antd 把 ant-dropdown-trigger 克隆到行元素上,旧规则以更高特异性顶掉了 .sftp-row 的 display:grid,导致列此前并未按网格对齐
- 4 语言词典补充列名与缩放键
2026-10-09 08:33:06 +08:00
Bill
5602949a4f
website: dark-first redesign + SFTP 面板截图
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
- 全站深色(#0b0e12 + 终端绿),右上角可切浅色;两套主题共用 CSS 令牌
- 自托管字体:Space Grotesk(展示)+ JetBrains Mono(等宽),不再依赖系统栈
- 「核心能力」改为横向滚动卡片轨道(箭头翻页 / 拖拽 / 键盘方向键)
- 新增 SFTP 文件面板截图(含空白处右键菜单),IP 已打码
- 补 og:image / theme-color / skip-link / 焦点环 / 导航当前位置高亮
2026-10-09 00:46:35 +08:00
Bill
9e5e959f80
docs(readme): add screenshots & advantages section; fix stale facts (11 themes, 19 tests, MSI dropped)
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-08 14:19:22 +08:00
Bill
309de439e8
website: v1.0.22 — drop MSI, refresh screenshots (agents/themes/lock)
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
Deploy website to GitHub Pages / deploy (push) Canceled after 0s
- download: NSIS exe only, v1.0.22 links, update-source order GitHub-first
- features: 22 highlight rules, 11 builtin themes, bg dim layer
- new rows: AI Agent workspace, lock screen & security
- changelog: 1.0.22 / 1.0.21 / 1.0.20
2026-10-08 14:10:15 +08:00
Bill
a381d7be03
docs: warn about auto-created wrong-target tags in release flow
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-08 13:31:54 +08:00
Bill
14f5963706
build: drop MSI installer, NSIS exe only
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
electron-updater never supported MSI auto-updates; the exe is the only
installer from v1.0.22 on. release.cjs no longer expects/uploads the msi.
2026-10-08 13:25:01 +08:00
Bill
40336d014d
release: v1.0.22
...
CI / typecheck + test + build (windows) (push) Canceled after 0s
fix(ime): actually ship @xterm/xterm 6.1.0-beta.304 (v1.0.21 built from stale
node_modules with 6.0.0); add predist dependency-consistency gate
(scripts/verify-deps.cjs) and rename-retry shim for the AV scan EPERM race
v1.0.22
2026-10-08 13:09:13 +08:00