# 更新日志

遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)，版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。

`0.x` 阶段：**次要版本可能包含不兼容变更**（配置项与插件 API 仍可能调整），补丁版本只修缺陷。

## [Unreleased]

## [0.2.19] - 2026-11-01

### 新增

- **主机列表「资产化」**：
  - 行内**状态芯片**取代原来 10 秒后自动消失的测试文字。成功显示 `✓ 123 ms`，**5 分钟后变暗、30 分钟后回到「未测试」**（一次测量不是状态，陈旧值不该伪装成现状）；**失败留到下一次测试有结论为止**（失败是状态，不是快照）。
  - **「测试全部」**：批量测试，最多 3 并发，显示进度，带重入锁。
  - **巡检抽屉**：点芯片打开，显示系统、内核数、内存、磁盘、上次测试时间；抽屉内可「重新巡检」「测试连接」。
  - **收藏置顶**：行内星标切换，同一分组内收藏项排在前面。
- 新路由 `POST /api/uniterminal/profiles/inspect`：开一条临时连接跑只读采集命令（`cat` / `grep` / `who` / `df`），**用完即关、不入会话列表**，8000 ms 总时限，字段缺失只降级不报错。
- `Profile` 新增可选字段 `pinned`（旧存档读作未收藏，不改写原文件）。
- 状态芯片的两道时间闸门、收藏排序、抽屉格式化、并发控制都抽成**纯函数**并单测；
  采集脚本改成**单一来源**（`monitor.ts` 导出 `MONITOR_SECTIONS`，状态栏与巡检共用），并加了「不许再抄一份字面量」的锁。
- 用例数 **923 → 1027**（新增 7 个测试文件）。

### 工程

- 新增 **CI**（`.github/workflows/ci.yml`）：push / PR 到 `main` 时在 Node 22 与 24 上依次跑 `typecheck` → `test` → `build`。
- `pnpm-workspace.yaml` 声明 `strictDepBuilds: false`：`ssh2` 与其可选加速件 `cpu-features` 的构建脚本被 pnpm 默认阻塞，
  而 pnpm 会因此**以非零码退出**（本地与 CI 都中招，容易误判成"依赖装不上"）。只关掉「跳过构建即报错」，不放开任何构建脚本。

### 变更

- **行内的「测试」按钮删掉了**：它和芯片上的「未测试」读起来是两件事，其实指向同一动作，还把行撑宽约 40px。
  测试仍在三处可达——芯片（进抽屉）、行尾 `⋯` 菜单、工具条的「测试全部」。行内现在是 `星标 · 芯片 · 连接 · ⋯`。
- **收藏星标换成圆角描边的 SVG**（原来用 `★`/`☆` 字形，尖端太锐、不同机器胖瘦不一），收藏后染**琥珀色**；
  列表顶部新增**「收藏」汇总区**——收藏的主机在那里随点随到，同时在它自己的分组里也保留一份（分组要完整）。
- 失败芯片不再显示后端的 `uniterminal: ` 前缀：那条前缀会把 92px 的芯片挤成 `✗ unitermi…`，
  剥掉之后留下的才是用户要的信息（截断上限仍是 8 字）。
- 私钥输入框的占位提示不再包含可被扫描器匹配的私钥签名（提示改为「粘贴私钥文件全文（含首尾 BEGIN / END 两行）」，指引不变）；
  `docs/SECURITY.md` 新增一节，逐条说明代码里三处私钥标记的合法用途（scrub 正则、测试假密钥、占位提示）。

### 修复

- **勾了「记住密码」再点「保存配置」，口令现在会立刻写进凭据库**（新路由 `POST /profiles/remember-password`）。
  此前口令只在**会话成功建立之后**才落库，「保存配置」只写档案却照样提示「已保存配置」——
  于是用户回头一测就是 `password required`（用户实报）。现在保存时同步写；写不进去会如实提示
  「配置已保存，但密码没写进凭据库：<原因>」，不再假报成功。
- **安装时会看到 `ERR_PNPM_IGNORED_BUILDS` 与退出码 1**：`ssh2` 的可选加速件 `cpu-features` 声明了构建脚本，
  pnpm 默认不执行它们、并因此以非零码退出。包其实已装好，但**自动化流程会把它当成失败、跳过 `dsh.profile.bundles` 登记**。
  README 的安装节与故障排查已写明：手动补登记那一行即可。插件侧无法消除（触发源在 `ssh2` 的依赖树里）。
- 两个凭据存储测试在 POSIX 上失败：它们用 `writeFile` 造「已存在的 `credentials.json`」，默认权限 0644，
  恰好被「权限过宽即拒绝加载」这条**正确**的安全行为拒绝。改为与该 store 自身写入一致的 **0600**。

## [0.2.18] - 2026-10-29

纯文档版本，**代码与 0.2.17 完全相同**。

### 文档

- README 新增**截图**（主机列表 / 终端 / 连接表单 / SFTP / 外观）：演示数据为 `demo01`–`demo03` 与 RFC 5737 文档段 `192.0.2.0/24`；
  图片经绝对 URL 引用，npm 页面同样能显示。
- 安装说明改为**一条命令**：`dsh plugin --profile <profile 名> add @winking-r/dsh-uniterminal@latest`；
  手工方式（`pnpm add` + 编辑 `dsh.profile.bundles`）作为备选保留。
- **已知限制去掉开发日志式条目**：划掉的旧问题、「已解决（M4-x）」、里程碑编号、"已在真实服务器验证"这类记录都不再出现在用户文档里；
  只保留用户实际会遇到的行为，凭据细节统一链到 [docs/SECURITY.md](docs/SECURITY.md)。
- [SECURITY.md](docs/SECURITY.md) 同步去掉里程碑编号与历史叙述，改为陈述当前行为。
- 新增 [CONTRIBUTING.md](CONTRIBUTING.md)：源码断言的约定、DOM 测试模板、CSS 契约。

## [0.2.17] - 2026-10-29

### 修复

- **行尾「更多操作」按钮的菜单被面板右边缘裁掉**：锚点靠右时菜单仍向右伸展，伸出面板后被宿主的
  `overflow` 裁掉，「移入分组…」「测试连接」只显示半截。现在锚点过半宽时改为**右对齐、向左展开**；
  鼠标右键、`Shift+F10`/菜单键、「⋯」按钮三条入口共用同一套判定（`src/client/menu-anchor.ts`）。

### 文档

- 新增 `CONTRIBUTING.md`：源码断言的约定（改 CSS/文案要同步更新断言、不要删断言）、
  DOM 测试模板（`// @vitest-environment jsdom` + `afterEach(cleanup)`）、CSS 契约、
  以及**禁止用固定字符数切源码**这条踩过两次的坑。
- README 补「右栏承载」一节：装了 `DSH-better-sidebar` 优先注册到 `ctx.betterSidebar`，
  否则回落官方 `sidebarRightTabs`。

## [0.2.16] - 2026-10-29

首个公开发布版本（MIT）。

### 新增

- SSH 终端（xterm.js）、SFTP 文件管理、端口转发（`-L` / `-R` / `-D`）、跳板链、分组管理、外观设置。
- 一个侧边栏标签装多条会话，顶部会话栏切换；同一主机连两次显示 `#2`；刷新页面自动接回会话。
- **凭据交给操作系统密码箱**（Windows 凭据管理器 / macOS 钥匙串 / Linux Secret Service），
  插件自身不实现任何加密；只有机器没有系统密码箱时才回落明文文件（0600 + 原子写），并在界面如实说明。
- 失败提示区分 7 类原因（超时 / 拒绝 / DNS / 不可达 / 主机指纹 / 认证 / 未知）并给出下一步动作；
  内部字段名不再出现在界面上（细节只进 diag）。

### 无障碍

- 右键菜单与确认弹框：打开即聚焦、方向键/Home/End、`Tab` 焦点陷阱、关闭后**把焦点还给触发元素**。
- 提示条改为常驻 live region（成功 `status/polite`、失败 `alert/assertive`），读屏能听见错误。
- SFTP 文件行支持键盘选中（`aria-pressed`）；主机行「连接 / 测试」的可访问名带主机名。

### 设计

- 引入 token 层（字号 13/14/16 三级阶梯、圆角 4/6/10/999、灰阶与遮罩、语义色单一来源）。
- 内联样式收敛 66%（541 → 182 条声明）；重复选择器 4 组 → 0 组。

### 质量

- 严格 TypeScript（`strict` + `noUncheckedIndexedAccess`）：`:any` 与 `@ts-ignore` 均为 0。
- 64 个测试文件 / 915 个用例（含 jsdom 真实交互用例）；`pnpm audit --prod` 零已知漏洞。
- `prepublishOnly` 强制跑 typecheck + test + build，过不了发不出去。

[Unreleased]: https://github.com/WinKing-R/dsh-uniterminal/compare/v0.2.19...HEAD
[0.2.19]: https://github.com/WinKing-R/dsh-uniterminal/compare/v0.2.18...v0.2.19
[0.2.18]: https://github.com/WinKing-R/dsh-uniterminal/compare/v0.2.17...v0.2.18
[0.2.17]: https://github.com/WinKing-R/dsh-uniterminal/compare/v0.2.16...v0.2.17
[0.2.16]: https://github.com/WinKing-R/dsh-uniterminal/releases/tag/v0.2.16
