Commit Graph
124 Commits
Author SHA1 Message Date
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
Bill ac43844f8a release: v1.0.21
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.21
2026-10-08 00:17:05 +08:00
Bill 2653ab1820 feat(i18n): tab auto titles follow the UI language
Titles are stored display text (layout templates, session snapshot,
broadcast registry), so a pane used to keep the wording of the language it
was opened in, and nextTerminalTitle could not even parse the number back
out of another language's pattern (numbering restarted, duplicates).

New pure module src/shared/terminalTitle.ts: resolution tries all four
languages' patterns, rendering uses the active one; i18n gains tFor(lang)
for off-language rendering. Workspace retitles auto-numbered local tabs in
place on language switch, snapshot restore and template apply; SSH panels
(user-typed connection names) are never touched. dockview's title-change
event propagates the new title to the broadcast registry and the snapshot
save with no extra wiring.

New test terminal-title.mjs (16 writer/reader language pairs, non-auto
title boundaries, gap filling); offline suite grows 17 -> 18.
2026-10-08 00:11:20 +08:00
Bill 9a46555fc1 docs: close out M11 in ROADMAP; AGENTS.md gains performance/security boundary notes
Test count 12 -> 17, dependency placement rule (main-only packages in
dependencies), and the new invariants: field-level subscriptions,
sftp row-height sync, localPathGrants admission, keyPath validation,
shared reservedAccelerator table, sftp per-op timeouts, explicit
webPreferences. Panel-title i18n fix deferred (5 consumers + persisted
data compat).
2026-10-07 23:12:33 +08:00
Bill eea40d87a6 build(deps): move renderer-only deps to devDependencies, shrink asar 98MB -> 8.1MB
Renderer code is fully bundled by Vite into out/renderer; externalizeDepsPlugin
only applies to main/preload, so renderer packages in 'dependencies' were
shipped twice. Moved to devDependencies: @xterm/*, antd, dockview-react,
react, react-dom, zustand. Kept in dependencies (imported by src/main):
@lydell/node-pty, ssh2, zmodem.js, font-list, electron-updater. undici is
now explicit (release.cjs/download-stats.cjs require it). Also dropped the
dead @xterm/addon-serialize (zero imports anywhere).

Verified: npm test 17/17 green, dist:dir builds, asar node_modules contains
only main-process deps, asarUnpack natives intact, win-unpacked smoke
(window, theme, pty spawn) passes.
2026-10-07 23:08:43 +08:00
Bill a0be827650 test(main): cover updater fallback, ipc sender guard, log sanitizer, sftp timeouts
- updater-fallback.mjs (82 assertions): GitHub probe fallback to Gitea,
  timeout budgets, in-flight check never stuck in 'checking'; updater.ts
  gains a setUpdateTimeouts test seam, electron-updater aliased to a stub
- ipc-guard.mjs (43): trusted-frame guard exercised through real
  registerIpc handlers with forged senderFrames; electron-stub now records
  registrations via globalThis so bundle and test share one instance
- log-sanitizer.mjs (71): CSI/OSC/charset state machine, alt-screen fold,
  byte-split fuzz equal to whole-chunk output; fixes a wrong comment
- sftp-timeout.mjs (39): per-op timeouts (metadata 30s, transfer chunk 60s,
  open 10s) evict half-dead channels with one retry, slow-but-progressing
  transfers untouched, late rejections never unhandled
- reservedAccelerators.ts: single pure isReservedAccelerator shared by the
  settings recorder and applyGlobalShortcut (the two tables had drifted —
  main now also refuses Ctrl+=/-/0/PgUp/PgDn legacy values); 56 assertions
- ssh-loopback.mjs loads the real ssh.ts via a bundle (50 assertions):
  TOFU pinning, fail-closed stores, auth gate, connect budget

Offline suite grows 13 -> 17. Renderer test framework evaluated: not
introducing vitest/jsdom; pure logic keeps being extracted and tested
through the existing bundle harness.
2026-10-07 22:57:16 +08:00
Bill 5ff311ea0f docs+chore: refresh README/STATE, cache electron in CI, lock chord by keycode, misc P3
- README: add lock-screen section, refresh test list (13 offline tests),
  updater fallback order, data locations, architecture tree
- STATE.md: v1.0.20, current release.cjs flow (no --skip-github), M11-M13
- ci.yml: actions/cache for the ~100MB Electron binary keyed on lockfile
- .gitignore: ignore .env.* but keep committed templates
- scripts/archive-releases.cjs moved in from tmp-test; KEEP_TAG is now a
  required CLI arg (a hardcoded default is how the wrong version gets wiped)
- lockShortcuts: isPanicLockChord matches input.code ('KeyL') so Dvorak and
  non-Latin layouts trigger Ctrl+L lock correctly
- settings: drop the dead single-option update-channel Select from About tab
- Workspace/App: memo(IconRail/LayoutFlyout), useMemo layoutMenu keyed on
  language, useCallback onOpenSettings; drop unused IconRail onSplit prop
2026-10-07 22:06:58 +08:00
Bill d22923aedd security(main): dialog-grant admission for local paths, explicit webPreferences
New localPathGrants.ts: an in-memory registry of paths the user picked in a
native dialog. Every check resolves realpath + stat at grant and use time;
Windows case folding; missing files, directories-as-files, devices and
symlinked parents can never pass. SFTP upload/download and zmodem send/
receive now refuse renderer-supplied local paths that were never granted,
returning the resolved path so callers never re-traverse a symlink. keyPath
is validated as a regular file <= 1MB before reading (a device node would
have blocked the UI thread forever). Tests inject a stub policy via
setLocalPathPolicy; production always defaults to the real registry.

Also: webPreferences now explicitly pins contextIsolation/nodeIntegration/
webSecurity instead of relying on defaults.

New offline test tests/local-path-grants.mjs (37 assertions incl. symlink
escape); offline suite grows to 13. i18n: 6 main.sftp/main.key error keys
in 4 languages.
2026-10-07 22:06:45 +08:00
Bill 9c75cdc7d4 perf(renderer): field-level settings subscriptions, file list virtualization, per-panel error boundary
- TerminalView: replace whole-settings subscription with five useShallow
  field groups; theme writes no longer refit every pane, and unrelated
  settings writes no longer touch xterm options at all. useResolvedTheme
  is now a shallow subscription + memoized lookup. TerminalHandle was dead
  (no caller ever passed a ref) — dropped forwardRef/useImperativeHandle
- FilePanel: fixed-row-height (24px) windowing above 200 entries, no new
  dependency (antd 6 ships @rc-component/virtual-list only transitively);
  per-row Dropdown kept. NOTE: .sftp-row is now box-sizing:border-box
  height:24px, keep in sync with ROW_HEIGHT in FilePanel.tsx
- PanelErrorBoundary wraps each dockview panel so a pane crash no longer
  unmounts the whole workspace (i18n: workspace.error.panelTitle/panelRetry)
- SshBottomPanel: memo(FilePanel) — sessionId is the only prop and constant
- TransferPanel: ref-held Map + version counter replaces per-event Map
  copies; memo rows skip unchanged entries
- MonitorPanel: ResizeObserver/canvas setup runs once, data updates only
  redraw
2026-10-07 22:06:31 +08:00
Bill 6c04f0e8c1 feat(theme): add background image dim scrim slider
New terminal.backgroundImageDim setting (0-90%, default 0 = off). A black
scrim layer sits between the background image and the xterm screen, so
bright wallpapers stay readable at any opacity: unlike the opacity slider
(which blends the image toward the dark dock base), the scrim darkens the
image while preserving its saturation, and the raised minimumContrastRatio
(4.5) keeps lifted text legible on top.

- settings: backgroundImageDim with deepMerge type-fallback sanitize
- TerminalView: render .term-bg-dim only when image set and dim > 0
- ThemeSettingsTab: slider follows the existing draft + onChangeComplete
  pattern (no settings writes while dragging)
- i18n: settings.theme.backgroundImageDim(+Desc) in zh-CN/zh-TW/en/ja
- AGENTS.md: document the third image-mode invariant
2026-10-07 21:24:27 +08:00
Bill e16c860c7a fix(theme): dim background image toward dark and lift text contrast in image mode
On light themes the pane base is near-white (--chrome-bg), so lowering the
background image opacity washed the wallpaper out to white instead of
darkening it, and the theme's dark foreground text became unreadable.

- terminal.css: in has-bg-image mode the dock gets a fixed dark base
  (#0d1117), so the opacity slider always dims toward dark regardless of
  theme
- TerminalView: raise xterm minimumContrastRatio from 1 to 4.5 (WCAG AA,
  same as VS Code's terminal default) while an image is set; xterm treats
  the transparent background as black luminance, so dark foreground colors
  are lifted to stay readable over the wallpaper. Also fix the option name
  (minContrastRatio is silently ignored; the real key is
  minimumContrastRatio)
- i18n: update backgroundImageDesc in zh-CN/zh-TW/en/ja
- AGENTS.md: document the two image-mode invariants
2026-10-07 21:02:14 +08:00
Bill f5acf26d1f docs: record this round's fixes in AGENTS.md; add download-stats script; plan M11 in ROADMAP 2026-10-07 20:44:46 +08:00
Bill 36627ee4b7 i18n: add keys for zmodem/startup/updater/sftp/template messages 2026-10-07 20:44:45 +08:00
Bill b7938de464 fix(ui): theme-derived sftp/monitor surfaces, transfer cancel button, dialog cleanup; drop dead autoWrap; gentler bg-image default 2026-10-07 20:44:31 +08:00
Bill fb65981bff fix(workspace): restore layout snapshot on failed template apply; inert late-mounted portals while locked 2026-10-07 20:44:30 +08:00
Bill ee667cdc2b fix(main): harden startup chain, updater/sftp timeouts, host-key guard, shell env scrub 2026-10-07 20:44:28 +08:00
Bill 7aca8c5cb0 fix(release): refuse channel downgrades; verify assets by sha512; harden .env parsing 2026-10-07 20:44:12 +08:00
Bill 46b76ebca7 fix(zmodem): finalize on sink errors, throttle progress, emit terminal events on detach 2026-10-07 20:44:11 +08:00
Bill 655c660607 fix(store): back up unparseable connections/commands files before rebuild 2026-10-07 20:44:10 +08:00
Bill 7438d84d89 Merge branch 'Dev_202609'
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-04 01:19:58 +08:00
954801926@qq.com d1376b7d1d chore: release v1.0.20
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.20
2026-10-01 21:56:24 +08:00
954801926@qq.com d04452cd7f fix(ime): pin @xterm/xterm 6.1.0-beta.304 for IME caret follow; sync lockfile root version in predist
CI / typecheck + test + build (windows) (push) Canceled after 0s
2026-10-01 21:28:07 +08:00
Bill 86f51df2e6 fix(lock): harden lock screen input paths
CI / typecheck + test + build (windows) (push) Canceled after 0s
- remove the application menu while locked (lockMenu.ts): Alt reveals the
  default menu and its mouse-clickable Reload/DevTools/Zoom items bypass
  before-input-event entirely; menu is rebuilt from the default template on
  unlock, startup-restored locks covered from initLockController
- extract the keyboard classification into pure lockShortcuts.ts
  (isLockBlockedShortcut/isPanicLockChord) with a table-driven test
  (lock-shortcuts.mjs, 29 cases) — the v1.0.17 lockout escaped CI because
  this decision lived inline in createWindow()
- reserve Ctrl+L in the global show/hide shortcut recorder: a global
  registration intercepts the chord at OS level and silently disables the
  panic lock
- skip auto-repeat keydowns in the panic-lock branch (held Ctrl+L on an
  unconfigured app re-read lock.json + settings.json per repeat)
- LockScreen: re-sync the cooldown clock on visibilitychange/focus/pageshow
  so a suspended renderer timer cannot leave the password input disabled
  past the real deadline
2026-09-30 00:38:57 +08:00
Bill f026400676 fix(release): GitHub publish survives partial runs and flaky proxies
CI / typecheck + test + build (windows) (push) Canceled after 0s
Skip assets a previous partial run already uploaded (the POST 422s on
duplicates, so a retry could never get past them), and retry transient
network errors on large proxied uploads.
2026-09-28 13:58:51 +08:00
Bill dd08f8054a chore: release v1.0.19
CI / typecheck + test + build (windows) (push) Canceled after 0s
v1.0.19
2026-09-28 13:39:27 +08:00